[Checkins] SVN: DateTime/branches/2.12/ Added forward compatibility with DateTime 3 pickle format.

Hano Schlichting cvs-admin at zope.org
Fri Aug 10 22:05:35 UTC 2012


Log message for revision 127471:
  Added forward compatibility with DateTime 3 pickle format.
  

Changed:
  U   DateTime/branches/2.12/CHANGES.txt
  U   DateTime/branches/2.12/src/DateTime/DateTime.py
  U   DateTime/branches/2.12/src/DateTime/tests/testDateTime.py

-=-
Modified: DateTime/branches/2.12/CHANGES.txt
===================================================================
--- DateTime/branches/2.12/CHANGES.txt	2012-08-10 21:06:05 UTC (rev 127470)
+++ DateTime/branches/2.12/CHANGES.txt	2012-08-10 22:05:31 UTC (rev 127471)
@@ -4,6 +4,12 @@
 2.12.7 (unreleased)
 -------------------
 
+- Added forward compatibility with DateTime 3 pickle format. DateTime
+  instances constructed under version 3 can be read and unpickled by this
+  version. The pickled data is converted to the current versions format
+  (old-style class / no slots). Once converted it will be stored again in the
+  old format. This should allow for a transparent upgrade/downgrade path
+  between DateTime 2 and 3.
 
 2.12.6 (2010-10-17)
 -------------------

Modified: DateTime/branches/2.12/src/DateTime/DateTime.py
===================================================================
--- DateTime/branches/2.12/src/DateTime/DateTime.py	2012-08-10 21:06:05 UTC (rev 127470)
+++ DateTime/branches/2.12/src/DateTime/DateTime.py	2012-08-10 22:05:31 UTC (rev 127471)
@@ -15,6 +15,7 @@
 __version__='$Revision: 1.99 $'[11:-2]
 
 
+import copy_reg
 import re, math,  DateTimeZone
 from time import time, gmtime, localtime
 from time import daylight, timezone, altzone, strftime
@@ -355,6 +356,12 @@
 
     def __setstate__(self, state):
         self.__dict__.clear()  # why doesn't Python's unpickler do this?
+        if isinstance(state, tuple):
+            # Add support for parsing the DateTime 3 format
+            self._parse_args(state[0], state[2])
+            self._timezone_naive = state[1]
+            self._micros = long(state[0] * 1000000)
+            return
         self.__dict__.update(state)
         if '_micros' not in state:
             self._micros = self._upgrade_old()
@@ -1853,3 +1860,15 @@
     """Return the list of recognized timezone names"""
     return sorted(list(PytzCache._zmap.values()))
 
+# Patch the copy_reg module, so we can deal with DateTime 3 new-style
+# classes being recreated as old-style classes
+
+orig_reconstructor = copy_reg._reconstructor
+
+
+def _dt_reconstructor(cls, base, state):
+    if cls is DateTime:
+        return cls(state)
+    return orig_reconstructor(cls, base, state)
+
+copy_reg._reconstructor = _dt_reconstructor

Modified: DateTime/branches/2.12/src/DateTime/tests/testDateTime.py
===================================================================
--- DateTime/branches/2.12/src/DateTime/tests/testDateTime.py	2012-08-10 21:06:05 UTC (rev 127470)
+++ DateTime/branches/2.12/src/DateTime/tests/testDateTime.py	2012-08-10 22:05:31 UTC (rev 127471)
@@ -275,6 +275,30 @@
         new = cPickle.loads(data)
         self.assertEqual(dt.__dict__, new.__dict__)
 
+    def test_pickle_new(self):
+        dt = DateTime('2002/5/2 8:00am')
+        data = ('ccopy_reg\n_reconstructor\nq\x01(cDateTime.DateTime\n'
+            'DateTime\nq\x02c__builtin__\nobject\nq\x03NtRq\x04(GA\xcehj'
+            '\xf0\x00\x00\x00I01\nU\x05GMT+2q\x05tb.')
+        new = cPickle.loads(data)
+        self._compare(dt, new)
+
+    def test_pickle_new_with_tz(self):
+        dt = DateTime('2002/5/2 8:00am GMT+8')
+        data = ('ccopy_reg\n_reconstructor\nq\x01(cDateTime.DateTime\n'
+            'DateTime\nq\x02c__builtin__\nobject\nq\x03NtRq\x04(GA\xceh@'
+            '\xc0\x00\x00\x00I00\nU\x05GMT+8q\x05tb.')
+        new = cPickle.loads(data)
+        self._compare(dt, new)
+
+    def test_pickle_new_with_micros(self):
+        dt = DateTime('2002/5/2 8:00:14.123 GMT+8')
+        data = ('ccopy_reg\n_reconstructor\nq\x01(cDateTime.DateTime\n'
+            'DateTime\nq\x02c__builtin__\nobject\nq\x03NtRq\x04(GA\xceh@'
+            '\xc7\x0f\xbewI00\nU\x05GMT+8q\x05tb.')
+        new = cPickle.loads(data)
+        self._compare(dt, new)
+
     def test_pickle_old(self):
         dt = DateTime('2002/5/2 8:00am GMT+0')
         data = ('(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05_amonq'



More information about the checkins mailing list