]> granicus.if.org Git - python/commitdiff
Support __reduce__ returning a 4-tuple or 5-tuple.
authorGuido van Rossum <guido@python.org>
Thu, 6 Feb 2003 18:18:23 +0000 (18:18 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 6 Feb 2003 18:18:23 +0000 (18:18 +0000)
Lib/copy.py
Lib/test/test_copy.py

index 59886cbe8ff8f37a7af0c89dce5bd7bda172776c..184528495118bcaab738ed62b0ff5199a10d8f26 100644 (file)
@@ -297,15 +297,34 @@ def _reconstruct(x, info, deep, memo=None):
     if memo is None:
         memo = {}
     n = len(info)
-    assert n in (2, 3)
+    assert n in (2, 3, 4, 5)
     callable, args = info[:2]
     if n > 2:
         state = info[2]
     else:
         state = {}
+    if n > 3:
+        listiter = info[3]
+    else:
+        listiter = None
+    if n > 4:
+        dictiter = info[4]
+    else:
+        dictiter = None
     if deep:
         args = deepcopy(args, memo)
     y = callable(*args)
+    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)
index 90ef3fae3eedf89c2f8b1fea9a6822f722bb7dac..a42b1499ad709e2821c6d3e7a8ba4a39bdf0eb79 100644 (file)
@@ -375,6 +375,42 @@ class TestCopy(unittest.TestCase):
         self.assertEqual(y, x)
         self.assert_(y.foo is not x.foo)
 
+    # Additions for Python 2.3 and pickle protocol 2
+
+    def test_reduce_4tuple(self):
+        class C(list):
+            def __reduce__(self):
+                return (C, (), self.__dict__, iter(self))
+            def __cmp__(self, other):
+                return (cmp(list(self), list(other)) or
+                        cmp(self.__dict__, other.__dict__))
+        x = C([[1, 2], 3])
+        y = copy.copy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x[0] is y[0])
+        y = copy.deepcopy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x[0] is not y[0])
+
+    def test_reduce_5tuple(self):
+        class C(dict):
+            def __reduce__(self):
+                return (C, (), self.__dict__, None, self.iteritems())
+            def __cmp__(self, other):
+                return (cmp(dict(self), list(dict)) or
+                        cmp(self.__dict__, other.__dict__))
+        x = C([("foo", [1, 2]), ("bar", 3)])
+        y = copy.copy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x["foo"] is y["foo"])
+        y = copy.deepcopy(x)
+        self.assertEqual(x, y)
+        self.assert_(x is not y)
+        self.assert_(x["foo"] is not y["foo"])
+
 def test_main():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(TestCopy))