https://github.com/python/cpython/commit/658612ae770aac8e1e5e060922d3364a4be7e547
commit: 658612ae770aac8e1e5e060922d3364a4be7e547
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-09-13T12:11:07Z
summary:
gh-128509: Use bytes singletons in marshal (#157398)
Replace soft deprecated PyBytes_FromStringAndSize(NULL, n) with
PyBytes_FromStringAndSize(str, n) so marshal can get bytes singleton.
files:
A Misc/NEWS.d/next/Library/2026-09-13-07-14-35.gh-issue-128509.9F2GCE.rst
M Lib/test/test_marshal.py
M Python/marshal.c
diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py
index c595e8cf14f1e15..042cad03ce80e79 100644
--- a/Lib/test/test_marshal.py
+++ b/Lib/test/test_marshal.py
@@ -116,6 +116,14 @@ def test_bytes(self):
for s in [b"", b"Andr\xe8 Previn", b"abc", b" "*10000]:
self.helper(s)
+ @support.cpython_only
+ def test_bytes_singleton(self):
+ for version in range(marshal.version + 1):
+ for sample in [b"", b"x"]:
+ new = marshal.loads(marshal.dumps(sample, version))
+ self.assertIs(new, sample)
+
+
class ExceptionTestCase(unittest.TestCase):
def test_exceptions(self):
new = marshal.loads(marshal.dumps(StopIteration))
diff --git
a/Misc/NEWS.d/next/Library/2026-09-13-07-14-35.gh-issue-128509.9F2GCE.rst
b/Misc/NEWS.d/next/Library/2026-09-13-07-14-35.gh-issue-128509.9F2GCE.rst
new file mode 100644
index 000000000000000..7699242c8c647ea
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-09-13-07-14-35.gh-issue-128509.9F2GCE.rst
@@ -0,0 +1,2 @@
+:func:`marshal.load` and :func:`marshal.loads` can now get 1-byte string
+singletons. Patch by Victor Stinner.
diff --git a/Python/marshal.c b/Python/marshal.c
index 1897d700c055bd3..420c3ee115a7377 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -1388,16 +1388,12 @@ r_object(RFILE *p)
}
break;
}
- v = PyBytes_FromStringAndSize((char *)NULL, n);
- if (v == NULL)
- break;
ptr = r_string(n, p);
if (ptr == NULL) {
- Py_DECREF(v);
break;
}
- memcpy(PyBytes_AS_STRING(v), ptr, n);
- retval = v;
+ // Get a singleton for 1-byte string
+ retval = PyBytes_FromStringAndSize(ptr, n); // can be NULL
R_REF(retval);
break;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]