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

This commit is contained in:
Serhiy Storchaka 2024-11-06 22:25:14 +02:00 committed by GitHub
parent e56fd449fb
commit 8fa4dc4ba8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 4 deletions

View File

@ -548,8 +548,9 @@ class _Pickler:
self.framer.commit_frame()
# Check for persistent id (defined by a subclass)
if save_persistent_id:
pid = self.persistent_id(obj)
if pid is not None and save_persistent_id:
if pid is not None:
self.save_pers(pid)
return

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