Skip to content

Commit 9d5218c

Browse files
serhiy-storchakaebonnal
authored andcommitted
pythongh-126489: Do not call persistent_id() for a persistent id in Python pickle (pythonGH-126490)
1 parent fa27cd0 commit 9d5218c

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

Lib/pickle.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,11 @@ def save(self, obj, save_persistent_id=True):
548548
self.framer.commit_frame()
549549

550550
# Check for persistent id (defined by a subclass)
551-
pid = self.persistent_id(obj)
552-
if pid is not None and save_persistent_id:
553-
self.save_pers(pid)
554-
return
551+
if save_persistent_id:
552+
pid = self.persistent_id(obj)
553+
if pid is not None:
554+
self.save_pers(pid)
555+
return
555556

556557
# Check the memo
557558
x = self.memo.get(id(obj))

Lib/test/test_pickle.py

+6
Original file line numberDiff line numberDiff line change
@@ -224,25 +224,31 @@ def persistent_load(pid):
224224
def test_pickler_super(self):
225225
class PersPickler(self.pickler):
226226
def persistent_id(subself, obj):
227+
called.append(obj)
227228
self.assertIsNone(super().persistent_id(obj))
228229
return obj
229230

230231
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
231232
f = io.BytesIO()
232233
pickler = PersPickler(f, proto)
234+
called = []
233235
pickler.dump('abc')
236+
self.assertEqual(called, ['abc'])
234237
self.assertEqual(self.loads(f.getvalue()), 'abc')
235238

236239
def test_unpickler_super(self):
237240
class PersUnpickler(self.unpickler):
238241
def persistent_load(subself, pid):
242+
called.append(pid)
239243
with self.assertRaises(self.persistent_load_error):
240244
super().persistent_load(pid)
241245
return pid
242246

243247
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
244248
unpickler = PersUnpickler(io.BytesIO(self.dumps('abc', proto)))
249+
called = []
245250
self.assertEqual(unpickler.load(), 'abc')
251+
self.assertEqual(called, ['abc'])
246252

247253
class PyPicklerUnpicklerObjectTests(AbstractPicklerUnpicklerObjectTests, unittest.TestCase):
248254

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The Python implementation of :mod:`pickle` no longer calls
2+
:meth:`pickle.Pickler.persistent_id` for the result of
3+
:meth:`!persistent_id`.

0 commit comments

Comments
 (0)