Commit 72af2c0b authored by Guido van Rossum's avatar Guido van Rossum

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.
parent add4c6e1
...@@ -101,8 +101,8 @@ TUPLE = 't' ...@@ -101,8 +101,8 @@ TUPLE = 't'
EMPTY_TUPLE = ')' EMPTY_TUPLE = ')'
SETITEMS = 'u' SETITEMS = 'u'
BINFLOAT = 'G' BINFLOAT = 'G'
TRUE = 'Z' TRUE = 'I01\n'
FALSE = 'z' FALSE = 'I00\n'
__all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)]) __all__.extend([x for x in dir() if re.match("[A-Z][A-Z0-9_]+$",x)])
...@@ -639,20 +639,18 @@ class Unpickler: ...@@ -639,20 +639,18 @@ class Unpickler:
self.append(None) self.append(None)
dispatch[NONE] = load_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): def load_int(self):
data = self.readline() data = self.readline()
try: if data == FALSE[1:]:
self.append(int(data)) val = False
except ValueError: elif data == TRUE[1:]:
self.append(long(data)) val = True
else:
try:
val = int(data)
except ValueError:
val = long(data)
self.append(val)
dispatch[INT] = load_int dispatch[INT] = load_int
def load_binint(self): def load_binint(self):
......
...@@ -224,5 +224,11 @@ veris(pickle.loads(cPickle.dumps(False)), False) ...@@ -224,5 +224,11 @@ veris(pickle.loads(cPickle.dumps(False)), False)
veris(cPickle.loads(pickle.dumps(True)), True) veris(cPickle.loads(pickle.dumps(True)), True)
veris(cPickle.loads(pickle.dumps(False)), False) 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: if verbose:
print "All OK" print "All OK"
...@@ -77,8 +77,8 @@ LONG Long (unbounded) integer; repr(i), then newline. ...@@ -77,8 +77,8 @@ LONG Long (unbounded) integer; repr(i), then newline.
#define TUPLE 't' #define TUPLE 't'
#define EMPTY_TUPLE ')' #define EMPTY_TUPLE ')'
#define SETITEMS 'u' #define SETITEMS 'u'
#define TRUE 'Z' #define TRUE "I01\n"
#define FALSE 'z' #define FALSE "I00\n"
static char MARKv = MARK; static char MARKv = MARK;
...@@ -936,10 +936,11 @@ save_none(Picklerobject *self, PyObject *args) ...@@ -936,10 +936,11 @@ save_none(Picklerobject *self, PyObject *args)
static int static int
save_bool(Picklerobject *self, PyObject *args) 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); 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 -1;
return 0; return 0;
...@@ -2655,7 +2656,12 @@ load_int(Unpicklerobject *self) ...@@ -2655,7 +2656,12 @@ load_int(Unpicklerobject *self)
} }
} }
else { 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); free(s);
...@@ -3763,16 +3769,6 @@ load(Unpicklerobject *self) ...@@ -3763,16 +3769,6 @@ load(Unpicklerobject *self)
break; break;
continue; continue;
case FALSE:
if (load_false(self) < 0)
break;
continue;
case TRUE:
if (load_true(self) < 0)
break;
continue;
case BININT: case BININT:
if (load_binint(self) < 0) if (load_binint(self) < 0)
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment