diff --git a/Lib/copy.py b/Lib/copy.py index fff7e93c2a1b89..d910b5494723f3 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -121,6 +121,7 @@ def deepcopy(x, memo=None): d = id(x) if memo is None: memo = {} + memo[id(memo)] = [] else: y = memo.get(d, None) if y is not None: @@ -159,7 +160,7 @@ def deepcopy(x, memo=None): # If is its own copy, don't memoize. if y is not x: memo[d] = y - _keep_alive(x, memo) # Make sure x lives at least as long as d + memo[id(memo)].append(x) # Make sure x lives at least as long as d return y _atomic_types = frozenset({types.NoneType, types.EllipsisType, types.NotImplementedType, @@ -209,22 +210,6 @@ def _deepcopy_method(x, memo): # Copy instance methods del d -def _keep_alive(x, memo): - """Keeps a reference to the object x in the memo. - - Because we remember objects by their id, we have - to assure that possibly temporary objects are kept - alive by referencing them. - We store a reference at the id of the memo, which should - normally not be used unless someone tries to deepcopy - the memo itself... - """ - try: - memo[id(memo)].append(x) - except KeyError: - # aha, this is the first one :-) - memo[id(memo)]=[x] - def _reconstruct(x, memo, func, args, state=None, listiter=None, dictiter=None, *, deepcopy=deepcopy): diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index 467ec09d99e462..1ea2540e875f6f 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -435,12 +435,14 @@ def test_deepcopy_reflexive_dict(self): def test_deepcopy_keepalive(self): memo = {} + memo[id(memo)] = [] x = [] y = copy.deepcopy(x, memo) self.assertIs(memo[id(memo)][0], x) def test_deepcopy_dont_memo_immutable(self): memo = {} + memo[id(memo)] = [] x = [1, 2, 3, 4] y = copy.deepcopy(x, memo) self.assertEqual(y, x) @@ -448,6 +450,7 @@ def test_deepcopy_dont_memo_immutable(self): self.assertEqual(len(memo), 2) memo = {} + memo[id(memo)] = [] x = [(1, 2)] y = copy.deepcopy(x, memo) self.assertEqual(y, x) diff --git a/Misc/NEWS.d/next/Library/2025-05-23-21-29-17.gh-issue-123746.dGpBeY.rst b/Misc/NEWS.d/next/Library/2025-05-23-21-29-17.gh-issue-123746.dGpBeY.rst new file mode 100644 index 00000000000000..c9f39d82aa1827 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-05-23-21-29-17.gh-issue-123746.dGpBeY.rst @@ -0,0 +1 @@ +Improve performance :meth:`copy.deepcopy` setting keep alive key on the memo construction.