From: Guido van Rossum Date: Fri, 5 Apr 2002 19:30:08 +0000 (+0000) Subject: Implement an idea by Paul Rubin: X-Git-Tag: v2.3c1~6110 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e276339cea6a8ea9ac9ff72ed9e1b8740eceac49;p=thirdparty%2FPython%2Fcpython.git Implement an idea by Paul Rubin: Change pickling format for bools to use a backwards compatible encoding. This means you can pickle True or False on Python 2.3 and Python 2.2 or before will read it back as 1 or 0. The code used for pickling bools before would create pickles that could not be read in previous Python versions. --- diff --git a/Lib/pickle.py b/Lib/pickle.py index 96ee5c17e22d..541624a22b75 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -101,8 +101,8 @@ TUPLE = 't' EMPTY_TUPLE = ')' SETITEMS = 'u' BINFLOAT = 'G' -TRUE = 'Z' -FALSE = 'z' +TRUE = 'I01\n' +FALSE = 'I00\n' __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) @@ -639,20 +639,18 @@ class Unpickler: self.append(None) dispatch[NONE] = load_none - def load_false(self): - self.append(False) - dispatch[FALSE] = load_false - - def load_true(self): - self.append(True) - dispatch[TRUE] = load_true - def load_int(self): data = self.readline() - try: - self.append(int(data)) - except ValueError: - self.append(long(data)) + if data == FALSE[1:]: + val = False + elif data == TRUE[1:]: + val = True + else: + try: + val = int(data) + except ValueError: + val = long(data) + self.append(val) dispatch[INT] = load_int def load_binint(self): diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index ee5d5faee9cd..0a60a3b4e265 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -224,5 +224,11 @@ veris(pickle.loads(cPickle.dumps(False)), False) veris(cPickle.loads(pickle.dumps(True)), True) veris(cPickle.loads(pickle.dumps(False)), False) +# Test for specific backwards-compatible pickle values +vereq(pickle.dumps(True), "I01\n.") +vereq(pickle.dumps(False), "I00\n.") +vereq(cPickle.dumps(True), "I01\n.") +vereq(cPickle.dumps(False), "I00\n.") + if verbose: print "All OK" diff --git a/Modules/cPickle.c b/Modules/cPickle.c index 9871627953d9..a99d69f31c1a 100644 --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -77,8 +77,8 @@ LONG Long (unbounded) integer; repr(i), then newline. #define TUPLE 't' #define EMPTY_TUPLE ')' #define SETITEMS 'u' -#define TRUE 'Z' -#define FALSE 'z' +#define TRUE "I01\n" +#define FALSE "I00\n" static char MARKv = MARK; @@ -936,10 +936,11 @@ save_none(Picklerobject *self, PyObject *args) static int save_bool(Picklerobject *self, PyObject *args) { - static char buf[2] = {FALSE, TRUE}; + static char *buf[2] = {FALSE, TRUE}; + static char len[2] = {sizeof(FALSE)-1, sizeof(TRUE)-1}; long l = PyInt_AS_LONG((PyIntObject *)args); - if ((*self->write_func)(self, buf + l, 1) < 0) + if ((*self->write_func)(self, buf[l], len[l]) < 0) return -1; return 0; @@ -2655,7 +2656,12 @@ load_int(Unpicklerobject *self) } } else { - if (!( py_int = PyInt_FromLong(l))) goto finally; + if (len == 3 && (l == 0 || l == 1)) { + if (!( py_int = PyBool_FromLong(l))) goto finally; + } + else { + if (!( py_int = PyInt_FromLong(l))) goto finally; + } } free(s); @@ -3763,16 +3769,6 @@ load(Unpicklerobject *self) break; continue; - case FALSE: - if (load_false(self) < 0) - break; - continue; - - case TRUE: - if (load_true(self) < 0) - break; - continue; - case BININT: if (load_binint(self) < 0) break;