blob: cdd2fdf8d38e88f543a34ee5aca55d224c78763f [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
Guido van Rossum409780f1995-01-10 00:34:21 +000064def copy(x):
Tim Peters88869f92001-01-14 23:36:06 +000065 """Shallow copy operation on arbitrary Python objects.
Guido van Rossumcc6764c1995-02-09 17:18:10 +000066
Tim Peters88869f92001-01-14 23:36:06 +000067 See the module's __doc__ string for more info.
68 """
Guido van Rossumcc6764c1995-02-09 17:18:10 +000069
Tim Peters88869f92001-01-14 23:36:06 +000070 try:
71 copierfunction = _copy_dispatch[type(x)]
72 except KeyError:
73 try:
74 copier = x.__copy__
75 except AttributeError:
76 raise error, \
77 "un(shallow)copyable object of type %s" % type(x)
78 y = copier()
79 else:
80 y = copierfunction(x)
81 return y
Guido van Rossum409780f1995-01-10 00:34:21 +000082
83_copy_dispatch = d = {}
84
85def _copy_atomic(x):
Tim Peters88869f92001-01-14 23:36:06 +000086 return x
Guido van Rossum409780f1995-01-10 00:34:21 +000087d[types.NoneType] = _copy_atomic
88d[types.IntType] = _copy_atomic
89d[types.LongType] = _copy_atomic
90d[types.FloatType] = _copy_atomic
91d[types.StringType] = _copy_atomic
Marc-André Lemburgf156a442000-09-07 11:00:03 +000092d[types.UnicodeType] = _copy_atomic
Guido van Rossum2fff84d1999-01-25 21:37:02 +000093try:
Tim Peters88869f92001-01-14 23:36:06 +000094 d[types.CodeType] = _copy_atomic
Guido van Rossum2fff84d1999-01-25 21:37:02 +000095except AttributeError:
Tim Peters88869f92001-01-14 23:36:06 +000096 pass
Guido van Rossum409780f1995-01-10 00:34:21 +000097d[types.TypeType] = _copy_atomic
98d[types.XRangeType] = _copy_atomic
Guido van Rossum55d2f391995-03-14 17:41:36 +000099d[types.ClassType] = _copy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +0000100
101def _copy_list(x):
Tim Peters88869f92001-01-14 23:36:06 +0000102 return x[:]
Guido van Rossum409780f1995-01-10 00:34:21 +0000103d[types.ListType] = _copy_list
104
105def _copy_tuple(x):
Tim Peters88869f92001-01-14 23:36:06 +0000106 return x[:]
Guido van Rossum409780f1995-01-10 00:34:21 +0000107d[types.TupleType] = _copy_tuple
108
109def _copy_dict(x):
Tim Peters88869f92001-01-14 23:36:06 +0000110 return x.copy()
Guido van Rossum409780f1995-01-10 00:34:21 +0000111d[types.DictionaryType] = _copy_dict
Guido van Rossumf8baad02000-11-27 21:53:14 +0000112if PyStringMap is not None:
113 d[PyStringMap] = _copy_dict
Guido van Rossum409780f1995-01-10 00:34:21 +0000114
115def _copy_inst(x):
Tim Peters88869f92001-01-14 23:36:06 +0000116 if hasattr(x, '__copy__'):
117 return x.__copy__()
118 if hasattr(x, '__getinitargs__'):
119 args = x.__getinitargs__()
120 y = apply(x.__class__, args)
121 else:
122 y = _EmptyClass()
123 y.__class__ = x.__class__
124 if hasattr(x, '__getstate__'):
125 state = x.__getstate__()
126 else:
127 state = x.__dict__
128 if hasattr(y, '__setstate__'):
129 y.__setstate__(state)
130 else:
131 y.__dict__.update(state)
132 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000133d[types.InstanceType] = _copy_inst
134
135del d
136
137def deepcopy(x, memo = None):
Tim Peters88869f92001-01-14 23:36:06 +0000138 """Deep copy operation on arbitrary Python objects.
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000139
Tim Peters88869f92001-01-14 23:36:06 +0000140 See the module's __doc__ string for more info.
141 """
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000142
Tim Peters88869f92001-01-14 23:36:06 +0000143 if memo is None:
144 memo = {}
145 d = id(x)
146 if memo.has_key(d):
147 return memo[d]
148 try:
149 copierfunction = _deepcopy_dispatch[type(x)]
150 except KeyError:
151 try:
152 copier = x.__deepcopy__
153 except AttributeError:
154 raise error, \
155 "un-deep-copyable object of type %s" % type(x)
156 y = copier(memo)
157 else:
158 y = copierfunction(x, memo)
159 memo[d] = y
160 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000161
162_deepcopy_dispatch = d = {}
163
164def _deepcopy_atomic(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000165 return x
Guido van Rossum409780f1995-01-10 00:34:21 +0000166d[types.NoneType] = _deepcopy_atomic
167d[types.IntType] = _deepcopy_atomic
168d[types.LongType] = _deepcopy_atomic
169d[types.FloatType] = _deepcopy_atomic
170d[types.StringType] = _deepcopy_atomic
Marc-André Lemburgf156a442000-09-07 11:00:03 +0000171d[types.UnicodeType] = _deepcopy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +0000172d[types.CodeType] = _deepcopy_atomic
173d[types.TypeType] = _deepcopy_atomic
174d[types.XRangeType] = _deepcopy_atomic
175
176def _deepcopy_list(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000177 y = []
178 memo[id(x)] = y
179 for a in x:
180 y.append(deepcopy(a, memo))
181 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000182d[types.ListType] = _deepcopy_list
183
184def _deepcopy_tuple(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000185 y = []
186 for a in x:
187 y.append(deepcopy(a, memo))
188 d = id(x)
189 try:
190 return memo[d]
191 except KeyError:
192 pass
193 for i in range(len(x)):
194 if x[i] is not y[i]:
195 y = tuple(y)
196 break
197 else:
198 y = x
199 memo[d] = y
200 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000201d[types.TupleType] = _deepcopy_tuple
202
203def _deepcopy_dict(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000204 y = {}
205 memo[id(x)] = y
206 for key in x.keys():
207 y[deepcopy(key, memo)] = deepcopy(x[key], memo)
208 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000209d[types.DictionaryType] = _deepcopy_dict
Guido van Rossumf8baad02000-11-27 21:53:14 +0000210if PyStringMap is not None:
211 d[PyStringMap] = _deepcopy_dict
Guido van Rossum409780f1995-01-10 00:34:21 +0000212
Guido van Rossum558be281997-08-20 22:26:19 +0000213def _keep_alive(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000214 """Keeps a reference to the object x in the memo.
Guido van Rossum558be281997-08-20 22:26:19 +0000215
Tim Peters88869f92001-01-14 23:36:06 +0000216 Because we remember objects by their id, we have
217 to assure that possibly temporary objects are kept
218 alive by referencing them.
219 We store a reference at the id of the memo, which should
220 normally not be used unless someone tries to deepcopy
221 the memo itself...
222 """
223 try:
224 memo[id(memo)].append(x)
225 except KeyError:
226 # aha, this is the first one :-)
227 memo[id(memo)]=[x]
Guido van Rossum558be281997-08-20 22:26:19 +0000228
Guido van Rossum409780f1995-01-10 00:34:21 +0000229def _deepcopy_inst(x, memo):
Tim Peters88869f92001-01-14 23:36:06 +0000230 if hasattr(x, '__deepcopy__'):
231 return x.__deepcopy__(memo)
232 if hasattr(x, '__getinitargs__'):
233 args = x.__getinitargs__()
234 _keep_alive(args, memo)
235 args = deepcopy(args, memo)
236 y = apply(x.__class__, args)
237 else:
238 y = _EmptyClass()
239 y.__class__ = x.__class__
240 memo[id(x)] = y
241 if hasattr(x, '__getstate__'):
242 state = x.__getstate__()
243 _keep_alive(state, memo)
244 else:
245 state = x.__dict__
246 state = deepcopy(state, memo)
247 if hasattr(y, '__setstate__'):
248 y.__setstate__(state)
249 else:
250 y.__dict__.update(state)
251 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000252d[types.InstanceType] = _deepcopy_inst
253
254del d
255
256del types
257
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000258# Helper for instance creation without calling __init__
259class _EmptyClass:
260 pass
261
Guido van Rossum409780f1995-01-10 00:34:21 +0000262def _test():
Tim Peters88869f92001-01-14 23:36:06 +0000263 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
264 {'abc': 'ABC'}, (), [], {}]
265 l1 = copy(l)
266 print l1==l
267 l1 = map(copy, l)
268 print l1==l
269 l1 = deepcopy(l)
270 print l1==l
271 class C:
272 def __init__(self, arg=None):
273 self.a = 1
274 self.arg = arg
275 if __name__ == '__main__':
276 import sys
277 file = sys.argv[0]
278 else:
279 file = __file__
280 self.fp = open(file)
281 self.fp.close()
282 def __getstate__(self):
283 return {'a': self.a, 'arg': self.arg}
284 def __setstate__(self, state):
285 for key in state.keys():
286 setattr(self, key, state[key])
287 def __deepcopy__(self, memo = None):
288 new = self.__class__(deepcopy(self.arg, memo))
289 new.a = self.a
290 return new
291 c = C('argument sketch')
292 l.append(c)
293 l2 = copy(l)
294 print l == l2
295 print l
296 print l2
297 l2 = deepcopy(l)
298 print l == l2
299 print l
300 print l2
301 l.append({l[1]: l, 'xyz': l[2]})
302 l3 = copy(l)
303 import repr
304 print map(repr.repr, l)
305 print map(repr.repr, l1)
306 print map(repr.repr, l2)
307 print map(repr.repr, l3)
308 l3 = deepcopy(l)
309 import repr
310 print map(repr.repr, l)
311 print map(repr.repr, l1)
312 print map(repr.repr, l2)
313 print map(repr.repr, l3)
Guido van Rossum409780f1995-01-10 00:34:21 +0000314
315if __name__ == '__main__':
Tim Peters88869f92001-01-14 23:36:06 +0000316 _test()