1"""Unit tests for the copy module."""
2
3import copy
4import copyreg
5import weakref
6import abc
7from operator import le, lt, ge, gt, eq, ne
8
9import unittest
10from test import support
11
12order_comparisons = le, lt, ge, gt
13equality_comparisons = eq, ne
14comparisons = order_comparisons + equality_comparisons
15
16class TestCopy(unittest.TestCase):
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 C(object):
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 C(object):
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 C(object):
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 C(object):
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 C(object):
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 Classic:
95            pass
96        class NewStyle(object):
97            pass
98        def f():
99            pass
100        class WithMetaclass(metaclass=abc.ABCMeta):
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 C:
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 C:
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 C:
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 C(int):
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 C(int):
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 C:
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 C:
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 C:
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 Meta(type):
291            pass
292        class C(metaclass=Meta):
293            pass
294        self.assertEqual(copy.deepcopy(C), C)
295
296    def test_deepcopy_deepcopy(self):
297        class C(object):
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 C(object):
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 C(object):
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 C(object):
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 C(object):
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 Classic:
360            pass
361        class NewStyle(object):
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 C:
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 C:
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 C:
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 C(int):
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 C(int):
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 C:
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 C:
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 C:
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 C:
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 C(object):
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 C(object):
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 C(object):
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 C(object):
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 C(object):
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 C(list):
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 C(dict):
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 C:
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 C:
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 C(object):
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 C(object):
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 C(dict):
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 C(list):
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 C(list):
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 C(tuple):
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 C(tuple):
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 EvilState(object):
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 C(object):
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 C(object):
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 C(object):
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 C(object):
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 Foo(object):
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
906def global_foo(x, y): return x+y
907
908if __name__ == "__main__":
909    unittest.main()
910