blob: c8cc88092c66de3e38a36dc9aa8bce5c3e908590 [file] [log] [blame]
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +00001"""Generic (shallow and deep) copying operations.
Guido van Rossum409780f1995-01-10 00:34:21 +00002
Guido van Rossumcc6764c1995-02-09 17:18:10 +00003Interface summary:
4
Tim Peters88869f92001-01-14 23:36:06 +00005 import copy
Guido van Rossumcc6764c1995-02-09 17:18:10 +00006
Tim Peters88869f92001-01-14 23:36:06 +00007 x = copy.copy(y) # make a shallow copy of y
8 x = copy.deepcopy(y) # make a deep copy of y
Guido van Rossumcc6764c1995-02-09 17:18:10 +00009
Guido van Rossum55d2f391995-03-14 17:41:36 +000010For module specific errors, copy.error is raised.
Guido van Rossumcc6764c1995-02-09 17:18:10 +000011
12The difference between shallow and deep copying is only relevant for
13compound objects (objects that contain other objects, like lists or
14class instances).
15
16- A shallow copy constructs a new compound object and then (to the
17 extent possible) inserts *the same objects* into in that the
18 original contains.
19
20- A deep copy constructs a new compound object and then, recursively,
21 inserts *copies* into it of the objects found in the original.
22
23Two problems often exist with deep copy operations that don't exist
24with shallow copy operations:
25
Guido van Rossumf7cea101997-05-28 19:31:14 +000026 a) recursive objects (compound objects that, directly or indirectly,
Guido van Rossumcc6764c1995-02-09 17:18:10 +000027 contain a reference to themselves) may cause a recursive loop
28
Guido van Rossumf7cea101997-05-28 19:31:14 +000029 b) because deep copy copies *everything* it may copy too much, e.g.
Guido van Rossumcc6764c1995-02-09 17:18:10 +000030 administrative data structures that should be shared even between
31 copies
32
33Python's deep copy operation avoids these problems by:
34
Guido van Rossumf7cea101997-05-28 19:31:14 +000035 a) keeping a table of objects already copied during the current
36 copying pass
Guido van Rossumcc6764c1995-02-09 17:18:10 +000037
Guido van Rossumf7cea101997-05-28 19:31:14 +000038 b) letting user-defined classes override the copying operation or the
Guido van Rossumcc6764c1995-02-09 17:18:10 +000039 set of components copied
40
41This version does not copy types like module, class, function, method,
42nor stack trace, stack frame, nor file, socket, window, nor array, nor
43any similar types.
44
45Classes can use the same interfaces to control copying that they use
46to control pickling: they can define methods called __getinitargs__(),
Guido van Rossumc5d2d511997-12-07 16:18:22 +000047__getstate__() and __setstate__(). See the documentation for module
Guido van Rossumcc6764c1995-02-09 17:18:10 +000048"pickle" for information on these methods.
49"""
Guido van Rossum409780f1995-01-10 00:34:21 +000050
Guido van Rossumabfdd701997-10-07 14:47:50 +000051# XXX need to support copy_reg here too...
52
Guido van Rossum409780f1995-01-10 00:34:21 +000053import types
54
Fred Drake227b1202000-08-17 05:06:49 +000055class Error(Exception):
Tim Peters88869f92001-01-14 23:36:06 +000056 pass
57error = Error # backward compatibility
Guido van Rossum409780f1995-01-10 00:34:21 +000058
Guido van Rossumf8baad02000-11-27 21:53:14 +000059try:
60 from org.python.core import PyStringMap
61except ImportError:
62 PyStringMap = None
63
Skip Montanaroe99d5ea2001-01-20 19:54:20 +000064__all__ = ["Error","error","copy","deepcopy"]
65
Guido van Rossum409780f1995-01-10 00:34:21 +000066def copy(x):
Tim Peters88869f92001-01-14 23:36:06 +000067 """Shallow copy operation on arbitrary Python objects.
Guido van Rossumcc6764c1995-02-09 17:18:10 +000068
Tim Peters88869f92001-01-14 23:36:06 +000069 See the module's __doc__ string for more info.
70 """
Guido van Rossumcc6764c1995-02-09 17:18:10 +000071
Tim Peters88869f92001-01-14 23:36:06 +000072 try:
73 copierfunction = _copy_dispatch[type(x)]
74 except KeyError:
75 try:
76 copier = x.__copy__
77 except AttributeError:
78 raise error, \
79 "un(shallow)copyable object of type %s" % type(x)
80 y = copier()
81 else:
82 y = copierfunction(x)
83 return y
Guido van Rossum409780f1995-01-10 00:34:21 +000084
85_copy_dispatch = d = {}
86
87def _copy_atomic(x):
Tim Peters88869f92001-01-14 23:36:06 +000088 return x
Guido van Rossum409780f1995-01-10 00:34:21 +000089d[types.NoneType] = _copy_atomic
90d[types.IntType] = _copy_atomic
91d[types.LongType] = _copy_atomic
92d[types.FloatType] = _copy_atomic
93d[types.StringType] = _copy_atomic
Martin v. Löwis339d0f72001-08-17 18:39:25 +000094try:
95 d[types.UnicodeType] = _copy_atomic
96except AttributeError:
97 pass
Guido van Rossum2fff84d1999-01-25 21:37:02 +000098try:
Tim Peters88869f92001-01-14 23:36:06 +000099 d[types.CodeType] = _copy_atomic
Guido van Rossum2fff84d1999-01-25 21:37:02 +0000100except AttributeError:
Tim Peters88869f92001-01-14 23:36:06 +0000101 pass
Guido van Rossum409780f1995-01-10 00:34:21 +0000102d[types.TypeType] = _copy_atomic
103d[types.XRangeType] = _copy_atomic
Guido van Rossum55d2f391995-03-14 17:41:36 +0000104d[types.ClassType] = _copy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +0000105
106def _copy_list(x):
Tim Peters88869f92001-01-14 23:36:06 +0000107 return x[:]
Guido van Rossum409780f1995-01-10 00:34:21 +0000108d[types.ListType] = _copy_list
109
110def _copy_tuple(x):
Tim Peters88869f92001-01-14 23:36:06 +0000111 return x[:]
Guido van Rossum409780f1995-01-10 00:34:21 +0000112d[types.TupleType] = _copy_tuple
113
114def _copy_dict(x):
Tim Peters88869f92001-01-14 23:36:06 +0000115 return x.copy()
Guido van Rossum409780f1995-01-10 00:34:21 +0000116d[types.DictionaryType] = _copy_dict
Guido van Rossumf8baad02000-11-27 21:53:14 +0000117if PyStringMap is not None:
118 d[PyStringMap] = _copy_dict
Guido van Rossum409780f1995-01-10 00:34:21 +0000119
120def _copy_inst(x):
Tim Peters88869f92001-01-14 23:36:06 +0000121 if hasattr(x, '__copy__'):
122 return x.__copy__()
123 if hasattr(x, '__getinitargs__'):
124 args = x.__getinitargs__()
125 y = apply(x.__class__, args)
126 else:
127 y = _EmptyClass()
128 y.__class__ = x.__class__
129 if hasattr(x, '__getstate__'):
130 state = x.__getstate__()
131 else:
132 state = x.__dict__
133 if hasattr(y, '__setstate__'):
134 y.__setstate__(state)
135 else:
136 y.__dict__.update(state)
137 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000138d[types.InstanceType] = _copy_inst
139
140del d
141
142def deepcopy(x, memo = None):
Tim Peters88869f92001-01-14 23:36:06 +0000143 """Deep copy operation on arbitrary Python objects.
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000144
Tim Peters88869f92001-01-14 23:36:06 +0000145 See the module's __doc__ string for more info.
146 """
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000147
Tim Peters88869f92001-01-14 23:36:06 +0000148 if memo is None:
149 memo = {}
150 d = id(x)
151 if memo.has_key(d):
152 return memo[d]
153 try:
154 copierfunction = _deepcopy_dispatch[type(x)]
155 except KeyError:
156 try:
157 copier = x.__deepcopy__
158 except AttributeError:
159 raise error, \
160 "un-deep-copyable object of type %s" % type(x)
161 y = copier(memo)
162 else:
163 y = copierfunction(x, memo)
164 memo[d] = y
165 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000166
167_deepcopy_dispatch = d = {}
168
169def _deepcopy_atomic(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000170 return x
Guido van Rossum409780f1995-01-10 00:34:21 +0000171d[types.NoneType] = _deepcopy_atomic
172d[types.IntType] = _deepcopy_atomic
173d[types.LongType] = _deepcopy_atomic
174d[types.FloatType] = _deepcopy_atomic
175d[types.StringType] = _deepcopy_atomic
Martin v. Löwis339d0f72001-08-17 18:39:25 +0000176try:
177 d[types.UnicodeType] = _deepcopy_atomic
178except AttributeError:
179 pass
Guido van Rossum409780f1995-01-10 00:34:21 +0000180d[types.CodeType] = _deepcopy_atomic
181d[types.TypeType] = _deepcopy_atomic
182d[types.XRangeType] = _deepcopy_atomic
183
184def _deepcopy_list(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000185 y = []
186 memo[id(x)] = y
187 for a in x:
188 y.append(deepcopy(a, memo))
189 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000190d[types.ListType] = _deepcopy_list
191
192def _deepcopy_tuple(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000193 y = []
194 for a in x:
195 y.append(deepcopy(a, memo))
196 d = id(x)
197 try:
198 return memo[d]
199 except KeyError:
200 pass
201 for i in range(len(x)):
202 if x[i] is not y[i]:
203 y = tuple(y)
204 break
205 else:
206 y = x
207 memo[d] = y
208 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000209d[types.TupleType] = _deepcopy_tuple
210
211def _deepcopy_dict(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000212 y = {}
213 memo[id(x)] = y
214 for key in x.keys():
215 y[deepcopy(key, memo)] = deepcopy(x[key], memo)
216 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000217d[types.DictionaryType] = _deepcopy_dict
Guido van Rossumf8baad02000-11-27 21:53:14 +0000218if PyStringMap is not None:
219 d[PyStringMap] = _deepcopy_dict
Guido van Rossum409780f1995-01-10 00:34:21 +0000220
Guido van Rossum558be281997-08-20 22:26:19 +0000221def _keep_alive(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000222 """Keeps a reference to the object x in the memo.
Guido van Rossum558be281997-08-20 22:26:19 +0000223
Tim Peters88869f92001-01-14 23:36:06 +0000224 Because we remember objects by their id, we have
225 to assure that possibly temporary objects are kept
226 alive by referencing them.
227 We store a reference at the id of the memo, which should
228 normally not be used unless someone tries to deepcopy
229 the memo itself...
230 """
231 try:
232 memo[id(memo)].append(x)
233 except KeyError:
234 # aha, this is the first one :-)
235 memo[id(memo)]=[x]
Guido van Rossum558be281997-08-20 22:26:19 +0000236
Guido van Rossum409780f1995-01-10 00:34:21 +0000237def _deepcopy_inst(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000238 if hasattr(x, '__deepcopy__'):
239 return x.__deepcopy__(memo)
240 if hasattr(x, '__getinitargs__'):
241 args = x.__getinitargs__()
242 _keep_alive(args, memo)
243 args = deepcopy(args, memo)
244 y = apply(x.__class__, args)
245 else:
246 y = _EmptyClass()
247 y.__class__ = x.__class__
248 memo[id(x)] = y
249 if hasattr(x, '__getstate__'):
250 state = x.__getstate__()
251 _keep_alive(state, memo)
252 else:
253 state = x.__dict__
254 state = deepcopy(state, memo)
255 if hasattr(y, '__setstate__'):
256 y.__setstate__(state)
257 else:
258 y.__dict__.update(state)
259 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000260d[types.InstanceType] = _deepcopy_inst
261
262del d
263
264del types
265
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000266# Helper for instance creation without calling __init__
267class _EmptyClass:
268 pass
269
Guido van Rossum409780f1995-01-10 00:34:21 +0000270def _test():
Tim Peters88869f92001-01-14 23:36:06 +0000271 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
272 {'abc': 'ABC'}, (), [], {}]
273 l1 = copy(l)
274 print l1==l
275 l1 = map(copy, l)
276 print l1==l
277 l1 = deepcopy(l)
278 print l1==l
279 class C:
280 def __init__(self, arg=None):
281 self.a = 1
282 self.arg = arg
283 if __name__ == '__main__':
284 import sys
285 file = sys.argv[0]
286 else:
287 file = __file__
288 self.fp = open(file)
289 self.fp.close()
290 def __getstate__(self):
291 return {'a': self.a, 'arg': self.arg}
292 def __setstate__(self, state):
293 for key in state.keys():
294 setattr(self, key, state[key])
295 def __deepcopy__(self, memo = None):
296 new = self.__class__(deepcopy(self.arg, memo))
297 new.a = self.a
298 return new
299 c = C('argument sketch')
300 l.append(c)
301 l2 = copy(l)
302 print l == l2
303 print l
304 print l2
305 l2 = deepcopy(l)
306 print l == l2
307 print l
308 print l2
309 l.append({l[1]: l, 'xyz': l[2]})
310 l3 = copy(l)
311 import repr
312 print map(repr.repr, l)
313 print map(repr.repr, l1)
314 print map(repr.repr, l2)
315 print map(repr.repr, l3)
316 l3 = deepcopy(l)
317 import repr
318 print map(repr.repr, l)
319 print map(repr.repr, l1)
320 print map(repr.repr, l2)
321 print map(repr.repr, l3)
Guido van Rossum409780f1995-01-10 00:34:21 +0000322
323if __name__ == '__main__':
Tim Peters88869f92001-01-14 23:36:06 +0000324 _test()