Merged revisions 84495-84496 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r84495 | antoine.pitrou | 2010-09-04 19:40:21 +0200 (sam., 04 sept. 2010) | 4 lines

  Issue #1100562: Fix deep-copying of objects derived from the list and dict types.
  Patch by Michele Orrù and Björn Lindqvist.
........
  r84496 | antoine.pitrou | 2010-09-04 19:40:51 +0200 (sam., 04 sept. 2010) | 3 lines

  Fix Björn's name in ACKS.
........
This commit is contained in:
Antoine Pitrou 2010-09-04 17:52:26 +00:00
parent dd806cef09
commit dca9de97b4
4 changed files with 47 additions and 12 deletions

View file

@ -328,17 +328,7 @@ def _reconstruct(x, info, deep, memo=None):
args = deepcopy(args, memo) args = deepcopy(args, memo)
y = callable(*args) y = callable(*args)
memo[id(x)] = y memo[id(x)] = y
if listiter is not None:
for item in listiter:
if deep:
item = deepcopy(item, memo)
y.append(item)
if dictiter is not None:
for key, value in dictiter:
if deep:
key = deepcopy(key, memo)
value = deepcopy(value, memo)
y[key] = value
if state: if state:
if deep: if deep:
state = deepcopy(state, memo) state = deepcopy(state, memo)
@ -354,6 +344,18 @@ def _reconstruct(x, info, deep, memo=None):
if slotstate is not None: if slotstate is not None:
for key, value in slotstate.iteritems(): for key, value in slotstate.iteritems():
setattr(y, key, value) setattr(y, key, value)
if listiter is not None:
for item in listiter:
if deep:
item = deepcopy(item, memo)
y.append(item)
if dictiter is not None:
for key, value in dictiter:
if deep:
key = deepcopy(key, memo)
value = deepcopy(value, memo)
y[key] = value
return y return y
del d del d
@ -416,6 +418,16 @@ def _test():
print map(repr.repr, l1) print map(repr.repr, l1)
print map(repr.repr, l2) print map(repr.repr, l2)
print map(repr.repr, l3) print map(repr.repr, l3)
class odict(dict):
def __init__(self, d = {}):
self.a = 99
dict.__init__(self, d)
def __setitem__(self, k, i):
dict.__setitem__(self, k, i)
self.a
o = odict({"A" : "B"})
x = deepcopy(o)
print(o, x)
if __name__ == '__main__': if __name__ == '__main__':
_test() _test()

View file

@ -526,6 +526,26 @@ class TestCopy(unittest.TestCase):
self.assertEqual(x.foo, y.foo) self.assertEqual(x.foo, y.foo)
self.assertTrue(x.foo is not y.foo) self.assertTrue(x.foo is not y.foo)
def test_deepcopy_dict_subclass(self):
class C(dict):
def __init__(self, d=None):
if not d:
d = {}
self._keys = list(d.keys())
dict.__init__(self, d)
def __setitem__(self, key, item):
dict.__setitem__(self, key, item)
if key not in self._keys:
self._keys.append(key)
x = C(d={'foo':0})
y = copy.deepcopy(x)
self.assertEqual(x, y)
self.assertEqual(x._keys, y._keys)
self.assertTrue(x is not y)
x['bar'] = 1
self.assertNotEqual(x, y)
self.assertNotEqual(x._keys, y._keys)
def test_copy_list_subclass(self): def test_copy_list_subclass(self):
class C(list): class C(list):
pass pass

View file

@ -472,7 +472,7 @@ Ross Light
Shawn Ligocki Shawn Ligocki
Martin Ligr Martin Ligr
Christopher Lindblad Christopher Lindblad
Bjorn Lindqvist Björn Lindqvist
Per Lindqvist Per Lindqvist
Eric Lindvall Eric Lindvall
Gregor Lingl Gregor Lingl

View file

@ -36,6 +36,9 @@ Core and Builtins
Library Library
------- -------
- Issue #1100562: Fix deep-copying of objects derived from the list and
dict types. Patch by Michele Orrù and Björn Lindqvist.
- Issue #7005: Fixed output of None values for RawConfigParser.write and - Issue #7005: Fixed output of None values for RawConfigParser.write and
ConfigParser.write. ConfigParser.write.