1 """Unit tests for the copy module."""
8 from test
import test_support
10 class TestCopy(unittest
.TestCase
):
12 # Attempt full line coverage of copy.py from top to bottom
14 def test_exceptions(self
):
15 self
.assertTrue(copy
.Error
is copy
.error
)
16 self
.assertTrue(issubclass(copy
.Error
, Exception))
20 def test_copy_basic(self
):
23 self
.assertEqual(x
, y
)
25 def test_copy_copy(self
):
27 def __init__(self
, foo
):
33 self
.assertEqual(y
.__class
__, x
.__class
__)
34 self
.assertEqual(y
.foo
, x
.foo
)
36 def test_copy_registry(self
):
38 def __new__(cls
, foo
):
39 obj
= object.__new
__(cls
)
43 return (C
, (obj
.foo
,))
45 self
.assertRaises(TypeError, copy
.copy
, x
)
46 copy_reg
.pickle(C
, pickle_C
, C
)
49 def test_copy_reduce_ex(self
):
51 def __reduce_ex__(self
, proto
):
54 raise test_support
.TestFailed
, "shouldn't call this"
57 self
.assertTrue(y
is x
)
59 def test_copy_reduce(self
):
65 self
.assertTrue(y
is x
)
67 def test_copy_cant(self
):
69 def __getattribute__(self
, name
):
70 if name
.startswith("__reduce"):
71 raise AttributeError, name
72 return object.__getattribute
__(self
, name
)
74 self
.assertRaises(copy
.Error
, copy
.copy
, x
)
76 # Type-specific _copy_xxx() methods
78 def test_copy_atomic(self
):
81 class NewStyle(object):
85 tests
= [None, 42, 2L**100, 3.14, True, False, 1j
,
86 "hello", u
"hello\u1234", f
.func_code
,
87 NewStyle
, xrange(10), Classic
, max]
89 self
.assertTrue(copy
.copy(x
) is x
, repr(x
))
91 def test_copy_list(self
):
93 self
.assertEqual(copy
.copy(x
), x
)
95 def test_copy_tuple(self
):
97 self
.assertEqual(copy
.copy(x
), x
)
99 def test_copy_dict(self
):
100 x
= {"foo": 1, "bar": 2}
101 self
.assertEqual(copy
.copy(x
), x
)
103 def test_copy_inst_vanilla(self
):
105 def __init__(self
, foo
):
107 def __cmp__(self
, other
):
108 return cmp(self
.foo
, other
.foo
)
110 self
.assertEqual(copy
.copy(x
), x
)
112 def test_copy_inst_copy(self
):
114 def __init__(self
, foo
):
118 def __cmp__(self
, other
):
119 return cmp(self
.foo
, other
.foo
)
121 self
.assertEqual(copy
.copy(x
), x
)
123 def test_copy_inst_getinitargs(self
):
125 def __init__(self
, foo
):
127 def __getinitargs__(self
):
129 def __cmp__(self
, other
):
130 return cmp(self
.foo
, other
.foo
)
132 self
.assertEqual(copy
.copy(x
), x
)
134 def test_copy_inst_getstate(self
):
136 def __init__(self
, foo
):
138 def __getstate__(self
):
139 return {"foo": self
.foo
}
140 def __cmp__(self
, other
):
141 return cmp(self
.foo
, other
.foo
)
143 self
.assertEqual(copy
.copy(x
), x
)
145 def test_copy_inst_setstate(self
):
147 def __init__(self
, foo
):
149 def __setstate__(self
, state
):
150 self
.foo
= state
["foo"]
151 def __cmp__(self
, other
):
152 return cmp(self
.foo
, other
.foo
)
154 self
.assertEqual(copy
.copy(x
), x
)
156 def test_copy_inst_getstate_setstate(self
):
158 def __init__(self
, foo
):
160 def __getstate__(self
):
162 def __setstate__(self
, state
):
164 def __cmp__(self
, other
):
165 return cmp(self
.foo
, other
.foo
)
167 self
.assertEqual(copy
.copy(x
), x
)
169 # The deepcopy() method
171 def test_deepcopy_basic(self
):
174 self
.assertEqual(y
, x
)
176 def test_deepcopy_memo(self
):
177 # Tests of reflexive objects are under type-specific sections below.
178 # This tests only repetitions of objects.
182 self
.assertEqual(y
, x
)
183 self
.assertTrue(y
is not x
)
184 self
.assertTrue(y
[0] is not x
[0])
185 self
.assertTrue(y
[0] is y
[1])
187 def test_deepcopy_issubclass(self
):
188 # XXX Note: there's no way to test the TypeError coming out of
189 # issubclass() -- this can only happen when an extension
190 # module defines a "type" that doesn't formally inherit from
196 self
.assertEqual(copy
.deepcopy(C
), C
)
198 def test_deepcopy_deepcopy(self
):
200 def __init__(self
, foo
):
202 def __deepcopy__(self
, memo
=None):
206 self
.assertEqual(y
.__class
__, x
.__class
__)
207 self
.assertEqual(y
.foo
, x
.foo
)
209 def test_deepcopy_registry(self
):
211 def __new__(cls
, foo
):
212 obj
= object.__new
__(cls
)
216 return (C
, (obj
.foo
,))
218 self
.assertRaises(TypeError, copy
.deepcopy
, x
)
219 copy_reg
.pickle(C
, pickle_C
, C
)
222 def test_deepcopy_reduce_ex(self
):
224 def __reduce_ex__(self
, proto
):
226 def __reduce__(self
):
227 raise test_support
.TestFailed
, "shouldn't call this"
230 self
.assertTrue(y
is x
)
232 def test_deepcopy_reduce(self
):
234 def __reduce__(self
):
238 self
.assertTrue(y
is x
)
240 def test_deepcopy_cant(self
):
242 def __getattribute__(self
, name
):
243 if name
.startswith("__reduce"):
244 raise AttributeError, name
245 return object.__getattribute
__(self
, name
)
247 self
.assertRaises(copy
.Error
, copy
.deepcopy
, x
)
249 # Type-specific _deepcopy_xxx() methods
251 def test_deepcopy_atomic(self
):
254 class NewStyle(object):
258 tests
= [None, 42, 2L**100, 3.14, True, False, 1j
,
259 "hello", u
"hello\u1234", f
.func_code
,
260 NewStyle
, xrange(10), Classic
, max]
262 self
.assertTrue(copy
.deepcopy(x
) is x
, repr(x
))
264 def test_deepcopy_list(self
):
267 self
.assertEqual(y
, x
)
268 self
.assertTrue(x
is not y
)
269 self
.assertTrue(x
[0] is not y
[0])
271 def test_deepcopy_reflexive_list(self
):
275 self
.assertRaises(RuntimeError, cmp, y
, x
)
276 self
.assertTrue(y
is not x
)
277 self
.assertTrue(y
[0] is y
)
278 self
.assertEqual(len(y
), 1)
280 def test_deepcopy_tuple(self
):
283 self
.assertEqual(y
, x
)
284 self
.assertTrue(x
is not y
)
285 self
.assertTrue(x
[0] is not y
[0])
287 def test_deepcopy_reflexive_tuple(self
):
291 self
.assertRaises(RuntimeError, cmp, y
, x
)
292 self
.assertTrue(y
is not x
)
293 self
.assertTrue(y
[0] is not x
[0])
294 self
.assertTrue(y
[0][0] is y
)
296 def test_deepcopy_dict(self
):
297 x
= {"foo": [1, 2], "bar": 3}
299 self
.assertEqual(y
, x
)
300 self
.assertTrue(x
is not y
)
301 self
.assertTrue(x
["foo"] is not y
["foo"])
303 def test_deepcopy_reflexive_dict(self
):
307 self
.assertRaises(RuntimeError, cmp, y
, x
)
308 self
.assertTrue(y
is not x
)
309 self
.assertTrue(y
['foo'] is y
)
310 self
.assertEqual(len(y
), 1)
312 def test_deepcopy_keepalive(self
):
315 y
= copy
.deepcopy(x
, memo
)
316 self
.assertTrue(memo
[id(x
)] is x
)
318 def test_deepcopy_inst_vanilla(self
):
320 def __init__(self
, foo
):
322 def __cmp__(self
, other
):
323 return cmp(self
.foo
, other
.foo
)
326 self
.assertEqual(y
, x
)
327 self
.assertTrue(y
.foo
is not x
.foo
)
329 def test_deepcopy_inst_deepcopy(self
):
331 def __init__(self
, foo
):
333 def __deepcopy__(self
, memo
):
334 return C(copy
.deepcopy(self
.foo
, memo
))
335 def __cmp__(self
, other
):
336 return cmp(self
.foo
, other
.foo
)
339 self
.assertEqual(y
, x
)
340 self
.assertTrue(y
is not x
)
341 self
.assertTrue(y
.foo
is not x
.foo
)
343 def test_deepcopy_inst_getinitargs(self
):
345 def __init__(self
, foo
):
347 def __getinitargs__(self
):
349 def __cmp__(self
, other
):
350 return cmp(self
.foo
, other
.foo
)
353 self
.assertEqual(y
, x
)
354 self
.assertTrue(y
is not x
)
355 self
.assertTrue(y
.foo
is not x
.foo
)
357 def test_deepcopy_inst_getstate(self
):
359 def __init__(self
, foo
):
361 def __getstate__(self
):
362 return {"foo": self
.foo
}
363 def __cmp__(self
, other
):
364 return cmp(self
.foo
, other
.foo
)
367 self
.assertEqual(y
, x
)
368 self
.assertTrue(y
is not x
)
369 self
.assertTrue(y
.foo
is not x
.foo
)
371 def test_deepcopy_inst_setstate(self
):
373 def __init__(self
, foo
):
375 def __setstate__(self
, state
):
376 self
.foo
= state
["foo"]
377 def __cmp__(self
, other
):
378 return cmp(self
.foo
, other
.foo
)
381 self
.assertEqual(y
, x
)
382 self
.assertTrue(y
is not x
)
383 self
.assertTrue(y
.foo
is not x
.foo
)
385 def test_deepcopy_inst_getstate_setstate(self
):
387 def __init__(self
, foo
):
389 def __getstate__(self
):
391 def __setstate__(self
, state
):
393 def __cmp__(self
, other
):
394 return cmp(self
.foo
, other
.foo
)
397 self
.assertEqual(y
, x
)
398 self
.assertTrue(y
is not x
)
399 self
.assertTrue(y
.foo
is not x
.foo
)
401 def test_deepcopy_reflexive_inst(self
):
407 self
.assertTrue(y
is not x
)
408 self
.assertTrue(y
.foo
is y
)
412 def test_reconstruct_string(self
):
414 def __reduce__(self
):
418 self
.assertTrue(y
is x
)
420 self
.assertTrue(y
is x
)
422 def test_reconstruct_nostate(self
):
424 def __reduce__(self
):
429 self
.assertTrue(y
.__class
__ is x
.__class
__)
431 self
.assertTrue(y
.__class
__ is x
.__class
__)
433 def test_reconstruct_state(self
):
435 def __reduce__(self
):
436 return (C
, (), self
.__dict
__)
437 def __cmp__(self
, other
):
438 return cmp(self
.__dict
__, other
.__dict
__)
439 __hash__
= None # Silence Py3k warning
443 self
.assertEqual(y
, x
)
445 self
.assertEqual(y
, x
)
446 self
.assertTrue(y
.foo
is not x
.foo
)
448 def test_reconstruct_state_setstate(self
):
450 def __reduce__(self
):
451 return (C
, (), self
.__dict
__)
452 def __setstate__(self
, state
):
453 self
.__dict
__.update(state
)
454 def __cmp__(self
, other
):
455 return cmp(self
.__dict
__, other
.__dict
__)
456 __hash__
= None # Silence Py3k warning
460 self
.assertEqual(y
, x
)
462 self
.assertEqual(y
, x
)
463 self
.assertTrue(y
.foo
is not x
.foo
)
465 def test_reconstruct_reflexive(self
):
471 self
.assertTrue(y
is not x
)
472 self
.assertTrue(y
.foo
is y
)
474 # Additions for Python 2.3 and pickle protocol 2
476 def test_reduce_4tuple(self
):
478 def __reduce__(self
):
479 return (C
, (), self
.__dict
__, iter(self
))
480 def __cmp__(self
, other
):
481 return (cmp(list(self
), list(other
)) or
482 cmp(self
.__dict
__, other
.__dict
__))
483 __hash__
= None # Silence Py3k warning
486 self
.assertEqual(x
, y
)
487 self
.assertTrue(x
is not y
)
488 self
.assertTrue(x
[0] is y
[0])
490 self
.assertEqual(x
, y
)
491 self
.assertTrue(x
is not y
)
492 self
.assertTrue(x
[0] is not y
[0])
494 def test_reduce_5tuple(self
):
496 def __reduce__(self
):
497 return (C
, (), self
.__dict
__, None, self
.iteritems())
498 def __cmp__(self
, other
):
499 return (cmp(dict(self
), list(dict)) or
500 cmp(self
.__dict
__, other
.__dict
__))
501 __hash__
= None # Silence Py3k warning
502 x
= C([("foo", [1, 2]), ("bar", 3)])
504 self
.assertEqual(x
, y
)
505 self
.assertTrue(x
is not y
)
506 self
.assertTrue(x
["foo"] is y
["foo"])
508 self
.assertEqual(x
, y
)
509 self
.assertTrue(x
is not y
)
510 self
.assertTrue(x
["foo"] is not y
["foo"])
512 def test_copy_slots(self
):
518 self
.assertTrue(x
.foo
is y
.foo
)
520 def test_deepcopy_slots(self
):
526 self
.assertEqual(x
.foo
, y
.foo
)
527 self
.assertTrue(x
.foo
is not y
.foo
)
529 def test_copy_list_subclass(self
):
535 self
.assertEqual(list(x
), list(y
))
536 self
.assertEqual(x
.foo
, y
.foo
)
537 self
.assertTrue(x
[0] is y
[0])
538 self
.assertTrue(x
.foo
is y
.foo
)
540 def test_deepcopy_list_subclass(self
):
546 self
.assertEqual(list(x
), list(y
))
547 self
.assertEqual(x
.foo
, y
.foo
)
548 self
.assertTrue(x
[0] is not y
[0])
549 self
.assertTrue(x
.foo
is not y
.foo
)
551 def test_copy_tuple_subclass(self
):
555 self
.assertEqual(tuple(x
), (1, 2, 3))
557 self
.assertEqual(tuple(y
), (1, 2, 3))
559 def test_deepcopy_tuple_subclass(self
):
563 self
.assertEqual(tuple(x
), ([1, 2], 3))
565 self
.assertEqual(tuple(y
), ([1, 2], 3))
566 self
.assertTrue(x
is not y
)
567 self
.assertTrue(x
[0] is not y
[0])
569 def test_getstate_exc(self
):
570 class EvilState(object):
571 def __getstate__(self
):
572 raise ValueError, "ain't got no stickin' state"
573 self
.assertRaises(ValueError, copy
.copy
, EvilState())
575 def test_copy_function(self
):
576 self
.assertEqual(copy
.copy(global_foo
), global_foo
)
577 def foo(x
, y
): return x
+y
578 self
.assertEqual(copy
.copy(foo
), foo
)
580 self
.assertEqual(copy
.copy(bar
), bar
)
582 def test_deepcopy_function(self
):
583 self
.assertEqual(copy
.deepcopy(global_foo
), global_foo
)
584 def foo(x
, y
): return x
+y
585 self
.assertEqual(copy
.deepcopy(foo
), foo
)
587 self
.assertEqual(copy
.deepcopy(bar
), bar
)
589 def _check_weakref(self
, _copy
):
595 self
.assertTrue(y
is x
)
598 self
.assertTrue(y
is x
)
600 def test_copy_weakref(self
):
601 self
._check
_weakref
(copy
.copy
)
603 def test_deepcopy_weakref(self
):
604 self
._check
_weakref
(copy
.deepcopy
)
606 def _check_copy_weakdict(self
, _dicttype
):
609 a
, b
, c
, d
= [C() for i
in xrange(4)]
614 self
.assertFalse(v
is u
)
615 self
.assertEqual(v
, u
)
616 self
.assertEqual(v
[a
], b
)
617 self
.assertEqual(v
[c
], d
)
618 self
.assertEqual(len(v
), 2)
620 self
.assertEqual(len(v
), 1)
622 # The underlying containers are decoupled
624 self
.assertNotIn(x
, u
)
626 def test_copy_weakkeydict(self
):
627 self
._check
_copy
_weakdict
(weakref
.WeakKeyDictionary
)
629 def test_copy_weakvaluedict(self
):
630 self
._check
_copy
_weakdict
(weakref
.WeakValueDictionary
)
632 def test_deepcopy_weakkeydict(self
):
634 def __init__(self
, i
):
636 a
, b
, c
, d
= [C(i
) for i
in xrange(4)]
637 u
= weakref
.WeakKeyDictionary()
640 # Keys aren't copied, values are
642 self
.assertNotEqual(v
, u
)
643 self
.assertEqual(len(v
), 2)
644 self
.assertFalse(v
[a
] is b
)
645 self
.assertFalse(v
[c
] is d
)
646 self
.assertEqual(v
[a
].i
, b
.i
)
647 self
.assertEqual(v
[c
].i
, d
.i
)
649 self
.assertEqual(len(v
), 1)
651 def test_deepcopy_weakvaluedict(self
):
653 def __init__(self
, i
):
655 a
, b
, c
, d
= [C(i
) for i
in xrange(4)]
656 u
= weakref
.WeakValueDictionary()
659 # Keys are copied, values aren't
661 self
.assertNotEqual(v
, u
)
662 self
.assertEqual(len(v
), 2)
663 (x
, y
), (z
, t
) = sorted(v
.items(), key
=lambda pair
: pair
[0].i
)
664 self
.assertFalse(x
is a
)
665 self
.assertEqual(x
.i
, a
.i
)
666 self
.assertTrue(y
is b
)
667 self
.assertFalse(z
is c
)
668 self
.assertEqual(z
.i
, c
.i
)
669 self
.assertTrue(t
is d
)
672 self
.assertEqual(len(v
), 1)
674 def test_deepcopy_bound_method(self
):
681 self
.assertEqual(g
.m
, g
.b
)
682 self
.assertTrue(g
.b
.im_self
is g
)
686 def global_foo(x
, y
): return x
+y
689 test_support
.run_unittest(TestCopy
)
691 if __name__
== "__main__":