diff options
Diffstat (limited to 'Lib/pickle.py')
-rw-r--r-- | Lib/pickle.py | 45 |
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( |