1 """Unit tests for the copy module."""
9 from test
import test_support
11 class TestCopy(unittest
.TestCase
):
13 # Attempt full line coverage of copy.py from top to bottom
15 def test_exceptions(self
):
16 self
.assertTrue(copy
.Error
is copy
.error
)
17 self
.assertTrue(issubclass(copy
.Error
, Exception))
21 def test_copy_basic(self
):
24 self
.assertEqual(x
, y
)
26 def test_copy_copy(self
):
28 def __init__(self
, foo
):
34 self
.assertEqual(y
.__class
__, x
.__class
__)
35 self
.assertEqual(y
.foo
, x
.foo
)
37 def test_copy_registry(self
):
39 def __new__(cls
, foo
):
40 obj
= object.__new
__(cls
)
44 return (C
, (obj
.foo
,))
46 self
.assertRaises(TypeError, copy
.copy
, x
)
47 copy_reg
.pickle(C
, pickle_C
, C
)
50 def test_copy_reduce_ex(self
):
52 def __reduce_ex__(self
, proto
):
55 raise test_support
.TestFailed
, "shouldn't call this"
58 self
.assertTrue(y
is x
)
60 def test_copy_reduce(self
):
66 self
.assertTrue(y
is x
)
68 def test_copy_cant(self
):
70 def __getattribute__(self
, name
):
71 if name
.startswith("__reduce"):
72 raise AttributeError, name
73 return object.__getattribute
__(self
, name
)
75 self
.assertRaises(copy
.Error
, copy
.copy
, x
)
77 # Type-specific _copy_xxx() methods
79 def test_copy_atomic(self
):
82 class NewStyle(object):
86 tests
= [None, 42, 2L**100, 3.14, True, False, 1j
,
87 "hello", u
"hello\u1234", f
.func_code
,
88 NewStyle
, xrange(10), Classic
, max]
90 self
.assertTrue(copy
.copy(x
) is x
, repr(x
))
92 def test_copy_list(self
):
94 self
.assertEqual(copy
.copy(x
), x
)
96 def test_copy_tuple(self
):
98 self
.assertEqual(copy
.copy(x
), x
)
100 def test_copy_dict(self
):
101 x
= {"foo": 1, "bar": 2}
102 self
.assertEqual(copy
.copy(x
), x
)
104 def test_copy_inst_vanilla(self
):
106 def __init__(self
, foo
):
108 def __cmp__(self
, other
):
109 return cmp(self
.foo
, other
.foo
)
111 self
.assertEqual(copy
.copy(x
), x
)
113 def test_copy_inst_copy(self
):
115 def __init__(self
, foo
):
119 def __cmp__(self
, other
):
120 return cmp(self
.foo
, other
.foo
)
122 self
.assertEqual(copy
.copy(x
), x
)
124 def test_copy_inst_getinitargs(self
):
126 def __init__(self
, foo
):
128 def __getinitargs__(self
):
130 def __cmp__(self
, other
):
131 return cmp(self
.foo
, other
.foo
)
133 self
.assertEqual(copy
.copy(x
), x
)
135 def test_copy_inst_getstate(self
):
137 def __init__(self
, foo
):
139 def __getstate__(self
):
140 return {"foo": self
.foo
}
141 def __cmp__(self
, other
):
142 return cmp(self
.foo
, other
.foo
)
144 self
.assertEqual(copy
.copy(x
), x
)
146 def test_copy_inst_setstate(self
):
148 def __init__(self
, foo
):
150 def __setstate__(self
, state
):
151 self
.foo
= state
["foo"]
152 def __cmp__(self
, other
):
153 return cmp(self
.foo
, other
.foo
)
155 self
.assertEqual(copy
.copy(x
), x
)
157 def test_copy_inst_getstate_setstate(self
):
159 def __init__(self
, foo
):
161 def __getstate__(self
):
163 def __setstate__(self
, state
):
165 def __cmp__(self
, other
):
166 return cmp(self
.foo
, other
.foo
)
168 self
.assertEqual(copy
.copy(x
), x
)
170 # The deepcopy() method
172 def test_deepcopy_basic(self
):
175 self
.assertEqual(y
, x
)
177 def test_deepcopy_memo(self
):
178 # Tests of reflexive objects are under type-specific sections below.
179 # This tests only repetitions of objects.
183 self
.assertEqual(y
, x
)
184 self
.assertTrue(y
is not x
)
185 self
.assertTrue(y
[0] is not x
[0])
186 self
.assertTrue(y
[0] is y
[1])
188 def test_deepcopy_issubclass(self
):
189 # XXX Note: there's no way to test the TypeError coming out of
190 # issubclass() -- this can only happen when an extension
191 # module defines a "type" that doesn't formally inherit from
197 self
.assertEqual(copy
.deepcopy(C
), C
)
199 def test_deepcopy_deepcopy(self
):
201 def __init__(self
, foo
):
203 def __deepcopy__(self
, memo
=None):
207 self
.assertEqual(y
.__class
__, x
.__class
__)
208 self
.assertEqual(y
.foo
, x
.foo
)
210 def test_deepcopy_registry(self
):
212 def __new__(cls
, foo
):
213 obj
= object.__new
__(cls
)
217 return (C
, (obj
.foo
,))
219 self
.assertRaises(TypeError, copy
.deepcopy
, x
)
220 copy_reg
.pickle(C
, pickle_C
, C
)
223 def test_deepcopy_reduce_ex(self
):
225 def __reduce_ex__(self
, proto
):
227 def __reduce__(self
):
228 raise test_support
.TestFailed
, "shouldn't call this"
231 self
.assertTrue(y
is x
)
233 def test_deepcopy_reduce(self
):
235 def __reduce__(self
):
239 self
.assertTrue(y
is x
)
241 def test_deepcopy_cant(self
):
243 def __getattribute__(self
, name
):
244 if name
.startswith("__reduce"):
245 raise AttributeError, name
246 return object.__getattribute
__(self
, name
)
248 self
.assertRaises(copy
.Error
, copy
.deepcopy
, x
)
250 # Type-specific _deepcopy_xxx() methods
252 def test_deepcopy_atomic(self
):
255 class NewStyle(object):
259 tests
= [None, 42, 2L**100, 3.14, True, False, 1j
,
260 "hello", u
"hello\u1234", f
.func_code
,
261 NewStyle
, xrange(10), Classic
, max]
263 self
.assertTrue(copy
.deepcopy(x
) is x
, repr(x
))
265 def test_deepcopy_list(self
):
268 self
.assertEqual(y
, x
)
269 self
.assertTrue(x
is not y
)
270 self
.assertTrue(x
[0] is not y
[0])
272 def test_deepcopy_reflexive_list(self
):
276 self
.assertRaises(RuntimeError, cmp, y
, x
)
277 self
.assertTrue(y
is not x
)
278 self
.assertTrue(y
[0] is y
)
279 self
.assertEqual(len(y
), 1)
281 def test_deepcopy_tuple(self
):
284 self
.assertEqual(y
, x
)
285 self
.assertTrue(x
is not y
)
286 self
.assertTrue(x
[0] is not y
[0])
288 def test_deepcopy_reflexive_tuple(self
):
292 self
.assertRaises(RuntimeError, cmp, y
, x
)
293 self
.assertTrue(y
is not x
)
294 self
.assertTrue(y
[0] is not x
[0])
295 self
.assertTrue(y
[0][0] is y
)
297 def test_deepcopy_dict(self
):
298 x
= {"foo": [1, 2], "bar": 3}
300 self
.assertEqual(y
, x
)
301 self
.assertTrue(x
is not y
)
302 self
.assertTrue(x
["foo"] is not y
["foo"])
304 def test_deepcopy_reflexive_dict(self
):
308 self
.assertRaises(RuntimeError, cmp, y
, x
)
309 self
.assertTrue(y
is not x
)
310 self
.assertTrue(y
['foo'] is y
)
311 self
.assertEqual(len(y
), 1)
313 def test_deepcopy_keepalive(self
):
316 y
= copy
.deepcopy(x
, memo
)
317 self
.assertTrue(memo
[id(x
)] is x
)
319 def test_deepcopy_inst_vanilla(self
):
321 def __init__(self
, foo
):
323 def __cmp__(self
, other
):
324 return cmp(self
.foo
, other
.foo
)
327 self
.assertEqual(y
, x
)
328 self
.assertTrue(y
.foo
is not x
.foo
)
330 def test_deepcopy_inst_deepcopy(self
):
332 def __init__(self
, foo
):
334 def __deepcopy__(self
, memo
):
335 return C(copy
.deepcopy(self
.foo
, memo
))
336 def __cmp__(self
, other
):
337 return cmp(self
.foo
, other
.foo
)
340 self
.assertEqual(y
, x
)
341 self
.assertTrue(y
is not x
)
342 self
.assertTrue(y
.foo
is not x
.foo
)
344 def test_deepcopy_inst_getinitargs(self
):
346 def __init__(self
, foo
):
348 def __getinitargs__(self
):
350 def __cmp__(self
, other
):
351 return cmp(self
.foo
, other
.foo
)
354 self
.assertEqual(y
, x
)
355 self
.assertTrue(y
is not x
)
356 self
.assertTrue(y
.foo
is not x
.foo
)
358 def test_deepcopy_inst_getstate(self
):
360 def __init__(self
, foo
):
362 def __getstate__(self
):
363 return {"foo": self
.foo
}
364 def __cmp__(self
, other
):
365 return cmp(self
.foo
, other
.foo
)
368 self
.assertEqual(y
, x
)
369 self
.assertTrue(y
is not x
)
370 self
.assertTrue(y
.foo
is not x
.foo
)
372 def test_deepcopy_inst_setstate(self
):
374 def __init__(self
, foo
):
376 def __setstate__(self
, state
):
377 self
.foo
= state
["foo"]
378 def __cmp__(self
, other
):
379 return cmp(self
.foo
, other
.foo
)
382 self
.assertEqual(y
, x
)
383 self
.assertTrue(y
is not x
)
384 self
.assertTrue(y
.foo
is not x
.foo
)
386 def test_deepcopy_inst_getstate_setstate(self
):
388 def __init__(self
, foo
):
390 def __getstate__(self
):
392 def __setstate__(self
, state
):
394 def __cmp__(self
, other
):
395 return cmp(self
.foo
, other
.foo
)
398 self
.assertEqual(y
, x
)
399 self
.assertTrue(y
is not x
)
400 self
.assertTrue(y
.foo
is not x
.foo
)
402 def test_deepcopy_reflexive_inst(self
):
408 self
.assertTrue(y
is not x
)
409 self
.assertTrue(y
.foo
is y
)
413 def test_reconstruct_string(self
):
415 def __reduce__(self
):
419 self
.assertTrue(y
is x
)
421 self
.assertTrue(y
is x
)
423 def test_reconstruct_nostate(self
):
425 def __reduce__(self
):
430 self
.assertTrue(y
.__class
__ is x
.__class
__)
432 self
.assertTrue(y
.__class
__ is x
.__class
__)
434 def test_reconstruct_state(self
):
436 def __reduce__(self
):
437 return (C
, (), self
.__dict
__)
438 def __cmp__(self
, other
):
439 return cmp(self
.__dict
__, other
.__dict
__)
440 __hash__
= None # Silence Py3k warning
444 self
.assertEqual(y
, x
)
446 self
.assertEqual(y
, x
)
447 self
.assertTrue(y
.foo
is not x
.foo
)
449 def test_reconstruct_state_setstate(self
):
451 def __reduce__(self
):
452 return (C
, (), self
.__dict
__)
453 def __setstate__(self
, state
):
454 self
.__dict
__.update(state
)
455 def __cmp__(self
, other
):
456 return cmp(self
.__dict
__, other
.__dict
__)
457 __hash__
= None # Silence Py3k warning
461 self
.assertEqual(y
, x
)
463 self
.assertEqual(y
, x
)
464 self
.assertTrue(y
.foo
is not x
.foo
)
466 def test_reconstruct_reflexive(self
):
472 self
.assertTrue(y
is not x
)
473 self
.assertTrue(y
.foo
is y
)
475 # Additions for Python 2.3 and pickle protocol 2
477 def test_reduce_4tuple(self
):
479 def __reduce__(self
):
480 return (C
, (), self
.__dict
__, iter(self
))
481 def __cmp__(self
, other
):
482 return (cmp(list(self
), list(other
)) or
483 cmp(self
.__dict
__, other
.__dict
__))
484 __hash__
= None # Silence Py3k warning
487 self
.assertEqual(x
, y
)
488 self
.assertTrue(x
is not y
)
489 self
.assertTrue(x
[0] is y
[0])
491 self
.assertEqual(x
, y
)
492 self
.assertTrue(x
is not y
)
493 self
.assertTrue(x
[0] is not y
[0])
495 def test_reduce_5tuple(self
):
497 def __reduce__(self
):
498 return (C
, (), self
.__dict
__, None, self
.iteritems())
499 def __cmp__(self
, other
):
500 return (cmp(dict(self
), list(dict)) or
501 cmp(self
.__dict
__, other
.__dict
__))
502 __hash__
= None # Silence Py3k warning
503 x
= C([("foo", [1, 2]), ("bar", 3)])
505 self
.assertEqual(x
, y
)
506 self
.assertTrue(x
is not y
)
507 self
.assertTrue(x
["foo"] is y
["foo"])
509 self
.assertEqual(x
, y
)
510 self
.assertTrue(x
is not y
)
511 self
.assertTrue(x
["foo"] is not y
["foo"])
513 def test_copy_slots(self
):
519 self
.assertTrue(x
.foo
is y
.foo
)
521 def test_deepcopy_slots(self
):
527 self
.assertEqual(x
.foo
, y
.foo
)
528 self
.assertTrue(x
.foo
is not y
.foo
)
530 def test_copy_list_subclass(self
):
536 self
.assertEqual(list(x
), list(y
))
537 self
.assertEqual(x
.foo
, y
.foo
)
538 self
.assertTrue(x
[0] is y
[0])
539 self
.assertTrue(x
.foo
is y
.foo
)
541 def test_deepcopy_list_subclass(self
):
547 self
.assertEqual(list(x
), list(y
))
548 self
.assertEqual(x
.foo
, y
.foo
)
549 self
.assertTrue(x
[0] is not y
[0])
550 self
.assertTrue(x
.foo
is not y
.foo
)
552 def test_copy_tuple_subclass(self
):
556 self
.assertEqual(tuple(x
), (1, 2, 3))
558 self
.assertEqual(tuple(y
), (1, 2, 3))
560 def test_deepcopy_tuple_subclass(self
):
564 self
.assertEqual(tuple(x
), ([1, 2], 3))
566 self
.assertEqual(tuple(y
), ([1, 2], 3))
567 self
.assertTrue(x
is not y
)
568 self
.assertTrue(x
[0] is not y
[0])
570 def test_getstate_exc(self
):
571 class EvilState(object):
572 def __getstate__(self
):
573 raise ValueError, "ain't got no stickin' state"
574 self
.assertRaises(ValueError, copy
.copy
, EvilState())
576 def test_copy_function(self
):
577 self
.assertEqual(copy
.copy(global_foo
), global_foo
)
578 def foo(x
, y
): return x
+y
579 self
.assertEqual(copy
.copy(foo
), foo
)
581 self
.assertEqual(copy
.copy(bar
), bar
)
583 def test_deepcopy_function(self
):
584 self
.assertEqual(copy
.deepcopy(global_foo
), global_foo
)
585 def foo(x
, y
): return x
+y
586 self
.assertEqual(copy
.deepcopy(foo
), foo
)
588 self
.assertEqual(copy
.deepcopy(bar
), bar
)
590 def _check_weakref(self
, _copy
):
596 self
.assertTrue(y
is x
)
599 self
.assertTrue(y
is x
)
601 def test_copy_weakref(self
):
602 self
._check
_weakref
(copy
.copy
)
604 def test_deepcopy_weakref(self
):
605 self
._check
_weakref
(copy
.deepcopy
)
607 def _check_copy_weakdict(self
, _dicttype
):
610 a
, b
, c
, d
= [C() for i
in xrange(4)]
615 self
.assertFalse(v
is u
)
616 self
.assertEqual(v
, u
)
617 self
.assertEqual(v
[a
], b
)
618 self
.assertEqual(v
[c
], d
)
619 self
.assertEqual(len(v
), 2)
621 self
.assertEqual(len(v
), 1)
623 # The underlying containers are decoupled
625 self
.assertFalse(x
in u
)
627 def test_copy_weakkeydict(self
):
628 self
._check
_copy
_weakdict
(weakref
.WeakKeyDictionary
)
630 def test_copy_weakvaluedict(self
):
631 self
._check
_copy
_weakdict
(weakref
.WeakValueDictionary
)
633 def test_deepcopy_weakkeydict(self
):
635 def __init__(self
, i
):
637 a
, b
, c
, d
= [C(i
) for i
in xrange(4)]
638 u
= weakref
.WeakKeyDictionary()
641 # Keys aren't copied, values are
643 self
.assertNotEqual(v
, u
)
644 self
.assertEqual(len(v
), 2)
645 self
.assertFalse(v
[a
] is b
)
646 self
.assertFalse(v
[c
] is d
)
647 self
.assertEqual(v
[a
].i
, b
.i
)
648 self
.assertEqual(v
[c
].i
, d
.i
)
650 self
.assertEqual(len(v
), 1)
652 def test_deepcopy_weakvaluedict(self
):
654 def __init__(self
, i
):
656 a
, b
, c
, d
= [C(i
) for i
in xrange(4)]
657 u
= weakref
.WeakValueDictionary()
660 # Keys are copied, values aren't
662 self
.assertNotEqual(v
, u
)
663 self
.assertEqual(len(v
), 2)
664 (x
, y
), (z
, t
) = sorted(v
.items(), key
=lambda (k
, v
): k
.i
)
665 self
.assertFalse(x
is a
)
666 self
.assertEqual(x
.i
, a
.i
)
667 self
.assertTrue(y
is b
)
668 self
.assertFalse(z
is c
)
669 self
.assertEqual(z
.i
, c
.i
)
670 self
.assertTrue(t
is d
)
673 self
.assertEqual(len(v
), 1)
676 def global_foo(x
, y
): return x
+y
679 test_support
.run_unittest(TestCopy
)
681 if __name__
== "__main__":