blob: 2d9de3cad35ebf581d8e63df06ffb42ea23dd04b [file] [log] [blame]
Guido van Rossumcc6764c1995-02-09 17:18:10 +00001"""\
2Generic (shallow and deep) copying operations
3=============================================
Guido van Rossum409780f1995-01-10 00:34:21 +00004
Guido van Rossumcc6764c1995-02-09 17:18:10 +00005Interface summary:
6
7 import copy
8
9 x = copy.copy(y) # make a shallow copy of y
10 x = copy.deepcopy(y) # make a deep copy of y
11
Guido van Rossum55d2f391995-03-14 17:41:36 +000012For module specific errors, copy.error is raised.
Guido van Rossumcc6764c1995-02-09 17:18:10 +000013
14The difference between shallow and deep copying is only relevant for
15compound objects (objects that contain other objects, like lists or
16class instances).
17
18- A shallow copy constructs a new compound object and then (to the
19 extent possible) inserts *the same objects* into in that the
20 original contains.
21
22- A deep copy constructs a new compound object and then, recursively,
23 inserts *copies* into it of the objects found in the original.
24
25Two problems often exist with deep copy operations that don't exist
26with shallow copy operations:
27
Guido van Rossumf7cea101997-05-28 19:31:14 +000028 a) recursive objects (compound objects that, directly or indirectly,
Guido van Rossumcc6764c1995-02-09 17:18:10 +000029 contain a reference to themselves) may cause a recursive loop
30
Guido van Rossumf7cea101997-05-28 19:31:14 +000031 b) because deep copy copies *everything* it may copy too much, e.g.
Guido van Rossumcc6764c1995-02-09 17:18:10 +000032 administrative data structures that should be shared even between
33 copies
34
35Python's deep copy operation avoids these problems by:
36
Guido van Rossumf7cea101997-05-28 19:31:14 +000037 a) keeping a table of objects already copied during the current
38 copying pass
Guido van Rossumcc6764c1995-02-09 17:18:10 +000039
Guido van Rossumf7cea101997-05-28 19:31:14 +000040 b) letting user-defined classes override the copying operation or the
Guido van Rossumcc6764c1995-02-09 17:18:10 +000041 set of components copied
42
43This version does not copy types like module, class, function, method,
44nor stack trace, stack frame, nor file, socket, window, nor array, nor
45any similar types.
46
47Classes can use the same interfaces to control copying that they use
48to control pickling: they can define methods called __getinitargs__(),
Guido van Rossumc5d2d511997-12-07 16:18:22 +000049__getstate__() and __setstate__(). See the documentation for module
Guido van Rossumcc6764c1995-02-09 17:18:10 +000050"pickle" for information on these methods.
51"""
Guido van Rossum409780f1995-01-10 00:34:21 +000052
Guido van Rossumabfdd701997-10-07 14:47:50 +000053# XXX need to support copy_reg here too...
54
Guido van Rossum409780f1995-01-10 00:34:21 +000055import types
56
Guido van Rossum55d2f391995-03-14 17:41:36 +000057error = 'copy.error'
58Error = error # backward compatibility
Guido van Rossum409780f1995-01-10 00:34:21 +000059
60def copy(x):
Guido van Rossumcc6764c1995-02-09 17:18:10 +000061 """Shallow copy operation on arbitrary Python objects.
62
63 See the module's __doc__ string for more info.
64 """
65
Guido van Rossum409780f1995-01-10 00:34:21 +000066 try:
67 copierfunction = _copy_dispatch[type(x)]
68 except KeyError:
69 try:
70 copier = x.__copy__
71 except AttributeError:
Guido van Rossum55d2f391995-03-14 17:41:36 +000072 raise error, \
Guido van Rossumcc6764c1995-02-09 17:18:10 +000073 "un(shallow)copyable object of type %s" % type(x)
Guido van Rossum409780f1995-01-10 00:34:21 +000074 y = copier()
75 else:
76 y = copierfunction(x)
77 return y
78
79_copy_dispatch = d = {}
80
81def _copy_atomic(x):
82 return x
83d[types.NoneType] = _copy_atomic
84d[types.IntType] = _copy_atomic
85d[types.LongType] = _copy_atomic
86d[types.FloatType] = _copy_atomic
87d[types.StringType] = _copy_atomic
Guido van Rossum2fff84d1999-01-25 21:37:02 +000088try:
89 d[types.CodeType] = _copy_atomic
90except AttributeError:
91 pass
Guido van Rossum409780f1995-01-10 00:34:21 +000092d[types.TypeType] = _copy_atomic
93d[types.XRangeType] = _copy_atomic
Guido van Rossum55d2f391995-03-14 17:41:36 +000094d[types.ClassType] = _copy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +000095
96def _copy_list(x):
97 return x[:]
98d[types.ListType] = _copy_list
99
100def _copy_tuple(x):
101 return x[:]
102d[types.TupleType] = _copy_tuple
103
104def _copy_dict(x):
Guido van Rossumf7cea101997-05-28 19:31:14 +0000105 return x.copy()
Guido van Rossum409780f1995-01-10 00:34:21 +0000106d[types.DictionaryType] = _copy_dict
107
108def _copy_inst(x):
109 if hasattr(x, '__copy__'):
110 return x.__copy__()
111 if hasattr(x, '__getinitargs__'):
112 args = x.__getinitargs__()
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000113 y = apply(x.__class__, args)
Guido van Rossum409780f1995-01-10 00:34:21 +0000114 else:
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000115 y = _EmptyClass()
116 y.__class__ = x.__class__
Guido van Rossum409780f1995-01-10 00:34:21 +0000117 if hasattr(x, '__getstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000118 state = x.__getstate__()
Guido van Rossum409780f1995-01-10 00:34:21 +0000119 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000120 state = x.__dict__
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000121 if hasattr(y, '__setstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000122 y.__setstate__(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000123 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000124 y.__dict__.update(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000125 return y
126d[types.InstanceType] = _copy_inst
127
128del d
129
130def deepcopy(x, memo = None):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000131 """Deep copy operation on arbitrary Python objects.
132
133 See the module's __doc__ string for more info.
134 """
135
Guido van Rossum409780f1995-01-10 00:34:21 +0000136 if memo is None:
137 memo = {}
138 d = id(x)
139 if memo.has_key(d):
140 return memo[d]
141 try:
142 copierfunction = _deepcopy_dispatch[type(x)]
143 except KeyError:
144 try:
145 copier = x.__deepcopy__
146 except AttributeError:
Guido van Rossum55d2f391995-03-14 17:41:36 +0000147 raise error, \
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000148 "un-deep-copyable object of type %s" % type(x)
Guido van Rossum409780f1995-01-10 00:34:21 +0000149 y = copier(memo)
150 else:
151 y = copierfunction(x, memo)
152 memo[d] = y
153 return y
154
155_deepcopy_dispatch = d = {}
156
157def _deepcopy_atomic(x, memo):
158 return x
159d[types.NoneType] = _deepcopy_atomic
160d[types.IntType] = _deepcopy_atomic
161d[types.LongType] = _deepcopy_atomic
162d[types.FloatType] = _deepcopy_atomic
163d[types.StringType] = _deepcopy_atomic
164d[types.CodeType] = _deepcopy_atomic
165d[types.TypeType] = _deepcopy_atomic
166d[types.XRangeType] = _deepcopy_atomic
167
168def _deepcopy_list(x, memo):
169 y = []
170 memo[id(x)] = y
171 for a in x:
172 y.append(deepcopy(a, memo))
173 return y
174d[types.ListType] = _deepcopy_list
175
176def _deepcopy_tuple(x, memo):
177 y = []
178 for a in x:
179 y.append(deepcopy(a, memo))
180 d = id(x)
181 try:
182 return memo[d]
183 except KeyError:
184 pass
185 for i in range(len(x)):
186 if x[i] is not y[i]:
Guido van Rossum6afff611996-06-17 17:10:11 +0000187 y = tuple(y)
188 break
189 else:
190 y = x
191 memo[d] = y
192 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000193d[types.TupleType] = _deepcopy_tuple
194
195def _deepcopy_dict(x, memo):
196 y = {}
197 memo[id(x)] = y
198 for key in x.keys():
199 y[deepcopy(key, memo)] = deepcopy(x[key], memo)
200 return y
201d[types.DictionaryType] = _deepcopy_dict
202
Guido van Rossum558be281997-08-20 22:26:19 +0000203def _keep_alive(x, memo):
Guido van Rossum8ca84201998-03-26 20:56:10 +0000204 """Keeps a reference to the object x in the memo.
Guido van Rossum558be281997-08-20 22:26:19 +0000205
Guido van Rossum8ca84201998-03-26 20:56:10 +0000206 Because we remember objects by their id, we have
207 to assure that possibly temporary objects are kept
208 alive by referencing them.
209 We store a reference at the id of the memo, which should
210 normally not be used unless someone tries to deepcopy
211 the memo itself...
212 """
213 try:
214 memo[id(memo)].append(x)
215 except KeyError:
216 # aha, this is the first one :-)
217 memo[id(memo)]=[x]
Guido van Rossum558be281997-08-20 22:26:19 +0000218
Guido van Rossum409780f1995-01-10 00:34:21 +0000219def _deepcopy_inst(x, memo):
220 if hasattr(x, '__deepcopy__'):
Guido van Rossum677fc841998-03-13 20:12:17 +0000221 return x.__deepcopy__(memo)
Guido van Rossum409780f1995-01-10 00:34:21 +0000222 if hasattr(x, '__getinitargs__'):
223 args = x.__getinitargs__()
Guido van Rossum558be281997-08-20 22:26:19 +0000224 _keep_alive(args, memo)
Guido van Rossum409780f1995-01-10 00:34:21 +0000225 args = deepcopy(args, memo)
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000226 y = apply(x.__class__, args)
Guido van Rossum409780f1995-01-10 00:34:21 +0000227 else:
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000228 y = _EmptyClass()
229 y.__class__ = x.__class__
Guido van Rossum409780f1995-01-10 00:34:21 +0000230 memo[id(x)] = y
231 if hasattr(x, '__getstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000232 state = x.__getstate__()
233 _keep_alive(state, memo)
Guido van Rossum409780f1995-01-10 00:34:21 +0000234 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000235 state = x.__dict__
Guido van Rossum409780f1995-01-10 00:34:21 +0000236 state = deepcopy(state, memo)
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000237 if hasattr(y, '__setstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000238 y.__setstate__(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000239 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000240 y.__dict__.update(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000241 return y
242d[types.InstanceType] = _deepcopy_inst
243
244del d
245
246del types
247
Guido van Rossumc5d2d511997-12-07 16:18:22 +0000248# Helper for instance creation without calling __init__
249class _EmptyClass:
250 pass
251
Guido van Rossum409780f1995-01-10 00:34:21 +0000252def _test():
Guido van Rossum55d2f391995-03-14 17:41:36 +0000253 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
254 {'abc': 'ABC'}, (), [], {}]
Guido van Rossum409780f1995-01-10 00:34:21 +0000255 l1 = copy(l)
256 print l1==l
257 l1 = map(copy, l)
258 print l1==l
259 l1 = deepcopy(l)
260 print l1==l
261 class C:
262 def __init__(self, arg=None):
263 self.a = 1
264 self.arg = arg
Guido van Rossumf7cea101997-05-28 19:31:14 +0000265 if __name__ == '__main__':
266 import sys
267 file = sys.argv[0]
268 else:
269 file = __file__
270 self.fp = open(file)
Guido van Rossum409780f1995-01-10 00:34:21 +0000271 self.fp.close()
272 def __getstate__(self):
273 return {'a': self.a, 'arg': self.arg}
274 def __setstate__(self, state):
275 for key in state.keys():
276 setattr(self, key, state[key])
277 def __deepcopy__(self, memo = None):
278 new = self.__class__(deepcopy(self.arg, memo))
279 new.a = self.a
280 return new
281 c = C('argument sketch')
282 l.append(c)
283 l2 = copy(l)
284 print l == l2
285 print l
286 print l2
287 l2 = deepcopy(l)
288 print l == l2
289 print l
290 print l2
291 l.append({l[1]: l, 'xyz': l[2]})
292 l3 = copy(l)
293 import repr
294 print map(repr.repr, l)
295 print map(repr.repr, l1)
296 print map(repr.repr, l2)
297 print map(repr.repr, l3)
298 l3 = deepcopy(l)
299 import repr
300 print map(repr.repr, l)
301 print map(repr.repr, l1)
302 print map(repr.repr, l2)
303 print map(repr.repr, l3)
304
305if __name__ == '__main__':
306 _test()