]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-43907: add missing memoize call in pure python pickling of bytearray (GH-25501)
authorCarl Friedrich Bolz-Tereick <cfbolz@gmx.de>
Fri, 23 Apr 2021 21:27:14 +0000 (23:27 +0200)
committerGitHub <noreply@github.com>
Fri, 23 Apr 2021 21:27:14 +0000 (23:27 +0200)
Lib/pickle.py
Lib/test/pickletester.py
Misc/NEWS.d/next/Library/2021-04-23-20-57-20.bpo-43907.3RJEjv.rst [new file with mode: 0644]

index e63a8b6e4dbb7006cc1383f43b26e61b3c90db79..5ab312f2acaee6c2cfb32595c9a779fb5a98262c 100644 (file)
@@ -818,6 +818,7 @@ class _Pickler:
             self._write_large_bytes(BYTEARRAY8 + pack("<Q", n), obj)
         else:
             self.write(BYTEARRAY8 + pack("<Q", n) + obj)
+        self.memoize(obj)
     dispatch[bytearray] = save_bytearray
 
     if _HAVE_PICKLE_BUFFER:
index fd05e7af94a1a78df2a5fdeceddf361452557105..8e01d311360e35898679debf2c32614960581afc 100644 (file)
@@ -1853,6 +1853,14 @@ class AbstractPickleTests(unittest.TestCase):
                     self.assertNotIn(b'bytearray', p)
                     self.assertTrue(opcode_in_pickle(pickle.BYTEARRAY8, p))
 
+    def test_bytearray_memoization_bug(self):
+        for proto in protocols:
+            for s in b'', b'xyz', b'xyz'*100:
+                b = bytearray(s)
+                p = self.dumps((b, b), proto)
+                b1, b2 = self.loads(p)
+                self.assertIs(b1, b2)
+
     def test_ints(self):
         for proto in protocols:
             n = sys.maxsize
diff --git a/Misc/NEWS.d/next/Library/2021-04-23-20-57-20.bpo-43907.3RJEjv.rst b/Misc/NEWS.d/next/Library/2021-04-23-20-57-20.bpo-43907.3RJEjv.rst
new file mode 100644 (file)
index 0000000..7da3a1c
--- /dev/null
@@ -0,0 +1,4 @@
+Fix a bug in the pure-Python pickle implementation when using protocol 5,
+where bytearray instances that occur several time in the pickled object
+graph would incorrectly unpickle into repeated copies of the bytearray
+object.