-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
Description
Feature or enhancement
Currently test_reduce_5tuple verifies that Lib/copy.py supports behavior which deviates from standard reduce protocol.
Here you can see that __reduce__ returns tuple with fifth element that is not an iterator:
Lines 672 to 687 in 598d4c6
| def test_reduce_5tuple(self): | |
| class C(dict): | |
| def __reduce__(self): | |
| return (C, (), self.__dict__, None, self.items()) | |
| def __eq__(self, other): | |
| return (dict(self) == dict(other) and | |
| self.__dict__ == other.__dict__) | |
| x = C([("foo", [1, 2]), ("bar", 3)]) | |
| y = copy.copy(x) | |
| self.assertEqual(x, y) | |
| self.assertIsNot(x, y) | |
| self.assertIs(x["foo"], y["foo"]) | |
| y = copy.deepcopy(x) | |
| self.assertEqual(x, y) | |
| self.assertIsNot(x, y) | |
| self.assertIsNot(x["foo"], y["foo"]) |
Pickle explicitly doesn't support that:
import pickle
class C(dict):
def __reduce__(self):
return (C, (), self.__dict__, None, self.items())
def __eq__(self, other):
return dict(self) == dict(other) and self.__dict__ == other.__dict__
x = C([("foo", [1, 2]), ("bar", 3)])
pickle.dumps(x) # _pickle.PicklingError: fifth item of the tuple returned by __reduce__ must be an iterator, not dict_itemsAnd when mentioning 4th and 5th elements, docs explicitly say:
Optionally, an iterator (and not a sequence)
Optionally, an iterator (not a sequence)
test_reduce_4tuple already correctly returns iterator:
Lines 655 to 658 in 598d4c6
| def test_reduce_4tuple(self): | |
| class C(list): | |
| def __reduce__(self): | |
| return (C, (), self.__dict__, iter(self)) |
Proposal
I propose changing self.items() to iter(self.items()) so that this test only verifies that Lib/copy.py supports pickle protocol as it is documented.
No changes to Lib/copy.py are proposed, current behavior may be classified as an implementation detail.
Motivation
This will allow alternative implementations to rely on strict protocol compliance without breaking Lib/test/test_copy.py.
Has this already been discussed elsewhere?
This is a minor feature, which does not need previous discussion elsewhere