blob: ef1598285b311dd22ed00fb1ae4bdbb31ff2006f [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__'):
114 state = x.__getstate__()
115 else:
116 state = x.__dict__
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000117 if hasattr(y, '__setstate__'):
Guido van Rossum409780f1995-01-10 00:34:21 +0000118 y.__setstate__(state)
119 else:
120 for key in state.keys():
121 setattr(y, key, state[key])
122 return y
123d[types.InstanceType] = _copy_inst
124
125del d
126
127def deepcopy(x, memo = None):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000128 """Deep copy operation on arbitrary Python objects.
129
130 See the module's __doc__ string for more info.
131 """
132
Guido van Rossum409780f1995-01-10 00:34:21 +0000133 if memo is None:
134 memo = {}
135 d = id(x)
136 if memo.has_key(d):
137 return memo[d]
138 try:
139 copierfunction = _deepcopy_dispatch[type(x)]
140 except KeyError:
141 try:
142 copier = x.__deepcopy__
143 except AttributeError:
Guido van Rossum55d2f391995-03-14 17:41:36 +0000144 raise error, \
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000145 "un-deep-copyable object of type %s" % type(x)
Guido van Rossum409780f1995-01-10 00:34:21 +0000146 y = copier(memo)
147 else:
148 y = copierfunction(x, memo)
149 memo[d] = y
150 return y
151
152_deepcopy_dispatch = d = {}
153
154def _deepcopy_atomic(x, memo):
155 return x
156d[types.NoneType] = _deepcopy_atomic
157d[types.IntType] = _deepcopy_atomic
158d[types.LongType] = _deepcopy_atomic
159d[types.FloatType] = _deepcopy_atomic
160d[types.StringType] = _deepcopy_atomic
161d[types.CodeType] = _deepcopy_atomic
162d[types.TypeType] = _deepcopy_atomic
163d[types.XRangeType] = _deepcopy_atomic
164
165def _deepcopy_list(x, memo):
166 y = []
167 memo[id(x)] = y
168 for a in x:
169 y.append(deepcopy(a, memo))
170 return y
171d[types.ListType] = _deepcopy_list
172
173def _deepcopy_tuple(x, memo):
174 y = []
175 for a in x:
176 y.append(deepcopy(a, memo))
177 d = id(x)
178 try:
179 return memo[d]
180 except KeyError:
181 pass
182 for i in range(len(x)):
183 if x[i] is not y[i]:
Guido van Rossum6afff611996-06-17 17:10:11 +0000184 y = tuple(y)
185 break
186 else:
187 y = x
188 memo[d] = y
189 return y
Guido van Rossum409780f1995-01-10 00:34:21 +0000190d[types.TupleType] = _deepcopy_tuple
191
192def _deepcopy_dict(x, memo):
193 y = {}
194 memo[id(x)] = y
195 for key in x.keys():
196 y[deepcopy(key, memo)] = deepcopy(x[key], memo)
197 return y
198d[types.DictionaryType] = _deepcopy_dict
199
Guido van Rossum558be281997-08-20 22:26:19 +0000200def _keep_alive(x, memo):
201 """Keeps a reference to the object x in the memo.
202
203 Because we remember objects by their id, we have
204 to assure that possibly temporary objects are kept
205 alive by referencing them.
206 We store a reference at the id of the memo, which should
207 normally not be used unless someone tries to deepcopy
208 the memo itself...
209 """
210 try:
211 memo[id(memo)].append(x)
212 except KeyError:
213 # aha, this is the first one :-)
214 memo[id(memo)]=[x]
215
Guido van Rossum409780f1995-01-10 00:34:21 +0000216def _deepcopy_inst(x, memo):
217 if hasattr(x, '__deepcopy__'):
218 return x.__deepcopy__()
219 if hasattr(x, '__getinitargs__'):
220 args = x.__getinitargs__()
Guido van Rossum558be281997-08-20 22:26:19 +0000221 _keep_alive(args, memo)
Guido van Rossum409780f1995-01-10 00:34:21 +0000222 args = deepcopy(args, memo)
223 else:
224 args = ()
225 y = apply(x.__class__, args)
226 memo[id(x)] = y
227 if hasattr(x, '__getstate__'):
228 state = x.__getstate__()
Guido van Rossum558be281997-08-20 22:26:19 +0000229 _keep_alive(state, memo)
Guido van Rossum409780f1995-01-10 00:34:21 +0000230 else:
231 state = x.__dict__
232 state = deepcopy(state, memo)
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000233 if hasattr(y, '__setstate__'):
Guido van Rossum409780f1995-01-10 00:34:21 +0000234 y.__setstate__(state)
235 else:
236 for key in state.keys():
237 setattr(y, key, state[key])
238 return y
239d[types.InstanceType] = _deepcopy_inst
240
241del d
242
243del types
244
245def _test():
Guido van Rossum55d2f391995-03-14 17:41:36 +0000246 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
247 {'abc': 'ABC'}, (), [], {}]
Guido van Rossum409780f1995-01-10 00:34:21 +0000248 l1 = copy(l)
249 print l1==l
250 l1 = map(copy, l)
251 print l1==l
252 l1 = deepcopy(l)
253 print l1==l
254 class C:
255 def __init__(self, arg=None):
256 self.a = 1
257 self.arg = arg
Guido van Rossumf7cea101997-05-28 19:31:14 +0000258 if __name__ == '__main__':
259 import sys
260 file = sys.argv[0]
261 else:
262 file = __file__
263 self.fp = open(file)
Guido van Rossum409780f1995-01-10 00:34:21 +0000264 self.fp.close()
265 def __getstate__(self):
266 return {'a': self.a, 'arg': self.arg}
267 def __setstate__(self, state):
268 for key in state.keys():
269 setattr(self, key, state[key])
270 def __deepcopy__(self, memo = None):
271 new = self.__class__(deepcopy(self.arg, memo))
272 new.a = self.a
273 return new
274 c = C('argument sketch')
275 l.append(c)
276 l2 = copy(l)
277 print l == l2
278 print l
279 print l2
280 l2 = deepcopy(l)
281 print l == l2
282 print l
283 print l2
284 l.append({l[1]: l, 'xyz': l[2]})
285 l3 = copy(l)
286 import repr
287 print map(repr.repr, l)
288 print map(repr.repr, l1)
289 print map(repr.repr, l2)
290 print map(repr.repr, l3)
291 l3 = deepcopy(l)
292 import repr
293 print map(repr.repr, l)
294 print map(repr.repr, l1)
295 print map(repr.repr, l2)
296 print map(repr.repr, l3)
297
298if __name__ == '__main__':
299 _test()