Skip to content

Commit

Permalink
Added back support for reading old DateTime pickles without a `_micro…
Browse files Browse the repository at this point in the history
…s` value.
  • Loading branch information
hannosch committed May 8, 2011
1 parent b348983 commit fb8a541
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGES.txt
Expand Up @@ -4,6 +4,8 @@ Changelog
3.0 (unreleased)
----------------

- Added back support for reading old DateTime pickles without a `_micros` value.

- Avoid storing `_t` representing the time as a float in seconds since the
epoch, as we already have `_micros` doing the same as a long. Memory use is
down to about 300 bytes per DateTime instance.
Expand Down
9 changes: 8 additions & 1 deletion src/DateTime/DateTime.py
Expand Up @@ -442,7 +442,9 @@ def __init__(self, *args, **kw):
def __getstate__(self):
# We store a float of _micros, instead of the _micros long, as we most
# often don't have any sub-second resolution and can save those bytes
return (self._micros / 1000000.0, self._timezone_naive, self._tz)
return (self._micros / 1000000.0,
getattr(self, '_timezone_naive', False),
self._tz)

def __setstate__(self, value):
if isinstance(value, tuple):
Expand All @@ -453,6 +455,11 @@ def __setstate__(self, value):
for k, v in value.items():
if k in self.__slots__:
setattr(self, k, v)
# BBB: support for very old DateTime pickles
if '_micros' not in value:
self._micros = long(value['_t'] * 1000000)
if '_timezone_naive' not in value:
self._timezone_naive = False

def _parse_args(self, *args, **kw):
"""Return a new date-time object.
Expand Down
17 changes: 17 additions & 0 deletions src/DateTime/tests/testDateTime.py
Expand Up @@ -237,6 +237,23 @@ def test_pickle_old(self):
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))

def test_pickle_old_without_micros(self):
dt = DateTime('2002/5/2 8:00am GMT+0')
data = ('(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05_amonq'
'\x04U\x03Mayq\x05U\x05_adayq\x06U\x03Thuq\x07U\x05_pmonq\x08h'
'\x05U\x05_hourq\tK\x08U\x05_fmonq\nh\x05U\x05_pdayq\x0bU'
'\x04Thu.q\x0cU\x05_fdayq\rU\x08Thursdayq\x0eU\x03_pmq\x0fU'
'\x02amq\x10U\x02_tq\x11GA\xcehy\x00\x00\x00\x00U\x07_minuteq'
'\x12K\x00U\x02_dq\x13G@\xe2\x12j\xaa\xaa\xaa\xabU\x07_secondq'
'\x14G\x00\x00\x00\x00\x00\x00\x00\x00U\x03_tzq\x15U\x05GMT+0q'
'\x16U\x06_monthq\x17K\x05U\x0f_timezone_naiveq\x18I00\nU'
'\x04_dayq\x19K\x02U\x05_yearq\x1aM\xd2\x07U\x08_nearsecq'
'\x1bG\x00\x00\x00\x00\x00\x00\x00\x00U\x07_pmhourq\x1cK\x08U'
'\n_dayoffsetq\x1dK\x04U\x04timeq\x1eG?\xd5UUUV\x00\x00ub.')
new = cPickle.loads(data)
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))

def testTZ2(self):
# Time zone manipulation test 2
dt = DateTime()
Expand Down

0 comments on commit fb8a541

Please sign in to comment.