Issue #3389: Allow resolving dotted names for handlers in logging configuration files...
[python.git] / Lib / test / test_copy.py
blobd2899bd4eab9f1184aeebdd53a94a9805770878c
1 """Unit tests for the copy module."""
3 import copy
4 import copy_reg
6 import unittest
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))
17 # The copy() method
19 def test_copy_basic(self):
20 x = 42
21 y = copy.copy(x)
22 self.assertEqual(x, y)
24 def test_copy_copy(self):
25 class C(object):
26 def __init__(self, foo):
27 self.foo = foo
28 def __copy__(self):
29 return C(self.foo)
30 x = C(42)
31 y = copy.copy(x)
32 self.assertEqual(y.__class__, x.__class__)
33 self.assertEqual(y.foo, x.foo)
35 def test_copy_registry(self):
36 class C(object):
37 def __new__(cls, foo):
38 obj = object.__new__(cls)
39 obj.foo = foo
40 return obj
41 def pickle_C(obj):
42 return (C, (obj.foo,))
43 x = C(42)
44 self.assertRaises(TypeError, copy.copy, x)
45 copy_reg.pickle(C, pickle_C, C)
46 y = copy.copy(x)
48 def test_copy_reduce_ex(self):
49 class C(object):
50 def __reduce_ex__(self, proto):
51 return ""
52 def __reduce__(self):
53 raise test_support.TestFailed, "shouldn't call this"
54 x = C()
55 y = copy.copy(x)
56 self.assert_(y is x)
58 def test_copy_reduce(self):
59 class C(object):
60 def __reduce__(self):
61 return ""
62 x = C()
63 y = copy.copy(x)
64 self.assert_(y is x)
66 def test_copy_cant(self):
67 class C(object):
68 def __getattribute__(self, name):
69 if name.startswith("__reduce"):
70 raise AttributeError, name
71 return object.__getattribute__(self, name)
72 x = C()
73 self.assertRaises(copy.Error, copy.copy, x)
75 # Type-specific _copy_xxx() methods
77 def test_copy_atomic(self):
78 class Classic:
79 pass
80 class NewStyle(object):
81 pass
82 def f():
83 pass
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]
87 for x in tests:
88 self.assert_(copy.copy(x) is x, repr(x))
90 def test_copy_list(self):
91 x = [1, 2, 3]
92 self.assertEqual(copy.copy(x), x)
94 def test_copy_tuple(self):
95 x = (1, 2, 3)
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):
103 class C:
104 def __init__(self, foo):
105 self.foo = foo
106 def __cmp__(self, other):
107 return cmp(self.foo, other.foo)
108 x = C(42)
109 self.assertEqual(copy.copy(x), x)
111 def test_copy_inst_copy(self):
112 class C:
113 def __init__(self, foo):
114 self.foo = foo
115 def __copy__(self):
116 return C(self.foo)
117 def __cmp__(self, other):
118 return cmp(self.foo, other.foo)
119 x = C(42)
120 self.assertEqual(copy.copy(x), x)
122 def test_copy_inst_getinitargs(self):
123 class C:
124 def __init__(self, foo):
125 self.foo = foo
126 def __getinitargs__(self):
127 return (self.foo,)
128 def __cmp__(self, other):
129 return cmp(self.foo, other.foo)
130 x = C(42)
131 self.assertEqual(copy.copy(x), x)
133 def test_copy_inst_getstate(self):
134 class C:
135 def __init__(self, foo):
136 self.foo = foo
137 def __getstate__(self):
138 return {"foo": self.foo}
139 def __cmp__(self, other):
140 return cmp(self.foo, other.foo)
141 x = C(42)
142 self.assertEqual(copy.copy(x), x)
144 def test_copy_inst_setstate(self):
145 class C:
146 def __init__(self, foo):
147 self.foo = foo
148 def __setstate__(self, state):
149 self.foo = state["foo"]
150 def __cmp__(self, other):
151 return cmp(self.foo, other.foo)
152 x = C(42)
153 self.assertEqual(copy.copy(x), x)
155 def test_copy_inst_getstate_setstate(self):
156 class C:
157 def __init__(self, foo):
158 self.foo = foo
159 def __getstate__(self):
160 return self.foo
161 def __setstate__(self, state):
162 self.foo = state
163 def __cmp__(self, other):
164 return cmp(self.foo, other.foo)
165 x = C(42)
166 self.assertEqual(copy.copy(x), x)
168 # The deepcopy() method
170 def test_deepcopy_basic(self):
171 x = 42
172 y = copy.deepcopy(x)
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.
178 x = []
179 x = [x, x]
180 y = copy.deepcopy(x)
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
190 # type.
191 class Meta(type):
192 pass
193 class C:
194 __metaclass__ = Meta
195 self.assertEqual(copy.deepcopy(C), C)
197 def test_deepcopy_deepcopy(self):
198 class C(object):
199 def __init__(self, foo):
200 self.foo = foo
201 def __deepcopy__(self, memo=None):
202 return C(self.foo)
203 x = C(42)
204 y = copy.deepcopy(x)
205 self.assertEqual(y.__class__, x.__class__)
206 self.assertEqual(y.foo, x.foo)
208 def test_deepcopy_registry(self):
209 class C(object):
210 def __new__(cls, foo):
211 obj = object.__new__(cls)
212 obj.foo = foo
213 return obj
214 def pickle_C(obj):
215 return (C, (obj.foo,))
216 x = C(42)
217 self.assertRaises(TypeError, copy.deepcopy, x)
218 copy_reg.pickle(C, pickle_C, C)
219 y = copy.deepcopy(x)
221 def test_deepcopy_reduce_ex(self):
222 class C(object):
223 def __reduce_ex__(self, proto):
224 return ""
225 def __reduce__(self):
226 raise test_support.TestFailed, "shouldn't call this"
227 x = C()
228 y = copy.deepcopy(x)
229 self.assert_(y is x)
231 def test_deepcopy_reduce(self):
232 class C(object):
233 def __reduce__(self):
234 return ""
235 x = C()
236 y = copy.deepcopy(x)
237 self.assert_(y is x)
239 def test_deepcopy_cant(self):
240 class C(object):
241 def __getattribute__(self, name):
242 if name.startswith("__reduce"):
243 raise AttributeError, name
244 return object.__getattribute__(self, name)
245 x = C()
246 self.assertRaises(copy.Error, copy.deepcopy, x)
248 # Type-specific _deepcopy_xxx() methods
250 def test_deepcopy_atomic(self):
251 class Classic:
252 pass
253 class NewStyle(object):
254 pass
255 def f():
256 pass
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]
260 for x in tests:
261 self.assert_(copy.deepcopy(x) is x, repr(x))
263 def test_deepcopy_list(self):
264 x = [[1, 2], 3]
265 y = copy.deepcopy(x)
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):
271 x = []
272 x.append(x)
273 y = copy.deepcopy(x)
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):
280 x = ([1, 2], 3)
281 y = copy.deepcopy(x)
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):
287 x = ([],)
288 x[0].append(x)
289 y = copy.deepcopy(x)
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}
297 y = copy.deepcopy(x)
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):
303 x = {}
304 x['foo'] = x
305 y = copy.deepcopy(x)
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):
312 memo = {}
313 x = 42
314 y = copy.deepcopy(x, memo)
315 self.assert_(memo[id(x)] is x)
317 def test_deepcopy_inst_vanilla(self):
318 class C:
319 def __init__(self, foo):
320 self.foo = foo
321 def __cmp__(self, other):
322 return cmp(self.foo, other.foo)
323 x = C([42])
324 y = copy.deepcopy(x)
325 self.assertEqual(y, x)
326 self.assert_(y.foo is not x.foo)
328 def test_deepcopy_inst_deepcopy(self):
329 class C:
330 def __init__(self, foo):
331 self.foo = 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)
336 x = C([42])
337 y = copy.deepcopy(x)
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):
343 class C:
344 def __init__(self, foo):
345 self.foo = foo
346 def __getinitargs__(self):
347 return (self.foo,)
348 def __cmp__(self, other):
349 return cmp(self.foo, other.foo)
350 x = C([42])
351 y = copy.deepcopy(x)
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):
357 class C:
358 def __init__(self, foo):
359 self.foo = foo
360 def __getstate__(self):
361 return {"foo": self.foo}
362 def __cmp__(self, other):
363 return cmp(self.foo, other.foo)
364 x = C([42])
365 y = copy.deepcopy(x)
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):
371 class C:
372 def __init__(self, foo):
373 self.foo = foo
374 def __setstate__(self, state):
375 self.foo = state["foo"]
376 def __cmp__(self, other):
377 return cmp(self.foo, other.foo)
378 x = C([42])
379 y = copy.deepcopy(x)
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):
385 class C:
386 def __init__(self, foo):
387 self.foo = foo
388 def __getstate__(self):
389 return self.foo
390 def __setstate__(self, state):
391 self.foo = state
392 def __cmp__(self, other):
393 return cmp(self.foo, other.foo)
394 x = C([42])
395 y = copy.deepcopy(x)
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):
401 class C:
402 pass
403 x = C()
404 x.foo = x
405 y = copy.deepcopy(x)
406 self.assert_(y is not x)
407 self.assert_(y.foo is y)
409 # _reconstruct()
411 def test_reconstruct_string(self):
412 class C(object):
413 def __reduce__(self):
414 return ""
415 x = C()
416 y = copy.copy(x)
417 self.assert_(y is x)
418 y = copy.deepcopy(x)
419 self.assert_(y is x)
421 def test_reconstruct_nostate(self):
422 class C(object):
423 def __reduce__(self):
424 return (C, ())
425 x = C()
426 x.foo = 42
427 y = copy.copy(x)
428 self.assert_(y.__class__ is x.__class__)
429 y = copy.deepcopy(x)
430 self.assert_(y.__class__ is x.__class__)
432 def test_reconstruct_state(self):
433 class C(object):
434 def __reduce__(self):
435 return (C, (), self.__dict__)
436 def __cmp__(self, other):
437 return cmp(self.__dict__, other.__dict__)
438 x = C()
439 x.foo = [42]
440 y = copy.copy(x)
441 self.assertEqual(y, x)
442 y = copy.deepcopy(x)
443 self.assertEqual(y, x)
444 self.assert_(y.foo is not x.foo)
446 def test_reconstruct_state_setstate(self):
447 class C(object):
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__)
454 x = C()
455 x.foo = [42]
456 y = copy.copy(x)
457 self.assertEqual(y, x)
458 y = copy.deepcopy(x)
459 self.assertEqual(y, x)
460 self.assert_(y.foo is not x.foo)
462 def test_reconstruct_reflexive(self):
463 class C(object):
464 pass
465 x = C()
466 x.foo = x
467 y = copy.deepcopy(x)
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):
474 class C(list):
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__))
480 x = C([[1, 2], 3])
481 y = copy.copy(x)
482 self.assertEqual(x, y)
483 self.assert_(x is not y)
484 self.assert_(x[0] is y[0])
485 y = copy.deepcopy(x)
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):
491 class C(dict):
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)])
498 y = copy.copy(x)
499 self.assertEqual(x, y)
500 self.assert_(x is not y)
501 self.assert_(x["foo"] is y["foo"])
502 y = copy.deepcopy(x)
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):
508 class C(object):
509 __slots__ = ["foo"]
510 x = C()
511 x.foo = [42]
512 y = copy.copy(x)
513 self.assert_(x.foo is y.foo)
515 def test_deepcopy_slots(self):
516 class C(object):
517 __slots__ = ["foo"]
518 x = C()
519 x.foo = [42]
520 y = copy.deepcopy(x)
521 self.assertEqual(x.foo, y.foo)
522 self.assert_(x.foo is not y.foo)
524 def test_copy_list_subclass(self):
525 class C(list):
526 pass
527 x = C([[1, 2], 3])
528 x.foo = [4, 5]
529 y = copy.copy(x)
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):
536 class C(list):
537 pass
538 x = C([[1, 2], 3])
539 x.foo = [4, 5]
540 y = copy.deepcopy(x)
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):
547 class C(tuple):
548 pass
549 x = C([1, 2, 3])
550 self.assertEqual(tuple(x), (1, 2, 3))
551 y = copy.copy(x)
552 self.assertEqual(tuple(y), (1, 2, 3))
554 def test_deepcopy_tuple_subclass(self):
555 class C(tuple):
556 pass
557 x = C([[1, 2], 3])
558 self.assertEqual(tuple(x), ([1, 2], 3))
559 y = copy.deepcopy(x)
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)
574 bar = lambda: None
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)
581 bar = lambda: None
582 self.assertEqual(copy.deepcopy(bar), bar)
584 def global_foo(x, y): return x+y
586 def test_main():
587 test_support.run_unittest(TestCopy)
589 if __name__ == "__main__":
590 test_main()