diff options
author | Guido van Rossum <guido@python.org> | 2001-09-28 18:13:29 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2001-09-28 18:13:29 (GMT) |
commit | 6cef6d5d62f083ada715da3610ce12147b625ee2 (patch) | |
tree | de5a51234c4e4675698d20abc03bd09c1b1ee0fc /Lib/copy.py | |
parent | 19405a4a2a68570cae67501935adea3f375f84bf (diff) | |
download | cpython-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.py | 46 |
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 |