14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"""Generic (shallow and deep) copying operations. 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmInterface summary: 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import copy 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = copy.copy(y) # make a shallow copy of y 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = copy.deepcopy(y) # make a deep copy of y 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmFor module specific errors, copy.Error is raised. 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe difference between shallow and deep copying is only relevant for 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcompound objects (objects that contain other objects, like lists or 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass instances). 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- A shallow copy constructs a new compound object and then (to the 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm extent possible) inserts *the same objects* into it that the 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm original contains. 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm- A deep copy constructs a new compound object and then, recursively, 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm inserts *copies* into it of the objects found in the original. 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmTwo problems often exist with deep copy operations that don't exist 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwith shallow copy operations: 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a) recursive objects (compound objects that, directly or indirectly, 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm contain a reference to themselves) may cause a recursive loop 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm b) because deep copy copies *everything* it may copy too much, e.g. 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm administrative data structures that should be shared even between 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm copies 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPython's deep copy operation avoids these problems by: 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a) keeping a table of objects already copied during the current 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm copying pass 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm b) letting user-defined classes override the copying operation or the 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm set of components copied 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis version does not copy types like module, class, function, method, 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmnor stack trace, stack frame, nor file, socket, window, nor array, nor 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmany similar types. 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmClasses can use the same interfaces to control copying that they use 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmto control pickling: they can define methods called __getinitargs__(), 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__getstate__() and __setstate__(). See the documentation for module 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"pickle" for information on these methods. 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm""" 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport types 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport weakref 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom copy_reg import dispatch_table 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Error(Exception): 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerror = Error # backward compatibility 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm from org.python.core import PyStringMap 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept ImportError: 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyStringMap = None 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__all__ = ["Error", "copy", "deepcopy"] 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef copy(x): 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Shallow copy operation on arbitrary Python objects. 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm See the module's __doc__ string for more info. 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cls = type(x) 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm copier = _copy_dispatch.get(cls) 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if copier: 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return copier(x) 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm copier = getattr(cls, "__copy__", None) 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if copier: 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return copier(x) 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reductor = dispatch_table.get(cls) 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reductor: 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reductor(x) 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reductor = getattr(x, "__reduce_ex__", None) 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reductor: 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reductor(2) 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reductor = getattr(x, "__reduce__", None) 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reductor: 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reductor() 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise Error("un(shallow)copyable object of type %s" % cls) 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _reconstruct(x, rv, 0) 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_copy_dispatch = d = {} 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _copy_immutable(x): 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfor t in (type(None), int, long, float, bool, str, tuple, 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm frozenset, type, xrange, types.ClassType, 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm types.BuiltinFunctionType, type(Ellipsis), 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm types.FunctionType, weakref.ref): 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[t] = _copy_immutable 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfor name in ("ComplexType", "UnicodeType", "CodeType"): 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm t = getattr(types, name, None) 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if t is not None: 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[t] = _copy_immutable 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _copy_with_constructor(x): 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return type(x)(x) 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfor t in (list, dict, set): 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[t] = _copy_with_constructor 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _copy_with_copy_method(x): 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x.copy() 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif PyStringMap is not None: 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[PyStringMap] = _copy_with_copy_method 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _copy_inst(x): 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(x, '__copy__'): 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x.__copy__() 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(x, '__getinitargs__'): 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = x.__getinitargs__() 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = x.__class__(*args) 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = _EmptyClass() 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__class__ = x.__class__ 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(x, '__getstate__'): 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = x.__getstate__() 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = x.__dict__ 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(y, '__setstate__'): 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__setstate__(state) 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__dict__.update(state) 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[types.InstanceType] = _copy_inst 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdel d 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef deepcopy(x, memo=None, _nil=[]): 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Deep copy operation on arbitrary Python objects. 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm See the module's __doc__ string for more info. 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if memo is None: 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo = {} 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d = id(x) 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = memo.get(d, _nil) 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if y is not _nil: 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm cls = type(x) 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm copier = _deepcopy_dispatch.get(cls) 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if copier: 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = copier(x, memo) 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm issc = issubclass(cls, type) 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except TypeError: # cls is not a class (old Boost; see SF #502085) 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm issc = 0 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if issc: 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = _deepcopy_atomic(x, memo) 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm copier = getattr(x, "__deepcopy__", None) 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if copier: 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = copier(memo) 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reductor = dispatch_table.get(cls) 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reductor: 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reductor(x) 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reductor = getattr(x, "__reduce_ex__", None) 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reductor: 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reductor(2) 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm reductor = getattr(x, "__reduce__", None) 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if reductor: 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm rv = reductor() 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm raise Error( 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "un(deep)copyable object of type %s" % cls) 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = _reconstruct(x, rv, 1, memo) 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[d] = y 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _keep_alive(x, memo) # Make sure x lives at least as long as d 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_deepcopy_dispatch = d = {} 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _deepcopy_atomic(x, memo): 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[type(None)] = _deepcopy_atomic 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[type(Ellipsis)] = _deepcopy_atomic 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[int] = _deepcopy_atomic 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[long] = _deepcopy_atomic 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[float] = _deepcopy_atomic 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[bool] = _deepcopy_atomic 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[complex] = _deepcopy_atomic 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept NameError: 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[str] = _deepcopy_atomic 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[unicode] = _deepcopy_atomic 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept NameError: 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtry: 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[types.CodeType] = _deepcopy_atomic 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmexcept AttributeError: 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[type] = _deepcopy_atomic 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[xrange] = _deepcopy_atomic 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[types.ClassType] = _deepcopy_atomic 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[types.BuiltinFunctionType] = _deepcopy_atomic 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[types.FunctionType] = _deepcopy_atomic 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[weakref.ref] = _deepcopy_atomic 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _deepcopy_list(x, memo): 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = [] 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(x)] = y 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for a in x: 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.append(deepcopy(a, memo)) 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[list] = _deepcopy_list 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _deepcopy_tuple(x, memo): 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = [] 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for a in x: 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.append(deepcopy(a, memo)) 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d = id(x) 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return memo[d] 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except KeyError: 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for i in range(len(x)): 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if x[i] is not y[i]: 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = tuple(y) 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = x 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[d] = y 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[tuple] = _deepcopy_tuple 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _deepcopy_dict(x, memo): 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = {} 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(x)] = y 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for key, value in x.iteritems(): 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y[deepcopy(key, memo)] = deepcopy(value, memo) 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[dict] = _deepcopy_dict 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif PyStringMap is not None: 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm d[PyStringMap] = _deepcopy_dict 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _deepcopy_method(x, memo): # Copy instance methods 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return type(x)(x.im_func, deepcopy(x.im_self, memo), x.im_class) 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_deepcopy_dispatch[types.MethodType] = _deepcopy_method 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _keep_alive(x, memo): 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """Keeps a reference to the object x in the memo. 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Because we remember objects by their id, we have 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm to assure that possibly temporary objects are kept 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm alive by referencing them. 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm We store a reference at the id of the memo, which should 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm normally not be used unless someone tries to deepcopy 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the memo itself... 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm """ 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm try: 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(memo)].append(x) 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm except KeyError: 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm # aha, this is the first one :-) 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(memo)]=[x] 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _deepcopy_inst(x, memo): 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(x, '__deepcopy__'): 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x.__deepcopy__(memo) 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(x, '__getinitargs__'): 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = x.__getinitargs__() 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = deepcopy(args, memo) 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = x.__class__(*args) 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = _EmptyClass() 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__class__ = x.__class__ 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(x)] = y 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(x, '__getstate__'): 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = x.__getstate__() 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = x.__dict__ 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = deepcopy(state, memo) 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(y, '__setstate__'): 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__setstate__(state) 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__dict__.update(state) 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmd[types.InstanceType] = _deepcopy_inst 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _reconstruct(x, info, deep, memo=None): 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(info, str): 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return x 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert isinstance(info, tuple) 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if memo is None: 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo = {} 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm n = len(info) 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert n in (2, 3, 4, 5) 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm callable, args = info[:2] 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n > 2: 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = info[2] 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = {} 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n > 3: 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm listiter = info[3] 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm listiter = None 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if n > 4: 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dictiter = info[4] 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dictiter = None 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if deep: 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm args = deepcopy(args, memo) 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y = callable(*args) 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm memo[id(x)] = y 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if state: 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if deep: 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state = deepcopy(state, memo) 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if hasattr(y, '__setstate__'): 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__setstate__(state) 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if isinstance(state, tuple) and len(state) == 2: 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm state, slotstate = state 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm slotstate = None 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if state is not None: 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.__dict__.update(state) 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if slotstate is not None: 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for key, value in slotstate.iteritems(): 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setattr(y, key, value) 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if listiter is not None: 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for item in listiter: 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if deep: 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm item = deepcopy(item, memo) 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y.append(item) 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if dictiter is not None: 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for key, value in dictiter: 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if deep: 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm key = deepcopy(key, memo) 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm value = deepcopy(value, memo) 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm y[key] = value 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return y 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdel d 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdel types 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# Helper for instance creation without calling __init__ 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass _EmptyClass: 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm pass 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef _test(): 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'], 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {'abc': 'ABC'}, (), [], {}] 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l1 = copy(l) 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l1==l 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l1 = map(copy, l) 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l1==l 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l1 = deepcopy(l) 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l1==l 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class C: 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, arg=None): 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.a = 1 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.arg = arg 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if __name__ == '__main__': 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import sys 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = sys.argv[0] 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else: 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm file = __file__ 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fp = open(file) 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.fp.close() 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __getstate__(self): 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return {'a': self.a, 'arg': self.arg} 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __setstate__(self, state): 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for key, value in state.iteritems(): 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm setattr(self, key, value) 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __deepcopy__(self, memo=None): 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm new = self.__class__(deepcopy(self.arg, memo)) 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm new.a = self.a 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return new 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm c = C('argument sketch') 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l.append(c) 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l2 = copy(l) 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l == l2 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l2 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l2 = deepcopy(l) 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l == l2 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print l2 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l.append({l[1]: l, 'xyz': l[2]}) 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l3 = copy(l) 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import repr 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l) 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l1) 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l2) 4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l3) 4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm l3 = deepcopy(l) 4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm import repr 4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l) 4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l1) 4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l2) 4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print map(repr.repr, l3) 4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm class odict(dict): 4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __init__(self, d = {}): 4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.a = 99 4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dict.__init__(self, d) 4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm def __setitem__(self, k, i): 4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dict.__setitem__(self, k, i) 4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm self.a 4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm o = odict({"A" : "B"}) 4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm x = deepcopy(o) 4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm print(o, x) 4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == '__main__': 4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm _test() 434