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.
This commit is contained in:
Serhiy Storchaka 2015-03-24 18:06:42 +02:00
parent 944fbcc478
commit 32af7549a7
3 changed files with 76 additions and 2 deletions

View 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:

View 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):

View File

@ -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).