blob: 123162cba1cee128ad25898f4e95b418a06974e8 [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
Marc-André Lemburgf156a442000-09-07 11:00:03 +000094d[types.UnicodeType] = _copy_atomic
Guido van Rossum2fff84d1999-01-25 21:37:02 +000095try:
Tim Peters88869f92001-01-14 23:36:06 +000096 d[types.CodeType] = _copy_atomic
Guido van Rossum2fff84d1999-01-25 21:37:02 +000097except AttributeError:
Tim Peters88869f92001-01-14 23:36:06 +000098 pass
Guido van Rossum409780f1995-01-10 00:34:21 +000099d[types.TypeType] = _copy_atomic
100d[types.XRangeType] = _copy_atomic
Guido van Rossum55d2f391995-03-14 17:41:36 +0000101d[types.ClassType] = _copy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +0000102
103def _copy_list(x):
Tim Peters88869f92001-01-14 23:36:06 +0000104 return x[:]
Guido van Rossum409780f1995-01-10 00:34:21 +0000105d[types.ListType] = _copy_list
106
107def _copy_tuple(x):
Tim Peters88869f92001-01-14 23:36:06 +0000108 return x[:]
Guido van Rossum409780f1995-01-10 00:34:21 +0000109d[types.TupleType] = _copy_tuple
110
111def _copy_dict(x):
Tim Peters88869f92001-01-14 23:36:06 +0000112 return x.copy()
Guido van Rossum409780f1995-01-10 00:34:21 +0000113d[types.DictionaryType] = _copy_dict
Guido van Rossumf8baad02000-11-27 21:53:14 +0000114if PyStringMap is not None:
115 d[PyStringMap] = _copy_dict
Guido van Rossum409780f1995-01-10 00:34:21 +0000116
117def _copy_inst(x):
Tim Peters88869f92001-01-14 23:36:06 +0000118 if hasattr(x, '__copy__'):
119 return x.__copy__()
120 if hasattr(x, '__getinitargs__'):
121 args = x.__getinitargs__()
122 y = apply(x.__class__, args)
123 else:
124 y = _EmptyClass()
125 y.__class__ = x.__class__
126 if hasattr(x, '__getstate__'):
127 state = x.__getstate__()
128 else:
129 state = x.__dict__
130 if hasattr(y, '__setstate__'):
131 y.__setstate__(state)
132 else:
133 y.__dict__.update(state)
134 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000135d[types.InstanceType] = _copy_inst
136
137del d
138
139def deepcopy(x, memo = None):
Tim Peters88869f92001-01-14 23:36:06 +0000140 """Deep copy operation on arbitrary Python objects.
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000141
Tim Peters88869f92001-01-14 23:36:06 +0000142 See the module's __doc__ string for more info.
143 """
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000144
Tim Peters88869f92001-01-14 23:36:06 +0000145 if memo is None:
146 memo = {}
147 d = id(x)
148 if memo.has_key(d):
149 return memo[d]
150 try:
151 copierfunction = _deepcopy_dispatch[type(x)]
152 except KeyError:
153 try:
154 copier = x.__deepcopy__
155 except AttributeError:
156 raise error, \
157 "un-deep-copyable object of type %s" % type(x)
158 y = copier(memo)
159 else:
160 y = copierfunction(x, memo)
161 memo[d] = y
162 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000163
164_deepcopy_dispatch = d = {}
165
166def _deepcopy_atomic(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000167 return x
Guido van Rossum409780f1995-01-10 00:34:21 +0000168d[types.NoneType] = _deepcopy_atomic
169d[types.IntType] = _deepcopy_atomic
170d[types.LongType] = _deepcopy_atomic
171d[types.FloatType] = _deepcopy_atomic
172d[types.StringType] = _deepcopy_atomic
Marc-André Lemburgf156a442000-09-07 11:00:03 +0000173d[types.UnicodeType] = _deepcopy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +0000174d[types.CodeType] = _deepcopy_atomic
175d[types.TypeType] = _deepcopy_atomic
176d[types.XRangeType] = _deepcopy_atomic
177
178def _deepcopy_list(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000179 y = []
180 memo[id(x)] = y
181 for a in x:
182 y.append(deepcopy(a, memo))
183 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000184d[types.ListType] = _deepcopy_list
185
186def _deepcopy_tuple(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000187 y = []
188 for a in x:
189 y.append(deepcopy(a, memo))
190 d = id(x)
191 try:
192 return memo[d]
193 except KeyError:
194 pass
195 for i in range(len(x)):
196 if x[i] is not y[i]:
197 y = tuple(y)
198 break
199 else:
200 y = x
201 memo[d] = y
202 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000203d[types.TupleType] = _deepcopy_tuple
204
205def _deepcopy_dict(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000206 y = {}
207 memo[id(x)] = y
208 for key in x.keys():
209 y[deepcopy(key, memo)] = deepcopy(x[key], memo)
210 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000211d[types.DictionaryType] = _deepcopy_dict
Guido van Rossumf8baad02000-11-27 21:53:14 +0000212if PyStringMap is not None:
213 d[PyStringMap] = _deepcopy_dict
Guido van Rossum409780f1995-01-10 00:34:21 +0000214
Guido van Rossum558be281997-08-20 22:26:19 +0000215def _keep_alive(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000216 """Keeps a reference to the object x in the memo.
Guido van Rossum558be281997-08-20 22:26:19 +0000217
Tim Peters88869f92001-01-14 23:36:06 +0000218 Because we remember objects by their id, we have
219 to assure that possibly temporary objects are kept
220 alive by referencing them.
221 We store a reference at the id of the memo, which should
222 normally not be used unless someone tries to deepcopy
223 the memo itself...
224 """
225 try:
226 memo[id(memo)].append(x)
227 except KeyError:
228 # aha, this is the first one :-)
229 memo[id(memo)]=[x]
Guido van Rossum558be281997-08-20 22:26:19 +0000230
Guido van Rossum409780f1995-01-10 00:34:21 +0000231def _deepcopy_inst(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000232 if hasattr(x, '__deepcopy__'):
233 return x.__deepcopy__(memo)
234 if hasattr(x, '__getinitargs__'):
235 args = x.__getinitargs__()
236 _keep_alive(args, memo)
237 args = deepcopy(args, memo)
238 y = apply(x.__class__, args)
239 else:
240 y = _EmptyClass()
241 y.__class__ = x.__class__
242 memo[id(x)] = y
243 if hasattr(x, '__getstate__'):
244 state = x.__getstate__()
245 _keep_alive(state, memo)
246 else:
247 state = x.__dict__
248 state = deepcopy(state, memo)
249 if hasattr(y, '__setstate__'):
250 y.__setstate__(state)
251 else:
252 y.__dict__.update(state)
253 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000254d[types.InstanceType] = _deepcopy_inst
255
256del d
257
258del types
259
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000260# Helper for instance creation without calling __init__
261class _EmptyClass:
262 pass
263
Guido van Rossum409780f1995-01-10 00:34:21 +0000264def _test():
Tim Peters88869f92001-01-14 23:36:06 +0000265 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
266 {'abc': 'ABC'}, (), [], {}]
267 l1 = copy(l)
268 print l1==l
269 l1 = map(copy, l)
270 print l1==l
271 l1 = deepcopy(l)
272 print l1==l
273 class C:
274 def __init__(self, arg=None):
275 self.a = 1
276 self.arg = arg
277 if __name__ == '__main__':
278 import sys
279 file = sys.argv[0]
280 else:
281 file = __file__
282 self.fp = open(file)
283 self.fp.close()
284 def __getstate__(self):
285 return {'a': self.a, 'arg': self.arg}
286 def __setstate__(self, state):
287 for key in state.keys():
288 setattr(self, key, state[key])
289 def __deepcopy__(self, memo = None):
290 new = self.__class__(deepcopy(self.arg, memo))
291 new.a = self.a
292 return new
293 c = C('argument sketch')
294 l.append(c)
295 l2 = copy(l)
296 print l == l2
297 print l
298 print l2
299 l2 = deepcopy(l)
300 print l == l2
301 print l
302 print l2
303 l.append({l[1]: l, 'xyz': l[2]})
304 l3 = copy(l)
305 import repr
306 print map(repr.repr, l)
307 print map(repr.repr, l1)
308 print map(repr.repr, l2)
309 print map(repr.repr, l3)
310 l3 = deepcopy(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)
Guido van Rossum409780f1995-01-10 00:34:21 +0000316
317if __name__ == '__main__':
Tim Peters88869f92001-01-14 23:36:06 +0000318 _test()