https://github.com/python/cpython/commit/9e115b10151304de340a1721e960f4b773641133
commit: 9e115b10151304de340a1721e960f4b773641133
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2024-11-06T22:54:48+02:00
summary:

[3.13] gh-126489: Do not call persistent_id() for a persistent id in Python 
pickle (GH-126490) (GH-126514)

(cherry picked from commit 8fa4dc4ba8646c59f945f2451c53e2919f066065)

Co-authored-by: Serhiy Storchaka <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-11-06-13-41-38.gh-issue-126489.toaf-0.rst
M Lib/pickle.py
M Lib/test/test_pickle.py

diff --git a/Lib/pickle.py b/Lib/pickle.py
index 3d4c1a7c9841c1..550f8675f2c890 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -533,10 +533,11 @@ def save(self, obj, save_persistent_id=True):
         self.framer.commit_frame()
 
         # Check for persistent id (defined by a subclass)
-        pid = self.persistent_id(obj)
-        if pid is not None and save_persistent_id:
-            self.save_pers(pid)
-            return
+        if save_persistent_id:
+            pid = self.persistent_id(obj)
+            if pid is not None:
+                self.save_pers(pid)
+                return
 
         # Check the memo
         x = self.memo.get(id(obj))
diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py
index c84e507cdf645f..9ec2eb97147fae 100644
--- a/Lib/test/test_pickle.py
+++ b/Lib/test/test_pickle.py
@@ -224,25 +224,31 @@ def persistent_load(pid):
     def test_pickler_super(self):
         class PersPickler(self.pickler):
             def persistent_id(subself, obj):
+                called.append(obj)
                 self.assertIsNone(super().persistent_id(obj))
                 return obj
 
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
             f = io.BytesIO()
             pickler = PersPickler(f, proto)
+            called = []
             pickler.dump('abc')
+            self.assertEqual(called, ['abc'])
             self.assertEqual(self.loads(f.getvalue()), 'abc')
 
     def test_unpickler_super(self):
         class PersUnpickler(self.unpickler):
             def persistent_load(subself, pid):
+                called.append(pid)
                 with self.assertRaises(self.persistent_load_error):
                     super().persistent_load(pid)
                 return pid
 
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
             unpickler = PersUnpickler(io.BytesIO(self.dumps('abc', proto)))
+            called = []
             self.assertEqual(unpickler.load(), 'abc')
+            self.assertEqual(called, ['abc'])
 
 class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests, 
unittest.TestCase):
 
diff --git 
a/Misc/NEWS.d/next/Library/2024-11-06-13-41-38.gh-issue-126489.toaf-0.rst 
b/Misc/NEWS.d/next/Library/2024-11-06-13-41-38.gh-issue-126489.toaf-0.rst
new file mode 100644
index 00000000000000..8a6573cdea7b42
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-11-06-13-41-38.gh-issue-126489.toaf-0.rst
@@ -0,0 +1,3 @@
+The Python implementation of :mod:`pickle` no longer calls
+:meth:`pickle.Pickler.persistent_id` for the result of
+:meth:`!persistent_id`.

_______________________________________________
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