From 86f41d5ee53a409c8e7f42fb7d44ef801cd4733b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?tonghuaroot=20=28=E7=AB=A5=E8=AF=9D=29?= Date: Fri, 18 Sep 2026 03:11:17 +0800 Subject: [PATCH] gh-154594: Fix deepcopy memo lookup when __deepcopy__ returns None (GH-154595) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * gh-154594: Fix deepcopy memo lookup when __deepcopy__ returns None * Use 'd in memo' lookup instead of a sentinel Addresses review: clearer, no sentinel, and the test treats memo as opaque. * Apply review suggestions: shorten NEWS, use class attribute in test --------- (cherry picked from commit 5539c2a5437acc4f4719aabac375368e0d310bd9) Co-authored-by: tonghuaroot (童话) Co-authored-by: Pieter Eendebak --- Lib/copy.py | 5 ++--- Lib/test/test_copy.py | 11 +++++++++++ .../2026-07-24-00-02-00.gh-issue-154594.Xk7mQ2.rst | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-07-24-00-02-00.gh-issue-154594.Xk7mQ2.rst diff --git a/Lib/copy.py b/Lib/copy.py index 6149301ad1389e2..f7fd680657b85a5 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -122,9 +122,8 @@ def deepcopy(x, memo=None): if memo is None: memo = {} else: - y = memo.get(d, None) - if y is not None: - return y + if d in memo: + return memo[d] copier = _deepcopy_dispatch.get(cls) if copier is not None: diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index 13b7ce29565deed..2a12a6737df1631 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -951,6 +951,17 @@ def m(self): self.assertIs(g.b.__self__, g) g.b() + def test_deepcopy_memo_none_result(self): + # Objects whose deepcopy result is None must still be memoized. + class C: + call_count = 0 + def __deepcopy__(self, memo): + C.call_count += 1 + return None + obj = C() + copy.deepcopy([obj, obj, obj]) + self.assertEqual(C.call_count, 1) + class TestReplace(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2026-07-24-00-02-00.gh-issue-154594.Xk7mQ2.rst b/Misc/NEWS.d/next/Library/2026-07-24-00-02-00.gh-issue-154594.Xk7mQ2.rst new file mode 100644 index 000000000000000..5f96bba97aa19f4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-24-00-02-00.gh-issue-154594.Xk7mQ2.rst @@ -0,0 +1,2 @@ +Fix :func:`copy.deepcopy` so that an object whose deep copy is ``None`` is +still memoized. Patch by tonghuaroot.