]> granicus.if.org Git - python/commitdiff
SF patch 707900, fixing bug 702858, by Steven Taschuk.
authorGuido van Rossum <guido@python.org>
Fri, 13 Jun 2003 19:28:47 +0000 (19:28 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 13 Jun 2003 19:28:47 +0000 (19:28 +0000)
Copying a new-style class that had a reference to itself didn't work.
(The same thing worked fine for old-style classes.)

Lib/copy.py
Lib/test/test_copy.py
Misc/NEWS

index a4a3cebd530af77de413922641a712871cd2b05d..02aa46b50331911515632a2ded31ec8d56881497 100644 (file)
@@ -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:
index c734a9a9d408390f364fca9d66724d73a54fdf30..a53f988292746808bc9cde72de7dac5a44338256 100644 (file)
@@ -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):
index 35b35b87fd576ed963c39675fbd18b7ffcd627f2..2ca8e9e2eb39b410824db078554a2e4d18b897f0 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -70,6 +70,10 @@ Extension modules
 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().
 
 - More fixes to urllib (SF 549151): (a) When redirecting, always use