]> granicus.if.org Git - python/commitdiff
Merged revisions 84495-84497 via svnmerge from
authorAntoine Pitrou <solipsis@pitrou.net>
Sat, 4 Sep 2010 17:49:13 +0000 (17:49 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Sat, 4 Sep 2010 17:49:13 +0000 (17:49 +0000)
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.
........
  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
Lib/test/test_copy.py
Misc/ACKS
Misc/NEWS

index 264635042ca8953f3f93c0b8173eef07a82921d0..4b755112d7958cfb873c0e4055a575da5666c681 100644 (file)
@@ -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()
index 2af21094eac2837271728ad3b6d8492dcea112e0..f4ca6b343f2d69751cdd4a01fc6a07ff2c279df9 100644 (file)
@@ -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
index b4ac3a70f816d96a72d2cbd8caff61177296abcf..ea774ab2144f585afefcec182ce3b439999416ac 100644 (file)
--- 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
index b5c4725c54cfea5e2e9b0a1a5d79beb2695e4a11..871396baea5d48dc1156230a13db55265aeeaa76 100644 (file)
--- 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.