diff --git a/NEWS b/NEWS index cde58b69..0efd9622 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,7 @@ What's new in psycopg 2.4.6 - connect() raises an exception instead of swallowing keyword arguments when a connection string is specified as well (ticket #131). - Discard any result produced by 'executemany()' (ticket #133). + - Fixed pickling of FixedOffsetTimezone objects (ticket #135). - 'errorcodes' map updated to PostgreSQL 9.2. diff --git a/lib/tz.py b/lib/tz.py index ec63f6c0..695a9253 100644 --- a/lib/tz.py +++ b/lib/tz.py @@ -72,6 +72,10 @@ class FixedOffsetTimezone(datetime.tzinfo): return "psycopg2.tz.FixedOffsetTimezone(offset=%r, name=%r)" \ % (offset_mins, self._name) + def __getinitargs__(self): + offset_mins = self._offset.seconds // 60 + self._offset.days * 24 * 60 + return (offset_mins, self._name) + def utcoffset(self, dt): return self._offset @@ -86,7 +90,7 @@ class FixedOffsetTimezone(datetime.tzinfo): return "%+03d:%d" % (hours, minutes) else: return "%+03d" % hours - + def dst(self, dt): return ZERO @@ -103,7 +107,6 @@ class LocalTimezone(datetime.tzinfo): This is the exact implementation from the Python 2.3 documentation. """ - def utcoffset(self, dt): if self._isdst(dt): return DSTOFFSET diff --git a/tests/test_dates.py b/tests/test_dates.py index 9be68a2c..0d18f663 100755 --- a/tests/test_dates.py +++ b/tests/test_dates.py @@ -539,6 +539,24 @@ class FixedOffsetTimezoneTests(unittest.TestCase): self.assert_(FixedOffsetTimezone(9 * 60) is not FixedOffsetTimezone(9 * 60, 'FOO')) self.assert_(FixedOffsetTimezone(name='FOO') is not FixedOffsetTimezone(9 * 60, 'FOO')) + def test_pickle(self): + # ticket #135 + import pickle + + tz11 = FixedOffsetTimezone(60) + tz12 = FixedOffsetTimezone(120) + for proto in [-1, 0, 1, 2]: + tz21, tz22 = pickle.loads(pickle.dumps([tz11, tz12], proto)) + self.assertEqual(tz11, tz21) + self.assertEqual(tz12, tz22) + + tz11 = FixedOffsetTimezone(60, name='foo') + tz12 = FixedOffsetTimezone(120, name='bar') + for proto in [-1, 0, 1, 2]: + tz21, tz22 = pickle.loads(pickle.dumps([tz11, tz12], proto)) + self.assertEqual(tz11, tz21) + self.assertEqual(tz12, tz22) + def test_suite(): return unittest.TestLoader().loadTestsFromName(__name__)