summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorAlex Martelli <aleaxit@gmail.com>2005-02-07 12:39:55 (GMT)
committerAlex Martelli <aleaxit@gmail.com>2005-02-07 12:39:55 (GMT)
commit4c337993c5afdfd9ebb40ff0847cf6015a875f4f (patch)
treeb41dab2d8307066e1df34d7d4eab210ac1a2f6d1 /Lib/test
parent339870121926f56294d8ccbca381d5d29c07cac0 (diff)
downloadcpython-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.py101
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):