summaryrefslogtreecommitdiff
path: root/Lib/test/test_copy.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-02-06 17:52:15 +0000
committerGuido van Rossum <guido@python.org>2003-02-06 17:52:15 +0000
commit581cb938d0650a44b8a959ebc924439992e595df (patch)
tree0c336b1301533af5a8ca45c06894a685668534fc /Lib/test/test_copy.py
parent8eb4044f7e42af1134a6a98e52201df0a8aaa01f (diff)
downloadcpython-git-581cb938d0650a44b8a959ebc924439992e595df.tar.gz
A test suite for the copy module. This should provide full code
coverage.
Diffstat (limited to 'Lib/test/test_copy.py')
-rw-r--r--Lib/test/test_copy.py384
1 files changed, 384 insertions, 0 deletions
diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py
new file mode 100644
index 0000000000..90ef3fae3e
--- /dev/null
+++ b/Lib/test/test_copy.py
@@ -0,0 +1,384 @@
+"""Unit tests for the copy module."""
+
+import sys
+import copy
+
+import unittest
+from test import test_support
+
+class TestCopy(unittest.TestCase):
+
+ # Attempt full line coverage of copy.py from top to bottom
+
+ def test_exceptions(self):
+ self.assert_(copy.Error is copy.error)
+ self.assert_(issubclass(copy.Error, Exception))
+
+ # The copy() method
+
+ def test_copy_basic(self):
+ x = 42
+ y = copy.copy(x)
+ self.assertEqual(x, y)
+
+ def test_copy_copy(self):
+ class C(object):
+ def __init__(self, foo):
+ self.foo = foo
+ def __copy__(self):
+ return C(self.foo)
+ x = C(42)
+ y = copy.copy(x)
+ self.assertEqual(y.__class__, x.__class__)
+ self.assertEqual(y.foo, x.foo)
+
+ def test_copy_reduce(self):
+ class C(object):
+ def __reduce__(self):
+ return ""
+ x = C()
+ y = copy.copy(x)
+ self.assert_(y is x)
+
+ def test_copy_cant(self):
+ class C(object):
+ def __getattribute__(self, name):
+ if name == "__reduce__":
+ raise AttributeError, name
+ return object.__getattribute__(self, name)
+ x = C()
+ self.assertRaises(copy.Error, copy.copy, x)
+
+ # Type-specific _copy_xxx() methods
+
+ def test_copy_atomic(self):
+ class Classic:
+ pass
+ class NewStyle(object):
+ pass
+ def f():
+ pass
+ tests = [None, 42, 2L**100, 3.14, True, False, 1j,
+ "hello", u"hello\u1234", f.func_code,
+ NewStyle, xrange(10), Classic]
+ for x in tests:
+ self.assert_(copy.copy(x) is x, `x`)
+
+ def test_copy_list(self):
+ x = [1, 2, 3]
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_tuple(self):
+ x = (1, 2, 3)
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_dict(self):
+ x = {"foo": 1, "bar": 2}
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_inst_vanilla(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C(42)
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_inst_copy(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __copy__(self):
+ return C(self.foo)
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C(42)
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_inst_getinitargs(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __getinitargs__(self):
+ return (self.foo,)
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C(42)
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_inst_getstate(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __getstate__(self):
+ return {"foo": self.foo}
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C(42)
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_inst_setstate(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __setstate__(self, state):
+ self.foo = state["foo"]
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C(42)
+ self.assertEqual(copy.copy(x), x)
+
+ def test_copy_inst_getstate_setstate(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __getstate__(self):
+ return self.foo
+ def __setstate__(self, state):
+ self.foo = state
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C(42)
+ self.assertEqual(copy.copy(x), x)
+
+ # The deepcopy() method
+
+ def test_deepcopy_basic(self):
+ x = 42
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+
+ def test_deepcopy_memo(self):
+ x = []
+ x.append(x)
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y is not x)
+ self.assert_(y[0] is not x[0])
+ self.assert_(y is y[0])
+
+ def test_deepcopy_issubclass(self):
+ # XXX Note: there's no way to test the TypeError coming out of
+ # issubclass() -- this can only happen when an extension
+ # module defines a "type" that doesn't formally inherit from
+ # type.
+ class Meta(type):
+ pass
+ class C:
+ __metaclass__ = Meta
+ self.assertEqual(copy.deepcopy(C), C)
+
+ def test_deepcopy_deepcopy(self):
+ class C(object):
+ def __init__(self, foo):
+ self.foo = foo
+ def __deepcopy__(self, memo=None):
+ return C(self.foo)
+ x = C(42)
+ y = copy.deepcopy(x)
+ self.assertEqual(y.__class__, x.__class__)
+ self.assertEqual(y.foo, x.foo)
+
+ def test_deepcopy_reduce(self):
+ class C(object):
+ def __reduce__(self):
+ return ""
+ x = C()
+ y = copy.deepcopy(x)
+ self.assert_(y is x)
+
+ def test_deepcopy_cant(self):
+ class C(object):
+ def __getattribute__(self, name):
+ if name == "__reduce__":
+ raise AttributeError, name
+ return object.__getattribute__(self, name)
+ x = C()
+ self.assertRaises(copy.Error, copy.deepcopy, x)
+
+ # Type-specific _deepcopy_xxx() methods
+
+ def test_deepcopy_atomic(self):
+ class Classic:
+ pass
+ class NewStyle(object):
+ pass
+ def f():
+ pass
+ tests = [None, 42, 2L**100, 3.14, True, False, 1j,
+ "hello", u"hello\u1234", f.func_code,
+ NewStyle, xrange(10)]
+ for x in tests:
+ self.assert_(copy.deepcopy(x) is x, `x`)
+
+ def test_deepcopy_list(self):
+ x = [[1, 2], 3]
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(x is not y)
+ self.assert_(x[0] is not y[0])
+
+ def test_deepcopy_tuple(self):
+ x = ([1, 2], 3)
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(x is not y)
+ self.assert_(x[0] is not y[0])
+
+ def test_deepcopy_dict(self):
+ x = {"foo": [1, 2], "bar": 3}
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(x is not y)
+ self.assert_(x["foo"] is not y["foo"])
+
+ def test_deepcopy_keepalive(self):
+ memo = {}
+ x = 42
+ y = copy.deepcopy(x, memo)
+ self.assert_(memo[id(x)] is x)
+
+ def test_deepcopy_inst_vanilla(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C([42])
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y.foo is not x.foo)
+
+ def test_deepcopy_inst_deepcopy(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __deepcopy__(self, memo):
+ return C(copy.deepcopy(self.foo, memo))
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C([42])
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y is not x)
+ self.assert_(y.foo is not x.foo)
+
+ def test_deepcopy_inst_getinitargs(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __getinitargs__(self):
+ return (self.foo,)
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C([42])
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y is not x)
+ self.assert_(y.foo is not x.foo)
+
+ def test_deepcopy_inst_getstate(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __getstate__(self):
+ return {"foo": self.foo}
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C([42])
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y is not x)
+ self.assert_(y.foo is not x.foo)
+
+ def test_deepcopy_inst_setstate(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __setstate__(self, state):
+ self.foo = state["foo"]
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C([42])
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y is not x)
+ self.assert_(y.foo is not x.foo)
+
+ def test_deepcopy_inst_getstate_setstate(self):
+ class C:
+ def __init__(self, foo):
+ self.foo = foo
+ def __getstate__(self):
+ return self.foo
+ def __setstate__(self, state):
+ self.foo = state
+ def __cmp__(self, other):
+ return cmp(self.foo, other.foo)
+ x = C([42])
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y is not x)
+ self.assert_(y.foo is not x.foo)
+
+ # _reconstruct()
+
+ def test_reconstruct_string(self):
+ class C(object):
+ def __reduce__(self):
+ return ""
+ x = C()
+ y = copy.copy(x)
+ self.assert_(y is x)
+ y = copy.deepcopy(x)
+ self.assert_(y is x)
+
+ def test_reconstruct_nostate(self):
+ class C(object):
+ def __reduce__(self):
+ return (C, ())
+ x = C()
+ x.foo = 42
+ y = copy.copy(x)
+ self.assert_(y.__class__ is x.__class__)
+ y = copy.deepcopy(x)
+ self.assert_(y.__class__ is x.__class__)
+
+ def test_reconstruct_state(self):
+ class C(object):
+ def __reduce__(self):
+ return (C, (), self.__dict__)
+ def __cmp__(self, other):
+ return cmp(self.__dict__, other.__dict__)
+ x = C()
+ x.foo = [42]
+ y = copy.copy(x)
+ self.assertEqual(y, x)
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y.foo is not x.foo)
+
+ def test_reconstruct_state_setstate(self):
+ class C(object):
+ def __reduce__(self):
+ return (C, (), self.__dict__)
+ def __setstate__(self, state):
+ self.__dict__.update(state)
+ def __cmp__(self, other):
+ return cmp(self.__dict__, other.__dict__)
+ x = C()
+ x.foo = [42]
+ y = copy.copy(x)
+ self.assertEqual(y, x)
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y.foo is not x.foo)
+
+def test_main():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TestCopy))
+ test_support.run_suite(suite)
+
+if __name__ == "__main__":
+ test_main()