Commit cfaa9a9a authored by Guido van Rossum's avatar Guido van Rossum

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.)
parent c1ea2192
...@@ -334,6 +334,7 @@ def _reconstruct(x, info, deep, memo=None): ...@@ -334,6 +334,7 @@ def _reconstruct(x, info, deep, memo=None):
if deep: if deep:
args = deepcopy(args, memo) args = deepcopy(args, memo)
y = callable(*args) y = callable(*args)
memo[id(x)] = y
if listiter is not None: if listiter is not None:
for item in listiter: for item in listiter:
if deep: if deep:
......
...@@ -174,13 +174,15 @@ class TestCopy(unittest.TestCase): ...@@ -174,13 +174,15 @@ class TestCopy(unittest.TestCase):
self.assertEqual(y, x) self.assertEqual(y, x)
def test_deepcopy_memo(self): def test_deepcopy_memo(self):
# Tests of reflexive objects are under type-specific sections below.
# This tests only repetitions of objects.
x = [] x = []
x.append(x) x = [x, x]
y = copy.deepcopy(x) y = copy.deepcopy(x)
self.assertEqual(y, x) self.assertEqual(y, x)
self.assert_(y is not x) self.assert_(y is not x)
self.assert_(y[0] is not x[0]) 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): def test_deepcopy_issubclass(self):
# XXX Note: there's no way to test the TypeError coming out of # XXX Note: there's no way to test the TypeError coming out of
...@@ -266,6 +268,15 @@ class TestCopy(unittest.TestCase): ...@@ -266,6 +268,15 @@ class TestCopy(unittest.TestCase):
self.assert_(x is not y) self.assert_(x is not y)
self.assert_(x[0] is not y[0]) 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): def test_deepcopy_tuple(self):
x = ([1, 2], 3) x = ([1, 2], 3)
y = copy.deepcopy(x) y = copy.deepcopy(x)
...@@ -273,6 +284,15 @@ class TestCopy(unittest.TestCase): ...@@ -273,6 +284,15 @@ class TestCopy(unittest.TestCase):
self.assert_(x is not y) self.assert_(x is not y)
self.assert_(x[0] is not y[0]) 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): def test_deepcopy_dict(self):
x = {"foo": [1, 2], "bar": 3} x = {"foo": [1, 2], "bar": 3}
y = copy.deepcopy(x) y = copy.deepcopy(x)
...@@ -280,6 +300,15 @@ class TestCopy(unittest.TestCase): ...@@ -280,6 +300,15 @@ class TestCopy(unittest.TestCase):
self.assert_(x is not y) self.assert_(x is not y)
self.assert_(x["foo"] is not y["foo"]) 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): def test_deepcopy_keepalive(self):
memo = {} memo = {}
x = 42 x = 42
...@@ -369,6 +398,15 @@ class TestCopy(unittest.TestCase): ...@@ -369,6 +398,15 @@ class TestCopy(unittest.TestCase):
self.assert_(y is not x) self.assert_(y is not x)
self.assert_(y.foo is not x.foo) 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() # _reconstruct()
def test_reconstruct_string(self): def test_reconstruct_string(self):
...@@ -422,6 +460,15 @@ class TestCopy(unittest.TestCase): ...@@ -422,6 +460,15 @@ class TestCopy(unittest.TestCase):
self.assertEqual(y, x) self.assertEqual(y, x)
self.assert_(y.foo is not x.foo) 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 # Additions for Python 2.3 and pickle protocol 2
def test_reduce_4tuple(self): def test_reduce_4tuple(self):
......
...@@ -70,6 +70,10 @@ Extension modules ...@@ -70,6 +70,10 @@ Extension modules
Library Library
------- -------
- copy.py: applied 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.)
- difflib.py has two new functions: context_diff() and unified_diff(). - difflib.py has two new functions: context_diff() and unified_diff().
- More fixes to urllib (SF 549151): (a) When redirecting, always use - More fixes to urllib (SF 549151): (a) When redirecting, always use
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment