Added a HIGHEST_PROTOCOL module attribute to pickle and cPickle.

This commit is contained in:
Tim Peters 2003-02-13 15:44:41 +00:00
parent fe62bc917d
commit 8587b3c073
3 changed files with 20 additions and 10 deletions

View File

@ -47,6 +47,10 @@ compatible_formats = ["1.0", # Original protocol 0
"2.0", # Protocol 2 "2.0", # Protocol 2
] # Old format versions we can read ] # Old format versions we can read
# Keep in synch with cPickle. This is the highest protocol number we
# know how to read.
HIGHEST_PROTOCOL = 2
# Why use struct.pack() for pickling but marshal.loads() for # Why use struct.pack() for pickling but marshal.loads() for
# unpickling? struct.pack() is 40% faster than marshal.dumps(), but # unpickling? struct.pack() is 40% faster than marshal.dumps(), but
# marshal.loads() is twice as fast as struct.unpack()! # marshal.loads() is twice as fast as struct.unpack()!
@ -200,9 +204,9 @@ class Pickler:
if protocol is None: if protocol is None:
protocol = 0 protocol = 0
if protocol < 0: if protocol < 0:
protocol = 2 protocol = HIGHEST_PROTOCOL
elif protocol not in (0, 1, 2): elif not 0 <= protocol <= HIGHEST_PROTOCOL:
raise ValueError, "pickle protocol must be 0, 1 or 2" raise ValueError("pickle protocol must be <= %d" % HIGHEST_PROTOCOL)
self.write = file.write self.write = file.write
self.memo = {} self.memo = {}
self.proto = int(protocol) self.proto = int(protocol)

View File

@ -1,5 +1,6 @@
import unittest import unittest
import pickle import pickle
import cPickle
import pickletools import pickletools
import copy_reg import copy_reg
@ -7,8 +8,9 @@ from test.test_support import TestFailed, have_unicode, TESTFN
# Tests that try a number of pickle protocols should have a # Tests that try a number of pickle protocols should have a
# for proto in protocols: # for proto in protocols:
# kind of outer loop. Bump the 3 to 4 if/when protocol 3 is invented. # kind of outer loop.
protocols = range(3) assert pickle.HIGHEST_PROTOCOL == cPickle.HIGHEST_PROTOCOL == 2
protocols = range(pickle.HIGHEST_PROTOCOL + 1)
# Return True if opcode code appears in the pickle, else False. # Return True if opcode code appears in the pickle, else False.

View File

@ -15,7 +15,7 @@ PyDoc_STRVAR(cPickle_module_documentation,
#define WRITE_BUF_SIZE 256 #define WRITE_BUF_SIZE 256
/* Bump this when new opcodes are added to the pickle protocol. */ /* Bump this when new opcodes are added to the pickle protocol. */
#define CURRENT_PROTOCOL_NUMBER 2 #define HIGHEST_PROTOCOL 2
/* /*
* Pickle opcodes. These must be kept in synch with pickle.py. Extensive * Pickle opcodes. These must be kept in synch with pickle.py. Extensive
@ -2743,11 +2743,11 @@ newPicklerobject(PyObject *file, int proto)
Picklerobject *self; Picklerobject *self;
if (proto < 0) if (proto < 0)
proto = CURRENT_PROTOCOL_NUMBER; proto = HIGHEST_PROTOCOL;
if (proto > CURRENT_PROTOCOL_NUMBER) { if (proto > HIGHEST_PROTOCOL) {
PyErr_Format(PyExc_ValueError, "pickle protocol %d asked for; " PyErr_Format(PyExc_ValueError, "pickle protocol %d asked for; "
"the highest available protocol is %d", "the highest available protocol is %d",
proto, CURRENT_PROTOCOL_NUMBER); proto, HIGHEST_PROTOCOL);
return NULL; return NULL;
} }
@ -4308,7 +4308,7 @@ load_proto(Unpicklerobject *self)
* int when chewing on 1 byte. * int when chewing on 1 byte.
*/ */
assert(i >= 0); assert(i >= 0);
if (i <= CURRENT_PROTOCOL_NUMBER) if (i <= HIGHEST_PROTOCOL)
return 0; return 0;
PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i); PyErr_Format(PyExc_ValueError, "unsupported pickle protocol: %d", i);
@ -5562,6 +5562,10 @@ initcPickle(void)
} }
Py_DECREF(di); Py_DECREF(di);
i = PyModule_AddIntConstant(m, "HIGHEST_PROTOCOL", HIGHEST_PROTOCOL);
if (i < 0)
return;
/* These are purely informational; no code uses them. */ /* These are purely informational; no code uses them. */
/* File format version we write. */ /* File format version we write. */
format_version = PyString_FromString("2.0"); format_version = PyString_FromString("2.0");