14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""Generic (shallow and deep) copying operations.
24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
34adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoInterface summary:
44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        import copy
64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        x = copy.copy(y)        # make a shallow copy of y
84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        x = copy.deepcopy(y)    # make a deep copy of y
94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
104adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoFor module specific errors, copy.Error is raised.
114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
124adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoThe difference between shallow and deep copying is only relevant for
134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaocompound objects (objects that contain other objects, like lists or
144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass instances).
154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao- A shallow copy constructs a new compound object and then (to the
174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao  extent possible) inserts *the same objects* into it that the
184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao  original contains.
194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao- A deep copy constructs a new compound object and then, recursively,
214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao  inserts *copies* into it of the objects found in the original.
224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
234adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoTwo problems often exist with deep copy operations that don't exist
244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaowith shallow copy operations:
254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a) recursive objects (compound objects that, directly or indirectly,
274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    contain a reference to themselves) may cause a recursive loop
284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b) because deep copy copies *everything* it may copy too much, e.g.
304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    administrative data structures that should be shared even between
314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    copies
324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
334adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoPython's deep copy operation avoids these problems by:
344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao a) keeping a table of objects already copied during the current
364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    copying pass
374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao b) letting user-defined classes override the copying operation or the
394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    set of components copied
404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
414adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoThis version does not copy types like module, class, function, method,
424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaonor stack trace, stack frame, nor file, socket, window, nor array, nor
434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoany similar types.
444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
454adfde8bc82dd39f59e0445588c3e599ada477dJosh GaoClasses can use the same interfaces to control copying that they use
464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoto control pickling: they can define methods called __getinitargs__(),
474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao__getstate__() and __setstate__().  See the documentation for module
484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"pickle" for information on these methods.
494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao"""
504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport types
524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport weakref
534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom copy_reg import dispatch_table
544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Error(Exception):
564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    pass
574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoerror = Error   # backward compatibility
584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry:
604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    from org.python.core import PyStringMap
614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept ImportError:
624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    PyStringMap = None
634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao__all__ = ["Error", "copy", "deepcopy"]
654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef copy(x):
674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """Shallow copy operation on arbitrary Python objects.
684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    See the module's __doc__ string for more info.
704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """
714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    cls = type(x)
734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    copier = _copy_dispatch.get(cls)
754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if copier:
764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return copier(x)
774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    copier = getattr(cls, "__copy__", None)
794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if copier:
804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return copier(x)
814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    reductor = dispatch_table.get(cls)
834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if reductor:
844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        rv = reductor(x)
854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        reductor = getattr(x, "__reduce_ex__", None)
874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if reductor:
884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            rv = reductor(2)
894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            reductor = getattr(x, "__reduce__", None)
914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if reductor:
924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                rv = reductor()
934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                raise Error("un(shallow)copyable object of type %s" % cls)
954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return _reconstruct(x, rv, 0)
974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao_copy_dispatch = d = {}
1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _copy_immutable(x):
1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return x
1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofor t in (type(None), int, long, float, bool, str, tuple,
1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao          frozenset, type, xrange, types.ClassType,
1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao          types.BuiltinFunctionType, type(Ellipsis),
1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao          types.FunctionType, weakref.ref):
1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d[t] = _copy_immutable
1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofor name in ("ComplexType", "UnicodeType", "CodeType"):
1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    t = getattr(types, name, None)
1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if t is not None:
1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        d[t] = _copy_immutable
1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _copy_with_constructor(x):
1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return type(x)(x)
1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofor t in (list, dict, set):
1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d[t] = _copy_with_constructor
1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _copy_with_copy_method(x):
1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return x.copy()
1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif PyStringMap is not None:
1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d[PyStringMap] = _copy_with_copy_method
1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _copy_inst(x):
1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(x, '__copy__'):
1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return x.__copy__()
1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(x, '__getinitargs__'):
1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        args = x.__getinitargs__()
1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y = x.__class__(*args)
1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y = _EmptyClass()
1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.__class__ = x.__class__
1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(x, '__getstate__'):
1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        state = x.__getstate__()
1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        state = x.__dict__
1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(y, '__setstate__'):
1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.__setstate__(state)
1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.__dict__.update(state)
1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return y
1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[types.InstanceType] = _copy_inst
1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodel d
1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef deepcopy(x, memo=None, _nil=[]):
1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """Deep copy operation on arbitrary Python objects.
1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    See the module's __doc__ string for more info.
1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """
1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if memo is None:
1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        memo = {}
1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d = id(x)
1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    y = memo.get(d, _nil)
1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if y is not _nil:
1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return y
1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    cls = type(x)
1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    copier = _deepcopy_dispatch.get(cls)
1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if copier:
1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y = copier(x, memo)
1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        try:
1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            issc = issubclass(cls, type)
1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        except TypeError: # cls is not a class (old Boost; see SF #502085)
1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            issc = 0
1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if issc:
1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            y = _deepcopy_atomic(x, memo)
1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            copier = getattr(x, "__deepcopy__", None)
1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if copier:
1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                y = copier(memo)
1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                reductor = dispatch_table.get(cls)
1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                if reductor:
1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    rv = reductor(x)
1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                else:
1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    reductor = getattr(x, "__reduce_ex__", None)
1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    if reductor:
1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        rv = reductor(2)
1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    else:
1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        reductor = getattr(x, "__reduce__", None)
1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        if reductor:
1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                            rv = reductor()
1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                        else:
1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                            raise Error(
1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                                "un(deep)copyable object of type %s" % cls)
1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                y = _reconstruct(x, rv, 1, memo)
1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    memo[d] = y
1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    _keep_alive(x, memo) # Make sure x lives at least as long as d
1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return y
1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao_deepcopy_dispatch = d = {}
1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _deepcopy_atomic(x, memo):
1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return x
2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[type(None)] = _deepcopy_atomic
2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[type(Ellipsis)] = _deepcopy_atomic
2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[int] = _deepcopy_atomic
2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[long] = _deepcopy_atomic
2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[float] = _deepcopy_atomic
2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[bool] = _deepcopy_atomic
2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry:
2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d[complex] = _deepcopy_atomic
2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept NameError:
2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    pass
2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[str] = _deepcopy_atomic
2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry:
2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d[unicode] = _deepcopy_atomic
2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept NameError:
2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    pass
2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotry:
2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d[types.CodeType] = _deepcopy_atomic
2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoexcept AttributeError:
2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    pass
2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[type] = _deepcopy_atomic
2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[xrange] = _deepcopy_atomic
2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[types.ClassType] = _deepcopy_atomic
2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[types.BuiltinFunctionType] = _deepcopy_atomic
2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[types.FunctionType] = _deepcopy_atomic
2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[weakref.ref] = _deepcopy_atomic
2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _deepcopy_list(x, memo):
2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    y = []
2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    memo[id(x)] = y
2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    for a in x:
2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.append(deepcopy(a, memo))
2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return y
2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[list] = _deepcopy_list
2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _deepcopy_tuple(x, memo):
2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    y = []
2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    for a in x:
2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.append(deepcopy(a, memo))
2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d = id(x)
2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    try:
2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return memo[d]
2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    except KeyError:
2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        pass
2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    for i in range(len(x)):
2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if x[i] is not y[i]:
2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            y = tuple(y)
2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            break
2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y = x
2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    memo[d] = y
2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return y
2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[tuple] = _deepcopy_tuple
2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _deepcopy_dict(x, memo):
2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    y = {}
2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    memo[id(x)] = y
2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    for key, value in x.iteritems():
2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y[deepcopy(key, memo)] = deepcopy(value, memo)
2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return y
2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[dict] = _deepcopy_dict
2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif PyStringMap is not None:
2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    d[PyStringMap] = _deepcopy_dict
2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _deepcopy_method(x, memo): # Copy instance methods
2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return type(x)(x.im_func, deepcopy(x.im_self, memo), x.im_class)
2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao_deepcopy_dispatch[types.MethodType] = _deepcopy_method
2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _keep_alive(x, memo):
2684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """Keeps a reference to the object x in the memo.
2694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    Because we remember objects by their id, we have
2714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    to assure that possibly temporary objects are kept
2724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    alive by referencing them.
2734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    We store a reference at the id of the memo, which should
2744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    normally not be used unless someone tries to deepcopy
2754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    the memo itself...
2764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    """
2774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    try:
2784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        memo[id(memo)].append(x)
2794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    except KeyError:
2804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        # aha, this is the first one :-)
2814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        memo[id(memo)]=[x]
2824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
2834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _deepcopy_inst(x, memo):
2844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(x, '__deepcopy__'):
2854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return x.__deepcopy__(memo)
2864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(x, '__getinitargs__'):
2874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        args = x.__getinitargs__()
2884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        args = deepcopy(args, memo)
2894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y = x.__class__(*args)
2904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
2914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y = _EmptyClass()
2924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.__class__ = x.__class__
2934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    memo[id(x)] = y
2944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(x, '__getstate__'):
2954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        state = x.__getstate__()
2964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
2974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        state = x.__dict__
2984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    state = deepcopy(state, memo)
2994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if hasattr(y, '__setstate__'):
3004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.__setstate__(state)
3014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
3024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        y.__dict__.update(state)
3034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return y
3044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaod[types.InstanceType] = _deepcopy_inst
3054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _reconstruct(x, info, deep, memo=None):
3074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if isinstance(info, str):
3084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        return x
3094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    assert isinstance(info, tuple)
3104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if memo is None:
3114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        memo = {}
3124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    n = len(info)
3134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    assert n in (2, 3, 4, 5)
3144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    callable, args = info[:2]
3154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if n > 2:
3164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        state = info[2]
3174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
3184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        state = {}
3194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if n > 3:
3204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        listiter = info[3]
3214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
3224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        listiter = None
3234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if n > 4:
3244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        dictiter = info[4]
3254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    else:
3264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        dictiter = None
3274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if deep:
3284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        args = deepcopy(args, memo)
3294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    y = callable(*args)
3304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    memo[id(x)] = y
3314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if state:
3334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if deep:
3344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            state = deepcopy(state, memo)
3354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        if hasattr(y, '__setstate__'):
3364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            y.__setstate__(state)
3374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        else:
3384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if isinstance(state, tuple) and len(state) == 2:
3394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                state, slotstate = state
3404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
3414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                slotstate = None
3424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if state is not None:
3434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                y.__dict__.update(state)
3444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if slotstate is not None:
3454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                for key, value in slotstate.iteritems():
3464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                    setattr(y, key, value)
3474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if listiter is not None:
3494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for item in listiter:
3504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if deep:
3514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                item = deepcopy(item, memo)
3524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            y.append(item)
3534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    if dictiter is not None:
3544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        for key, value in dictiter:
3554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if deep:
3564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                key = deepcopy(key, memo)
3574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                value = deepcopy(value, memo)
3584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            y[key] = value
3594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    return y
3604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodel d
3624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodel types
3644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Helper for instance creation without calling __init__
3664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass _EmptyClass:
3674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    pass
3684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
3694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _test():
3704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
3714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao         {'abc': 'ABC'}, (), [], {}]
3724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l1 = copy(l)
3734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l1==l
3744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l1 = map(copy, l)
3754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l1==l
3764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l1 = deepcopy(l)
3774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l1==l
3784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    class C:
3794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def __init__(self, arg=None):
3804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.a = 1
3814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.arg = arg
3824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            if __name__ == '__main__':
3834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                import sys
3844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                file = sys.argv[0]
3854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            else:
3864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                file = __file__
3874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.fp = open(file)
3884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.fp.close()
3894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def __getstate__(self):
3904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return {'a': self.a, 'arg': self.arg}
3914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def __setstate__(self, state):
3924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            for key, value in state.iteritems():
3934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao                setattr(self, key, value)
3944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def __deepcopy__(self, memo=None):
3954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            new = self.__class__(deepcopy(self.arg, memo))
3964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            new.a = self.a
3974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            return new
3984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    c = C('argument sketch')
3994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l.append(c)
4004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l2 = copy(l)
4014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l == l2
4024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l
4034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l2
4044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l2 = deepcopy(l)
4054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l == l2
4064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l
4074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print l2
4084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l.append({l[1]: l, 'xyz': l[2]})
4094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l3 = copy(l)
4104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    import repr
4114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l)
4124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l1)
4134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l2)
4144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l3)
4154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    l3 = deepcopy(l)
4164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    import repr
4174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l)
4184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l1)
4194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l2)
4204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print map(repr.repr, l3)
4214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    class odict(dict):
4224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def __init__(self, d = {}):
4234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.a = 99
4244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            dict.__init__(self, d)
4254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao        def __setitem__(self, k, i):
4264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            dict.__setitem__(self, k, i)
4274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao            self.a
4284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    o = odict({"A" : "B"})
4294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    x = deepcopy(o)
4304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    print(o, x)
4314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao
4324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoif __name__ == '__main__':
4334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao    _test()
434