]> granicus.if.org Git - python/commitdiff
Implement an idea by Paul Rubin:
authorGuido van Rossum <guido@python.org>
Fri, 5 Apr 2002 19:30:08 +0000 (19:30 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 5 Apr 2002 19:30:08 +0000 (19:30 +0000)
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.

Lib/pickle.py
Lib/test/test_bool.py
Modules/cPickle.c

index 96ee5c17e22d15a17d075424d04bad4d9d4b1f9e..541624a22b7550d99bb54926742f072da9b00465 100644 (file)
@@ -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):
index ee5d5faee9cd7dee3b96acd56d3bc8db9300ec40..0a60a3b4e265bdace6211fed944bbf53afbcb418 100644 (file)
@@ -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"
index 9871627953d95e72e79ed1280a177e442c4372c3..a99d69f31c1ac9f34592e3c2050a0c8834328e8b 100644 (file)
@@ -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;