]> granicus.if.org Git - python/commitdiff
Issue #16231: Allow false values other than None to be used as persistent IDs.
authorAlexandre Vassalotti <alexandre@peadrop.com>
Sat, 30 Nov 2013 21:24:13 +0000 (13:24 -0800)
committerAlexandre Vassalotti <alexandre@peadrop.com>
Sat, 30 Nov 2013 21:24:13 +0000 (13:24 -0800)
Lib/pickle.py
Lib/test/pickletester.py
Misc/NEWS

index 508e858d816969c00758bf9c2d966626ad22e8ca..299de16f519b56a7cc964fa1af3fdab7b9e6b030 100644 (file)
@@ -269,7 +269,7 @@ class Pickler:
     def save(self, obj):
         # Check for persistent id (defined by a subclass)
         pid = self.persistent_id(obj)
-        if pid:
+        if pid is not None:
             self.save_pers(pid)
             return
 
index 34cafcb7b8602a33b257d2a31905030f24a27a7c..1599893d8a60abb0ae5c4f20e1a07efe6279a2a7 100644 (file)
@@ -1152,30 +1152,34 @@ class AbstractPersistentPicklerTests(unittest.TestCase):
         if isinstance(object, int) and object % 2 == 0:
             self.id_count += 1
             return str(object)
+        elif object == "test_false_value":
+            self.false_count += 1
+            return ""
         else:
             return None
 
     def persistent_load(self, oid):
-        self.load_count += 1
-        object = int(oid)
-        assert object % 2 == 0
-        return object
+        if not oid:
+            self.load_false_count += 1
+            return "test_false_value"
+        else:
+            self.load_count += 1
+            object = int(oid)
+            assert object % 2 == 0
+            return object
 
     def test_persistence(self):
-        self.id_count = 0
-        self.load_count = 0
-        L = range(10)
-        self.assertEqual(self.loads(self.dumps(L)), L)
-        self.assertEqual(self.id_count, 5)
-        self.assertEqual(self.load_count, 5)
-
-    def test_bin_persistence(self):
-        self.id_count = 0
-        self.load_count = 0
-        L = range(10)
-        self.assertEqual(self.loads(self.dumps(L, 1)), L)
-        self.assertEqual(self.id_count, 5)
-        self.assertEqual(self.load_count, 5)
+        L = range(10) + ["test_false_value"]
+        for proto in protocols:
+            self.id_count = 0
+            self.false_count = 0
+            self.load_false_count = 0
+            self.load_count = 0
+            self.assertEqual(self.loads(self.dumps(L, proto)), L)
+            self.assertEqual(self.id_count, 5)
+            self.assertEqual(self.false_count, 1)
+            self.assertEqual(self.load_count, 5)
+            self.assertEqual(self.load_false_count, 1)
 
 class AbstractPicklerUnpicklerObjectTests(unittest.TestCase):
 
index e894f3e408fc3c7bce20d362c2742047174c89bf..0581dd2d924879f34ad6a31be0038c27c713ca82 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -15,6 +15,11 @@ Core and Builtins
 Library
 -------
 
+- Issue #16231: Fixed pickle.Pickler to only fallback to its default pickling
+  behaviour when Pickler.persistent_id returns None, but not for any other
+  false values.  This allows false values other values other than None to be
+  used as persistent IDs.  This behaviour is consistent with cPickle.
+
 - Issue #11508: Fixed uuid.getnode() and uuid.uuid1() on environment with
   virtual interface.  Original patch by Kent Frazier.