summaryrefslogtreecommitdiff
path: root/Lib/pickle.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/pickle.py')
-rw-r--r--Lib/pickle.py45
1 files changed, 33 insertions, 12 deletions
diff --git a/Lib/pickle.py b/Lib/pickle.py
index a690ccd8bc..386ffba7e2 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -23,8 +23,6 @@ Misc variables:
"""
-__version__ = "$Revision$" # Code version
-
from types import FunctionType, BuiltinFunctionType
from copyreg import dispatch_table
from copyreg import _extension_registry, _inverted_registry, _extension_cache
@@ -299,8 +297,8 @@ class _Pickler:
f(self, obj) # Call unbound method with explicit self
return
- # Check copyreg.dispatch_table
- reduce = dispatch_table.get(t)
+ # Check private dispatch table if any, or else copyreg.dispatch_table
+ reduce = getattr(self, 'dispatch_table', dispatch_table).get(t)
if reduce:
rv = reduce(obj)
else:
@@ -377,7 +375,7 @@ class _Pickler:
# allowing protocol 0 and 1 to work normally. For this to
# work, the function returned by __reduce__ should be
# called __newobj__, and its first argument should be a
- # new-style class. The implementation for __newobj__
+ # class. The implementation for __newobj__
# should be as follows, although pickle has no way to
# verify this:
#
@@ -440,6 +438,14 @@ class _Pickler:
self.write(NONE)
dispatch[type(None)] = save_none
+ def save_ellipsis(self, obj):
+ self.save_global(Ellipsis, 'Ellipsis')
+ dispatch[type(Ellipsis)] = save_ellipsis
+
+ def save_notimplemented(self, obj):
+ self.save_global(NotImplemented, 'NotImplemented')
+ dispatch[type(NotImplemented)] = save_notimplemented
+
def save_bool(self, obj):
if self.proto >= 2:
self.write(obj and NEWTRUE or NEWFALSE)
@@ -722,9 +728,18 @@ class _Pickler:
self.memoize(obj)
+ def save_type(self, obj):
+ if obj is type(None):
+ return self.save_reduce(type, (None,), obj=obj)
+ elif obj is type(NotImplemented):
+ return self.save_reduce(type, (NotImplemented,), obj=obj)
+ elif obj is type(...):
+ return self.save_reduce(type, (...,), obj=obj)
+ return self.save_global(obj)
+
dispatch[FunctionType] = save_global
dispatch[BuiltinFunctionType] = save_global
- dispatch[type] = save_global
+ dispatch[type] = save_type
# Pickling helpers
@@ -945,7 +960,7 @@ class _Unpickler:
rep = orig[:-1]
for q in (b'"', b"'"): # double or single quote
if rep.startswith(q):
- if not rep.endswith(q):
+ if len(rep) < 2 or not rep.endswith(q):
raise ValueError("insecure string pickle")
rep = rep[len(q):-len(q)]
break
@@ -1202,8 +1217,14 @@ class _Unpickler:
def load_appends(self):
stack = self.stack
mark = self.marker()
- list = stack[mark - 1]
- list.extend(stack[mark + 1:])
+ list_obj = stack[mark - 1]
+ items = stack[mark + 1:]
+ if isinstance(list_obj, list):
+ list_obj.extend(items)
+ else:
+ append = list_obj.append
+ for item in items:
+ append(item)
del stack[mark:]
dispatch[APPENDS[0]] = load_appends
@@ -1258,7 +1279,7 @@ class _Unpickler:
raise _Stop(value)
dispatch[STOP[0]] = load_stop
-# Encode/decode longs.
+# Encode/decode ints.
def encode_long(x):
r"""Encode a long to a two's complement little-endian binary string.
@@ -1291,7 +1312,7 @@ def encode_long(x):
return result
def decode_long(data):
- r"""Decode a long from a two's complement little-endian binary string.
+ r"""Decode an int from a two's complement little-endian binary string.
>>> decode_long(b'')
0
@@ -1345,7 +1366,7 @@ def _test():
return doctest.testmod()
if __name__ == "__main__":
- import sys, argparse
+ import argparse
parser = argparse.ArgumentParser(
description='display contents of the pickle files')
parser.add_argument(