blob: a48e8c8e3a97ebfaaffcbfa08902471692d736ed [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
28(a) recursive objects (compound objects that, directly or indirectly,
29 contain a reference to themselves) may cause a recursive loop
30
31(b) because deep copy copies *everything* it may copy too much, e.g.
32 administrative data structures that should be shared even between
33 copies
34
35Python's deep copy operation avoids these problems by:
36
37(a) keeping a table of objects already copied during the current
38copying pass
39
40(b) letting user-defined classes override the copying operation or the
41 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
53import types
54
Guido van Rossum55d2f391995-03-14 17:41:36 +000055error = 'copy.error'
56Error = error # backward compatibility
Guido van Rossum409780f1995-01-10 00:34:21 +000057
58def copy(x):
Guido van Rossumcc6764c1995-02-09 17:18:10 +000059 """Shallow copy operation on arbitrary Python objects.
60
61 See the module's __doc__ string for more info.
62 """
63
Guido van Rossum409780f1995-01-10 00:34:21 +000064 try:
65 copierfunction = _copy_dispatch[type(x)]
66 except KeyError:
67 try:
68 copier = x.__copy__
69 except AttributeError:
Guido van Rossum55d2f391995-03-14 17:41:36 +000070 raise error, \
Guido van Rossumcc6764c1995-02-09 17:18:10 +000071 "un(shallow)copyable object of type %s" % type(x)
Guido van Rossum409780f1995-01-10 00:34:21 +000072 y = copier()
73 else:
74 y = copierfunction(x)
75 return y
76
77_copy_dispatch = d = {}
78
79def _copy_atomic(x):
80 return x
81d[types.NoneType] = _copy_atomic
82d[types.IntType] = _copy_atomic
83d[types.LongType] = _copy_atomic
84d[types.FloatType] = _copy_atomic
85d[types.StringType] = _copy_atomic
86d[types.CodeType] = _copy_atomic
87d[types.TypeType] = _copy_atomic
88d[types.XRangeType] = _copy_atomic
Guido van Rossum55d2f391995-03-14 17:41:36 +000089d[types.ClassType] = _copy_atomic
Guido van Rossum409780f1995-01-10 00:34:21 +000090
91def _copy_list(x):
92 return x[:]
93d[types.ListType] = _copy_list
94
95def _copy_tuple(x):
96 return x[:]
97d[types.TupleType] = _copy_tuple
98
99def _copy_dict(x):
100 y = {}
101 for key in x.keys():
102 y[key] = x[key]
103 return y
104d[types.DictionaryType] = _copy_dict
105
106def _copy_inst(x):
107 if hasattr(x, '__copy__'):
108 return x.__copy__()
109 if hasattr(x, '__getinitargs__'):
110 args = x.__getinitargs__()
111 else:
112 args = ()
113 y = apply(x.__class__, args)
114 if hasattr(x, '__getstate__'):
115 state = x.__getstate__()
116 else:
117 state = x.__dict__
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000118 if hasattr(y, '__setstate__'):
Guido van Rossum409780f1995-01-10 00:34:21 +0000119 y.__setstate__(state)
120 else:
121 for key in state.keys():
122 setattr(y, key, state[key])
123 return y
124d[types.InstanceType] = _copy_inst
125
126del d
127
128def deepcopy(x, memo = None):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000129 """Deep copy operation on arbitrary Python objects.
130
131 See the module's __doc__ string for more info.
132 """
133
Guido van Rossum409780f1995-01-10 00:34:21 +0000134 if memo is None:
135 memo = {}
136 d = id(x)
137 if memo.has_key(d):
138 return memo[d]
139 try:
140 copierfunction = _deepcopy_dispatch[type(x)]
141 except KeyError:
142 try:
143 copier = x.__deepcopy__
144 except AttributeError:
Guido van Rossum55d2f391995-03-14 17:41:36 +0000145 raise error, \
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000146 "un-deep-copyable object of type %s" % type(x)
Guido van Rossum409780f1995-01-10 00:34:21 +0000147 y = copier(memo)
148 else:
149 y = copierfunction(x, memo)
150 memo[d] = y
151 return y
152
153_deepcopy_dispatch = d = {}
154
155def _deepcopy_atomic(x, memo):
156 return x
157d[types.NoneType] = _deepcopy_atomic
158d[types.IntType] = _deepcopy_atomic
159d[types.LongType] = _deepcopy_atomic
160d[types.FloatType] = _deepcopy_atomic
161d[types.StringType] = _deepcopy_atomic
162d[types.CodeType] = _deepcopy_atomic
163d[types.TypeType] = _deepcopy_atomic
164d[types.XRangeType] = _deepcopy_atomic
165
166def _deepcopy_list(x, memo):
167 y = []
168 memo[id(x)] = y
169 for a in x:
170 y.append(deepcopy(a, memo))
171 return y
172d[types.ListType] = _deepcopy_list
173
174def _deepcopy_tuple(x, memo):
175 y = []
176 for a in x:
177 y.append(deepcopy(a, memo))
178 d = id(x)
179 try:
180 return memo[d]
181 except KeyError:
182 pass
183 for i in range(len(x)):
184 if x[i] is not y[i]:
185 return tuple(y)
186 return x
187d[types.TupleType] = _deepcopy_tuple
188
189def _deepcopy_dict(x, memo):
190 y = {}
191 memo[id(x)] = y
192 for key in x.keys():
193 y[deepcopy(key, memo)] = deepcopy(x[key], memo)
194 return y
195d[types.DictionaryType] = _deepcopy_dict
196
197def _deepcopy_inst(x, memo):
198 if hasattr(x, '__deepcopy__'):
199 return x.__deepcopy__()
200 if hasattr(x, '__getinitargs__'):
201 args = x.__getinitargs__()
202 args = deepcopy(args, memo)
203 else:
204 args = ()
205 y = apply(x.__class__, args)
206 memo[id(x)] = y
207 if hasattr(x, '__getstate__'):
208 state = x.__getstate__()
209 else:
210 state = x.__dict__
211 state = deepcopy(state, memo)
Guido van Rossumfefbbe51995-03-22 10:10:31 +0000212 if hasattr(y, '__setstate__'):
Guido van Rossum409780f1995-01-10 00:34:21 +0000213 y.__setstate__(state)
214 else:
215 for key in state.keys():
216 setattr(y, key, state[key])
217 return y
218d[types.InstanceType] = _deepcopy_inst
219
220del d
221
222del types
223
224def _test():
Guido van Rossum55d2f391995-03-14 17:41:36 +0000225 l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'],
226 {'abc': 'ABC'}, (), [], {}]
Guido van Rossum409780f1995-01-10 00:34:21 +0000227 l1 = copy(l)
228 print l1==l
229 l1 = map(copy, l)
230 print l1==l
231 l1 = deepcopy(l)
232 print l1==l
233 class C:
234 def __init__(self, arg=None):
235 self.a = 1
236 self.arg = arg
237 self.fp = open('copy.py')
238 self.fp.close()
239 def __getstate__(self):
240 return {'a': self.a, 'arg': self.arg}
241 def __setstate__(self, state):
242 for key in state.keys():
243 setattr(self, key, state[key])
244 def __deepcopy__(self, memo = None):
245 new = self.__class__(deepcopy(self.arg, memo))
246 new.a = self.a
247 return new
248 c = C('argument sketch')
249 l.append(c)
250 l2 = copy(l)
251 print l == l2
252 print l
253 print l2
254 l2 = deepcopy(l)
255 print l == l2
256 print l
257 print l2
258 l.append({l[1]: l, 'xyz': l[2]})
259 l3 = copy(l)
260 import repr
261 print map(repr.repr, l)
262 print map(repr.repr, l1)
263 print map(repr.repr, l2)
264 print map(repr.repr, l3)
265 l3 = deepcopy(l)
266 import repr
267 print map(repr.repr, l)
268 print map(repr.repr, l1)
269 print map(repr.repr, l2)
270 print map(repr.repr, l3)
271
272if __name__ == '__main__':
273 _test()