summaryrefslogtreecommitdiffstats
path: root/Lib/copy.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2001-09-28 18:13:29 (GMT)
committerGuido van Rossum <guido@python.org>2001-09-28 18:13:29 (GMT)
commit6cef6d5d62f083ada715da3610ce12147b625ee2 (patch)
treede5a51234c4e4675698d20abc03bd09c1b1ee0fc /Lib/copy.py
parent19405a4a2a68570cae67501935adea3f375f84bf (diff)
downloadcpython-6cef6d5d62f083ada715da3610ce12147b625ee2.zip
cpython-6cef6d5d62f083ada715da3610ce12147b625ee2.tar.gz
cpython-6cef6d5d62f083ada715da3610ce12147b625ee2.tar.bz2
Changes to copy() and deepcopy() in copy.py to support __reduce__ as a
fallback for objects that are neither supported by our dispatch table nor have a __copy__ or __deepcopy__ method. Changes to _reduce() in copy_reg.py to support reducing objects that don't have a __dict__ -- copy.copy(complex()) now invokes _reduce(). Add tests for copy.copy() and copy.deepcopy() to test_regrtest.py.
Diffstat (limited to 'Lib/copy.py')
-rw-r--r--Lib/copy.py46
1 files changed, 39 insertions, 7 deletions
diff --git a/Lib/copy.py b/Lib/copy.py
index c8cc880..e907738 100644
--- a/Lib/copy.py
+++ b/Lib/copy.py
@@ -61,7 +61,7 @@ try:
except ImportError:
PyStringMap = None
-__all__ = ["Error","error","copy","deepcopy"]
+__all__ = ["Error", "error", "copy", "deepcopy"]
def copy(x):
"""Shallow copy operation on arbitrary Python objects.
@@ -75,9 +75,15 @@ def copy(x):
try:
copier = x.__copy__
except AttributeError:
- raise error, \
- "un(shallow)copyable object of type %s" % type(x)
- y = copier()
+ try:
+ reductor = x.__reduce__
+ except AttributeError:
+ raise error, \
+ "un(shallow)copyable object of type %s" % type(x)
+ else:
+ y = _reconstruct(x, reductor(), 0)
+ else:
+ y = copier()
else:
y = copierfunction(x)
return y
@@ -156,9 +162,15 @@ def deepcopy(x, memo = None):
try:
copier = x.__deepcopy__
except AttributeError:
- raise error, \
- "un-deep-copyable object of type %s" % type(x)
- y = copier(memo)
+ try:
+ reductor = x.__reduce__
+ except AttributeError:
+ raise error, \
+ "un-deep-copyable object of type %s" % type(x)
+ else:
+ y = _reconstruct(x, reductor(), 1)
+ else:
+ y = copier(memo)
else:
y = copierfunction(x, memo)
memo[d] = y
@@ -259,6 +271,26 @@ def _deepcopy_inst(x, memo):
return y
d[types.InstanceType] = _deepcopy_inst
+def _reconstruct(x, info, deep):
+ if isinstance(info, str):
+ return x
+ assert isinstance(info, tuple)
+ n = len(info)
+ assert n in (2, 3)
+ callable, args = info[:2]
+ if n > 2:
+ state = info[2]
+ else:
+ state = {}
+ if deep:
+ args = deepcopy(args)
+ y = callable(*args)
+ if state:
+ if deep:
+ state = deepcopy(state)
+ y.__dict__.update(state)
+ return y
+
del d
del types