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

(cherry picked from commit 8fa4dc4ba8)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-11-06 21:54:48 +01:00 committed by GitHub
parent 83827ad819
commit 9e115b1015
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 4 deletions

View File

@ -533,10 +533,11 @@ class _Pickler:
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))

View File

@ -224,25 +224,31 @@ class PyIdPersPicklerTests(AbstractIdentityPersistentPicklerTests,
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):

View File

@ -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`.