blob: aefc433e825ac8c8d1a70533547f9ace7736fcbb [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
85 tests = [None, 42, 2L**100, 3.14, True, False, 1j,
86 "hello", u"hello\u1234", f.func_code,
Martin v. Löwisba8f5ff2003-06-14 07:10:06 +000087 NewStyle, xrange(10), Classic, max]
Guido van Rossum581cb932003-02-06 17:52:15 +000088 for x in tests:
Benjamin Peterson5c8da862009-06-30 22:57:08 +000089 self.assertTrue(copy.copy(x) is x, repr(x))
Guido van Rossum581cb932003-02-06 17:52:15 +000090
91 def test_copy_list(self):
92 x = [1, 2, 3]
93 self.assertEqual(copy.copy(x), x)
94
95 def test_copy_tuple(self):
96 x = (1, 2, 3)
97 self.assertEqual(copy.copy(x), x)
98
99 def test_copy_dict(self):
100 x = {"foo": 1, "bar": 2}
101 self.assertEqual(copy.copy(x), x)
102
103 def test_copy_inst_vanilla(self):
104 class C:
105 def __init__(self, foo):
106 self.foo = foo
107 def __cmp__(self, other):
108 return cmp(self.foo, other.foo)
109 x = C(42)
110 self.assertEqual(copy.copy(x), x)
111
112 def test_copy_inst_copy(self):
113 class C:
114 def __init__(self, foo):
115 self.foo = foo
116 def __copy__(self):
117 return C(self.foo)
118 def __cmp__(self, other):
119 return cmp(self.foo, other.foo)
120 x = C(42)
121 self.assertEqual(copy.copy(x), x)
122
123 def test_copy_inst_getinitargs(self):
124 class C:
125 def __init__(self, foo):
126 self.foo = foo
127 def __getinitargs__(self):
128 return (self.foo,)
129 def __cmp__(self, other):
130 return cmp(self.foo, other.foo)
131 x = C(42)
132 self.assertEqual(copy.copy(x), x)
133
134 def test_copy_inst_getstate(self):
135 class C:
136 def __init__(self, foo):
137 self.foo = foo
138 def __getstate__(self):
139 return {"foo": self.foo}
140 def __cmp__(self, other):
141 return cmp(self.foo, other.foo)
142 x = C(42)
143 self.assertEqual(copy.copy(x), x)
144
145 def test_copy_inst_setstate(self):
146 class C:
147 def __init__(self, foo):
148 self.foo = foo
149 def __setstate__(self, state):
150 self.foo = state["foo"]
151 def __cmp__(self, other):
152 return cmp(self.foo, other.foo)
153 x = C(42)
154 self.assertEqual(copy.copy(x), x)
155
156 def test_copy_inst_getstate_setstate(self):
157 class C:
158 def __init__(self, foo):
159 self.foo = foo
160 def __getstate__(self):
161 return self.foo
162 def __setstate__(self, state):
163 self.foo = state
164 def __cmp__(self, other):
165 return cmp(self.foo, other.foo)
166 x = C(42)
167 self.assertEqual(copy.copy(x), x)
Serhiy Storchaka2329eed2015-11-30 17:20:02 +0200168 # State with boolean value is false (issue #25718)
169 x = C(0.0)
170 self.assertEqual(copy.copy(x), x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000171
172 # The deepcopy() method
173
174 def test_deepcopy_basic(self):
175 x = 42
176 y = copy.deepcopy(x)
177 self.assertEqual(y, x)
178
179 def test_deepcopy_memo(self):
Guido van Rossum99d2c252003-06-13 19:28:47 +0000180 # Tests of reflexive objects are under type-specific sections below.
181 # This tests only repetitions of objects.
Guido van Rossum581cb932003-02-06 17:52:15 +0000182 x = []
Guido van Rossum99d2c252003-06-13 19:28:47 +0000183 x = [x, x]
Guido van Rossum581cb932003-02-06 17:52:15 +0000184 y = copy.deepcopy(x)
185 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000186 self.assertTrue(y is not x)
187 self.assertTrue(y[0] is not x[0])
188 self.assertTrue(y[0] is y[1])
Guido van Rossum581cb932003-02-06 17:52:15 +0000189
190 def test_deepcopy_issubclass(self):
191 # XXX Note: there's no way to test the TypeError coming out of
192 # issubclass() -- this can only happen when an extension
193 # module defines a "type" that doesn't formally inherit from
194 # type.
195 class Meta(type):
196 pass
197 class C:
198 __metaclass__ = Meta
199 self.assertEqual(copy.deepcopy(C), C)
200
201 def test_deepcopy_deepcopy(self):
202 class C(object):
203 def __init__(self, foo):
204 self.foo = foo
205 def __deepcopy__(self, memo=None):
206 return C(self.foo)
207 x = C(42)
208 y = copy.deepcopy(x)
209 self.assertEqual(y.__class__, x.__class__)
210 self.assertEqual(y.foo, x.foo)
211
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000212 def test_deepcopy_registry(self):
213 class C(object):
214 def __new__(cls, foo):
215 obj = object.__new__(cls)
216 obj.foo = foo
217 return obj
218 def pickle_C(obj):
219 return (C, (obj.foo,))
220 x = C(42)
221 self.assertRaises(TypeError, copy.deepcopy, x)
Georg Brandldffbf5f2008-05-20 07:49:57 +0000222 copy_reg.pickle(C, pickle_C, C)
Guido van Rossumc06e3ac2003-02-07 17:30:18 +0000223 y = copy.deepcopy(x)
224
Guido van Rossume6908832003-02-19 01:19:28 +0000225 def test_deepcopy_reduce_ex(self):
226 class C(object):
227 def __reduce_ex__(self, proto):
228 return ""
229 def __reduce__(self):
230 raise test_support.TestFailed, "shouldn't call this"
231 x = C()
232 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000233 self.assertTrue(y is x)
Guido van Rossume6908832003-02-19 01:19:28 +0000234
Guido van Rossum581cb932003-02-06 17:52:15 +0000235 def test_deepcopy_reduce(self):
236 class C(object):
237 def __reduce__(self):
238 return ""
239 x = C()
240 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000241 self.assertTrue(y is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000242
243 def test_deepcopy_cant(self):
Guido van Rossume6908832003-02-19 01:19:28 +0000244 class C(object):
Guido van Rossum581cb932003-02-06 17:52:15 +0000245 def __getattribute__(self, name):
Guido van Rossume6908832003-02-19 01:19:28 +0000246 if name.startswith("__reduce"):
Guido van Rossum581cb932003-02-06 17:52:15 +0000247 raise AttributeError, name
248 return object.__getattribute__(self, name)
249 x = C()
250 self.assertRaises(copy.Error, copy.deepcopy, x)
251
252 # Type-specific _deepcopy_xxx() methods
253
254 def test_deepcopy_atomic(self):
255 class Classic:
256 pass
257 class NewStyle(object):
258 pass
259 def f():
260 pass
261 tests = [None, 42, 2L**100, 3.14, True, False, 1j,
262 "hello", u"hello\u1234", f.func_code,
Martin v. Löwisba8f5ff2003-06-14 07:10:06 +0000263 NewStyle, xrange(10), Classic, max]
Guido van Rossum581cb932003-02-06 17:52:15 +0000264 for x in tests:
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000265 self.assertTrue(copy.deepcopy(x) is x, repr(x))
Guido van Rossum581cb932003-02-06 17:52:15 +0000266
267 def test_deepcopy_list(self):
268 x = [[1, 2], 3]
269 y = copy.deepcopy(x)
270 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000271 self.assertTrue(x is not y)
272 self.assertTrue(x[0] is not y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000273
Guido van Rossum99d2c252003-06-13 19:28:47 +0000274 def test_deepcopy_reflexive_list(self):
275 x = []
276 x.append(x)
277 y = copy.deepcopy(x)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000278 self.assertRaises(RuntimeError, cmp, y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000279 self.assertTrue(y is not x)
280 self.assertTrue(y[0] is y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000281 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000282
Guido van Rossum581cb932003-02-06 17:52:15 +0000283 def test_deepcopy_tuple(self):
284 x = ([1, 2], 3)
285 y = copy.deepcopy(x)
286 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000287 self.assertTrue(x is not y)
288 self.assertTrue(x[0] is not y[0])
Guido van Rossum581cb932003-02-06 17:52:15 +0000289
Guido van Rossum99d2c252003-06-13 19:28:47 +0000290 def test_deepcopy_reflexive_tuple(self):
291 x = ([],)
292 x[0].append(x)
293 y = copy.deepcopy(x)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000294 self.assertRaises(RuntimeError, cmp, y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000295 self.assertTrue(y is not x)
296 self.assertTrue(y[0] is not x[0])
297 self.assertTrue(y[0][0] is y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000298
Guido van Rossum581cb932003-02-06 17:52:15 +0000299 def test_deepcopy_dict(self):
300 x = {"foo": [1, 2], "bar": 3}
301 y = copy.deepcopy(x)
302 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000303 self.assertTrue(x is not y)
304 self.assertTrue(x["foo"] is not y["foo"])
Guido van Rossum581cb932003-02-06 17:52:15 +0000305
Guido van Rossum99d2c252003-06-13 19:28:47 +0000306 def test_deepcopy_reflexive_dict(self):
307 x = {}
308 x['foo'] = x
309 y = copy.deepcopy(x)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000310 self.assertRaises(RuntimeError, cmp, y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000311 self.assertTrue(y is not x)
312 self.assertTrue(y['foo'] is y)
Armin Rigo2b3eb402003-10-28 12:05:48 +0000313 self.assertEqual(len(y), 1)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000314
Guido van Rossum581cb932003-02-06 17:52:15 +0000315 def test_deepcopy_keepalive(self):
316 memo = {}
317 x = 42
318 y = copy.deepcopy(x, memo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000319 self.assertTrue(memo[id(x)] is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000320
321 def test_deepcopy_inst_vanilla(self):
322 class C:
323 def __init__(self, foo):
324 self.foo = foo
325 def __cmp__(self, other):
326 return cmp(self.foo, other.foo)
327 x = C([42])
328 y = copy.deepcopy(x)
329 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000330 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000331
332 def test_deepcopy_inst_deepcopy(self):
333 class C:
334 def __init__(self, foo):
335 self.foo = foo
336 def __deepcopy__(self, memo):
337 return C(copy.deepcopy(self.foo, memo))
338 def __cmp__(self, other):
339 return cmp(self.foo, other.foo)
340 x = C([42])
341 y = copy.deepcopy(x)
342 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000343 self.assertTrue(y is not x)
344 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000345
346 def test_deepcopy_inst_getinitargs(self):
347 class C:
348 def __init__(self, foo):
349 self.foo = foo
350 def __getinitargs__(self):
351 return (self.foo,)
352 def __cmp__(self, other):
353 return cmp(self.foo, other.foo)
354 x = C([42])
355 y = copy.deepcopy(x)
356 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000357 self.assertTrue(y is not x)
358 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000359
360 def test_deepcopy_inst_getstate(self):
361 class C:
362 def __init__(self, foo):
363 self.foo = foo
364 def __getstate__(self):
365 return {"foo": self.foo}
366 def __cmp__(self, other):
367 return cmp(self.foo, other.foo)
368 x = C([42])
369 y = copy.deepcopy(x)
370 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000371 self.assertTrue(y is not x)
372 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000373
374 def test_deepcopy_inst_setstate(self):
375 class C:
376 def __init__(self, foo):
377 self.foo = foo
378 def __setstate__(self, state):
379 self.foo = state["foo"]
380 def __cmp__(self, other):
381 return cmp(self.foo, other.foo)
382 x = C([42])
383 y = copy.deepcopy(x)
384 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000385 self.assertTrue(y is not x)
386 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000387
388 def test_deepcopy_inst_getstate_setstate(self):
389 class C:
390 def __init__(self, foo):
391 self.foo = foo
392 def __getstate__(self):
393 return self.foo
394 def __setstate__(self, state):
395 self.foo = state
396 def __cmp__(self, other):
397 return cmp(self.foo, other.foo)
398 x = C([42])
399 y = copy.deepcopy(x)
400 self.assertEqual(y, x)
Serhiy Storchaka2329eed2015-11-30 17:20:02 +0200401 self.assertIsNot(y, x)
402 self.assertIsNot(y.foo, x.foo)
403 # State with boolean value is false (issue #25718)
404 x = C([])
405 y = copy.deepcopy(x)
406 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000407 self.assertTrue(y is not x)
408 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000409
Guido van Rossum99d2c252003-06-13 19:28:47 +0000410 def test_deepcopy_reflexive_inst(self):
411 class C:
412 pass
413 x = C()
414 x.foo = x
415 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000416 self.assertTrue(y is not x)
417 self.assertTrue(y.foo is y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000418
Guido van Rossum581cb932003-02-06 17:52:15 +0000419 # _reconstruct()
420
421 def test_reconstruct_string(self):
422 class C(object):
423 def __reduce__(self):
424 return ""
425 x = C()
426 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000427 self.assertTrue(y is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000428 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000429 self.assertTrue(y is x)
Guido van Rossum581cb932003-02-06 17:52:15 +0000430
431 def test_reconstruct_nostate(self):
432 class C(object):
433 def __reduce__(self):
434 return (C, ())
435 x = C()
436 x.foo = 42
437 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000438 self.assertTrue(y.__class__ is x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000439 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000440 self.assertTrue(y.__class__ is x.__class__)
Guido van Rossum581cb932003-02-06 17:52:15 +0000441
442 def test_reconstruct_state(self):
443 class C(object):
444 def __reduce__(self):
445 return (C, (), self.__dict__)
446 def __cmp__(self, other):
447 return cmp(self.__dict__, other.__dict__)
Nick Coghlan48361f52008-08-11 15:45:58 +0000448 __hash__ = None # Silence Py3k warning
Guido van Rossum581cb932003-02-06 17:52:15 +0000449 x = C()
450 x.foo = [42]
451 y = copy.copy(x)
452 self.assertEqual(y, x)
453 y = copy.deepcopy(x)
454 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000455 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000456
457 def test_reconstruct_state_setstate(self):
458 class C(object):
459 def __reduce__(self):
460 return (C, (), self.__dict__)
461 def __setstate__(self, state):
462 self.__dict__.update(state)
463 def __cmp__(self, other):
464 return cmp(self.__dict__, other.__dict__)
Nick Coghlan48361f52008-08-11 15:45:58 +0000465 __hash__ = None # Silence Py3k warning
Guido van Rossum581cb932003-02-06 17:52:15 +0000466 x = C()
467 x.foo = [42]
468 y = copy.copy(x)
469 self.assertEqual(y, x)
470 y = copy.deepcopy(x)
471 self.assertEqual(y, x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000472 self.assertTrue(y.foo is not x.foo)
Guido van Rossum581cb932003-02-06 17:52:15 +0000473
Guido van Rossum99d2c252003-06-13 19:28:47 +0000474 def test_reconstruct_reflexive(self):
475 class C(object):
476 pass
477 x = C()
478 x.foo = x
479 y = copy.deepcopy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000480 self.assertTrue(y is not x)
481 self.assertTrue(y.foo is y)
Guido van Rossum99d2c252003-06-13 19:28:47 +0000482
Guido van Rossum90e05b02003-02-06 18:18:23 +0000483 # Additions for Python 2.3 and pickle protocol 2
484
485 def test_reduce_4tuple(self):
486 class C(list):
487 def __reduce__(self):
488 return (C, (), self.__dict__, iter(self))
489 def __cmp__(self, other):
490 return (cmp(list(self), list(other)) or
491 cmp(self.__dict__, other.__dict__))
Nick Coghlan48361f52008-08-11 15:45:58 +0000492 __hash__ = None # Silence Py3k warning
Guido van Rossum90e05b02003-02-06 18:18:23 +0000493 x = C([[1, 2], 3])
494 y = copy.copy(x)
495 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000496 self.assertTrue(x is not y)
497 self.assertTrue(x[0] is y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000498 y = copy.deepcopy(x)
499 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000500 self.assertTrue(x is not y)
501 self.assertTrue(x[0] is not y[0])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000502
503 def test_reduce_5tuple(self):
504 class C(dict):
505 def __reduce__(self):
506 return (C, (), self.__dict__, None, self.iteritems())
507 def __cmp__(self, other):
508 return (cmp(dict(self), list(dict)) or
509 cmp(self.__dict__, other.__dict__))
Nick Coghlan48361f52008-08-11 15:45:58 +0000510 __hash__ = None # Silence Py3k warning
Guido van Rossum90e05b02003-02-06 18:18:23 +0000511 x = C([("foo", [1, 2]), ("bar", 3)])
512 y = copy.copy(x)
513 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000514 self.assertTrue(x is not y)
515 self.assertTrue(x["foo"] is y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000516 y = copy.deepcopy(x)
517 self.assertEqual(x, y)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000518 self.assertTrue(x is not y)
519 self.assertTrue(x["foo"] is not y["foo"])
Guido van Rossum90e05b02003-02-06 18:18:23 +0000520
Guido van Rossumc7557582003-02-06 19:53:22 +0000521 def test_copy_slots(self):
522 class C(object):
523 __slots__ = ["foo"]
524 x = C()
525 x.foo = [42]
526 y = copy.copy(x)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000527 self.assertTrue(x.foo is y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000528
529 def test_deepcopy_slots(self):
530 class C(object):
531 __slots__ = ["foo"]
532 x = C()
533 x.foo = [42]
534 y = copy.deepcopy(x)
535 self.assertEqual(x.foo, y.foo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000536 self.assertTrue(x.foo is not y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000537
Antoine Pitroudca9de92010-09-04 17:52:26 +0000538 def test_deepcopy_dict_subclass(self):
539 class C(dict):
540 def __init__(self, d=None):
541 if not d:
542 d = {}
543 self._keys = list(d.keys())
544 dict.__init__(self, d)
545 def __setitem__(self, key, item):
546 dict.__setitem__(self, key, item)
547 if key not in self._keys:
548 self._keys.append(key)
549 x = C(d={'foo':0})
550 y = copy.deepcopy(x)
551 self.assertEqual(x, y)
552 self.assertEqual(x._keys, y._keys)
553 self.assertTrue(x is not y)
554 x['bar'] = 1
555 self.assertNotEqual(x, y)
556 self.assertNotEqual(x._keys, y._keys)
557
Guido van Rossumc7557582003-02-06 19:53:22 +0000558 def test_copy_list_subclass(self):
559 class C(list):
560 pass
561 x = C([[1, 2], 3])
562 x.foo = [4, 5]
563 y = copy.copy(x)
564 self.assertEqual(list(x), list(y))
565 self.assertEqual(x.foo, y.foo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000566 self.assertTrue(x[0] is y[0])
567 self.assertTrue(x.foo is y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000568
569 def test_deepcopy_list_subclass(self):
570 class C(list):
571 pass
572 x = C([[1, 2], 3])
573 x.foo = [4, 5]
574 y = copy.deepcopy(x)
575 self.assertEqual(list(x), list(y))
576 self.assertEqual(x.foo, y.foo)
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000577 self.assertTrue(x[0] is not y[0])
578 self.assertTrue(x.foo is not y.foo)
Guido van Rossumc7557582003-02-06 19:53:22 +0000579
Guido van Rossum85233bf2003-02-06 21:25:12 +0000580 def test_copy_tuple_subclass(self):
581 class C(tuple):
582 pass
583 x = C([1, 2, 3])
584 self.assertEqual(tuple(x), (1, 2, 3))
585 y = copy.copy(x)
586 self.assertEqual(tuple(y), (1, 2, 3))
587
588 def test_deepcopy_tuple_subclass(self):
589 class C(tuple):
590 pass
591 x = C([[1, 2], 3])
592 self.assertEqual(tuple(x), ([1, 2], 3))
593 y = copy.deepcopy(x)
594 self.assertEqual(tuple(y), ([1, 2], 3))
Benjamin Peterson5c8da862009-06-30 22:57:08 +0000595 self.assertTrue(x is not y)
596 self.assertTrue(x[0] is not y[0])
Guido van Rossum85233bf2003-02-06 21:25:12 +0000597
Neal Norwitze2fdc612003-06-08 13:19:58 +0000598 def test_getstate_exc(self):
599 class EvilState(object):
600 def __getstate__(self):
601 raise ValueError, "ain't got no stickin' state"
602 self.assertRaises(ValueError, copy.copy, EvilState())
603
Guido van Rossum1968ad32006-02-25 22:38:04 +0000604 def test_copy_function(self):
605 self.assertEqual(copy.copy(global_foo), global_foo)
606 def foo(x, y): return x+y
607 self.assertEqual(copy.copy(foo), foo)
608 bar = lambda: None
609 self.assertEqual(copy.copy(bar), bar)
610
611 def test_deepcopy_function(self):
612 self.assertEqual(copy.deepcopy(global_foo), global_foo)
613 def foo(x, y): return x+y
614 self.assertEqual(copy.deepcopy(foo), foo)
615 bar = lambda: None
616 self.assertEqual(copy.deepcopy(bar), bar)
617
Antoine Pitrou775fd662009-05-15 16:54:52 +0000618 def _check_weakref(self, _copy):
619 class C(object):
620 pass
621 obj = C()
622 x = weakref.ref(obj)
623 y = _copy(x)
624 self.assertTrue(y is x)
625 del obj
626 y = _copy(x)
627 self.assertTrue(y is x)
628
629 def test_copy_weakref(self):
630 self._check_weakref(copy.copy)
631
632 def test_deepcopy_weakref(self):
633 self._check_weakref(copy.deepcopy)
634
635 def _check_copy_weakdict(self, _dicttype):
636 class C(object):
637 pass
638 a, b, c, d = [C() for i in xrange(4)]
639 u = _dicttype()
640 u[a] = b
641 u[c] = d
642 v = copy.copy(u)
643 self.assertFalse(v is u)
644 self.assertEqual(v, u)
645 self.assertEqual(v[a], b)
646 self.assertEqual(v[c], d)
647 self.assertEqual(len(v), 2)
648 del c, d
649 self.assertEqual(len(v), 1)
650 x, y = C(), C()
651 # The underlying containers are decoupled
652 v[x] = y
Ezio Melottiaa980582010-01-23 23:04:36 +0000653 self.assertNotIn(x, u)
Antoine Pitrou775fd662009-05-15 16:54:52 +0000654
655 def test_copy_weakkeydict(self):
656 self._check_copy_weakdict(weakref.WeakKeyDictionary)
657
658 def test_copy_weakvaluedict(self):
659 self._check_copy_weakdict(weakref.WeakValueDictionary)
660
661 def test_deepcopy_weakkeydict(self):
662 class C(object):
663 def __init__(self, i):
664 self.i = i
665 a, b, c, d = [C(i) for i in xrange(4)]
666 u = weakref.WeakKeyDictionary()
667 u[a] = b
668 u[c] = d
669 # Keys aren't copied, values are
670 v = copy.deepcopy(u)
671 self.assertNotEqual(v, u)
672 self.assertEqual(len(v), 2)
673 self.assertFalse(v[a] is b)
674 self.assertFalse(v[c] is d)
675 self.assertEqual(v[a].i, b.i)
676 self.assertEqual(v[c].i, d.i)
677 del c
678 self.assertEqual(len(v), 1)
679
680 def test_deepcopy_weakvaluedict(self):
681 class C(object):
682 def __init__(self, i):
683 self.i = i
684 a, b, c, d = [C(i) for i in xrange(4)]
685 u = weakref.WeakValueDictionary()
686 u[a] = b
687 u[c] = d
688 # Keys are copied, values aren't
689 v = copy.deepcopy(u)
690 self.assertNotEqual(v, u)
691 self.assertEqual(len(v), 2)
Ezio Melottidde5b942010-02-03 05:37:26 +0000692 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i)
Antoine Pitrou775fd662009-05-15 16:54:52 +0000693 self.assertFalse(x is a)
694 self.assertEqual(x.i, a.i)
695 self.assertTrue(y is b)
696 self.assertFalse(z is c)
697 self.assertEqual(z.i, c.i)
698 self.assertTrue(t is d)
699 del x, y, z, t
700 del d
701 self.assertEqual(len(v), 1)
702
Antoine Pitroud16f57b2009-11-28 15:55:58 +0000703 def test_deepcopy_bound_method(self):
704 class Foo(object):
705 def m(self):
706 pass
707 f = Foo()
708 f.b = f.m
709 g = copy.deepcopy(f)
710 self.assertEqual(g.m, g.b)
711 self.assertTrue(g.b.im_self is g)
712 g.b()
713
Antoine Pitrou775fd662009-05-15 16:54:52 +0000714
Guido van Rossum1968ad32006-02-25 22:38:04 +0000715def global_foo(x, y): return x+y
716
Guido van Rossum581cb932003-02-06 17:52:15 +0000717def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000718 test_support.run_unittest(TestCopy)
Guido van Rossum581cb932003-02-06 17:52:15 +0000719
720if __name__ == "__main__":
721 test_main()