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]

Reply via email to