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