blob: 51c375d65fcf53959547077c93e0ac8577e0d30a [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__(),
49__getstate__() and __setstate__(). See the __doc__ string of module
50"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
88d[types.CodeType] = _copy_atomic
89d[types.TypeType] = _copy_atomic
90d[types.XRangeType] = _copy_atomic
Guido van Rossum55d2f391995-03-14 17:41:36 +000091d[types.ClassType] = _copy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +000092
93def _copy_list(x):
94 return x[:]
95d[types.ListType] = _copy_list
96
97def _copy_tuple(x):
98 return x[:]
99d[types.TupleType] = _copy_tuple
100
101def _copy_dict(x):
Guido van Rossumf7cea101997-05-28 19:31:14 +0000102 return x.copy()
Guido van Rossum409780f1995-01-10 00:34:21 +0000103d[types.DictionaryType] = _copy_dict
104
105def _copy_inst(x):
106 if hasattr(x, '__copy__'):
107 return x.__copy__()
108 if hasattr(x, '__getinitargs__'):
109 args = x.__getinitargs__()
110 else:
111 args = ()
112 y = apply(x.__class__, args)
113 if hasattr(x, '__getstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000114 state = x.__getstate__()
Guido van Rossum409780f1995-01-10 00:34:21 +0000115 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000116 state = x.__dict__
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000117 if hasattr(y, '__setstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000118 y.__setstate__(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000119 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000120 y.__dict__.update(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000121 return y
122d[types.InstanceType] = _copy_inst
123
124del d
125
126def deepcopy(x, memo = None):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000127 """Deep copy operation on arbitrary Python objects.
128
129 See the module's __doc__ string for more info.
130 """
131
Guido van Rossum409780f1995-01-10 00:34:21 +0000132 if memo is None:
133 memo = {}
134 d = id(x)
135 if memo.has_key(d):
136 return memo[d]
137 try:
138 copierfunction = _deepcopy_dispatch[type(x)]
139 except KeyError:
140 try:
141 copier = x.__deepcopy__
142 except AttributeError:
Guido van Rossum55d2f391995-03-14 17:41:36 +0000143 raise error, \
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000144 "un-deep-copyable object of type %s" % type(x)
Guido van Rossum409780f1995-01-10 00:34:21 +0000145 y = copier(memo)
146 else:
147 y = copierfunction(x, memo)
148 memo[d] = y
149 return y
150
151_deepcopy_dispatch = d = {}
152
153def _deepcopy_atomic(x, memo):
154 return x
155d[types.NoneType] = _deepcopy_atomic
156d[types.IntType] = _deepcopy_atomic
157d[types.LongType] = _deepcopy_atomic
158d[types.FloatType] = _deepcopy_atomic
159d[types.StringType] = _deepcopy_atomic
160d[types.CodeType] = _deepcopy_atomic
161d[types.TypeType] = _deepcopy_atomic
162d[types.XRangeType] = _deepcopy_atomic
163
164def _deepcopy_list(x, memo):
165 y = []
166 memo[id(x)] = y
167 for a in x:
168 y.append(deepcopy(a, memo))
169 return y
170d[types.ListType] = _deepcopy_list
171
172def _deepcopy_tuple(x, memo):
173 y = []
174 for a in x:
175 y.append(deepcopy(a, memo))
176 d = id(x)
177 try:
178 return memo[d]
179 except KeyError:
180 pass
181 for i in range(len(x)):
182 if x[i] is not y[i]:
Guido van Rossum6afff611996-06-17 17:10:11 +0000183 y = tuple(y)
184 break
185 else:
186 y = x
187 memo[d] = y
188 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000189d[types.TupleType] = _deepcopy_tuple
190
191def _deepcopy_dict(x, memo):
192 y = {}
193 memo[id(x)] = y
194 for key in x.keys():
195 y[deepcopy(key, memo)] = deepcopy(x[key], memo)
196 return y
197d[types.DictionaryType] = _deepcopy_dict
198
Guido van Rossum558be281997-08-20 22:26:19 +0000199def _keep_alive(x, memo):
200 """Keeps a reference to the object x in the memo.
201
202 Because we remember objects by their id, we have
203 to assure that possibly temporary objects are kept
204 alive by referencing them.
205 We store a reference at the id of the memo, which should
206 normally not be used unless someone tries to deepcopy
207 the memo itself...
208 """
209 try:
210 memo[id(memo)].append(x)
211 except KeyError:
212 # aha, this is the first one :-)
213 memo[id(memo)]=[x]
214
Guido van Rossum409780f1995-01-10 00:34:21 +0000215def _deepcopy_inst(x, memo):
216 if hasattr(x, '__deepcopy__'):
217 return x.__deepcopy__()
218 if hasattr(x, '__getinitargs__'):
219 args = x.__getinitargs__()
Guido van Rossum558be281997-08-20 22:26:19 +0000220 _keep_alive(args, memo)
Guido van Rossum409780f1995-01-10 00:34:21 +0000221 args = deepcopy(args, memo)
222 else:
223 args = ()
224 y = apply(x.__class__, args)
225 memo[id(x)] = y
226 if hasattr(x, '__getstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000227 state = x.__getstate__()
228 _keep_alive(state, memo)
Guido van Rossum409780f1995-01-10 00:34:21 +0000229 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000230 state = x.__dict__
Guido van Rossum409780f1995-01-10 00:34:21 +0000231 state = deepcopy(state, memo)
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000232 if hasattr(y, '__setstate__'):
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000233 y.__setstate__(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000234 else:
Guido van Rossume6eef4b1997-10-26 17:00:25 +0000235 y.__dict__.update(state)
Guido van Rossum409780f1995-01-10 00:34:21 +0000236 return y
237d[types.InstanceType] = _deepcopy_inst
238
239del d
240
241del types
242
243def _test():
Guido van Rossum55d2f391995-03-14 17:41:36 +0000244 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
245 {'abc': 'ABC'}, (), [], {}]
Guido van Rossum409780f1995-01-10 00:34:21 +0000246 l1 = copy(l)
247 print l1==l
248 l1 = map(copy, l)
249 print l1==l
250 l1 = deepcopy(l)
251 print l1==l
252 class C:
253 def __init__(self, arg=None):
254 self.a = 1
255 self.arg = arg
Guido van Rossumf7cea101997-05-28 19:31:14 +0000256 if __name__ == '__main__':
257 import sys
258 file = sys.argv[0]
259 else:
260 file = __file__
261 self.fp = open(file)
Guido van Rossum409780f1995-01-10 00:34:21 +0000262 self.fp.close()
263 def __getstate__(self):
264 return {'a': self.a, 'arg': self.arg}
265 def __setstate__(self, state):
266 for key in state.keys():
267 setattr(self, key, state[key])
268 def __deepcopy__(self, memo = None):
269 new = self.__class__(deepcopy(self.arg, memo))
270 new.a = self.a
271 return new
272 c = C('argument sketch')
273 l.append(c)
274 l2 = copy(l)
275 print l == l2
276 print l
277 print l2
278 l2 = deepcopy(l)
279 print l == l2
280 print l
281 print l2
282 l.append({l[1]: l, 'xyz': l[2]})
283 l3 = copy(l)
284 import repr
285 print map(repr.repr, l)
286 print map(repr.repr, l1)
287 print map(repr.repr, l2)
288 print map(repr.repr, l3)
289 l3 = deepcopy(l)
290 import repr
291 print map(repr.repr, l)
292 print map(repr.repr, l1)
293 print map(repr.repr, l2)
294 print map(repr.repr, l3)
295
296if __name__ == '__main__':
297 _test()