summaryrefslogtreecommitdiff
path: root/Lib/pickle.py
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2019-06-13 13:58:51 +0200
committerGitHub <noreply@github.com>2019-06-13 13:58:51 +0200
commit63ab4ba07b492448844940c347787ba30735b7f2 (patch)
treee76e84e6bd8355398833353bf9afdf6f2a1b6da8 /Lib/pickle.py
parent6f75c873752a16a7ad8f35855b1e29f59d048e84 (diff)
downloadcpython-git-63ab4ba07b492448844940c347787ba30735b7f2.tar.gz
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.
Diffstat (limited to 'Lib/pickle.py')
-rw-r--r--Lib/pickle.py59
1 files changed, 33 insertions, 26 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py
index a67ac7dd8b..71aa57d500 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -36,10 +36,16 @@ import io
import codecs
import _compat_pickle
-from _pickle import PickleBuffer
-
__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
bytes_types = (bytes, bytearray)
@@ -812,31 +818,32 @@ class _Pickler:
self.write(BYTEARRAY8 + pack("<Q", n) + obj)
dispatch[bytearray] = save_bytearray
- def save_picklebuffer(self, obj):
- if self.proto < 5:
- raise PicklingError("PickleBuffer can only pickled with "
- "protocol >= 5")
- with obj.raw() as m:
- if not m.contiguous:
- raise PicklingError("PickleBuffer can not be pickled when "
- "pointing to a non-contiguous buffer")
- in_band = True
- if self._buffer_callback is not None:
- in_band = bool(self._buffer_callback(obj))
- if in_band:
- # Write data in-band
- # XXX The C implementation avoids a copy here
- if m.readonly:
- self.save_bytes(m.tobytes())
+ if _HAVE_PICKLE_BUFFER:
+ def save_picklebuffer(self, obj):
+ if self.proto < 5:
+ raise PicklingError("PickleBuffer can only pickled with "
+ "protocol >= 5")
+ with obj.raw() as m:
+ if not m.contiguous:
+ raise PicklingError("PickleBuffer can not be pickled when "
+ "pointing to a non-contiguous buffer")
+ in_band = True
+ if self._buffer_callback is not None:
+ in_band = bool(self._buffer_callback(obj))
+ if in_band:
+ # Write data in-band
+ # XXX The C implementation avoids a copy here
+ if m.readonly:
+ self.save_bytes(m.tobytes())
+ else:
+ self.save_bytearray(m.tobytes())
else:
- self.save_bytearray(m.tobytes())
- else:
- # Write data out-of-band
- self.write(NEXT_BUFFER)
- if m.readonly:
- self.write(READONLY_BUFFER)
+ # Write data out-of-band
+ self.write(NEXT_BUFFER)
+ if m.readonly:
+ self.write(READONLY_BUFFER)
- dispatch[PickleBuffer] = save_picklebuffer
+ dispatch[PickleBuffer] = save_picklebuffer
def save_str(self, obj):
if self.bin: