summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2003-06-13 19:28:47 (GMT)
committerGuido van Rossum <guido@python.org>2003-06-13 19:28:47 (GMT)
commit99d2c251df4782c52c3e1cb89064374af39ecb46 (patch)
treed50963ae51d6285c621c5840a23024bbeaf68588 /Lib
parent097da0dc012d8c8164a043eee8f4b9622bc7b843 (diff)
downloadcpython-99d2c251df4782c52c3e1cb89064374af39ecb46.zip
cpython-99d2c251df4782c52c3e1cb89064374af39ecb46.tar.gz
cpython-99d2c251df4782c52c3e1cb89064374af39ecb46.tar.bz2
SF patch 707900, fixing bug 702858, by Steven Taschuk.
Copying a new-style class that had a reference to itself didn't work. (The same thing worked fine for old-style classes.)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/copy.py1
-rw-r--r--Lib/test/test_copy.py51
2 files changed, 50 insertions, 2 deletions
diff --git a/Lib/copy.py b/Lib/copy.py
index a4a3ceb..02aa46b 100644
--- a/Lib/copy.py
+++ b/Lib/copy.py
@@ -334,6 +334,7 @@ def _reconstruct(x, info, deep, memo=None):
if deep:
args = deepcopy(args, memo)
y = callable(*args)
+ memo[id(x)] = y
if listiter is not None:
for item in listiter:
if deep:
diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py
index c734a9a..a53f988 100644
--- a/Lib/test/test_copy.py
+++ b/Lib/test/test_copy.py
@@ -174,13 +174,15 @@ class TestCopy(unittest.TestCase):
self.assertEqual(y, x)
def test_deepcopy_memo(self):
+ # Tests of reflexive objects are under type-specific sections below.
+ # This tests only repetitions of objects.
x = []
- x.append(x)
+ x = [x, 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])
+ self.assert_(y[0] is y[1])
def test_deepcopy_issubclass(self):
# XXX Note: there's no way to test the TypeError coming out of
@@ -266,6 +268,15 @@ class TestCopy(unittest.TestCase):
self.assert_(x is not y)
self.assert_(x[0] is not y[0])
+ def test_deepcopy_reflexive_list(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_tuple(self):
x = ([1, 2], 3)
y = copy.deepcopy(x)
@@ -273,6 +284,15 @@ class TestCopy(unittest.TestCase):
self.assert_(x is not y)
self.assert_(x[0] is not y[0])
+ def test_deepcopy_reflexive_tuple(self):
+ x = ([],)
+ x[0].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[0][0] is y)
+
def test_deepcopy_dict(self):
x = {"foo": [1, 2], "bar": 3}
y = copy.deepcopy(x)
@@ -280,6 +300,15 @@ class TestCopy(unittest.TestCase):
self.assert_(x is not y)
self.assert_(x["foo"] is not y["foo"])
+ def test_deepcopy_reflexive_dict(self):
+ x = {}
+ x['foo'] = x
+ y = copy.deepcopy(x)
+ self.assertEqual(y, x)
+ self.assert_(y is not x)
+ self.assert_(y['foo'] is y)
+ self.assertEqual(y, {'foo': y})
+
def test_deepcopy_keepalive(self):
memo = {}
x = 42
@@ -369,6 +398,15 @@ class TestCopy(unittest.TestCase):
self.assert_(y is not x)
self.assert_(y.foo is not x.foo)
+ def test_deepcopy_reflexive_inst(self):
+ class C:
+ pass
+ x = C()
+ x.foo = x
+ y = copy.deepcopy(x)
+ self.assert_(y is not x)
+ self.assert_(y.foo is y)
+
# _reconstruct()
def test_reconstruct_string(self):
@@ -422,6 +460,15 @@ class TestCopy(unittest.TestCase):
self.assertEqual(y, x)
self.assert_(y.foo is not x.foo)
+ def test_reconstruct_reflexive(self):
+ class C(object):
+ pass
+ x = C()
+ x.foo = x
+ y = copy.deepcopy(x)
+ self.assert_(y is not x)
+ self.assert_(y.foo is y)
+
# Additions for Python 2.3 and pickle protocol 2
def test_reduce_4tuple(self):