Kaydet (Commit) 90e05b0e authored tarafından Guido van Rossum's avatar Guido van Rossum

Support __reduce__ returning a 4-tuple or 5-tuple.

üst 93cf58b0
......@@ -297,15 +297,34 @@ def _reconstruct(x, info, deep, memo=None):
if memo is None:
memo = {}
n = len(info)
assert n in (2, 3)
assert n in (2, 3, 4, 5)
callable, args = info[:2]
if n > 2:
state = info[2]
else:
state = {}
if n > 3:
listiter = info[3]
else:
listiter = None
if n > 4:
dictiter = info[4]
else:
dictiter = None
if deep:
args = deepcopy(args, memo)
y = callable(*args)
if listiter is not None:
for item in listiter:
if deep:
item = deepcopy(item, memo)
y.append(item)
if dictiter is not None:
for key, value in dictiter:
if deep:
key = deepcopy(key, memo)
value = deepcopy(value, memo)
y[key] = value
if state:
if deep:
state = deepcopy(state, memo)
......
......@@ -375,6 +375,42 @@ class TestCopy(unittest.TestCase):
self.assertEqual(y, x)
self.assert_(y.foo is not x.foo)
# Additions for Python 2.3 and pickle protocol 2
def test_reduce_4tuple(self):
class C(list):
def __reduce__(self):
return (C, (), self.__dict__, iter(self))
def __cmp__(self, other):
return (cmp(list(self), list(other)) or
cmp(self.__dict__, other.__dict__))
x = C([[1, 2], 3])
y = copy.copy(x)
self.assertEqual(x, y)
self.assert_(x is not y)
self.assert_(x[0] is y[0])
y = copy.deepcopy(x)
self.assertEqual(x, y)
self.assert_(x is not y)
self.assert_(x[0] is not y[0])
def test_reduce_5tuple(self):
class C(dict):
def __reduce__(self):
return (C, (), self.__dict__, None, self.iteritems())
def __cmp__(self, other):
return (cmp(dict(self), list(dict)) or
cmp(self.__dict__, other.__dict__))
x = C([("foo", [1, 2]), ("bar", 3)])
y = copy.copy(x)
self.assertEqual(x, y)
self.assert_(x is not y)
self.assert_(x["foo"] is y["foo"])
y = copy.deepcopy(x)
self.assertEqual(x, y)
self.assert_(x is not y)
self.assert_(x["foo"] is not y["foo"])
def test_main():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestCopy))
......
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