diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2015-10-10 19:42:18 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2015-10-10 19:42:18 (GMT) |
commit | 0d554d7ef159761439ade414fcd028262eae656c (patch) | |
tree | 11aa1a1dfd3cfa07302f98d6b7b7409e9354d568 /Lib/pickle.py | |
parent | 4e96df3b595ed87957ee12e86e49f63b2d1cd05f (diff) | |
download | cpython-0d554d7ef159761439ade414fcd028262eae656c.zip cpython-0d554d7ef159761439ade414fcd028262eae656c.tar.gz cpython-0d554d7ef159761439ade414fcd028262eae656c.tar.bz2 |
Issue #24164: Objects that need calling ``__new__`` with keyword arguments,
can now be pickled using pickle protocols older than protocol version 4.
Diffstat (limited to 'Lib/pickle.py')
-rw-r--r-- | Lib/pickle.py | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py index e93057a..d41753d 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -27,6 +27,7 @@ from types import FunctionType from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache from itertools import islice +from functools import partial import sys from sys import maxsize from struct import pack, unpack @@ -544,7 +545,7 @@ class _Pickler: write = self.write func_name = getattr(func, "__name__", "") - if self.proto >= 4 and func_name == "__newobj_ex__": + if self.proto >= 2 and func_name == "__newobj_ex__": cls, args, kwargs = args if not hasattr(cls, "__new__"): raise PicklingError("args[0] from {} args has no __new__" @@ -552,10 +553,16 @@ class _Pickler: if obj is not None and cls is not obj.__class__: raise PicklingError("args[0] from {} args has the wrong class" .format(func_name)) - save(cls) - save(args) - save(kwargs) - write(NEWOBJ_EX) + if self.proto >= 4: + save(cls) + save(args) + save(kwargs) + write(NEWOBJ_EX) + else: + func = partial(cls.__new__, cls, *args, **kwargs) + save(func) + save(()) + write(REDUCE) elif self.proto >= 2 and func_name == "__newobj__": # A __reduce__ implementation can direct protocol 2 or newer to # use the more efficient NEWOBJ opcode, while still |