diff -r 5d08c2a6274d Lib/copy.py --- a/Lib/copy.py Mon Jun 27 09:18:46 2011 -0500 +++ b/Lib/copy.py Mon Jun 27 08:49:22 2011 -0700 @@ -161,6 +161,8 @@ copier = _deepcopy_dispatch.get(cls) if copier: y = copier(x, memo) + if y is x: + return y else: try: issc = issubclass(cls, type) @@ -246,7 +248,6 @@ break else: y = x - memo[d] = y return y d[tuple] = _deepcopy_tuple diff -r 5d08c2a6274d Lib/test/test_copy.py --- a/Lib/test/test_copy.py Mon Jun 27 09:18:46 2011 -0500 +++ b/Lib/test/test_copy.py Mon Jun 27 08:49:22 2011 -0700 @@ -311,9 +311,24 @@ def test_deepcopy_keepalive(self): memo = {} - x = 42 + x = [] y = copy.deepcopy(x, memo) - self.assertTrue(memo[id(x)] is x) + self.assertTrue(memo[id(memo)][0] is x) + + def test_deepcopy_dont_memo_immutable(self): + memo = {} + x = [1, 2, 3, 4] + y = copy.deepcopy(x, memo) + self.assertEqual(y, x) + # There's the entry for the new list, and the keep alive. + self.assertEqual(len(memo), 2) + + memo = {} + x = [(1, 2)] + y = copy.deepcopy(x, memo) + self.assertEqual(y, x) + # Tuples with immutable contents are immutable for deepcopy. + self.assertEqual(len(memo), 2) def test_deepcopy_inst_vanilla(self): class C: