blob: d65f6a2f78306384c17cfbcf85af9f71b13edb4a [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
Georg Brandldffbf5f2008-05-20 07:49:57 +00004import copy_reg
Antoine Pitrou775fd662009-05-15 16:54:52 +00005import weakref
Guido van Rossum581cb932003-02-06 17:52:15 +00006
7import unittest
8from test import test_support
9
10class TestCopy(unittest.TestCase):
11
12 # Attempt full line coverage of copy.py from top to bottom
13
14 def test_exceptions(self):
Benjamin Peterson5c8da862009-06-30 22:57:08 +000015 self.assertTrue(copy.Error is copy.error)
16 self.assertTrue(issubclass(copy.Error, Exception))
Guido van Rossum581cb932003-02-06 17:52:15 +000017
18 # The copy() method
19
20 def test_copy_basic(self):
21 x = 42
22 y = copy.copy(x)
23 self.assertEqual(x, y)
24
25 def test_copy_copy(self):
26 class C(object):
27 def __init__(self, foo):
28 self.foo = foo
29 def __copy__(self):
30 return C(self.foo)
31 x = C(42)
32 y = copy.copy(x)
33 self.assertEqual(y.__class__, x.__class__)
34 self.assertEqual(y.foo, x.foo)
35
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000036 def test_copy_registry(self):
37 class C(object):
38 def __new__(cls, foo):
39 obj = object.__new__(cls)
40 obj.foo = foo
41 return obj
42 def pickle_C(obj):
43 return (C, (obj.foo,))
44 x = C(42)
45 self.assertRaises(TypeError, copy.copy, x)
Georg Brandldffbf5f2008-05-20 07:49:57 +000046 copy_reg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +000047 y = copy.copy(x)
48
Guido van Rossume6908832003-02-19 01:19:28 +000049 def test_copy_reduce_ex(self):
50 class C(object):
51 def __reduce_ex__(self, proto):
52 return ""
53 def __reduce__(self):
54 raise test_support.TestFailed, "shouldn't call this"
55 x = C()
56 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000057 self.assertTrue(y is x)
Guido van Rossume6908832003-02-19 01:19:28 +000058
Guido van Rossum581cb932003-02-06 17:52:15 +000059 def test_copy_reduce(self):
60 class C(object):
61 def __reduce__(self):
62 return ""
63 x = C()
64 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +000065 self.assertTrue(y is x)
Guido van Rossum581cb932003-02-06 17:52:15 +000066
67 def test_copy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +000068 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +000069 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +000070 if name.startswith("__reduce"):
Guido van Rossum581cb932003-02-06 17:52:15 +000071 raise AttributeError, name
72 return object.__getattribute__(self, name)
73 x = C()
74 self.assertRaises(copy.Error, copy.copy, x)
75
76 # Type-specific _copy_xxx() methods
77
78 def test_copy_atomic(self):
79 class Classic:
80 pass
81 class NewStyle(object):
82 pass
83 def f():
84 pass
Serhiy Storchaka9e000882016-03-06 15:03:16 +020085 tests = [None, Ellipsis,
86 42, 2L**100, 3.14, True, False, 1j,
Guido van Rossum581cb932003-02-06 17:52:15 +000087 "hello", u"hello\u1234", f.func_code,
Martin v. Löwisba8f5ff2003-06-14 07:10:06 +000088 NewStyle, xrange(10), Classic, max]
Guido van Rossum581cb932003-02-06 17:52:15 +000089 for x in tests:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000090 self.assertTrue(copy.copy(x) is x, repr(x))
Guido van Rossum581cb932003-02-06 17:52:15 +000091
92 def test_copy_list(self):
93 x = [1, 2, 3]
Serhiy Storchaka9e000882016-03-06 15:03:16 +020094 y = copy.copy(x)
95 self.assertEqual(y, x)
96 self.assertIsNot(y, x)
97 x = []
98 y = copy.copy(x)
99 self.assertEqual(y, x)
100 self.assertIsNot(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000101
102 def test_copy_tuple(self):
103 x = (1, 2, 3)
Serhiy Storchaka9e000882016-03-06 15:03:16 +0200104 self.assertIs(copy.copy(x), x)
105 x = ()
106 self.assertIs(copy.copy(x), x)
107 x = (1, 2, 3, [])
108 self.assertIs(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000109
110 def test_copy_dict(self):
111 x = {"foo": 1, "bar": 2}
Serhiy Storchaka9e000882016-03-06 15:03:16 +0200112 y = copy.copy(x)
113 self.assertEqual(y, x)
114 self.assertIsNot(y, x)
115 x = {}
116 y = copy.copy(x)
117 self.assertEqual(y, x)
118 self.assertIsNot(y, x)
119
120 def test_copy_set(self):
121 x = {1, 2, 3}
122 y = copy.copy(x)
123 self.assertEqual(y, x)
124 self.assertIsNot(y, x)
125 x = set()
126 y = copy.copy(x)
127 self.assertEqual(y, x)
128 self.assertIsNot(y, x)
129
130 def test_copy_frozenset(self):
131 x = frozenset({1, 2, 3})
132 self.assertIs(copy.copy(x), x)
133 x = frozenset()
134 self.assertIs(copy.copy(x), x)
135
136 def test_copy_bytearray(self):
137 x = bytearray(b'abc')
138 y = copy.copy(x)
139 self.assertEqual(y, x)
140 self.assertIsNot(y, x)
141 x = bytearray()
142 y = copy.copy(x)
143 self.assertEqual(y, x)
144 self.assertIsNot(y, x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000145
146 def test_copy_inst_vanilla(self):
147 class C:
148 def __init__(self, foo):
149 self.foo = foo
150 def __cmp__(self, other):
151 return cmp(self.foo, other.foo)
152 x = C(42)
153 self.assertEqual(copy.copy(x), x)
154
155 def test_copy_inst_copy(self):
156 class C:
157 def __init__(self, foo):
158 self.foo = foo
159 def __copy__(self):
160 return C(self.foo)
161 def __cmp__(self, other):
162 return cmp(self.foo, other.foo)
163 x = C(42)
164 self.assertEqual(copy.copy(x), x)
165
166 def test_copy_inst_getinitargs(self):
167 class C:
168 def __init__(self, foo):
169 self.foo = foo
170 def __getinitargs__(self):
171 return (self.foo,)
172 def __cmp__(self, other):
173 return cmp(self.foo, other.foo)
174 x = C(42)
175 self.assertEqual(copy.copy(x), x)
176
177 def test_copy_inst_getstate(self):
178 class C:
179 def __init__(self, foo):
180 self.foo = foo
181 def __getstate__(self):
182 return {"foo": self.foo}
183 def __cmp__(self, other):
184 return cmp(self.foo, other.foo)
185 x = C(42)
186 self.assertEqual(copy.copy(x), x)
187
188 def test_copy_inst_setstate(self):
189 class C:
190 def __init__(self, foo):
191 self.foo = foo
192 def __setstate__(self, state):
193 self.foo = state["foo"]
194 def __cmp__(self, other):
195 return cmp(self.foo, other.foo)
196 x = C(42)
197 self.assertEqual(copy.copy(x), x)
198
199 def test_copy_inst_getstate_setstate(self):
200 class C:
201 def __init__(self, foo):
202 self.foo = foo
203 def __getstate__(self):
204 return self.foo
205 def __setstate__(self, state):
206 self.foo = state
207 def __cmp__(self, other):
208 return cmp(self.foo, other.foo)
209 x = C(42)
210 self.assertEqual(copy.copy(x), x)
Serhiy Storchaka2329eed2015-11-30 17:20:02 +0200211 # State with boolean value is false (issue #25718)
212 x = C(0.0)
213 self.assertEqual(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000214
215 # The deepcopy() method
216
217 def test_deepcopy_basic(self):
218 x = 42
219 y = copy.deepcopy(x)
220 self.assertEqual(y, x)
221
222 def test_deepcopy_memo(self):
Guido van Rossum99d2c252003-06-13 19:28:47 +0000223 # Tests of reflexive objects are under type-specific sections below.
224 # This tests only repetitions of objects.
Guido van Rossum581cb932003-02-06 17:52:15 +0000225 x = []
Guido van Rossum99d2c252003-06-13 19:28:47 +0000226 x = [x, x]
Guido van Rossum581cb932003-02-06 17:52:15 +0000227 y = copy.deepcopy(x)
228 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000229 self.assertTrue(y is not x)
230 self.assertTrue(y[0] is not x[0])
231 self.assertTrue(y[0] is y[1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000232
233 def test_deepcopy_issubclass(self):
234 # XXX Note: there's no way to test the TypeError coming out of
235 # issubclass() -- this can only happen when an extension
236 # module defines a "type" that doesn't formally inherit from
237 # type.
238 class Meta(type):
239 pass
240 class C:
241 __metaclass__ = Meta
242 self.assertEqual(copy.deepcopy(C), C)
243
244 def test_deepcopy_deepcopy(self):
245 class C(object):
246 def __init__(self, foo):
247 self.foo = foo
248 def __deepcopy__(self, memo=None):
249 return C(self.foo)
250 x = C(42)
251 y = copy.deepcopy(x)
252 self.assertEqual(y.__class__, x.__class__)
253 self.assertEqual(y.foo, x.foo)
254
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000255 def test_deepcopy_registry(self):
256 class C(object):
257 def __new__(cls, foo):
258 obj = object.__new__(cls)
259 obj.foo = foo
260 return obj
261 def pickle_C(obj):
262 return (C, (obj.foo,))
263 x = C(42)
264 self.assertRaises(TypeError, copy.deepcopy, x)
Georg Brandldffbf5f2008-05-20 07:49:57 +0000265 copy_reg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000266 y = copy.deepcopy(x)
267
Guido van Rossume6908832003-02-19 01:19:28 +0000268 def test_deepcopy_reduce_ex(self):
269 class C(object):
270 def __reduce_ex__(self, proto):
271 return ""
272 def __reduce__(self):
273 raise test_support.TestFailed, "shouldn't call this"
274 x = C()
275 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000276 self.assertTrue(y is x)
Guido van Rossume6908832003-02-19 01:19:28 +0000277
Guido van Rossum581cb932003-02-06 17:52:15 +0000278 def test_deepcopy_reduce(self):
279 class C(object):
280 def __reduce__(self):
281 return ""
282 x = C()
283 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000284 self.assertTrue(y is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000285
286 def test_deepcopy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +0000287 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +0000288 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +0000289 if name.startswith("__reduce"):
Guido van Rossum581cb932003-02-06 17:52:15 +0000290 raise AttributeError, name
291 return object.__getattribute__(self, name)
292 x = C()
293 self.assertRaises(copy.Error, copy.deepcopy, x)
294
295 # Type-specific _deepcopy_xxx() methods
296
297 def test_deepcopy_atomic(self):
298 class Classic:
299 pass
300 class NewStyle(object):
301 pass
302 def f():
303 pass
304 tests = [None, 42, 2L**100, 3.14, True, False, 1j,
305 "hello", u"hello\u1234", f.func_code,
Martin v. Löwisba8f5ff2003-06-14 07:10:06 +0000306 NewStyle, xrange(10), Classic, max]
Guido van Rossum581cb932003-02-06 17:52:15 +0000307 for x in tests:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000308 self.assertTrue(copy.deepcopy(x) is x, repr(x))
Guido van Rossum581cb932003-02-06 17:52:15 +0000309
310 def test_deepcopy_list(self):
311 x = [[1, 2], 3]
312 y = copy.deepcopy(x)
313 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000314 self.assertTrue(x is not y)
315 self.assertTrue(x[0] is not y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000316
Guido van Rossum99d2c252003-06-13 19:28:47 +0000317 def test_deepcopy_reflexive_list(self):
318 x = []
319 x.append(x)
320 y = copy.deepcopy(x)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000321 self.assertRaises(RuntimeError, cmp, y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000322 self.assertTrue(y is not x)
323 self.assertTrue(y[0] is y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000324 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000325
Guido van Rossum581cb932003-02-06 17:52:15 +0000326 def test_deepcopy_tuple(self):
327 x = ([1, 2], 3)
328 y = copy.deepcopy(x)
329 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000330 self.assertTrue(x is not y)
331 self.assertTrue(x[0] is not y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000332
Guido van Rossum99d2c252003-06-13 19:28:47 +0000333 def test_deepcopy_reflexive_tuple(self):
334 x = ([],)
335 x[0].append(x)
336 y = copy.deepcopy(x)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000337 self.assertRaises(RuntimeError, cmp, y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000338 self.assertTrue(y is not x)
339 self.assertTrue(y[0] is not x[0])
340 self.assertTrue(y[0][0] is y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000341
Guido van Rossum581cb932003-02-06 17:52:15 +0000342 def test_deepcopy_dict(self):
343 x = {"foo": [1, 2], "bar": 3}
344 y = copy.deepcopy(x)
345 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000346 self.assertTrue(x is not y)
347 self.assertTrue(x["foo"] is not y["foo"])
Guido van Rossum581cb932003-02-06 17:52:15 +0000348
Guido van Rossum99d2c252003-06-13 19:28:47 +0000349 def test_deepcopy_reflexive_dict(self):
350 x = {}
351 x['foo'] = x
352 y = copy.deepcopy(x)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000353 self.assertRaises(RuntimeError, cmp, y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000354 self.assertTrue(y is not x)
355 self.assertTrue(y['foo'] is y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000356 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000357
Guido van Rossum581cb932003-02-06 17:52:15 +0000358 def test_deepcopy_keepalive(self):
359 memo = {}
360 x = 42
361 y = copy.deepcopy(x, memo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000362 self.assertTrue(memo[id(x)] is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000363
364 def test_deepcopy_inst_vanilla(self):
365 class C:
366 def __init__(self, foo):
367 self.foo = foo
368 def __cmp__(self, other):
369 return cmp(self.foo, other.foo)
370 x = C([42])
371 y = copy.deepcopy(x)
372 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000373 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000374
375 def test_deepcopy_inst_deepcopy(self):
376 class C:
377 def __init__(self, foo):
378 self.foo = foo
379 def __deepcopy__(self, memo):
380 return C(copy.deepcopy(self.foo, memo))
381 def __cmp__(self, other):
382 return cmp(self.foo, other.foo)
383 x = C([42])
384 y = copy.deepcopy(x)
385 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000386 self.assertTrue(y is not x)
387 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000388
389 def test_deepcopy_inst_getinitargs(self):
390 class C:
391 def __init__(self, foo):
392 self.foo = foo
393 def __getinitargs__(self):
394 return (self.foo,)
395 def __cmp__(self, other):
396 return cmp(self.foo, other.foo)
397 x = C([42])
398 y = copy.deepcopy(x)
399 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000400 self.assertTrue(y is not x)
401 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000402
403 def test_deepcopy_inst_getstate(self):
404 class C:
405 def __init__(self, foo):
406 self.foo = foo
407 def __getstate__(self):
408 return {"foo": self.foo}
409 def __cmp__(self, other):
410 return cmp(self.foo, other.foo)
411 x = C([42])
412 y = copy.deepcopy(x)
413 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000414 self.assertTrue(y is not x)
415 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000416
417 def test_deepcopy_inst_setstate(self):
418 class C:
419 def __init__(self, foo):
420 self.foo = foo
421 def __setstate__(self, state):
422 self.foo = state["foo"]
423 def __cmp__(self, other):
424 return cmp(self.foo, other.foo)
425 x = C([42])
426 y = copy.deepcopy(x)
427 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000428 self.assertTrue(y is not x)
429 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000430
431 def test_deepcopy_inst_getstate_setstate(self):
432 class C:
433 def __init__(self, foo):
434 self.foo = foo
435 def __getstate__(self):
436 return self.foo
437 def __setstate__(self, state):
438 self.foo = state
439 def __cmp__(self, other):
440 return cmp(self.foo, other.foo)
441 x = C([42])
442 y = copy.deepcopy(x)
443 self.assertEqual(y, x)
Serhiy Storchaka2329eed2015-11-30 17:20:02 +0200444 self.assertIsNot(y, x)
445 self.assertIsNot(y.foo, x.foo)
446 # State with boolean value is false (issue #25718)
447 x = C([])
448 y = copy.deepcopy(x)
449 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000450 self.assertTrue(y is not x)
451 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000452
Guido van Rossum99d2c252003-06-13 19:28:47 +0000453 def test_deepcopy_reflexive_inst(self):
454 class C:
455 pass
456 x = C()
457 x.foo = x
458 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000459 self.assertTrue(y is not x)
460 self.assertTrue(y.foo is y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000461
Guido van Rossum581cb932003-02-06 17:52:15 +0000462 # _reconstruct()
463
464 def test_reconstruct_string(self):
465 class C(object):
466 def __reduce__(self):
467 return ""
468 x = C()
469 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000470 self.assertTrue(y is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000471 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000472 self.assertTrue(y is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000473
474 def test_reconstruct_nostate(self):
475 class C(object):
476 def __reduce__(self):
477 return (C, ())
478 x = C()
479 x.foo = 42
480 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000481 self.assertTrue(y.__class__ is x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000482 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000483 self.assertTrue(y.__class__ is x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000484
485 def test_reconstruct_state(self):
486 class C(object):
487 def __reduce__(self):
488 return (C, (), self.__dict__)
489 def __cmp__(self, other):
490 return cmp(self.__dict__, other.__dict__)
Nick Coghlan48361f52008-08-11 15:45:58 +0000491 __hash__ = None # Silence Py3k warning
Guido van Rossum581cb932003-02-06 17:52:15 +0000492 x = C()
493 x.foo = [42]
494 y = copy.copy(x)
495 self.assertEqual(y, x)
496 y = copy.deepcopy(x)
497 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000498 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000499
500 def test_reconstruct_state_setstate(self):
501 class C(object):
502 def __reduce__(self):
503 return (C, (), self.__dict__)
504 def __setstate__(self, state):
505 self.__dict__.update(state)
506 def __cmp__(self, other):
507 return cmp(self.__dict__, other.__dict__)
Nick Coghlan48361f52008-08-11 15:45:58 +0000508 __hash__ = None # Silence Py3k warning
Guido van Rossum581cb932003-02-06 17:52:15 +0000509 x = C()
510 x.foo = [42]
511 y = copy.copy(x)
512 self.assertEqual(y, x)
513 y = copy.deepcopy(x)
514 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000515 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000516
Guido van Rossum99d2c252003-06-13 19:28:47 +0000517 def test_reconstruct_reflexive(self):
518 class C(object):
519 pass
520 x = C()
521 x.foo = x
522 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000523 self.assertTrue(y is not x)
524 self.assertTrue(y.foo is y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000525
Guido van Rossum90e05b02003-02-06 18:18:23 +0000526 # Additions for Python 2.3 and pickle protocol 2
527
528 def test_reduce_4tuple(self):
529 class C(list):
530 def __reduce__(self):
531 return (C, (), self.__dict__, iter(self))
532 def __cmp__(self, other):
533 return (cmp(list(self), list(other)) or
534 cmp(self.__dict__, other.__dict__))
Nick Coghlan48361f52008-08-11 15:45:58 +0000535 __hash__ = None # Silence Py3k warning
Guido van Rossum90e05b02003-02-06 18:18:23 +0000536 x = C([[1, 2], 3])
537 y = copy.copy(x)
538 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000539 self.assertTrue(x is not y)
540 self.assertTrue(x[0] is y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000541 y = copy.deepcopy(x)
542 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000543 self.assertTrue(x is not y)
544 self.assertTrue(x[0] is not y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000545
546 def test_reduce_5tuple(self):
547 class C(dict):
548 def __reduce__(self):
549 return (C, (), self.__dict__, None, self.iteritems())
550 def __cmp__(self, other):
551 return (cmp(dict(self), list(dict)) or
552 cmp(self.__dict__, other.__dict__))
Nick Coghlan48361f52008-08-11 15:45:58 +0000553 __hash__ = None # Silence Py3k warning
Guido van Rossum90e05b02003-02-06 18:18:23 +0000554 x = C([("foo", [1, 2]), ("bar", 3)])
555 y = copy.copy(x)
556 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000557 self.assertTrue(x is not y)
558 self.assertTrue(x["foo"] is y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000559 y = copy.deepcopy(x)
560 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000561 self.assertTrue(x is not y)
562 self.assertTrue(x["foo"] is not y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000563
Guido van Rossumc7557582003-02-06 19:53:22 +0000564 def test_copy_slots(self):
565 class C(object):
566 __slots__ = ["foo"]
567 x = C()
568 x.foo = [42]
569 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000570 self.assertTrue(x.foo is y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000571
572 def test_deepcopy_slots(self):
573 class C(object):
574 __slots__ = ["foo"]
575 x = C()
576 x.foo = [42]
577 y = copy.deepcopy(x)
578 self.assertEqual(x.foo, y.foo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000579 self.assertTrue(x.foo is not y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000580
Antoine Pitroudca9de92010-09-04 17:52:26 +0000581 def test_deepcopy_dict_subclass(self):
582 class C(dict):
583 def __init__(self, d=None):
584 if not d:
585 d = {}
586 self._keys = list(d.keys())
587 dict.__init__(self, d)
588 def __setitem__(self, key, item):
589 dict.__setitem__(self, key, item)
590 if key not in self._keys:
591 self._keys.append(key)
592 x = C(d={'foo':0})
593 y = copy.deepcopy(x)
594 self.assertEqual(x, y)
595 self.assertEqual(x._keys, y._keys)
596 self.assertTrue(x is not y)
597 x['bar'] = 1
598 self.assertNotEqual(x, y)
599 self.assertNotEqual(x._keys, y._keys)
600
Guido van Rossumc7557582003-02-06 19:53:22 +0000601 def test_copy_list_subclass(self):
602 class C(list):
603 pass
604 x = C([[1, 2], 3])
605 x.foo = [4, 5]
606 y = copy.copy(x)
607 self.assertEqual(list(x), list(y))
608 self.assertEqual(x.foo, y.foo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000609 self.assertTrue(x[0] is y[0])
610 self.assertTrue(x.foo is y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000611
612 def test_deepcopy_list_subclass(self):
613 class C(list):
614 pass
615 x = C([[1, 2], 3])
616 x.foo = [4, 5]
617 y = copy.deepcopy(x)
618 self.assertEqual(list(x), list(y))
619 self.assertEqual(x.foo, y.foo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000620 self.assertTrue(x[0] is not y[0])
621 self.assertTrue(x.foo is not y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000622
Guido van Rossum85233bf2003-02-06 21:25:12 +0000623 def test_copy_tuple_subclass(self):
624 class C(tuple):
625 pass
626 x = C([1, 2, 3])
627 self.assertEqual(tuple(x), (1, 2, 3))
628 y = copy.copy(x)
629 self.assertEqual(tuple(y), (1, 2, 3))
630
631 def test_deepcopy_tuple_subclass(self):
632 class C(tuple):
633 pass
634 x = C([[1, 2], 3])
635 self.assertEqual(tuple(x), ([1, 2], 3))
636 y = copy.deepcopy(x)
637 self.assertEqual(tuple(y), ([1, 2], 3))
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000638 self.assertTrue(x is not y)
639 self.assertTrue(x[0] is not y[0])
Guido van Rossum85233bf2003-02-06 21:25:12 +0000640
Neal Norwitze2fdc612003-06-08 13:19:58 +0000641 def test_getstate_exc(self):
642 class EvilState(object):
643 def __getstate__(self):
644 raise ValueError, "ain't got no stickin' state"
645 self.assertRaises(ValueError, copy.copy, EvilState())
646
Guido van Rossum1968ad32006-02-25 22:38:04 +0000647 def test_copy_function(self):
648 self.assertEqual(copy.copy(global_foo), global_foo)
649 def foo(x, y): return x+y
650 self.assertEqual(copy.copy(foo), foo)
651 bar = lambda: None
652 self.assertEqual(copy.copy(bar), bar)
653
654 def test_deepcopy_function(self):
655 self.assertEqual(copy.deepcopy(global_foo), global_foo)
656 def foo(x, y): return x+y
657 self.assertEqual(copy.deepcopy(foo), foo)
658 bar = lambda: None
659 self.assertEqual(copy.deepcopy(bar), bar)
660
Antoine Pitrou775fd662009-05-15 16:54:52 +0000661 def _check_weakref(self, _copy):
662 class C(object):
663 pass
664 obj = C()
665 x = weakref.ref(obj)
666 y = _copy(x)
667 self.assertTrue(y is x)
668 del obj
669 y = _copy(x)
670 self.assertTrue(y is x)
671
672 def test_copy_weakref(self):
673 self._check_weakref(copy.copy)
674
675 def test_deepcopy_weakref(self):
676 self._check_weakref(copy.deepcopy)
677
678 def _check_copy_weakdict(self, _dicttype):
679 class C(object):
680 pass
681 a, b, c, d = [C() for i in xrange(4)]
682 u = _dicttype()
683 u[a] = b
684 u[c] = d
685 v = copy.copy(u)
686 self.assertFalse(v is u)
687 self.assertEqual(v, u)
688 self.assertEqual(v[a], b)
689 self.assertEqual(v[c], d)
690 self.assertEqual(len(v), 2)
691 del c, d
692 self.assertEqual(len(v), 1)
693 x, y = C(), C()
694 # The underlying containers are decoupled
695 v[x] = y
Ezio Melottiaa980582010-01-23 23:04:36 +0000696 self.assertNotIn(x, u)
Antoine Pitrou775fd662009-05-15 16:54:52 +0000697
698 def test_copy_weakkeydict(self):
699 self._check_copy_weakdict(weakref.WeakKeyDictionary)
700
701 def test_copy_weakvaluedict(self):
702 self._check_copy_weakdict(weakref.WeakValueDictionary)
703
704 def test_deepcopy_weakkeydict(self):
705 class C(object):
706 def __init__(self, i):
707 self.i = i
708 a, b, c, d = [C(i) for i in xrange(4)]
709 u = weakref.WeakKeyDictionary()
710 u[a] = b
711 u[c] = d
712 # Keys aren't copied, values are
713 v = copy.deepcopy(u)
714 self.assertNotEqual(v, u)
715 self.assertEqual(len(v), 2)
716 self.assertFalse(v[a] is b)
717 self.assertFalse(v[c] is d)
718 self.assertEqual(v[a].i, b.i)
719 self.assertEqual(v[c].i, d.i)
720 del c
721 self.assertEqual(len(v), 1)
722
723 def test_deepcopy_weakvaluedict(self):
724 class C(object):
725 def __init__(self, i):
726 self.i = i
727 a, b, c, d = [C(i) for i in xrange(4)]
728 u = weakref.WeakValueDictionary()
729 u[a] = b
730 u[c] = d
731 # Keys are copied, values aren't
732 v = copy.deepcopy(u)
733 self.assertNotEqual(v, u)
734 self.assertEqual(len(v), 2)
Ezio Melottidde5b942010-02-03 05:37:26 +0000735 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i)
Antoine Pitrou775fd662009-05-15 16:54:52 +0000736 self.assertFalse(x is a)
737 self.assertEqual(x.i, a.i)
738 self.assertTrue(y is b)
739 self.assertFalse(z is c)
740 self.assertEqual(z.i, c.i)
741 self.assertTrue(t is d)
742 del x, y, z, t
743 del d
744 self.assertEqual(len(v), 1)
745
Antoine Pitroud16f57b2009-11-28 15:55:58 +0000746 def test_deepcopy_bound_method(self):
747 class Foo(object):
748 def m(self):
749 pass
750 f = Foo()
751 f.b = f.m
752 g = copy.deepcopy(f)
753 self.assertEqual(g.m, g.b)
754 self.assertTrue(g.b.im_self is g)
755 g.b()
756
Antoine Pitrou775fd662009-05-15 16:54:52 +0000757
Guido van Rossum1968ad32006-02-25 22:38:04 +0000758def global_foo(x, y): return x+y
759
Guido van Rossum581cb932003-02-06 17:52:15 +0000760def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000761 test_support.run_unittest(TestCopy)
Guido van Rossum581cb932003-02-06 17:52:15 +0000762
763if __name__ == "__main__":
764 test_main()