diff options
author | Alex Martelli <aleaxit@gmail.com> | 2005-02-07 12:39:55 (GMT) |
---|---|---|
committer | Alex Martelli <aleaxit@gmail.com> | 2005-02-07 12:39:55 (GMT) |
commit | 4c337993c5afdfd9ebb40ff0847cf6015a875f4f (patch) | |
tree | b41dab2d8307066e1df34d7d4eab210ac1a2f6d1 /Lib/test | |
parent | 339870121926f56294d8ccbca381d5d29c07cac0 (diff) | |
download | cpython-4c337993c5afdfd9ebb40ff0847cf6015a875f4f.zip cpython-4c337993c5afdfd9ebb40ff0847cf6015a875f4f.tar.gz cpython-4c337993c5afdfd9ebb40ff0847cf6015a875f4f.tar.bz2 |
forwardport of 2.3.5 fixes to copy.py
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_copy.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index bd5a3e1..02dede4 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -166,6 +166,107 @@ class TestCopy(unittest.TestCase): x = C(42) self.assertEqual(copy.copy(x), x) + # tests for copying extension types, iff module trycopy is installed + def test_copy_classictype(self): + from _testcapi import make_copyable + x = make_copyable([23]) + y = copy.copy(x) + self.assertEqual(x, y) + self.assertEqual(x.tag, y.tag) + self.assert_(x is not y) + self.assert_(x.tag is y.tag) + + def test_deepcopy_classictype(self): + from _testcapi import make_copyable + x = make_copyable([23]) + y = copy.deepcopy(x) + self.assertEqual(x, y) + self.assertEqual(x.tag, y.tag) + self.assert_(x is not y) + self.assert_(x.tag is not y.tag) + + # regression tests for class-vs-instance and metaclass-confusion + def test_copy_classoverinstance(self): + class C(object): + def __init__(self, v): + self.v = v + def __cmp__(self, other): + return -cmp(other, self.v) + def __copy__(self): + return self.__class__(self.v) + x = C(23) + self.assertEqual(copy.copy(x), x) + x.__copy__ = lambda: 42 + self.assertEqual(copy.copy(x), x) + + def test_deepcopy_classoverinstance(self): + class C(object): + def __init__(self, v): + self.v = v + def __cmp__(self, other): + return -cmp(other, self.v) + def __deepcopy__(self, memo): + return self.__class__(copy.deepcopy(self.v, memo)) + x = C(23) + self.assertEqual(copy.deepcopy(x), x) + x.__deepcopy__ = lambda memo: 42 + self.assertEqual(copy.deepcopy(x), x) + + + def test_copy_metaclassconfusion(self): + class MyOwnError(copy.Error): + pass + class Meta(type): + def __copy__(cls): + raise MyOwnError("can't copy classes w/this metaclass") + class C: + __metaclass__ = Meta + def __init__(self, tag): + self.tag = tag + def __cmp__(self, other): + return -cmp(other, self.tag) + # the metaclass can forbid shallow copying of its classes + self.assertRaises(MyOwnError, copy.copy, C) + # check that there is no interference with instances + x = C(23) + self.assertEqual(copy.copy(x), x) + + def test_deepcopy_metaclassconfusion(self): + class MyOwnError(copy.Error): + pass + class Meta(type): + def __deepcopy__(cls, memo): + raise MyOwnError("can't deepcopy classes w/this metaclass") + class C: + __metaclass__ = Meta + def __init__(self, tag): + self.tag = tag + def __cmp__(self, other): + return -cmp(other, self.tag) + # types are ALWAYS deepcopied atomically, no matter what + self.assertEqual(copy.deepcopy(C), C) + # check that there is no interference with instances + x = C(23) + self.assertEqual(copy.deepcopy(x), x) + + def _nomro(self): + class C(type): + def __getattribute__(self, attr): + if attr == '__mro__': + raise AttributeError, "What, *me*, a __mro__? Nevah!" + return super(C, self).__getattribute__(attr) + class D(object): + __metaclass__ = C + return D() + + def test_copy_mro(self): + x = self._nomro() + y = copy.copy(x) + + def test_deepcopy_mro(self): + x = self._nomro() + y = copy.deepcopy(x) + # The deepcopy() method def test_deepcopy_basic(self): |