__all__ = ["PickleError", "PicklingError", "UnpicklingError", "Pickler",
"Unpickler", "dump", "dumps", "load", "loads"]
-format_version = "1.3" # File format version we write
-compatible_formats = ["1.0", "1.1", "1.2"] # Old format versions we can read
+# These are purely informational; no code usues these
+format_version = "2.0" # File format version we write
+compatible_formats = ["1.0", # Original protocol 0
+ "1.1", # Protocol 0 with class supprt added
+ "1.2", # Original protocol 1
+ "1.3", # Protocol 1 with BINFLOAT added
+ "2.0", # Protocol 2
+ ] # Old format versions we can read
mdumps = marshal.dumps
mloads = marshal.loads
class Pickler:
- def __init__(self, file, bin = 0):
+ def __init__(self, file, proto=1):
"""This takes a file-like object for writing a pickle data stream.
- The optional bin parameter if true, tells the pickler to use the more
- efficient binary pickle format, otherwise the ASCII format is used
- (this is the default).
+ The optional proto argument tells the pickler to use the given
+ protocol; supported protocols are 0, 1, 2. The default
+ protocol is 1 (in previous Python versions the default was 0).
+
+ Protocol 1 is more efficient than protocol 0; protocol 2 is
+ more efficient than protocol 1. Protocol 2 is not the default
+ because it is not supported by older Python versions.
+
+ XXX Protocol 2 is not yet implemented.
The file parameter must have a write() method that accepts a single
string argument. It can thus be an open file object, a StringIO
"""
self.write = file.write
self.memo = {}
- self.bin = bin
+ self.proto = proto
+ self.bin = proto >= 1
def clear_memo(self):
"""Clears the pickler's "memo".
except ImportError:
from StringIO import StringIO
-def dump(object, file, bin = 0):
- Pickler(file, bin).dump(object)
+def dump(object, file, proto=1):
+ Pickler(file, proto).dump(object)
-def dumps(object, bin = 0):
+def dumps(object, proto=1):
file = StringIO()
- Pickler(file, bin).dump(object)
+ Pickler(file, proto).dump(object)
return file.getvalue()
def load(file):
_dis_test = """
>>> import pickle
>>> x = [1, 2, (3, 4), {'abc': u"def"}]
->>> pik = pickle.dumps(x)
+>>> pik = pickle.dumps(x, 0)
>>> dis(pik)
0: ( MARK
1: l LIST (MARK at 0)
Exercise the INST/OBJ/BUILD family.
>>> import random
->>> dis(pickle.dumps(random.random))
+>>> dis(pickle.dumps(random.random, 0))
0: c GLOBAL 'random random'
15: p PUT 0
18: . STOP
>>> x = [pickle.PicklingError()] * 2
->>> dis(pickle.dumps(x))
+>>> dis(pickle.dumps(x, 0))
0: ( MARK
1: l LIST (MARK at 0)
2: p PUT 0
True
>>> T[0][0] is T
True
->>> dis(pickle.dumps(L))
+>>> dis(pickle.dumps(L, 0))
0: ( MARK
1: l LIST (MARK at 0)
2: p PUT 0
POP_MARK gets rid of the MARK. Doing a better job on the protocol 0
pickle would require the disassembler to emulate the stack.
->>> dis(pickle.dumps(T))
+>>> dis(pickle.dumps(T, 0))
0: ( MARK
1: ( MARK
2: l LIST (MARK at 1)