mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-37210: Fix pure Python pickle when _pickle is unavailable (GH-14016)
Allow pure Python implementation of pickle to work
even when the C _pickle module is unavailable.
Fix test_pickle when _pickle is missing: declare PyPicklerHookTests
outside "if has_c_implementation:" block.
(cherry picked from commit 63ab4ba07b
)
Co-authored-by: Victor Stinner <vstinner@redhat.com>
This commit is contained in:
parent
e40a97a721
commit
cbda40db7b
3 changed files with 41 additions and 32 deletions
|
@ -36,10 +36,16 @@ import io
|
||||||
import codecs
|
import codecs
|
||||||
import _compat_pickle
|
import _compat_pickle
|
||||||
|
|
||||||
from _pickle import PickleBuffer
|
|
||||||
|
|
||||||
__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
|
__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
|
||||||
"Unpickler", "dump", "dumps", "load", "loads", "PickleBuffer"]
|
"Unpickler", "dump", "dumps", "load", "loads"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
from _pickle import PickleBuffer
|
||||||
|
__all__.append("PickleBuffer")
|
||||||
|
_HAVE_PICKLE_BUFFER = True
|
||||||
|
except ImportError:
|
||||||
|
_HAVE_PICKLE_BUFFER = False
|
||||||
|
|
||||||
|
|
||||||
# Shortcut for use in isinstance testing
|
# Shortcut for use in isinstance testing
|
||||||
bytes_types = (bytes, bytearray)
|
bytes_types = (bytes, bytearray)
|
||||||
|
@ -812,6 +818,7 @@ class _Pickler:
|
||||||
self.write(BYTEARRAY8 + pack("<Q", n) + obj)
|
self.write(BYTEARRAY8 + pack("<Q", n) + obj)
|
||||||
dispatch[bytearray] = save_bytearray
|
dispatch[bytearray] = save_bytearray
|
||||||
|
|
||||||
|
if _HAVE_PICKLE_BUFFER:
|
||||||
def save_picklebuffer(self, obj):
|
def save_picklebuffer(self, obj):
|
||||||
if self.proto < 5:
|
if self.proto < 5:
|
||||||
raise PicklingError("PickleBuffer can only pickled with "
|
raise PicklingError("PickleBuffer can only pickled with "
|
||||||
|
|
|
@ -203,6 +203,13 @@ class PyChainDispatchTableTests(AbstractDispatchTableTests):
|
||||||
return collections.ChainMap({}, pickle.dispatch_table)
|
return collections.ChainMap({}, pickle.dispatch_table)
|
||||||
|
|
||||||
|
|
||||||
|
class PyPicklerHookTests(AbstractHookTests):
|
||||||
|
class CustomPyPicklerClass(pickle._Pickler,
|
||||||
|
AbstractCustomPicklerClass):
|
||||||
|
pass
|
||||||
|
pickler_class = CustomPyPicklerClass
|
||||||
|
|
||||||
|
|
||||||
if has_c_implementation:
|
if has_c_implementation:
|
||||||
class CPickleTests(AbstractPickleModuleTests):
|
class CPickleTests(AbstractPickleModuleTests):
|
||||||
from _pickle import dump, dumps, load, loads, Pickler, Unpickler
|
from _pickle import dump, dumps, load, loads, Pickler, Unpickler
|
||||||
|
@ -255,12 +262,6 @@ if has_c_implementation:
|
||||||
def get_dispatch_table(self):
|
def get_dispatch_table(self):
|
||||||
return collections.ChainMap({}, pickle.dispatch_table)
|
return collections.ChainMap({}, pickle.dispatch_table)
|
||||||
|
|
||||||
class PyPicklerHookTests(AbstractHookTests):
|
|
||||||
class CustomPyPicklerClass(pickle._Pickler,
|
|
||||||
AbstractCustomPicklerClass):
|
|
||||||
pass
|
|
||||||
pickler_class = CustomPyPicklerClass
|
|
||||||
|
|
||||||
class CPicklerHookTests(AbstractHookTests):
|
class CPicklerHookTests(AbstractHookTests):
|
||||||
class CustomCPicklerClass(_pickle.Pickler, AbstractCustomPicklerClass):
|
class CustomCPicklerClass(_pickle.Pickler, AbstractCustomPicklerClass):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Allow pure Python implementation of :mod:`pickle` to work even when the C :mod:`_pickle` module is unavailable.
|
Loading…
Add table
Add a link
Reference in a new issue