blob: c4baae48611c373ed27d146e3a948f31f03941b7 [file] [log] [blame]
Guido van Rossum581cb932003-02-06 17:52:15 +00001"""Unit tests for the copy module."""
2
Guido van Rossum581cb932003-02-06 17:52:15 +00003import copy
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +00004import copyreg
Antoine Pitrou6e610062009-05-15 17:04:50 +00005import weakref
Mark Dickinsona56c4672009-01-27 18:17:45 +00006from operator import le, lt, ge, gt, eq, ne
Antoine Pitrou6e610062009-05-15 17:04:50 +00007
Guido van Rossum581cb932003-02-06 17:52:15 +00008import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009from test import support
Guido van Rossum581cb932003-02-06 17:52:15 +000010
Mark Dickinsona56c4672009-01-27 18:17:45 +000011order_comparisons = le, lt, ge, gt
12equality_comparisons = eq, ne
13comparisons = order_comparisons + equality_comparisons
14
Guido van Rossum581cb932003-02-06 17:52:15 +000015class TestCopy(unittest.TestCase):
16
17 # Attempt full line coverage of copy.py from top to bottom
18
19 def test_exceptions(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020020 self.assertIs(copy.Error, copy.error)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000021 self.assertTrue(issubclass(copy.Error, Exception))
Guido van Rossum581cb932003-02-06 17:52:15 +000022
23 # The copy() method
24
25 def test_copy_basic(self):
26 x = 42
27 y = copy.copy(x)
28 self.assertEqual(x, y)
29
30 def test_copy_copy(self):
31 class C(object):
32 def __init__(self, foo):
33 self.foo = foo
34 def __copy__(self):
35 return C(self.foo)
36 x = C(42)
37 y = copy.copy(x)
38 self.assertEqual(y.__class__, x.__class__)
39 self.assertEqual(y.foo, x.foo)
40
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000041 def test_copy_registry(self):
42 class C(object):
43 def __new__(cls, foo):
44 obj = object.__new__(cls)
45 obj.foo = foo
46 return obj
47 def pickle_C(obj):
48 return (C, (obj.foo,))
49 x = C(42)
50 self.assertRaises(TypeError, copy.copy, x)
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +000051 copyreg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000052 y = copy.copy(x)
53
Guido van Rossume6908832003-02-19 01:19:28 +000054 def test_copy_reduce_ex(self):
55 class C(object):
56 def __reduce_ex__(self, proto):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020057 c.append(1)
Guido van Rossume6908832003-02-19 01:19:28 +000058 return ""
59 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020060 self.fail("shouldn't call this")
61 c = []
Guido van Rossume6908832003-02-19 01:19:28 +000062 x = C()
63 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +020064 self.assertIs(y, x)
65 self.assertEqual(c, [1])
Guido van Rossume6908832003-02-19 01:19:28 +000066
Guido van Rossum581cb932003-02-06 17:52:15 +000067 def test_copy_reduce(self):
68 class C(object):
69 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +020070 c.append(1)
Guido van Rossum581cb932003-02-06 17:52:15 +000071 return ""
Sandro Tosi4dc9c842011-08-05 23:05:35 +020072 c = []
Guido van Rossum581cb932003-02-06 17:52:15 +000073 x = C()
74 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +020075 self.assertIs(y, x)
76 self.assertEqual(c, [1])
Guido van Rossum581cb932003-02-06 17:52:15 +000077
78 def test_copy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +000079 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +000080 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +000081 if name.startswith("__reduce"):
Collin Winter3add4d72007-08-29 23:37:32 +000082 raise AttributeError(name)
Guido van Rossum581cb932003-02-06 17:52:15 +000083 return object.__getattribute__(self, name)
84 x = C()
85 self.assertRaises(copy.Error, copy.copy, x)
86
87 # Type-specific _copy_xxx() methods
88
89 def test_copy_atomic(self):
90 class Classic:
91 pass
92 class NewStyle(object):
93 pass
94 def f():
95 pass
Guido van Rossume2a383d2007-01-15 16:59:06 +000096 tests = [None, 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +000097 "hello", "hello\u1234", f.__code__,
Guido van Rossum805365e2007-05-07 22:24:25 +000098 NewStyle, range(10), Classic, max]
Guido van Rossum581cb932003-02-06 17:52:15 +000099 for x in tests:
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200100 self.assertIs(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000101
102 def test_copy_list(self):
103 x = [1, 2, 3]
104 self.assertEqual(copy.copy(x), x)
105
106 def test_copy_tuple(self):
107 x = (1, 2, 3)
108 self.assertEqual(copy.copy(x), x)
109
110 def test_copy_dict(self):
111 x = {"foo": 1, "bar": 2}
112 self.assertEqual(copy.copy(x), x)
113
114 def test_copy_inst_vanilla(self):
115 class C:
116 def __init__(self, foo):
117 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000118 def __eq__(self, other):
119 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000120 x = C(42)
121 self.assertEqual(copy.copy(x), x)
122
123 def test_copy_inst_copy(self):
124 class C:
125 def __init__(self, foo):
126 self.foo = foo
127 def __copy__(self):
128 return C(self.foo)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000129 def __eq__(self, other):
130 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000131 x = C(42)
132 self.assertEqual(copy.copy(x), x)
133
134 def test_copy_inst_getinitargs(self):
135 class C:
136 def __init__(self, foo):
137 self.foo = foo
138 def __getinitargs__(self):
139 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000140 def __eq__(self, other):
141 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000142 x = C(42)
143 self.assertEqual(copy.copy(x), x)
144
145 def test_copy_inst_getstate(self):
146 class C:
147 def __init__(self, foo):
148 self.foo = foo
149 def __getstate__(self):
150 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000151 def __eq__(self, other):
152 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000153 x = C(42)
154 self.assertEqual(copy.copy(x), x)
155
156 def test_copy_inst_setstate(self):
157 class C:
158 def __init__(self, foo):
159 self.foo = foo
160 def __setstate__(self, state):
161 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000162 def __eq__(self, other):
163 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000164 x = C(42)
165 self.assertEqual(copy.copy(x), x)
166
167 def test_copy_inst_getstate_setstate(self):
168 class C:
169 def __init__(self, foo):
170 self.foo = foo
171 def __getstate__(self):
172 return self.foo
173 def __setstate__(self, state):
174 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000175 def __eq__(self, other):
176 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000177 x = C(42)
178 self.assertEqual(copy.copy(x), x)
179
180 # The deepcopy() method
181
182 def test_deepcopy_basic(self):
183 x = 42
184 y = copy.deepcopy(x)
185 self.assertEqual(y, x)
186
187 def test_deepcopy_memo(self):
Guido van Rossum99d2c252003-06-13 19:28:47 +0000188 # Tests of reflexive objects are under type-specific sections below.
189 # This tests only repetitions of objects.
Guido van Rossum581cb932003-02-06 17:52:15 +0000190 x = []
Guido van Rossum99d2c252003-06-13 19:28:47 +0000191 x = [x, x]
Guido van Rossum581cb932003-02-06 17:52:15 +0000192 y = copy.deepcopy(x)
193 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200194 self.assertIsNot(y, x)
195 self.assertIsNot(y[0], x[0])
196 self.assertIs(y[0], y[1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000197
198 def test_deepcopy_issubclass(self):
199 # XXX Note: there's no way to test the TypeError coming out of
200 # issubclass() -- this can only happen when an extension
201 # module defines a "type" that doesn't formally inherit from
202 # type.
203 class Meta(type):
204 pass
Guido van Rossum52cc1d82007-03-18 15:41:51 +0000205 class C(metaclass=Meta):
206 pass
Guido van Rossum581cb932003-02-06 17:52:15 +0000207 self.assertEqual(copy.deepcopy(C), C)
208
209 def test_deepcopy_deepcopy(self):
210 class C(object):
211 def __init__(self, foo):
212 self.foo = foo
213 def __deepcopy__(self, memo=None):
214 return C(self.foo)
215 x = C(42)
216 y = copy.deepcopy(x)
217 self.assertEqual(y.__class__, x.__class__)
218 self.assertEqual(y.foo, x.foo)
219
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000220 def test_deepcopy_registry(self):
221 class C(object):
222 def __new__(cls, foo):
223 obj = object.__new__(cls)
224 obj.foo = foo
225 return obj
226 def pickle_C(obj):
227 return (C, (obj.foo,))
228 x = C(42)
229 self.assertRaises(TypeError, copy.deepcopy, x)
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000230 copyreg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000231 y = copy.deepcopy(x)
232
Guido van Rossume6908832003-02-19 01:19:28 +0000233 def test_deepcopy_reduce_ex(self):
234 class C(object):
235 def __reduce_ex__(self, proto):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200236 c.append(1)
Guido van Rossume6908832003-02-19 01:19:28 +0000237 return ""
238 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200239 self.fail("shouldn't call this")
240 c = []
Guido van Rossume6908832003-02-19 01:19:28 +0000241 x = C()
242 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200243 self.assertIs(y, x)
244 self.assertEqual(c, [1])
Guido van Rossume6908832003-02-19 01:19:28 +0000245
Guido van Rossum581cb932003-02-06 17:52:15 +0000246 def test_deepcopy_reduce(self):
247 class C(object):
248 def __reduce__(self):
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200249 c.append(1)
Guido van Rossum581cb932003-02-06 17:52:15 +0000250 return ""
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200251 c = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000252 x = C()
253 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200254 self.assertIs(y, x)
255 self.assertEqual(c, [1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000256
257 def test_deepcopy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +0000258 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +0000259 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +0000260 if name.startswith("__reduce"):
Collin Winter3add4d72007-08-29 23:37:32 +0000261 raise AttributeError(name)
Guido van Rossum581cb932003-02-06 17:52:15 +0000262 return object.__getattribute__(self, name)
263 x = C()
264 self.assertRaises(copy.Error, copy.deepcopy, x)
265
266 # Type-specific _deepcopy_xxx() methods
267
268 def test_deepcopy_atomic(self):
269 class Classic:
270 pass
271 class NewStyle(object):
272 pass
273 def f():
274 pass
Guido van Rossume2a383d2007-01-15 16:59:06 +0000275 tests = [None, 42, 2**100, 3.14, True, False, 1j,
Guido van Rossumef87d6e2007-05-02 19:09:54 +0000276 "hello", "hello\u1234", f.__code__,
Guido van Rossum805365e2007-05-07 22:24:25 +0000277 NewStyle, range(10), Classic, max]
Guido van Rossum581cb932003-02-06 17:52:15 +0000278 for x in tests:
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200279 self.assertIs(copy.deepcopy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000280
281 def test_deepcopy_list(self):
282 x = [[1, 2], 3]
283 y = copy.deepcopy(x)
284 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200285 self.assertIsNot(x, y)
286 self.assertIsNot(x[0], y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000287
Guido van Rossum99d2c252003-06-13 19:28:47 +0000288 def test_deepcopy_reflexive_list(self):
289 x = []
290 x.append(x)
291 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000292 for op in comparisons:
293 self.assertRaises(RuntimeError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200294 self.assertIsNot(y, x)
295 self.assertIs(y[0], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000296 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000297
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200298 def test_deepcopy_empty_tuple(self):
299 x = ()
300 y = copy.deepcopy(x)
301 self.assertIs(x, y)
302
Guido van Rossum581cb932003-02-06 17:52:15 +0000303 def test_deepcopy_tuple(self):
304 x = ([1, 2], 3)
305 y = copy.deepcopy(x)
306 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200307 self.assertIsNot(x, y)
308 self.assertIsNot(x[0], y[0])
309
310 def test_deepcopy_tuple_of_immutables(self):
311 x = ((1, 2), 3)
312 y = copy.deepcopy(x)
313 self.assertIs(x, y)
Guido van Rossum581cb932003-02-06 17:52:15 +0000314
Guido van Rossum99d2c252003-06-13 19:28:47 +0000315 def test_deepcopy_reflexive_tuple(self):
316 x = ([],)
317 x[0].append(x)
318 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000319 for op in comparisons:
320 self.assertRaises(RuntimeError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200321 self.assertIsNot(y, x)
322 self.assertIsNot(y[0], x[0])
323 self.assertIs(y[0][0], y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000324
Guido van Rossum581cb932003-02-06 17:52:15 +0000325 def test_deepcopy_dict(self):
326 x = {"foo": [1, 2], "bar": 3}
327 y = copy.deepcopy(x)
328 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200329 self.assertIsNot(x, y)
330 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum581cb932003-02-06 17:52:15 +0000331
Guido van Rossum99d2c252003-06-13 19:28:47 +0000332 def test_deepcopy_reflexive_dict(self):
333 x = {}
334 x['foo'] = x
335 y = copy.deepcopy(x)
Mark Dickinsona56c4672009-01-27 18:17:45 +0000336 for op in order_comparisons:
337 self.assertRaises(TypeError, op, y, x)
338 for op in equality_comparisons:
339 self.assertRaises(RuntimeError, op, y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200340 self.assertIsNot(y, x)
341 self.assertIs(y['foo'], y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000342 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000343
Guido van Rossum581cb932003-02-06 17:52:15 +0000344 def test_deepcopy_keepalive(self):
345 memo = {}
Benjamin Petersone90ec362011-06-27 16:22:46 -0500346 x = []
Guido van Rossum581cb932003-02-06 17:52:15 +0000347 y = copy.deepcopy(x, memo)
Benjamin Petersone90ec362011-06-27 16:22:46 -0500348 self.assertIs(memo[id(memo)][0], x)
349
350 def test_deepcopy_dont_memo_immutable(self):
351 memo = {}
352 x = [1, 2, 3, 4]
353 y = copy.deepcopy(x, memo)
354 self.assertEqual(y, x)
355 # There's the entry for the new list, and the keep alive.
356 self.assertEqual(len(memo), 2)
357
358 memo = {}
359 x = [(1, 2)]
360 y = copy.deepcopy(x, memo)
361 self.assertEqual(y, x)
362 # Tuples with immutable contents are immutable for deepcopy.
363 self.assertEqual(len(memo), 2)
Guido van Rossum581cb932003-02-06 17:52:15 +0000364
365 def test_deepcopy_inst_vanilla(self):
366 class C:
367 def __init__(self, foo):
368 self.foo = foo
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000369 def __eq__(self, other):
370 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000371 x = C([42])
372 y = copy.deepcopy(x)
373 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200374 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000375
376 def test_deepcopy_inst_deepcopy(self):
377 class C:
378 def __init__(self, foo):
379 self.foo = foo
380 def __deepcopy__(self, memo):
381 return C(copy.deepcopy(self.foo, memo))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000382 def __eq__(self, other):
383 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000384 x = C([42])
385 y = copy.deepcopy(x)
386 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200387 self.assertIsNot(y, x)
388 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000389
390 def test_deepcopy_inst_getinitargs(self):
391 class C:
392 def __init__(self, foo):
393 self.foo = foo
394 def __getinitargs__(self):
395 return (self.foo,)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000396 def __eq__(self, other):
397 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000398 x = C([42])
399 y = copy.deepcopy(x)
400 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200401 self.assertIsNot(y, x)
402 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000403
404 def test_deepcopy_inst_getstate(self):
405 class C:
406 def __init__(self, foo):
407 self.foo = foo
408 def __getstate__(self):
409 return {"foo": self.foo}
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000410 def __eq__(self, other):
411 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000412 x = C([42])
413 y = copy.deepcopy(x)
414 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200415 self.assertIsNot(y, x)
416 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000417
418 def test_deepcopy_inst_setstate(self):
419 class C:
420 def __init__(self, foo):
421 self.foo = foo
422 def __setstate__(self, state):
423 self.foo = state["foo"]
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000424 def __eq__(self, other):
425 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000426 x = C([42])
427 y = copy.deepcopy(x)
428 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200429 self.assertIsNot(y, x)
430 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000431
432 def test_deepcopy_inst_getstate_setstate(self):
433 class C:
434 def __init__(self, foo):
435 self.foo = foo
436 def __getstate__(self):
437 return self.foo
438 def __setstate__(self, state):
439 self.foo = state
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000440 def __eq__(self, other):
441 return self.foo == other.foo
Guido van Rossum581cb932003-02-06 17:52:15 +0000442 x = C([42])
443 y = copy.deepcopy(x)
444 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200445 self.assertIsNot(y, x)
446 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000447
Guido van Rossum99d2c252003-06-13 19:28:47 +0000448 def test_deepcopy_reflexive_inst(self):
449 class C:
450 pass
451 x = C()
452 x.foo = x
453 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200454 self.assertIsNot(y, x)
455 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000456
Guido van Rossum581cb932003-02-06 17:52:15 +0000457 # _reconstruct()
458
459 def test_reconstruct_string(self):
460 class C(object):
461 def __reduce__(self):
462 return ""
463 x = C()
464 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200465 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000466 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200467 self.assertIs(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000468
469 def test_reconstruct_nostate(self):
470 class C(object):
471 def __reduce__(self):
472 return (C, ())
473 x = C()
474 x.foo = 42
475 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200476 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000477 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200478 self.assertIs(y.__class__, x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000479
480 def test_reconstruct_state(self):
481 class C(object):
482 def __reduce__(self):
483 return (C, (), self.__dict__)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000484 def __eq__(self, other):
485 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000486 x = C()
487 x.foo = [42]
488 y = copy.copy(x)
489 self.assertEqual(y, x)
490 y = copy.deepcopy(x)
491 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200492 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000493
494 def test_reconstruct_state_setstate(self):
495 class C(object):
496 def __reduce__(self):
497 return (C, (), self.__dict__)
498 def __setstate__(self, state):
499 self.__dict__.update(state)
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000500 def __eq__(self, other):
501 return self.__dict__ == other.__dict__
Guido van Rossum581cb932003-02-06 17:52:15 +0000502 x = C()
503 x.foo = [42]
504 y = copy.copy(x)
505 self.assertEqual(y, x)
506 y = copy.deepcopy(x)
507 self.assertEqual(y, x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200508 self.assertIsNot(y.foo, x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000509
Guido van Rossum99d2c252003-06-13 19:28:47 +0000510 def test_reconstruct_reflexive(self):
511 class C(object):
512 pass
513 x = C()
514 x.foo = x
515 y = copy.deepcopy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200516 self.assertIsNot(y, x)
517 self.assertIs(y.foo, y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000518
Guido van Rossum90e05b02003-02-06 18:18:23 +0000519 # Additions for Python 2.3 and pickle protocol 2
520
521 def test_reduce_4tuple(self):
522 class C(list):
523 def __reduce__(self):
524 return (C, (), self.__dict__, iter(self))
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000525 def __eq__(self, other):
526 return (list(self) == list(other) and
527 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000528 x = C([[1, 2], 3])
529 y = copy.copy(x)
530 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200531 self.assertIsNot(x, y)
532 self.assertIs(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000533 y = copy.deepcopy(x)
534 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200535 self.assertIsNot(x, y)
536 self.assertIsNot(x[0], y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000537
538 def test_reduce_5tuple(self):
539 class C(dict):
540 def __reduce__(self):
Guido van Rossumcc2b0162007-02-11 06:12:03 +0000541 return (C, (), self.__dict__, None, self.items())
Guido van Rossum47b9ff62006-08-24 00:41:19 +0000542 def __eq__(self, other):
543 return (dict(self) == dict(other) and
544 self.__dict__ == other.__dict__)
Guido van Rossum90e05b02003-02-06 18:18:23 +0000545 x = C([("foo", [1, 2]), ("bar", 3)])
546 y = copy.copy(x)
547 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200548 self.assertIsNot(x, y)
549 self.assertIs(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000550 y = copy.deepcopy(x)
551 self.assertEqual(x, y)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200552 self.assertIsNot(x, y)
553 self.assertIsNot(x["foo"], y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000554
Guido van Rossumc7557582003-02-06 19:53:22 +0000555 def test_copy_slots(self):
556 class C(object):
557 __slots__ = ["foo"]
558 x = C()
559 x.foo = [42]
560 y = copy.copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200561 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000562
563 def test_deepcopy_slots(self):
564 class C(object):
565 __slots__ = ["foo"]
566 x = C()
567 x.foo = [42]
568 y = copy.deepcopy(x)
569 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200570 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000571
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000572 def test_deepcopy_dict_subclass(self):
573 class C(dict):
574 def __init__(self, d=None):
575 if not d:
576 d = {}
577 self._keys = list(d.keys())
578 super().__init__(d)
579 def __setitem__(self, key, item):
580 super().__setitem__(key, item)
581 if key not in self._keys:
582 self._keys.append(key)
583 x = C(d={'foo':0})
584 y = copy.deepcopy(x)
585 self.assertEqual(x, y)
586 self.assertEqual(x._keys, y._keys)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200587 self.assertIsNot(x, y)
Antoine Pitrou3941a8f2010-09-04 17:40:21 +0000588 x['bar'] = 1
589 self.assertNotEqual(x, y)
590 self.assertNotEqual(x._keys, y._keys)
591
Guido van Rossumc7557582003-02-06 19:53:22 +0000592 def test_copy_list_subclass(self):
593 class C(list):
594 pass
595 x = C([[1, 2], 3])
596 x.foo = [4, 5]
597 y = copy.copy(x)
598 self.assertEqual(list(x), list(y))
599 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200600 self.assertIs(x[0], y[0])
601 self.assertIs(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000602
603 def test_deepcopy_list_subclass(self):
604 class C(list):
605 pass
606 x = C([[1, 2], 3])
607 x.foo = [4, 5]
608 y = copy.deepcopy(x)
609 self.assertEqual(list(x), list(y))
610 self.assertEqual(x.foo, y.foo)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200611 self.assertIsNot(x[0], y[0])
612 self.assertIsNot(x.foo, y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000613
Guido van Rossum85233bf2003-02-06 21:25:12 +0000614 def test_copy_tuple_subclass(self):
615 class C(tuple):
616 pass
617 x = C([1, 2, 3])
618 self.assertEqual(tuple(x), (1, 2, 3))
619 y = copy.copy(x)
620 self.assertEqual(tuple(y), (1, 2, 3))
621
622 def test_deepcopy_tuple_subclass(self):
623 class C(tuple):
624 pass
625 x = C([[1, 2], 3])
626 self.assertEqual(tuple(x), ([1, 2], 3))
627 y = copy.deepcopy(x)
628 self.assertEqual(tuple(y), ([1, 2], 3))
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200629 self.assertIsNot(x, y)
630 self.assertIsNot(x[0], y[0])
Guido van Rossum85233bf2003-02-06 21:25:12 +0000631
Neal Norwitze2fdc612003-06-08 13:19:58 +0000632 def test_getstate_exc(self):
633 class EvilState(object):
634 def __getstate__(self):
Collin Winter3add4d72007-08-29 23:37:32 +0000635 raise ValueError("ain't got no stickin' state")
Neal Norwitze2fdc612003-06-08 13:19:58 +0000636 self.assertRaises(ValueError, copy.copy, EvilState())
637
Guido van Rossum1968ad32006-02-25 22:38:04 +0000638 def test_copy_function(self):
639 self.assertEqual(copy.copy(global_foo), global_foo)
640 def foo(x, y): return x+y
641 self.assertEqual(copy.copy(foo), foo)
642 bar = lambda: None
643 self.assertEqual(copy.copy(bar), bar)
644
645 def test_deepcopy_function(self):
646 self.assertEqual(copy.deepcopy(global_foo), global_foo)
647 def foo(x, y): return x+y
648 self.assertEqual(copy.deepcopy(foo), foo)
649 bar = lambda: None
650 self.assertEqual(copy.deepcopy(bar), bar)
651
Antoine Pitrou6e610062009-05-15 17:04:50 +0000652 def _check_weakref(self, _copy):
653 class C(object):
654 pass
655 obj = C()
656 x = weakref.ref(obj)
657 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200658 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000659 del obj
660 y = _copy(x)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200661 self.assertIs(y, x)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000662
663 def test_copy_weakref(self):
664 self._check_weakref(copy.copy)
665
666 def test_deepcopy_weakref(self):
667 self._check_weakref(copy.deepcopy)
668
669 def _check_copy_weakdict(self, _dicttype):
670 class C(object):
671 pass
672 a, b, c, d = [C() for i in range(4)]
673 u = _dicttype()
674 u[a] = b
675 u[c] = d
676 v = copy.copy(u)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200677 self.assertIsNot(v, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000678 self.assertEqual(v, u)
679 self.assertEqual(v[a], b)
680 self.assertEqual(v[c], d)
681 self.assertEqual(len(v), 2)
682 del c, d
683 self.assertEqual(len(v), 1)
684 x, y = C(), C()
685 # The underlying containers are decoupled
686 v[x] = y
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000687 self.assertNotIn(x, u)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000688
689 def test_copy_weakkeydict(self):
690 self._check_copy_weakdict(weakref.WeakKeyDictionary)
691
692 def test_copy_weakvaluedict(self):
693 self._check_copy_weakdict(weakref.WeakValueDictionary)
694
695 def test_deepcopy_weakkeydict(self):
696 class C(object):
697 def __init__(self, i):
698 self.i = i
699 a, b, c, d = [C(i) for i in range(4)]
700 u = weakref.WeakKeyDictionary()
701 u[a] = b
702 u[c] = d
703 # Keys aren't copied, values are
704 v = copy.deepcopy(u)
705 self.assertNotEqual(v, u)
706 self.assertEqual(len(v), 2)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200707 self.assertIsNot(v[a], b)
708 self.assertIsNot(v[c], d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000709 self.assertEqual(v[a].i, b.i)
710 self.assertEqual(v[c].i, d.i)
711 del c
712 self.assertEqual(len(v), 1)
713
714 def test_deepcopy_weakvaluedict(self):
715 class C(object):
716 def __init__(self, i):
717 self.i = i
718 a, b, c, d = [C(i) for i in range(4)]
719 u = weakref.WeakValueDictionary()
720 u[a] = b
721 u[c] = d
722 # Keys are copied, values aren't
723 v = copy.deepcopy(u)
724 self.assertNotEqual(v, u)
725 self.assertEqual(len(v), 2)
726 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200727 self.assertIsNot(x, a)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000728 self.assertEqual(x.i, a.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200729 self.assertIs(y, b)
730 self.assertIsNot(z, c)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000731 self.assertEqual(z.i, c.i)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200732 self.assertIs(t, d)
Antoine Pitrou6e610062009-05-15 17:04:50 +0000733 del x, y, z, t
734 del d
735 self.assertEqual(len(v), 1)
736
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000737 def test_deepcopy_bound_method(self):
738 class Foo(object):
739 def m(self):
740 pass
741 f = Foo()
742 f.b = f.m
743 g = copy.deepcopy(f)
744 self.assertEqual(g.m, g.b)
Sandro Tosi4dc9c842011-08-05 23:05:35 +0200745 self.assertIs(g.b.__self__, g)
Antoine Pitrou1fc0d2b2009-11-28 15:58:27 +0000746 g.b()
747
Antoine Pitrou6e610062009-05-15 17:04:50 +0000748
Guido van Rossum1968ad32006-02-25 22:38:04 +0000749def global_foo(x, y): return x+y
750
Guido van Rossum581cb932003-02-06 17:52:15 +0000751def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000752 support.run_unittest(TestCopy)
Guido van Rossum581cb932003-02-06 17:52:15 +0000753
754if __name__ == "__main__":
755 test_main()