From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:54:48 +0000 (+0100) Subject: [3.13] gh-126489: Do not call persistent_id() for a persistent id in Python pickle... X-Git-Tag: v3.13.1~154 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9e115b10151304de340a1721e960f4b773641133;p=thirdparty%2FPython%2Fcpython.git [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 --- diff --git a/Lib/pickle.py b/Lib/pickle.py index 3d4c1a7c9841..550f8675f2c8 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -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)) diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index c84e507cdf64..9ec2eb97147f 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -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): 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 000000000000..8a6573cdea7b --- /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`.