1 """Unit tests for the copy module."""
2
3 import copy
4 import copyreg
5 import weakref
6 import abc
7 from operator import le, lt, ge, gt, eq, ne
8
9 import unittest
10 from test import support
11
12 order_comparisons = le, lt, ge, gt
13 equality_comparisons = eq, ne
14 comparisons = order_comparisons + equality_comparisons
15
16 class ESC[4;38;5;81mTestCopy(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
17
18 # Attempt full line coverage of copy.py from top to bottom
19
20 def test_exceptions(self):
21 self.assertIs(copy.Error, copy.error)
22 self.assertTrue(issubclass(copy.Error, Exception))
23
24 # The copy() method
25
26 def test_copy_basic(self):
27 x = 42
28 y = copy.copy(x)
29 self.assertEqual(x, y)
30
31 def test_copy_copy(self):
32 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
33 def __init__(self, foo):
34 self.foo = foo
35 def __copy__(self):
36 return C(self.foo)
37 x = C(42)
38 y = copy.copy(x)
39 self.assertEqual(y.__class__, x.__class__)
40 self.assertEqual(y.foo, x.foo)
41
42 def test_copy_registry(self):
43 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
44 def __new__(cls, foo):
45 obj = object.__new__(cls)
46 obj.foo = foo
47 return obj
48 def pickle_C(obj):
49 return (C, (obj.foo,))
50 x = C(42)
51 self.assertRaises(TypeError, copy.copy, x)
52 copyreg.pickle(C, pickle_C, C)
53 y = copy.copy(x)
54 self.assertIsNot(x, y)
55 self.assertEqual(type(y), C)
56 self.assertEqual(y.foo, x.foo)
57
58 def test_copy_reduce_ex(self):
59 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
60 def __reduce_ex__(self, proto):
61 c.append(1)
62 return ""
63 def __reduce__(self):
64 self.fail("shouldn't call this")
65 c = []
66 x = C()
67 y = copy.copy(x)
68 self.assertIs(y, x)
69 self.assertEqual(c, [1])
70
71 def test_copy_reduce(self):
72 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
73 def __reduce__(self):
74 c.append(1)
75 return ""
76 c = []
77 x = C()
78 y = copy.copy(x)
79 self.assertIs(y, x)
80 self.assertEqual(c, [1])
81
82 def test_copy_cant(self):
83 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
84 def __getattribute__(self, name):
85 if name.startswith("__reduce"):
86 raise AttributeError(name)
87 return object.__getattribute__(self, name)
88 x = C()
89 self.assertRaises(copy.Error, copy.copy, x)
90
91 # Type-specific _copy_xxx() methods
92
93 def test_copy_atomic(self):
94 class ESC[4;38;5;81mClassic:
95 pass
96 class ESC[4;38;5;81mNewStyle(ESC[4;38;5;149mobject):
97 pass
98 def f():
99 pass
100 class ESC[4;38;5;81mWithMetaclass(metaclass=ESC[4;38;5;149mabcESC[4;38;5;149m.ESC[4;38;5;149mABCMeta):
101 pass
102 tests = [None, ..., NotImplemented,
103 42, 2**100, 3.14, True, False, 1j,
104 "hello", "hello\u1234", f.__code__,
105 b"world", bytes(range(256)), range(10), slice(1, 10, 2),
106 NewStyle, Classic, max, WithMetaclass, property()]
107 for x in tests:
108 self.assertIs(copy.copy(x), x)
109
110 def test_copy_list(self):
111 x = [1, 2, 3]
112 y = copy.copy(x)
113 self.assertEqual(y, x)
114 self.assertIsNot(y, x)
115 x = []
116 y = copy.copy(x)
117 self.assertEqual(y, x)
118 self.assertIsNot(y, x)
119
120 def test_copy_tuple(self):
121 x = (1, 2, 3)
122 self.assertIs(copy.copy(x), x)
123 x = ()
124 self.assertIs(copy.copy(x), x)
125 x = (1, 2, 3, [])
126 self.assertIs(copy.copy(x), x)
127
128 def test_copy_dict(self):
129 x = {"foo": 1, "bar": 2}
130 y = copy.copy(x)
131 self.assertEqual(y, x)
132 self.assertIsNot(y, x)
133 x = {}
134 y = copy.copy(x)
135 self.assertEqual(y, x)
136 self.assertIsNot(y, x)
137
138 def test_copy_set(self):
139 x = {1, 2, 3}
140 y = copy.copy(x)
141 self.assertEqual(y, x)
142 self.assertIsNot(y, x)
143 x = set()
144 y = copy.copy(x)
145 self.assertEqual(y, x)
146 self.assertIsNot(y, x)
147
148 def test_copy_frozenset(self):
149 x = frozenset({1, 2, 3})
150 self.assertIs(copy.copy(x), x)
151 x = frozenset()
152 self.assertIs(copy.copy(x), x)
153
154 def test_copy_bytearray(self):
155 x = bytearray(b'abc')
156 y = copy.copy(x)
157 self.assertEqual(y, x)
158 self.assertIsNot(y, x)
159 x = bytearray()
160 y = copy.copy(x)
161 self.assertEqual(y, x)
162 self.assertIsNot(y, x)
163
164 def test_copy_inst_vanilla(self):
165 class ESC[4;38;5;81mC:
166 def __init__(self, foo):
167 self.foo = foo
168 def __eq__(self, other):
169 return self.foo == other.foo
170 x = C(42)
171 self.assertEqual(copy.copy(x), x)
172
173 def test_copy_inst_copy(self):
174 class ESC[4;38;5;81mC:
175 def __init__(self, foo):
176 self.foo = foo
177 def __copy__(self):
178 return C(self.foo)
179 def __eq__(self, other):
180 return self.foo == other.foo
181 x = C(42)
182 self.assertEqual(copy.copy(x), x)
183
184 def test_copy_inst_getinitargs(self):
185 class ESC[4;38;5;81mC:
186 def __init__(self, foo):
187 self.foo = foo
188 def __getinitargs__(self):
189 return (self.foo,)
190 def __eq__(self, other):
191 return self.foo == other.foo
192 x = C(42)
193 self.assertEqual(copy.copy(x), x)
194
195 def test_copy_inst_getnewargs(self):
196 class ESC[4;38;5;81mC(ESC[4;38;5;149mint):
197 def __new__(cls, foo):
198 self = int.__new__(cls)
199 self.foo = foo
200 return self
201 def __getnewargs__(self):
202 return self.foo,
203 def __eq__(self, other):
204 return self.foo == other.foo
205 x = C(42)
206 y = copy.copy(x)
207 self.assertIsInstance(y, C)
208 self.assertEqual(y, x)
209 self.assertIsNot(y, x)
210 self.assertEqual(y.foo, x.foo)
211
212 def test_copy_inst_getnewargs_ex(self):
213 class ESC[4;38;5;81mC(ESC[4;38;5;149mint):
214 def __new__(cls, *, foo):
215 self = int.__new__(cls)
216 self.foo = foo
217 return self
218 def __getnewargs_ex__(self):
219 return (), {'foo': self.foo}
220 def __eq__(self, other):
221 return self.foo == other.foo
222 x = C(foo=42)
223 y = copy.copy(x)
224 self.assertIsInstance(y, C)
225 self.assertEqual(y, x)
226 self.assertIsNot(y, x)
227 self.assertEqual(y.foo, x.foo)
228
229 def test_copy_inst_getstate(self):
230 class ESC[4;38;5;81mC:
231 def __init__(self, foo):
232 self.foo = foo
233 def __getstate__(self):
234 return {"foo": self.foo}
235 def __eq__(self, other):
236 return self.foo == other.foo
237 x = C(42)
238 self.assertEqual(copy.copy(x), x)
239
240 def test_copy_inst_setstate(self):
241 class ESC[4;38;5;81mC:
242 def __init__(self, foo):
243 self.foo = foo
244 def __setstate__(self, state):
245 self.foo = state["foo"]
246 def __eq__(self, other):
247 return self.foo == other.foo
248 x = C(42)
249 self.assertEqual(copy.copy(x), x)
250
251 def test_copy_inst_getstate_setstate(self):
252 class ESC[4;38;5;81mC:
253 def __init__(self, foo):
254 self.foo = foo
255 def __getstate__(self):
256 return self.foo
257 def __setstate__(self, state):
258 self.foo = state
259 def __eq__(self, other):
260 return self.foo == other.foo
261 x = C(42)
262 self.assertEqual(copy.copy(x), x)
263 # State with boolean value is false (issue #25718)
264 x = C(0.0)
265 self.assertEqual(copy.copy(x), x)
266
267 # The deepcopy() method
268
269 def test_deepcopy_basic(self):
270 x = 42
271 y = copy.deepcopy(x)
272 self.assertEqual(y, x)
273
274 def test_deepcopy_memo(self):
275 # Tests of reflexive objects are under type-specific sections below.
276 # This tests only repetitions of objects.
277 x = []
278 x = [x, x]
279 y = copy.deepcopy(x)
280 self.assertEqual(y, x)
281 self.assertIsNot(y, x)
282 self.assertIsNot(y[0], x[0])
283 self.assertIs(y[0], y[1])
284
285 def test_deepcopy_issubclass(self):
286 # XXX Note: there's no way to test the TypeError coming out of
287 # issubclass() -- this can only happen when an extension
288 # module defines a "type" that doesn't formally inherit from
289 # type.
290 class ESC[4;38;5;81mMeta(ESC[4;38;5;149mtype):
291 pass
292 class ESC[4;38;5;81mC(metaclass=ESC[4;38;5;149mMeta):
293 pass
294 self.assertEqual(copy.deepcopy(C), C)
295
296 def test_deepcopy_deepcopy(self):
297 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
298 def __init__(self, foo):
299 self.foo = foo
300 def __deepcopy__(self, memo=None):
301 return C(self.foo)
302 x = C(42)
303 y = copy.deepcopy(x)
304 self.assertEqual(y.__class__, x.__class__)
305 self.assertEqual(y.foo, x.foo)
306
307 def test_deepcopy_registry(self):
308 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
309 def __new__(cls, foo):
310 obj = object.__new__(cls)
311 obj.foo = foo
312 return obj
313 def pickle_C(obj):
314 return (C, (obj.foo,))
315 x = C(42)
316 self.assertRaises(TypeError, copy.deepcopy, x)
317 copyreg.pickle(C, pickle_C, C)
318 y = copy.deepcopy(x)
319 self.assertIsNot(x, y)
320 self.assertEqual(type(y), C)
321 self.assertEqual(y.foo, x.foo)
322
323 def test_deepcopy_reduce_ex(self):
324 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
325 def __reduce_ex__(self, proto):
326 c.append(1)
327 return ""
328 def __reduce__(self):
329 self.fail("shouldn't call this")
330 c = []
331 x = C()
332 y = copy.deepcopy(x)
333 self.assertIs(y, x)
334 self.assertEqual(c, [1])
335
336 def test_deepcopy_reduce(self):
337 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
338 def __reduce__(self):
339 c.append(1)
340 return ""
341 c = []
342 x = C()
343 y = copy.deepcopy(x)
344 self.assertIs(y, x)
345 self.assertEqual(c, [1])
346
347 def test_deepcopy_cant(self):
348 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
349 def __getattribute__(self, name):
350 if name.startswith("__reduce"):
351 raise AttributeError(name)
352 return object.__getattribute__(self, name)
353 x = C()
354 self.assertRaises(copy.Error, copy.deepcopy, x)
355
356 # Type-specific _deepcopy_xxx() methods
357
358 def test_deepcopy_atomic(self):
359 class ESC[4;38;5;81mClassic:
360 pass
361 class ESC[4;38;5;81mNewStyle(ESC[4;38;5;149mobject):
362 pass
363 def f():
364 pass
365 tests = [None, ..., NotImplemented, 42, 2**100, 3.14, True, False, 1j,
366 b"bytes", "hello", "hello\u1234", f.__code__,
367 NewStyle, range(10), Classic, max, property()]
368 for x in tests:
369 self.assertIs(copy.deepcopy(x), x)
370
371 def test_deepcopy_list(self):
372 x = [[1, 2], 3]
373 y = copy.deepcopy(x)
374 self.assertEqual(y, x)
375 self.assertIsNot(x, y)
376 self.assertIsNot(x[0], y[0])
377
378 def test_deepcopy_reflexive_list(self):
379 x = []
380 x.append(x)
381 y = copy.deepcopy(x)
382 for op in comparisons:
383 self.assertRaises(RecursionError, op, y, x)
384 self.assertIsNot(y, x)
385 self.assertIs(y[0], y)
386 self.assertEqual(len(y), 1)
387
388 def test_deepcopy_empty_tuple(self):
389 x = ()
390 y = copy.deepcopy(x)
391 self.assertIs(x, y)
392
393 def test_deepcopy_tuple(self):
394 x = ([1, 2], 3)
395 y = copy.deepcopy(x)
396 self.assertEqual(y, x)
397 self.assertIsNot(x, y)
398 self.assertIsNot(x[0], y[0])
399
400 def test_deepcopy_tuple_of_immutables(self):
401 x = ((1, 2), 3)
402 y = copy.deepcopy(x)
403 self.assertIs(x, y)
404
405 def test_deepcopy_reflexive_tuple(self):
406 x = ([],)
407 x[0].append(x)
408 y = copy.deepcopy(x)
409 for op in comparisons:
410 self.assertRaises(RecursionError, op, y, x)
411 self.assertIsNot(y, x)
412 self.assertIsNot(y[0], x[0])
413 self.assertIs(y[0][0], y)
414
415 def test_deepcopy_dict(self):
416 x = {"foo": [1, 2], "bar": 3}
417 y = copy.deepcopy(x)
418 self.assertEqual(y, x)
419 self.assertIsNot(x, y)
420 self.assertIsNot(x["foo"], y["foo"])
421
422 def test_deepcopy_reflexive_dict(self):
423 x = {}
424 x['foo'] = x
425 y = copy.deepcopy(x)
426 for op in order_comparisons:
427 self.assertRaises(TypeError, op, y, x)
428 for op in equality_comparisons:
429 self.assertRaises(RecursionError, op, y, x)
430 self.assertIsNot(y, x)
431 self.assertIs(y['foo'], y)
432 self.assertEqual(len(y), 1)
433
434 def test_deepcopy_keepalive(self):
435 memo = {}
436 x = []
437 y = copy.deepcopy(x, memo)
438 self.assertIs(memo[id(memo)][0], x)
439
440 def test_deepcopy_dont_memo_immutable(self):
441 memo = {}
442 x = [1, 2, 3, 4]
443 y = copy.deepcopy(x, memo)
444 self.assertEqual(y, x)
445 # There's the entry for the new list, and the keep alive.
446 self.assertEqual(len(memo), 2)
447
448 memo = {}
449 x = [(1, 2)]
450 y = copy.deepcopy(x, memo)
451 self.assertEqual(y, x)
452 # Tuples with immutable contents are immutable for deepcopy.
453 self.assertEqual(len(memo), 2)
454
455 def test_deepcopy_inst_vanilla(self):
456 class ESC[4;38;5;81mC:
457 def __init__(self, foo):
458 self.foo = foo
459 def __eq__(self, other):
460 return self.foo == other.foo
461 x = C([42])
462 y = copy.deepcopy(x)
463 self.assertEqual(y, x)
464 self.assertIsNot(y.foo, x.foo)
465
466 def test_deepcopy_inst_deepcopy(self):
467 class ESC[4;38;5;81mC:
468 def __init__(self, foo):
469 self.foo = foo
470 def __deepcopy__(self, memo):
471 return C(copy.deepcopy(self.foo, memo))
472 def __eq__(self, other):
473 return self.foo == other.foo
474 x = C([42])
475 y = copy.deepcopy(x)
476 self.assertEqual(y, x)
477 self.assertIsNot(y, x)
478 self.assertIsNot(y.foo, x.foo)
479
480 def test_deepcopy_inst_getinitargs(self):
481 class ESC[4;38;5;81mC:
482 def __init__(self, foo):
483 self.foo = foo
484 def __getinitargs__(self):
485 return (self.foo,)
486 def __eq__(self, other):
487 return self.foo == other.foo
488 x = C([42])
489 y = copy.deepcopy(x)
490 self.assertEqual(y, x)
491 self.assertIsNot(y, x)
492 self.assertIsNot(y.foo, x.foo)
493
494 def test_deepcopy_inst_getnewargs(self):
495 class ESC[4;38;5;81mC(ESC[4;38;5;149mint):
496 def __new__(cls, foo):
497 self = int.__new__(cls)
498 self.foo = foo
499 return self
500 def __getnewargs__(self):
501 return self.foo,
502 def __eq__(self, other):
503 return self.foo == other.foo
504 x = C([42])
505 y = copy.deepcopy(x)
506 self.assertIsInstance(y, C)
507 self.assertEqual(y, x)
508 self.assertIsNot(y, x)
509 self.assertEqual(y.foo, x.foo)
510 self.assertIsNot(y.foo, x.foo)
511
512 def test_deepcopy_inst_getnewargs_ex(self):
513 class ESC[4;38;5;81mC(ESC[4;38;5;149mint):
514 def __new__(cls, *, foo):
515 self = int.__new__(cls)
516 self.foo = foo
517 return self
518 def __getnewargs_ex__(self):
519 return (), {'foo': self.foo}
520 def __eq__(self, other):
521 return self.foo == other.foo
522 x = C(foo=[42])
523 y = copy.deepcopy(x)
524 self.assertIsInstance(y, C)
525 self.assertEqual(y, x)
526 self.assertIsNot(y, x)
527 self.assertEqual(y.foo, x.foo)
528 self.assertIsNot(y.foo, x.foo)
529
530 def test_deepcopy_inst_getstate(self):
531 class ESC[4;38;5;81mC:
532 def __init__(self, foo):
533 self.foo = foo
534 def __getstate__(self):
535 return {"foo": self.foo}
536 def __eq__(self, other):
537 return self.foo == other.foo
538 x = C([42])
539 y = copy.deepcopy(x)
540 self.assertEqual(y, x)
541 self.assertIsNot(y, x)
542 self.assertIsNot(y.foo, x.foo)
543
544 def test_deepcopy_inst_setstate(self):
545 class ESC[4;38;5;81mC:
546 def __init__(self, foo):
547 self.foo = foo
548 def __setstate__(self, state):
549 self.foo = state["foo"]
550 def __eq__(self, other):
551 return self.foo == other.foo
552 x = C([42])
553 y = copy.deepcopy(x)
554 self.assertEqual(y, x)
555 self.assertIsNot(y, x)
556 self.assertIsNot(y.foo, x.foo)
557
558 def test_deepcopy_inst_getstate_setstate(self):
559 class ESC[4;38;5;81mC:
560 def __init__(self, foo):
561 self.foo = foo
562 def __getstate__(self):
563 return self.foo
564 def __setstate__(self, state):
565 self.foo = state
566 def __eq__(self, other):
567 return self.foo == other.foo
568 x = C([42])
569 y = copy.deepcopy(x)
570 self.assertEqual(y, x)
571 self.assertIsNot(y, x)
572 self.assertIsNot(y.foo, x.foo)
573 # State with boolean value is false (issue #25718)
574 x = C([])
575 y = copy.deepcopy(x)
576 self.assertEqual(y, x)
577 self.assertIsNot(y, x)
578 self.assertIsNot(y.foo, x.foo)
579
580 def test_deepcopy_reflexive_inst(self):
581 class ESC[4;38;5;81mC:
582 pass
583 x = C()
584 x.foo = x
585 y = copy.deepcopy(x)
586 self.assertIsNot(y, x)
587 self.assertIs(y.foo, y)
588
589 # _reconstruct()
590
591 def test_reconstruct_string(self):
592 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
593 def __reduce__(self):
594 return ""
595 x = C()
596 y = copy.copy(x)
597 self.assertIs(y, x)
598 y = copy.deepcopy(x)
599 self.assertIs(y, x)
600
601 def test_reconstruct_nostate(self):
602 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
603 def __reduce__(self):
604 return (C, ())
605 x = C()
606 x.foo = 42
607 y = copy.copy(x)
608 self.assertIs(y.__class__, x.__class__)
609 y = copy.deepcopy(x)
610 self.assertIs(y.__class__, x.__class__)
611
612 def test_reconstruct_state(self):
613 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
614 def __reduce__(self):
615 return (C, (), self.__dict__)
616 def __eq__(self, other):
617 return self.__dict__ == other.__dict__
618 x = C()
619 x.foo = [42]
620 y = copy.copy(x)
621 self.assertEqual(y, x)
622 y = copy.deepcopy(x)
623 self.assertEqual(y, x)
624 self.assertIsNot(y.foo, x.foo)
625
626 def test_reconstruct_state_setstate(self):
627 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
628 def __reduce__(self):
629 return (C, (), self.__dict__)
630 def __setstate__(self, state):
631 self.__dict__.update(state)
632 def __eq__(self, other):
633 return self.__dict__ == other.__dict__
634 x = C()
635 x.foo = [42]
636 y = copy.copy(x)
637 self.assertEqual(y, x)
638 y = copy.deepcopy(x)
639 self.assertEqual(y, x)
640 self.assertIsNot(y.foo, x.foo)
641
642 def test_reconstruct_reflexive(self):
643 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
644 pass
645 x = C()
646 x.foo = x
647 y = copy.deepcopy(x)
648 self.assertIsNot(y, x)
649 self.assertIs(y.foo, y)
650
651 # Additions for Python 2.3 and pickle protocol 2
652
653 def test_reduce_4tuple(self):
654 class ESC[4;38;5;81mC(ESC[4;38;5;149mlist):
655 def __reduce__(self):
656 return (C, (), self.__dict__, iter(self))
657 def __eq__(self, other):
658 return (list(self) == list(other) and
659 self.__dict__ == other.__dict__)
660 x = C([[1, 2], 3])
661 y = copy.copy(x)
662 self.assertEqual(x, y)
663 self.assertIsNot(x, y)
664 self.assertIs(x[0], y[0])
665 y = copy.deepcopy(x)
666 self.assertEqual(x, y)
667 self.assertIsNot(x, y)
668 self.assertIsNot(x[0], y[0])
669
670 def test_reduce_5tuple(self):
671 class ESC[4;38;5;81mC(ESC[4;38;5;149mdict):
672 def __reduce__(self):
673 return (C, (), self.__dict__, None, self.items())
674 def __eq__(self, other):
675 return (dict(self) == dict(other) and
676 self.__dict__ == other.__dict__)
677 x = C([("foo", [1, 2]), ("bar", 3)])
678 y = copy.copy(x)
679 self.assertEqual(x, y)
680 self.assertIsNot(x, y)
681 self.assertIs(x["foo"], y["foo"])
682 y = copy.deepcopy(x)
683 self.assertEqual(x, y)
684 self.assertIsNot(x, y)
685 self.assertIsNot(x["foo"], y["foo"])
686
687 def test_reduce_6tuple(self):
688 def state_setter(*args, **kwargs):
689 self.fail("shouldn't call this")
690 class ESC[4;38;5;81mC:
691 def __reduce__(self):
692 return C, (), self.__dict__, None, None, state_setter
693 x = C()
694 with self.assertRaises(TypeError):
695 copy.copy(x)
696 with self.assertRaises(TypeError):
697 copy.deepcopy(x)
698
699 def test_reduce_6tuple_none(self):
700 class ESC[4;38;5;81mC:
701 def __reduce__(self):
702 return C, (), self.__dict__, None, None, None
703 x = C()
704 with self.assertRaises(TypeError):
705 copy.copy(x)
706 with self.assertRaises(TypeError):
707 copy.deepcopy(x)
708
709 def test_copy_slots(self):
710 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
711 __slots__ = ["foo"]
712 x = C()
713 x.foo = [42]
714 y = copy.copy(x)
715 self.assertIs(x.foo, y.foo)
716
717 def test_deepcopy_slots(self):
718 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
719 __slots__ = ["foo"]
720 x = C()
721 x.foo = [42]
722 y = copy.deepcopy(x)
723 self.assertEqual(x.foo, y.foo)
724 self.assertIsNot(x.foo, y.foo)
725
726 def test_deepcopy_dict_subclass(self):
727 class ESC[4;38;5;81mC(ESC[4;38;5;149mdict):
728 def __init__(self, d=None):
729 if not d:
730 d = {}
731 self._keys = list(d.keys())
732 super().__init__(d)
733 def __setitem__(self, key, item):
734 super().__setitem__(key, item)
735 if key not in self._keys:
736 self._keys.append(key)
737 x = C(d={'foo':0})
738 y = copy.deepcopy(x)
739 self.assertEqual(x, y)
740 self.assertEqual(x._keys, y._keys)
741 self.assertIsNot(x, y)
742 x['bar'] = 1
743 self.assertNotEqual(x, y)
744 self.assertNotEqual(x._keys, y._keys)
745
746 def test_copy_list_subclass(self):
747 class ESC[4;38;5;81mC(ESC[4;38;5;149mlist):
748 pass
749 x = C([[1, 2], 3])
750 x.foo = [4, 5]
751 y = copy.copy(x)
752 self.assertEqual(list(x), list(y))
753 self.assertEqual(x.foo, y.foo)
754 self.assertIs(x[0], y[0])
755 self.assertIs(x.foo, y.foo)
756
757 def test_deepcopy_list_subclass(self):
758 class ESC[4;38;5;81mC(ESC[4;38;5;149mlist):
759 pass
760 x = C([[1, 2], 3])
761 x.foo = [4, 5]
762 y = copy.deepcopy(x)
763 self.assertEqual(list(x), list(y))
764 self.assertEqual(x.foo, y.foo)
765 self.assertIsNot(x[0], y[0])
766 self.assertIsNot(x.foo, y.foo)
767
768 def test_copy_tuple_subclass(self):
769 class ESC[4;38;5;81mC(ESC[4;38;5;149mtuple):
770 pass
771 x = C([1, 2, 3])
772 self.assertEqual(tuple(x), (1, 2, 3))
773 y = copy.copy(x)
774 self.assertEqual(tuple(y), (1, 2, 3))
775
776 def test_deepcopy_tuple_subclass(self):
777 class ESC[4;38;5;81mC(ESC[4;38;5;149mtuple):
778 pass
779 x = C([[1, 2], 3])
780 self.assertEqual(tuple(x), ([1, 2], 3))
781 y = copy.deepcopy(x)
782 self.assertEqual(tuple(y), ([1, 2], 3))
783 self.assertIsNot(x, y)
784 self.assertIsNot(x[0], y[0])
785
786 def test_getstate_exc(self):
787 class ESC[4;38;5;81mEvilState(ESC[4;38;5;149mobject):
788 def __getstate__(self):
789 raise ValueError("ain't got no stickin' state")
790 self.assertRaises(ValueError, copy.copy, EvilState())
791
792 def test_copy_function(self):
793 self.assertEqual(copy.copy(global_foo), global_foo)
794 def foo(x, y): return x+y
795 self.assertEqual(copy.copy(foo), foo)
796 bar = lambda: None
797 self.assertEqual(copy.copy(bar), bar)
798
799 def test_deepcopy_function(self):
800 self.assertEqual(copy.deepcopy(global_foo), global_foo)
801 def foo(x, y): return x+y
802 self.assertEqual(copy.deepcopy(foo), foo)
803 bar = lambda: None
804 self.assertEqual(copy.deepcopy(bar), bar)
805
806 def _check_weakref(self, _copy):
807 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
808 pass
809 obj = C()
810 x = weakref.ref(obj)
811 y = _copy(x)
812 self.assertIs(y, x)
813 del obj
814 y = _copy(x)
815 self.assertIs(y, x)
816
817 def test_copy_weakref(self):
818 self._check_weakref(copy.copy)
819
820 def test_deepcopy_weakref(self):
821 self._check_weakref(copy.deepcopy)
822
823 def _check_copy_weakdict(self, _dicttype):
824 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
825 pass
826 a, b, c, d = [C() for i in range(4)]
827 u = _dicttype()
828 u[a] = b
829 u[c] = d
830 v = copy.copy(u)
831 self.assertIsNot(v, u)
832 self.assertEqual(v, u)
833 self.assertEqual(v[a], b)
834 self.assertEqual(v[c], d)
835 self.assertEqual(len(v), 2)
836 del c, d
837 support.gc_collect() # For PyPy or other GCs.
838 self.assertEqual(len(v), 1)
839 x, y = C(), C()
840 # The underlying containers are decoupled
841 v[x] = y
842 self.assertNotIn(x, u)
843
844 def test_copy_weakkeydict(self):
845 self._check_copy_weakdict(weakref.WeakKeyDictionary)
846
847 def test_copy_weakvaluedict(self):
848 self._check_copy_weakdict(weakref.WeakValueDictionary)
849
850 def test_deepcopy_weakkeydict(self):
851 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
852 def __init__(self, i):
853 self.i = i
854 a, b, c, d = [C(i) for i in range(4)]
855 u = weakref.WeakKeyDictionary()
856 u[a] = b
857 u[c] = d
858 # Keys aren't copied, values are
859 v = copy.deepcopy(u)
860 self.assertNotEqual(v, u)
861 self.assertEqual(len(v), 2)
862 self.assertIsNot(v[a], b)
863 self.assertIsNot(v[c], d)
864 self.assertEqual(v[a].i, b.i)
865 self.assertEqual(v[c].i, d.i)
866 del c
867 support.gc_collect() # For PyPy or other GCs.
868 self.assertEqual(len(v), 1)
869
870 def test_deepcopy_weakvaluedict(self):
871 class ESC[4;38;5;81mC(ESC[4;38;5;149mobject):
872 def __init__(self, i):
873 self.i = i
874 a, b, c, d = [C(i) for i in range(4)]
875 u = weakref.WeakValueDictionary()
876 u[a] = b
877 u[c] = d
878 # Keys are copied, values aren't
879 v = copy.deepcopy(u)
880 self.assertNotEqual(v, u)
881 self.assertEqual(len(v), 2)
882 (x, y), (z, t) = sorted(v.items(), key=lambda pair: pair[0].i)
883 self.assertIsNot(x, a)
884 self.assertEqual(x.i, a.i)
885 self.assertIs(y, b)
886 self.assertIsNot(z, c)
887 self.assertEqual(z.i, c.i)
888 self.assertIs(t, d)
889 del x, y, z, t
890 del d
891 support.gc_collect() # For PyPy or other GCs.
892 self.assertEqual(len(v), 1)
893
894 def test_deepcopy_bound_method(self):
895 class ESC[4;38;5;81mFoo(ESC[4;38;5;149mobject):
896 def m(self):
897 pass
898 f = Foo()
899 f.b = f.m
900 g = copy.deepcopy(f)
901 self.assertEqual(g.m, g.b)
902 self.assertIs(g.b.__self__, g)
903 g.b()
904
905
906 def global_foo(x, y): return x+y
907
908 if __name__ == "__main__":
909 unittest.main()