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