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