Update of /cvsroot/python/python/nondist/sandbox/datetime In directory sc8-pr-cvs1:/tmp/cvs-serv6575 Modified Files: datetime.py doc.txt test_datetime.py Log Message: Changes sufficient so that pickles written by the Python implementation can be read by the C implementation. I don't really understand this. The docs have changed to note the new requirement that tzinfo subclasses have _an _init__ method that can be called with no arguments. They may also need a __safe_for_unpickling__ magic attr. Index: datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v retrieving revision 1.112 retrieving revision 1.113 diff -C2 -d -r1.112 -r1.113 *** datetime.py 20 Dec 2002 20:42:34 -0000 1.112 --- datetime.py 21 Dec 2002 05:03:13 -0000 1.113 *************** *** 933,936 **** --- 933,942 ---- raise NotImplementedError("tzinfo subclass must override dst()") + # pickle support + + __safe_for_unpickling__ = True + + def __reduce__(self): + return type(self), (), self.__dict__ class timetz(time): Index: doc.txt =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** doc.txt 20 Dec 2002 20:42:35 -0000 1.62 --- doc.txt 21 Dec 2002 05:03:13 -0000 1.63 *************** *** 5,8 **** --- 5,11 ---- - LaTeXize the docs. + + CLOSED + ====== - Pickle incompatibility? It occurs to me that, because the implementations are so different, a pickle created by the Python *************** *** 12,84 **** and has no wiggle room (TOOWTDI indeed <wink>). ! OK, after lots of fiddling, here's the scoop: the Python implementation ! can now read pickles written by the C and Python implementations. The ! C implementation can read pickles written by the C implementation, ! and date, datetime, and time pickles produced by the Python implementation. - However, the C implementation cannot read timedelta, timetz, or - datetimetz pickles written by the Python implementation. This is - bad, because Zope3 will use the Python implementation at first; if - "something isn't done about it", pickles written via the Python - implementation won't be readable when Zope3 moves to Python 2.3. - - XXX This one (timedelta) is probably fixed now. - Trying to read a Python (2.2.2) timedelta pickle under the C - implementation (2.3): - - File "ptest.py", line 31, in check - got = pickler.load(f) - File "C:\CODE\PYTHON\lib\pickle.py", line 1058, in load - return Unpickler(file).load() - File "C:\CODE\PYTHON\lib\pickle.py", line 666, in load - dispatch[key](self) - File "C:\CODE\PYTHON\lib\pickle.py", line 928, in load_reduce - value = apply(callable, arg_tup) - File "C:\CODE\PYTHON\lib\copy_reg.py", line 40, in _reconstructor - obj = base.__new__(cls, state) - TypeError: object.__new__(datetime.timedelta) is not safe, use datetime.timedelta.__new__() - - - Trying to read a Python (2.2.2) timetz pickle under the C - implementation (2.3): - - File "ptest.py", line 58, in ? - t.check() - File "ptest.py", line 31, in check - got = pickler.load(f) - File "C:\CODE\PYTHON\lib\pickle.py", line 1058, in load - return Unpickler(file).load() - File "C:\CODE\PYTHON\lib\pickle.py", line 666, in load - dispatch[key](self) - File "C:\CODE\PYTHON\lib\pickle.py", line 928, in load_reduce - value = apply(callable, arg_tup) - File "C:\CODE\PYTHON\lib\copy_reg.py", line 40, in _reconstructor - obj = base.__new__(cls, state) - TypeError: object.__new__(EST) is not safe, use datetime.tzinfo.__new__() - - - Trying to read a Python (2.2.2) datetimetz pickle under the C - implementation (2.3): - - Traceback (most recent call last): - File "ptest.py", line 58, in ? - t.check() - File "ptest.py", line 31, in check - got = pickler.load(f) - File "C:\CODE\PYTHON\lib\pickle.py", line 1058, in load - return Unpickler(file).load() - File "C:\CODE\PYTHON\lib\pickle.py", line 666, in load - dispatch[key](self) - File "C:\CODE\PYTHON\lib\pickle.py", line 928, in load_reduce - value = apply(callable, arg_tup) - File "C:\CODE\PYTHON\lib\copy_reg.py", line 40, in _reconstructor - obj = base.__new__(cls, state) - TypeError: object.__new__(EST) is not safe, use datetime.tzinfo.__new__() - - - - CLOSED - ====== - The test suite doesn't pass under 2.2.2, due to what Guido tracked to a bug in 2.2.2's implementation of __cmp__ for new-style classes. --- 15,27 ---- and has no wiggle room (TOOWTDI indeed <wink>). ! Resolution: Jim Fulton suggested adding various __reduce__ methods ! to the Python implementation, and that did lead to pickles that the ! C implementation groks. I'm not sure why, and tzinfo subclasses must ! have an __init__ that can be called without arguments now (if ! they want to play with pickles). It appears they must also set ! class attr __safe_for_unpickling__ = True, but only if they want a ! pickle written by the Python implementation to be readable by the C implementation. - The test suite doesn't pass under 2.2.2, due to what Guido tracked to a bug in 2.2.2's implementation of __cmp__ for new-style classes. *************** *** 797,800 **** --- 740,748 ---- to them. + Special requirement for pickling: A tzinfo subclass must have an + __init__ method that can be called with no arguments, else it can + be pickled but possibly not unpickled again. This is a technical + requirement that may be relaxed in the future. + A concrete subclass of tzinfo may need to implement the following methods. Exactly which methods are needed depends on the uses made *************** *** 802,808 **** The methods are called by a datetimetz or timetz object, passing itself as the argument. A tzinfo subclass's methods should be prepared to ! accept a dt argument of type None, timetz, or datetimetz. If is not ! None, and dt.tzinfo is not None and not equal to self, an exception ! should be raised. - utcoffset(dt) --- 750,756 ---- The methods are called by a datetimetz or timetz object, passing itself as the argument. A tzinfo subclass's methods should be prepared to ! accept a dt argument of type None, timetz, or datetimetz. If the dt ! argument is not None, and dt.tzinfo is not None and not equal to self, ! an exception should be raised. - utcoffset(dt) Index: test_datetime.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** test_datetime.py 16 Dec 2002 22:59:59 -0000 1.73 --- test_datetime.py 21 Dec 2002 05:03:14 -0000 1.74 *************** *** 56,59 **** --- 56,63 ---- return self.__dstoffset + class PicklableFixedOffset(FixedOffset): + def __init__(self, offset=None, name=None, dstoffset=None): + FixedOffset.__init__(self, offset, name, dstoffset) + class TestTZInfo(unittest.TestCase): *************** *** 108,114 **** # Make sure we can pickle/unpickle an instance of a subclass. ! orig = FixedOffset(-300, 'cookie') self.failUnless(isinstance(orig, tzinfo)) ! self.failUnless(type(orig) is FixedOffset) self.assertEqual(orig.utcoffset(None), -300) self.assertEqual(orig.tzname(None), 'cookie') --- 112,118 ---- # Make sure we can pickle/unpickle an instance of a subclass. ! orig = PicklableFixedOffset(-300, 'cookie') self.failUnless(isinstance(orig, tzinfo)) ! self.failUnless(type(orig) is PicklableFixedOffset) self.assertEqual(orig.utcoffset(None), -300) self.assertEqual(orig.tzname(None), 'cookie') *************** *** 118,122 **** derived = pickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) ! self.failUnless(type(derived) is FixedOffset) self.assertEqual(derived.utcoffset(None), -300) self.assertEqual(derived.tzname(None), 'cookie') --- 122,126 ---- derived = pickler.loads(green) self.failUnless(isinstance(derived, tzinfo)) ! self.failUnless(type(derived) is PicklableFixedOffset) self.assertEqual(derived.utcoffset(None), -300) self.assertEqual(derived.tzname(None), 'cookie') *************** *** 1619,1623 **** # Try one with a tzinfo. ! tinfo = FixedOffset(-300, 'cookie') orig = self.theclass(5, 6, 7, tzinfo=tinfo) state = orig.__getstate__() --- 1623,1627 ---- # Try one with a tzinfo. ! tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(5, 6, 7, tzinfo=tinfo) state = orig.__getstate__() *************** *** 1625,1629 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, FixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie') --- 1629,1633 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie') *************** *** 1634,1638 **** derived = pickler.loads(green) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, FixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie') --- 1638,1643 ---- derived = pickler.loads(green) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie') *************** *** 1780,1784 **** # Try one with a tzinfo. ! tinfo = FixedOffset(-300, 'cookie') orig = self.theclass(*args, **{'tzinfo': tinfo}) state = orig.__getstate__() --- 1785,1789 ---- # Try one with a tzinfo. ! tinfo = PicklableFixedOffset(-300, 'cookie') orig = self.theclass(*args, **{'tzinfo': tinfo}) state = orig.__getstate__() *************** *** 1786,1790 **** derived.__setstate__(state) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, FixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie') --- 1791,1795 ---- derived.__setstate__(state) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, PicklableFixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie') *************** *** 1795,1799 **** derived = pickler.loads(green) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, FixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie') --- 1800,1805 ---- derived = pickler.loads(green) self.assertEqual(orig, derived) ! self.failUnless(isinstance(derived.tzinfo, ! PicklableFixedOffset)) self.assertEqual(derived.utcoffset(), -300) self.assertEqual(derived.tzname(), 'cookie')
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4