[Zope3-checkins] CVS: Zope3/src/datetime/tests - test_datetime.py:1.27

Tim Peters tim.one@comcast.net
Thu, 30 Jan 2003 21:24:37 -0500


Update of /cvs-repository/Zope3/src/datetime/tests
In directory cvs.zope.org:/tmp/cvs-serv15264/src/datetime/tests

Modified Files:
	test_datetime.py 
Log Message:
New pickling scheme, so that pickles produced by datetime.py and by
Python 2.3 datetimemodule.c are identical.  This is bought at the cost
of a tiny type insecurity:  in addition to the normal collection of
constructor arguments, __new__ also accepts a state string now.  This
means the type object can be returned directly as "the callable" by
__reduce__, and "the argument" can be a compact string (a copy of
the object memory, in the C implementation; the motivation isn't
really clear in this pure-Python implementation).

This also allows normal paths to be taken, allowing to remove all the
copy_reg() initialization hair, and layers of artificial pickler and
unpickler functions.  Thank Guido for the design!

I think it's still the case that tzinfo subclasses need to supply an
__init__ that's callable with no arguments (unless they arrange for
their own pickling).


=== Zope3/src/datetime/tests/test_datetime.py 1.26 => 1.27 ===
--- Zope3/src/datetime/tests/test_datetime.py:1.26	Fri Jan 24 17:35:21 2003
+++ Zope3/src/datetime/tests/test_datetime.py	Thu Jan 30 21:24:34 2003
@@ -4,6 +4,8 @@
 """
 
 import sys
+import pickle
+import cPickle
 import unittest
 
 from datetime import MINYEAR, MAXYEAR
@@ -13,6 +15,22 @@
 from datetime import date, datetime
 
 
+pickle_choices = [
+    (pickle, pickle, 0),
+    (pickle, pickle, 1),
+    (pickle, pickle, 2),
+    (cPickle, cPickle, 0),
+    (cPickle, cPickle, 1),
+##    (cPickle, cPickle, 2),
+    (pickle, cPickle, 0),
+    (pickle, cPickle, 1),
+##    (pickle, cPickle, 2),
+    (cPickle, pickle, 0),
+    (cPickle, pickle, 1),
+##    (cPickle, pickle, 2),
+    ]
+
+
 # XXX The test suite uncovered a bug in Python 2.2.2:  if x and y are
 # XXX instances of new-style classes (like date and time) that both
 # XXX define __cmp__, and x is compared to y, and one of the __cmp__
@@ -98,22 +116,17 @@
             self.assertEqual(fo.dst(dt), timedelta(minutes=42))
 
     def test_pickling_base(self):
-        import pickle, cPickle
-
         # There's no point to pickling tzinfo objects on their own (they
         # carry no data), but they need to be picklable anyway else
         # concrete subclasses can't be pickled.
         orig = tzinfo.__new__(tzinfo)
         self.failUnless(type(orig) is tzinfo)
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.failUnless(type(derived) is tzinfo)
 
     def test_pickling_subclass(self):
-        import pickle, cPickle
-
         # Make sure we can pickle/unpickle an instance of a subclass.
         offset = timedelta(minutes=-300)
         orig = PicklableFixedOffset(offset, 'cookie')
@@ -121,10 +134,9 @@
         self.failUnless(type(orig) is PicklableFixedOffset)
         self.assertEqual(orig.utcoffset(None), offset)
         self.assertEqual(orig.tzname(None), 'cookie')
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.failUnless(isinstance(derived, tzinfo))
                 self.failUnless(type(derived) is PicklableFixedOffset)
                 self.assertEqual(derived.utcoffset(None), offset)
@@ -262,7 +274,6 @@
         self.assertEqual(d[t1], 2)
 
     def test_pickling(self):
-        import pickle, cPickle
         args = 12, 34, 56
         orig = timedelta(*args)
         state = orig.__getstate__()
@@ -270,10 +281,9 @@
         derived = timedelta()
         derived.__setstate__(state)
         self.assertEqual(orig, derived)
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
 
     def test_compare(self):
@@ -821,18 +831,16 @@
             self.assertEqual(t.tm_isdst, -1)
 
     def test_pickling(self):
-        import pickle, cPickle
         args = 6, 7, 23
         orig = self.theclass(*args)
         state = orig.__getstate__()
-        self.assertEqual(state, '\x00\x06\x07\x17')
+        self.assertEqual(state, ('\x00\x06\x07\x17',), self.theclass)
         derived = self.theclass(1, 1, 1)
         derived.__setstate__(state)
         self.assertEqual(orig, derived)
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
 
     def test_compare(self):
@@ -1180,7 +1188,6 @@
         self.assertRaises(TypeError, lambda: a + a)
 
     def test_pickling(self):
-        import pickle, cPickle
         args = 6, 7, 23, 20, 59, 1, 64**2
         orig = self.theclass(*args)
         state = orig.__getstate__()
@@ -1188,10 +1195,9 @@
         derived = self.theclass(1, 1, 1)
         derived.__setstate__(state)
         self.assertEqual(orig, derived)
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
 
     def test_more_compare(self):
@@ -1566,7 +1572,6 @@
         self.assert_(self.theclass.max > self.theclass.min)
 
     def test_pickling(self):
-        import pickle, cPickle
         args = 20, 59, 16, 64**2
         orig = self.theclass(*args)
         state = orig.__getstate__()
@@ -1574,10 +1579,9 @@
         derived = self.theclass()
         derived.__setstate__(state)
         self.assertEqual(orig, derived)
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
 
     def test_bool(self):
@@ -1880,8 +1884,6 @@
         self.assertEqual(hash(t1), hash(t2))
 
     def test_pickling(self):
-        import pickle, cPickle
-
         # Try one without a tzinfo.
         args = 20, 59, 16, 64**2
         orig = self.theclass(*args)
@@ -1890,10 +1892,9 @@
         derived = self.theclass()
         derived.__setstate__(state)
         self.assertEqual(orig, derived)
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
 
         # Try one with a tzinfo.
@@ -1907,10 +1908,9 @@
         self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
         self.assertEqual(derived.tzname(), 'cookie')
 
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
                 self.failUnless(isinstance(derived.tzinfo,
                                 PicklableFixedOffset))
@@ -2099,8 +2099,6 @@
         self.assertRaises(ValueError, lambda: t1 == t2)
 
     def test_pickling(self):
-        import pickle, cPickle
-
         # Try one without a tzinfo.
         args = 6, 7, 23, 20, 59, 1, 64**2
         orig = self.theclass(*args)
@@ -2109,10 +2107,9 @@
         derived = self.theclass(1, 1, 1)
         derived.__setstate__(state)
         self.assertEqual(orig, derived)
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
 
         # Try one with a tzinfo.
@@ -2126,10 +2123,9 @@
         self.assertEqual(derived.utcoffset(), timedelta(minutes=-300))
         self.assertEqual(derived.tzname(), 'cookie')
 
-        for pickler in pickle, cPickle:
-            for binary in 0, 1:
-                green = pickler.dumps(orig, binary)
-                derived = pickler.loads(green)
+        for pickler, unpickler, proto in pickle_choices:
+                green = pickler.dumps(orig, proto)
+                derived = unpickler.loads(green)
                 self.assertEqual(orig, derived)
                 self.failUnless(isinstance(derived.tzinfo,
                                 PicklableFixedOffset))