Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 99d2c25

Browse files
committed
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.)
1 parent 097da0d commit 99d2c25

3 files changed

Lines changed: 54 additions & 2 deletions

File tree

Lib/copy.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ def _reconstruct(x, info, deep, memo=None):
334334
if deep:
335335
args = deepcopy(args, memo)
336336
y = callable(*args)
337+
memo[id(x)] = y
337338
if listiter is not None:
338339
for item in listiter:
339340
if deep:

Lib/test/test_copy.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,15 @@ def test_deepcopy_basic(self):
174174
self.assertEqual(y, x)
175175

176176
def test_deepcopy_memo(self):
177+
# Tests of reflexive objects are under type-specific sections below.
178+
# This tests only repetitions of objects.
177179
x = []
178-
x.append(x)
180+
x = [x, x]
179181
y = copy.deepcopy(x)
180182
self.assertEqual(y, x)
181183
self.assert_(y is not x)
182184
self.assert_(y[0] is not x[0])
183-
self.assert_(y is y[0])
185+
self.assert_(y[0] is y[1])
184186

185187
def test_deepcopy_issubclass(self):
186188
# XXX Note: there's no way to test the TypeError coming out of
@@ -266,20 +268,47 @@ def test_deepcopy_list(self):
266268
self.assert_(x is not y)
267269
self.assert_(x[0] is not y[0])
268270

271+
def test_deepcopy_reflexive_list(self):
272+
x = []
273+
x.append(x)
274+
y = copy.deepcopy(x)
275+
self.assertEqual(y, x)
276+
self.assert_(y is not x)
277+
self.assert_(y[0] is not x[0])
278+
self.assert_(y is y[0])
279+
269280
def test_deepcopy_tuple(self):
270281
x = ([1, 2], 3)
271282
y = copy.deepcopy(x)
272283
self.assertEqual(y, x)
273284
self.assert_(x is not y)
274285
self.assert_(x[0] is not y[0])
275286

287+
def test_deepcopy_reflexive_tuple(self):
288+
x = ([],)
289+
x[0].append(x)
290+
y = copy.deepcopy(x)
291+
self.assertEqual(y, x)
292+
self.assert_(y is not x)
293+
self.assert_(y[0] is not x[0])
294+
self.assert_(y[0][0] is y)
295+
276296
def test_deepcopy_dict(self):
277297
x = {"foo": [1, 2], "bar": 3}
278298
y = copy.deepcopy(x)
279299
self.assertEqual(y, x)
280300
self.assert_(x is not y)
281301
self.assert_(x["foo"] is not y["foo"])
282302

303+
def test_deepcopy_reflexive_dict(self):
304+
x = {}
305+
x['foo'] = x
306+
y = copy.deepcopy(x)
307+
self.assertEqual(y, x)
308+
self.assert_(y is not x)
309+
self.assert_(y['foo'] is y)
310+
self.assertEqual(y, {'foo': y})
311+
283312
def test_deepcopy_keepalive(self):
284313
memo = {}
285314
x = 42
@@ -369,6 +398,15 @@ def __cmp__(self, other):
369398
self.assert_(y is not x)
370399
self.assert_(y.foo is not x.foo)
371400

401+
def test_deepcopy_reflexive_inst(self):
402+
class C:
403+
pass
404+
x = C()
405+
x.foo = x
406+
y = copy.deepcopy(x)
407+
self.assert_(y is not x)
408+
self.assert_(y.foo is y)
409+
372410
# _reconstruct()
373411

374412
def test_reconstruct_string(self):
@@ -422,6 +460,15 @@ def __cmp__(self, other):
422460
self.assertEqual(y, x)
423461
self.assert_(y.foo is not x.foo)
424462

463+
def test_reconstruct_reflexive(self):
464+
class C(object):
465+
pass
466+
x = C()
467+
x.foo = x
468+
y = copy.deepcopy(x)
469+
self.assert_(y is not x)
470+
self.assert_(y.foo is y)
471+
425472
# Additions for Python 2.3 and pickle protocol 2
426473

427474
def test_reduce_4tuple(self):

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ Extension modules
7070
Library
7171
-------
7272

73+
- copy.py: applied SF patch 707900, fixing bug 702858, by Steven
74+
Taschuk. Copying a new-style class that had a reference to itself
75+
didn't work. (The same thing worked fine for old-style classes.)
76+
7377
- difflib.py has two new functions: context_diff() and unified_diff().
7478

7579
- More fixes to urllib (SF 549151): (a) When redirecting, always use

0 commit comments

Comments
 (0)