Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3941a8f

Browse files
committed
Issue #1100562: Fix deep-copying of objects derived from the list and dict types.
Patch by Michele Orrù and Björn Lindqvist.
1 parent e5a9101 commit 3941a8f

3 files changed

Lines changed: 46 additions & 11 deletions

File tree

Lib/copy.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -283,17 +283,7 @@ def _reconstruct(x, info, deep, memo=None):
283283
args = deepcopy(args, memo)
284284
y = callable(*args)
285285
memo[id(x)] = y
286-
if listiter is not None:
287-
for item in listiter:
288-
if deep:
289-
item = deepcopy(item, memo)
290-
y.append(item)
291-
if dictiter is not None:
292-
for key, value in dictiter:
293-
if deep:
294-
key = deepcopy(key, memo)
295-
value = deepcopy(value, memo)
296-
y[key] = value
286+
297287
if state:
298288
if deep:
299289
state = deepcopy(state, memo)
@@ -309,6 +299,18 @@ def _reconstruct(x, info, deep, memo=None):
309299
if slotstate is not None:
310300
for key, value in slotstate.items():
311301
setattr(y, key, value)
302+
303+
if listiter is not None:
304+
for item in listiter:
305+
if deep:
306+
item = deepcopy(item, memo)
307+
y.append(item)
308+
if dictiter is not None:
309+
for key, value in dictiter:
310+
if deep:
311+
key = deepcopy(key, memo)
312+
value = deepcopy(value, memo)
313+
y[key] = value
312314
return y
313315

314316
del d
@@ -370,6 +372,16 @@ def __deepcopy__(self, memo=None):
370372
print(map(reprlib.repr, l1))
371373
print(map(reprlib.repr, l2))
372374
print(map(reprlib.repr, l3))
375+
class odict(dict):
376+
def __init__(self, d = {}):
377+
self.a = 99
378+
dict.__init__(self, d)
379+
def __setitem__(self, k, i):
380+
dict.__setitem__(self, k, i)
381+
self.a
382+
o = odict({"A" : "B"})
383+
x = deepcopy(o)
384+
print(o, x)
373385

374386
if __name__ == '__main__':
375387
_test()

Lib/test/test_copy.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,26 @@ class C(object):
532532
self.assertEqual(x.foo, y.foo)
533533
self.assertTrue(x.foo is not y.foo)
534534

535+
def test_deepcopy_dict_subclass(self):
536+
class C(dict):
537+
def __init__(self, d=None):
538+
if not d:
539+
d = {}
540+
self._keys = list(d.keys())
541+
super().__init__(d)
542+
def __setitem__(self, key, item):
543+
super().__setitem__(key, item)
544+
if key not in self._keys:
545+
self._keys.append(key)
546+
x = C(d={'foo':0})
547+
y = copy.deepcopy(x)
548+
self.assertEqual(x, y)
549+
self.assertEqual(x._keys, y._keys)
550+
self.assertTrue(x is not y)
551+
x['bar'] = 1
552+
self.assertNotEqual(x, y)
553+
self.assertNotEqual(x._keys, y._keys)
554+
535555
def test_copy_list_subclass(self):
536556
class C(list):
537557
pass

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ Extensions
158158
Library
159159
-------
160160

161+
- Issue #1100562: Fix deep-copying of objects derived from the list and
162+
dict types. Patch by Michele Orrù and Björn Lindqvist.
163+
161164
- Issue #9753: Fixed socket.dup, which did not always work correctly
162165
on Windows.
163166

0 commit comments

Comments
 (0)