From ce111caaeb9ae6cf3c04dfdc26cc4e53f015f31d Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sat, 4 Sep 2010 17:49:13 +0000 Subject: [PATCH] Merged revisions 84495-84497 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/py3k MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ........ 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. ........ r84497 | antoine.pitrou | 2010-09-04 19:46:44 +0200 (sam., 04 sept. 2010) | 3 lines Fix running the copy module from the command-line (however use{ful,less} it may be). ........ --- Lib/copy.py | 37 +++++++++++++++++++++++++------------ Lib/test/test_copy.py | 20 ++++++++++++++++++++ Misc/ACKS | 2 +- Misc/NEWS | 3 +++ 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/Lib/copy.py b/Lib/copy.py index 264635042ca..4b755112d79 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -51,6 +51,7 @@ __getstate__() and __setstate__(). See the documentation for module import types import weakref from copyreg import dispatch_table +import builtins class Error(Exception): pass @@ -109,7 +110,7 @@ t = getattr(types, "CodeType", None) if t is not None: d[t] = _copy_immutable for name in ("complex", "unicode"): - t = globals()['__builtins__'].get(name) + t = getattr(builtins, name, None) if t is not None: d[t] = _copy_immutable @@ -279,17 +280,7 @@ def _reconstruct(x, info, deep, memo=None): args = deepcopy(args, memo) y = callable(*args) 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 deep: state = deepcopy(state, memo) @@ -305,6 +296,18 @@ def _reconstruct(x, info, deep, memo=None): if slotstate is not None: for key, value in slotstate.items(): 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 del d @@ -366,6 +369,16 @@ def _test(): print(map(reprlib.repr, l1)) print(map(reprlib.repr, l2)) print(map(reprlib.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__': _test() diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index 2af21094eac..f4ca6b343f2 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -532,6 +532,26 @@ class TestCopy(unittest.TestCase): self.assertEqual(x.foo, 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()) + super().__init__(d) + def __setitem__(self, key, item): + super().__setitem__(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): class C(list): pass diff --git a/Misc/ACKS b/Misc/ACKS index b4ac3a70f81..ea774ab2144 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -469,7 +469,7 @@ Shawn Ligocki Martin Ligr Grant Limberg Christopher Lindblad -Bjorn Lindqvist +Björn Lindqvist Per Lindqvist Eric Lindvall Gregor Lingl diff --git a/Misc/NEWS b/Misc/NEWS index b5c4725c54c..871396baea5 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -105,6 +105,9 @@ C-API Library ------- +- Issue #1100562: Fix deep-copying of objects derived from the list and + dict types. Patch by Michele Orrù and Björn Lindqvist. + - Issue #9753: Fixed socket.dup, which did not always work correctly on Windows.