]> granicus.if.org Git - python/commitdiff
Issue #20289: The copy module now uses pickle protocol 4 (PEP 3154) and
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 24 Mar 2015 16:06:42 +0000 (18:06 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Tue, 24 Mar 2015 16:06:42 +0000 (18:06 +0200)
supports copying of instances of classes whose __new__ method takes
keyword-only arguments.

Lib/copy.py
Lib/test/test_copy.py
Misc/NEWS

index 383609bc648f832e1cda3c5ad01a3b4b08636462..3a45fdf49b23788eea55051f9e35c55a3643f4e0 100644 (file)
@@ -94,7 +94,7 @@ def copy(x):
     else:
         reductor = getattr(x, "__reduce_ex__", None)
         if reductor:
-            rv = reductor(2)
+            rv = reductor(4)
         else:
             reductor = getattr(x, "__reduce__", None)
             if reductor:
@@ -171,7 +171,7 @@ def deepcopy(x, memo=None, _nil=[]):
                 else:
                     reductor = getattr(x, "__reduce_ex__", None)
                     if reductor:
-                        rv = reductor(2)
+                        rv = reductor(4)
                     else:
                         reductor = getattr(x, "__reduce__", None)
                         if reductor:
index eb8d18cf0b1217490af804bb7a68b86055e89546..498c270dd2415494ed342568e2b91c9cfc7c0b4b 100644 (file)
@@ -146,6 +146,40 @@ class TestCopy(unittest.TestCase):
         x = C(42)
         self.assertEqual(copy.copy(x), x)
 
+    def test_copy_inst_getnewargs(self):
+        class C(int):
+            def __new__(cls, foo):
+                self = int.__new__(cls)
+                self.foo = foo
+                return self
+            def __getnewargs__(self):
+                return self.foo,
+            def __eq__(self, other):
+                return self.foo == other.foo
+        x = C(42)
+        y = copy.copy(x)
+        self.assertIsInstance(y, C)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        self.assertEqual(y.foo, x.foo)
+
+    def test_copy_inst_getnewargs_ex(self):
+        class C(int):
+            def __new__(cls, *, foo):
+                self = int.__new__(cls)
+                self.foo = foo
+                return self
+            def __getnewargs_ex__(self):
+                return (), {'foo': self.foo}
+            def __eq__(self, other):
+                return self.foo == other.foo
+        x = C(foo=42)
+        y = copy.copy(x)
+        self.assertIsInstance(y, C)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        self.assertEqual(y.foo, x.foo)
+
     def test_copy_inst_getstate(self):
         class C:
             def __init__(self, foo):
@@ -405,6 +439,42 @@ class TestCopy(unittest.TestCase):
         self.assertIsNot(y, x)
         self.assertIsNot(y.foo, x.foo)
 
+    def test_deepcopy_inst_getnewargs(self):
+        class C(int):
+            def __new__(cls, foo):
+                self = int.__new__(cls)
+                self.foo = foo
+                return self
+            def __getnewargs__(self):
+                return self.foo,
+            def __eq__(self, other):
+                return self.foo == other.foo
+        x = C([42])
+        y = copy.deepcopy(x)
+        self.assertIsInstance(y, C)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        self.assertEqual(y.foo, x.foo)
+        self.assertIsNot(y.foo, x.foo)
+
+    def test_deepcopy_inst_getnewargs_ex(self):
+        class C(int):
+            def __new__(cls, *, foo):
+                self = int.__new__(cls)
+                self.foo = foo
+                return self
+            def __getnewargs_ex__(self):
+                return (), {'foo': self.foo}
+            def __eq__(self, other):
+                return self.foo == other.foo
+        x = C(foo=[42])
+        y = copy.deepcopy(x)
+        self.assertIsInstance(y, C)
+        self.assertEqual(y, x)
+        self.assertIsNot(y, x)
+        self.assertEqual(y.foo, x.foo)
+        self.assertIsNot(y.foo, x.foo)
+
     def test_deepcopy_inst_getstate(self):
         class C:
             def __init__(self, foo):
index 5cc553718b88e9c8a424e396473a2a7effae9d5c..7d888a291fa5e7e4b9e7bec3c9523eadc3db1bfd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -26,6 +26,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #20289: The copy module now uses pickle protocol 4 (PEP 3154) and
+  supports copying of instances of classes whose __new__ method takes
+  keyword-only arguments.
+
 - Issue #23491: Added a zipapp module to support creating executable zip
   file archives of Python code. Registered ".pyz" and ".pyzw" extensions
   on Windows for these archives (PEP 441).