summaryrefslogtreecommitdiffstats
path: root/Lib/pickle.py
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2015-10-10 19:42:18 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2015-10-10 19:42:18 (GMT)
commit0d554d7ef159761439ade414fcd028262eae656c (patch)
tree11aa1a1dfd3cfa07302f98d6b7b7409e9354d568 /Lib/pickle.py
parent4e96df3b595ed87957ee12e86e49f63b2d1cd05f (diff)
downloadcpython-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.py17
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