1 """Unit tests for the copy module."""
7 from test
import test_support
9 class TestCopy(unittest
.TestCase
):
11 # Attempt full line coverage of copy.py from top to bottom
13 def test_exceptions(self
):
14 self
.assert_(copy
.Error
is copy
.error
)
15 self
.assert_(issubclass(copy
.Error
, Exception))
19 def test_copy_basic(self
):
22 self
.assertEqual(x
, y
)
24 def test_copy_copy(self
):
26 def __init__(self
, foo
):
32 self
.assertEqual(y
.__class
__, x
.__class
__)
33 self
.assertEqual(y
.foo
, x
.foo
)
35 def test_copy_registry(self
):
37 def __new__(cls
, foo
):
38 obj
= object.__new
__(cls
)
42 return (C
, (obj
.foo
,))
44 self
.assertRaises(TypeError, copy
.copy
, x
)
45 copy_reg
.pickle(C
, pickle_C
, C
)
48 def test_copy_reduce_ex(self
):
50 def __reduce_ex__(self
, proto
):
53 raise test_support
.TestFailed
, "shouldn't call this"
58 def test_copy_reduce(self
):
66 def test_copy_cant(self
):
68 def __getattribute__(self
, name
):
69 if name
.startswith("__reduce"):
70 raise AttributeError, name
71 return object.__getattribute
__(self
, name
)
73 self
.assertRaises(copy
.Error
, copy
.copy
, x
)
75 # Type-specific _copy_xxx() methods
77 def test_copy_atomic(self
):
80 class NewStyle(object):
84 tests
= [None, 42, 2L**100, 3.14, True, False, 1j
,
85 "hello", u
"hello\u1234", f
.func_code
,
86 NewStyle
, xrange(10), Classic
, max]
88 self
.assert_(copy
.copy(x
) is x
, repr(x
))
90 def test_copy_list(self
):
92 self
.assertEqual(copy
.copy(x
), x
)
94 def test_copy_tuple(self
):
96 self
.assertEqual(copy
.copy(x
), x
)
98 def test_copy_dict(self
):
99 x
= {"foo": 1, "bar": 2}
100 self
.assertEqual(copy
.copy(x
), x
)
102 def test_copy_inst_vanilla(self
):
104 def __init__(self
, foo
):
106 def __cmp__(self
, other
):
107 return cmp(self
.foo
, other
.foo
)
109 self
.assertEqual(copy
.copy(x
), x
)
111 def test_copy_inst_copy(self
):
113 def __init__(self
, foo
):
117 def __cmp__(self
, other
):
118 return cmp(self
.foo
, other
.foo
)
120 self
.assertEqual(copy
.copy(x
), x
)
122 def test_copy_inst_getinitargs(self
):
124 def __init__(self
, foo
):
126 def __getinitargs__(self
):
128 def __cmp__(self
, other
):
129 return cmp(self
.foo
, other
.foo
)
131 self
.assertEqual(copy
.copy(x
), x
)
133 def test_copy_inst_getstate(self
):
135 def __init__(self
, foo
):
137 def __getstate__(self
):
138 return {"foo": self
.foo
}
139 def __cmp__(self
, other
):
140 return cmp(self
.foo
, other
.foo
)
142 self
.assertEqual(copy
.copy(x
), x
)
144 def test_copy_inst_setstate(self
):
146 def __init__(self
, foo
):
148 def __setstate__(self
, state
):
149 self
.foo
= state
["foo"]
150 def __cmp__(self
, other
):
151 return cmp(self
.foo
, other
.foo
)
153 self
.assertEqual(copy
.copy(x
), x
)
155 def test_copy_inst_getstate_setstate(self
):
157 def __init__(self
, foo
):
159 def __getstate__(self
):
161 def __setstate__(self
, state
):
163 def __cmp__(self
, other
):
164 return cmp(self
.foo
, other
.foo
)
166 self
.assertEqual(copy
.copy(x
), x
)
168 # The deepcopy() method
170 def test_deepcopy_basic(self
):
173 self
.assertEqual(y
, x
)
175 def test_deepcopy_memo(self
):
176 # Tests of reflexive objects are under type-specific sections below.
177 # This tests only repetitions of objects.
181 self
.assertEqual(y
, x
)
182 self
.assert_(y
is not x
)
183 self
.assert_(y
[0] is not x
[0])
184 self
.assert_(y
[0] is y
[1])
186 def test_deepcopy_issubclass(self
):
187 # XXX Note: there's no way to test the TypeError coming out of
188 # issubclass() -- this can only happen when an extension
189 # module defines a "type" that doesn't formally inherit from
195 self
.assertEqual(copy
.deepcopy(C
), C
)
197 def test_deepcopy_deepcopy(self
):
199 def __init__(self
, foo
):
201 def __deepcopy__(self
, memo
=None):
205 self
.assertEqual(y
.__class
__, x
.__class
__)
206 self
.assertEqual(y
.foo
, x
.foo
)
208 def test_deepcopy_registry(self
):
210 def __new__(cls
, foo
):
211 obj
= object.__new
__(cls
)
215 return (C
, (obj
.foo
,))
217 self
.assertRaises(TypeError, copy
.deepcopy
, x
)
218 copy_reg
.pickle(C
, pickle_C
, C
)
221 def test_deepcopy_reduce_ex(self
):
223 def __reduce_ex__(self
, proto
):
225 def __reduce__(self
):
226 raise test_support
.TestFailed
, "shouldn't call this"
231 def test_deepcopy_reduce(self
):
233 def __reduce__(self
):
239 def test_deepcopy_cant(self
):
241 def __getattribute__(self
, name
):
242 if name
.startswith("__reduce"):
243 raise AttributeError, name
244 return object.__getattribute
__(self
, name
)
246 self
.assertRaises(copy
.Error
, copy
.deepcopy
, x
)
248 # Type-specific _deepcopy_xxx() methods
250 def test_deepcopy_atomic(self
):
253 class NewStyle(object):
257 tests
= [None, 42, 2L**100, 3.14, True, False, 1j
,
258 "hello", u
"hello\u1234", f
.func_code
,
259 NewStyle
, xrange(10), Classic
, max]
261 self
.assert_(copy
.deepcopy(x
) is x
, repr(x
))
263 def test_deepcopy_list(self
):
266 self
.assertEqual(y
, x
)
267 self
.assert_(x
is not y
)
268 self
.assert_(x
[0] is not y
[0])
270 def test_deepcopy_reflexive_list(self
):
274 self
.assertRaises(RuntimeError, cmp, y
, x
)
275 self
.assert_(y
is not x
)
276 self
.assert_(y
[0] is y
)
277 self
.assertEqual(len(y
), 1)
279 def test_deepcopy_tuple(self
):
282 self
.assertEqual(y
, x
)
283 self
.assert_(x
is not y
)
284 self
.assert_(x
[0] is not y
[0])
286 def test_deepcopy_reflexive_tuple(self
):
290 self
.assertRaises(RuntimeError, cmp, y
, x
)
291 self
.assert_(y
is not x
)
292 self
.assert_(y
[0] is not x
[0])
293 self
.assert_(y
[0][0] is y
)
295 def test_deepcopy_dict(self
):
296 x
= {"foo": [1, 2], "bar": 3}
298 self
.assertEqual(y
, x
)
299 self
.assert_(x
is not y
)
300 self
.assert_(x
["foo"] is not y
["foo"])
302 def test_deepcopy_reflexive_dict(self
):
306 self
.assertRaises(RuntimeError, cmp, y
, x
)
307 self
.assert_(y
is not x
)
308 self
.assert_(y
['foo'] is y
)
309 self
.assertEqual(len(y
), 1)
311 def test_deepcopy_keepalive(self
):
314 y
= copy
.deepcopy(x
, memo
)
315 self
.assert_(memo
[id(x
)] is x
)
317 def test_deepcopy_inst_vanilla(self
):
319 def __init__(self
, foo
):
321 def __cmp__(self
, other
):
322 return cmp(self
.foo
, other
.foo
)
325 self
.assertEqual(y
, x
)
326 self
.assert_(y
.foo
is not x
.foo
)
328 def test_deepcopy_inst_deepcopy(self
):
330 def __init__(self
, foo
):
332 def __deepcopy__(self
, memo
):
333 return C(copy
.deepcopy(self
.foo
, memo
))
334 def __cmp__(self
, other
):
335 return cmp(self
.foo
, other
.foo
)
338 self
.assertEqual(y
, x
)
339 self
.assert_(y
is not x
)
340 self
.assert_(y
.foo
is not x
.foo
)
342 def test_deepcopy_inst_getinitargs(self
):
344 def __init__(self
, foo
):
346 def __getinitargs__(self
):
348 def __cmp__(self
, other
):
349 return cmp(self
.foo
, other
.foo
)
352 self
.assertEqual(y
, x
)
353 self
.assert_(y
is not x
)
354 self
.assert_(y
.foo
is not x
.foo
)
356 def test_deepcopy_inst_getstate(self
):
358 def __init__(self
, foo
):
360 def __getstate__(self
):
361 return {"foo": self
.foo
}
362 def __cmp__(self
, other
):
363 return cmp(self
.foo
, other
.foo
)
366 self
.assertEqual(y
, x
)
367 self
.assert_(y
is not x
)
368 self
.assert_(y
.foo
is not x
.foo
)
370 def test_deepcopy_inst_setstate(self
):
372 def __init__(self
, foo
):
374 def __setstate__(self
, state
):
375 self
.foo
= state
["foo"]
376 def __cmp__(self
, other
):
377 return cmp(self
.foo
, other
.foo
)
380 self
.assertEqual(y
, x
)
381 self
.assert_(y
is not x
)
382 self
.assert_(y
.foo
is not x
.foo
)
384 def test_deepcopy_inst_getstate_setstate(self
):
386 def __init__(self
, foo
):
388 def __getstate__(self
):
390 def __setstate__(self
, state
):
392 def __cmp__(self
, other
):
393 return cmp(self
.foo
, other
.foo
)
396 self
.assertEqual(y
, x
)
397 self
.assert_(y
is not x
)
398 self
.assert_(y
.foo
is not x
.foo
)
400 def test_deepcopy_reflexive_inst(self
):
406 self
.assert_(y
is not x
)
407 self
.assert_(y
.foo
is y
)
411 def test_reconstruct_string(self
):
413 def __reduce__(self
):
421 def test_reconstruct_nostate(self
):
423 def __reduce__(self
):
428 self
.assert_(y
.__class
__ is x
.__class
__)
430 self
.assert_(y
.__class
__ is x
.__class
__)
432 def test_reconstruct_state(self
):
434 def __reduce__(self
):
435 return (C
, (), self
.__dict
__)
436 def __cmp__(self
, other
):
437 return cmp(self
.__dict
__, other
.__dict
__)
441 self
.assertEqual(y
, x
)
443 self
.assertEqual(y
, x
)
444 self
.assert_(y
.foo
is not x
.foo
)
446 def test_reconstruct_state_setstate(self
):
448 def __reduce__(self
):
449 return (C
, (), self
.__dict
__)
450 def __setstate__(self
, state
):
451 self
.__dict
__.update(state
)
452 def __cmp__(self
, other
):
453 return cmp(self
.__dict
__, other
.__dict
__)
457 self
.assertEqual(y
, x
)
459 self
.assertEqual(y
, x
)
460 self
.assert_(y
.foo
is not x
.foo
)
462 def test_reconstruct_reflexive(self
):
468 self
.assert_(y
is not x
)
469 self
.assert_(y
.foo
is y
)
471 # Additions for Python 2.3 and pickle protocol 2
473 def test_reduce_4tuple(self
):
475 def __reduce__(self
):
476 return (C
, (), self
.__dict
__, iter(self
))
477 def __cmp__(self
, other
):
478 return (cmp(list(self
), list(other
)) or
479 cmp(self
.__dict
__, other
.__dict
__))
482 self
.assertEqual(x
, y
)
483 self
.assert_(x
is not y
)
484 self
.assert_(x
[0] is y
[0])
486 self
.assertEqual(x
, y
)
487 self
.assert_(x
is not y
)
488 self
.assert_(x
[0] is not y
[0])
490 def test_reduce_5tuple(self
):
492 def __reduce__(self
):
493 return (C
, (), self
.__dict
__, None, self
.iteritems())
494 def __cmp__(self
, other
):
495 return (cmp(dict(self
), list(dict)) or
496 cmp(self
.__dict
__, other
.__dict
__))
497 x
= C([("foo", [1, 2]), ("bar", 3)])
499 self
.assertEqual(x
, y
)
500 self
.assert_(x
is not y
)
501 self
.assert_(x
["foo"] is y
["foo"])
503 self
.assertEqual(x
, y
)
504 self
.assert_(x
is not y
)
505 self
.assert_(x
["foo"] is not y
["foo"])
507 def test_copy_slots(self
):
513 self
.assert_(x
.foo
is y
.foo
)
515 def test_deepcopy_slots(self
):
521 self
.assertEqual(x
.foo
, y
.foo
)
522 self
.assert_(x
.foo
is not y
.foo
)
524 def test_copy_list_subclass(self
):
530 self
.assertEqual(list(x
), list(y
))
531 self
.assertEqual(x
.foo
, y
.foo
)
532 self
.assert_(x
[0] is y
[0])
533 self
.assert_(x
.foo
is y
.foo
)
535 def test_deepcopy_list_subclass(self
):
541 self
.assertEqual(list(x
), list(y
))
542 self
.assertEqual(x
.foo
, y
.foo
)
543 self
.assert_(x
[0] is not y
[0])
544 self
.assert_(x
.foo
is not y
.foo
)
546 def test_copy_tuple_subclass(self
):
550 self
.assertEqual(tuple(x
), (1, 2, 3))
552 self
.assertEqual(tuple(y
), (1, 2, 3))
554 def test_deepcopy_tuple_subclass(self
):
558 self
.assertEqual(tuple(x
), ([1, 2], 3))
560 self
.assertEqual(tuple(y
), ([1, 2], 3))
561 self
.assert_(x
is not y
)
562 self
.assert_(x
[0] is not y
[0])
564 def test_getstate_exc(self
):
565 class EvilState(object):
566 def __getstate__(self
):
567 raise ValueError, "ain't got no stickin' state"
568 self
.assertRaises(ValueError, copy
.copy
, EvilState())
570 def test_copy_function(self
):
571 self
.assertEqual(copy
.copy(global_foo
), global_foo
)
572 def foo(x
, y
): return x
+y
573 self
.assertEqual(copy
.copy(foo
), foo
)
575 self
.assertEqual(copy
.copy(bar
), bar
)
577 def test_deepcopy_function(self
):
578 self
.assertEqual(copy
.deepcopy(global_foo
), global_foo
)
579 def foo(x
, y
): return x
+y
580 self
.assertEqual(copy
.deepcopy(foo
), foo
)
582 self
.assertEqual(copy
.deepcopy(bar
), bar
)
584 def global_foo(x
, y
): return x
+y
587 test_support
.run_unittest(TestCopy
)
589 if __name__
== "__main__":