Skip to content

Commit a8dd8e4

Browse files
serhiy-storchakamiss-islington
authored andcommitted
pythongh-126489: Do not call persistent_id() for a persistent id in Python pickle (pythonGH-126490)
(cherry picked from commit 8fa4dc4) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 83827ad commit a8dd8e4

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
@@ -533,10 +533,11 @@ def save(self, obj, save_persistent_id=True):
533533
self.framer.commit_frame()
534534

535535
# Check for persistent id (defined by a subclass)
536-
pid = self.persistent_id(obj)
537-
if pid is not None and save_persistent_id:
538-
self.save_pers(pid)
539-
return
536+
if save_persistent_id:
537+
pid = self.persistent_id(obj)
538+
if pid is not None:
539+
self.save_pers(pid)
540+
return
540541

541542
# Check the memo
542543
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)