[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.152,1.153 test_datetime.py,1.106,1.107
gvanrossum@users.sourceforge.net
gvanrossum@users.sourceforge.net
Wed, 29 Jan 2003 22:01:10 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv29803
Modified Files:
datetime.py test_datetime.py
Log Message:
Experimental support for pickle protocol 2. Classes timedelta, date,
time, and datetime now have a __new__ method instead of __init__.
(Class tzinfo not yet; I'll have to think more about it.) I've added
__getnewargs__ as an alias for __getstate__ for each of these classes.
The state for date is now a tuple (for the others it already was a
tuple).
The test suite now tests protocols 0, 1 and 2; this is the only change
(except one place where the state of a date was compared to a string
literal). It passes for Python 2.2 as well as for Python 2.3.
XXX The pickles are not compatible with those of the C implementation!
XXX But I think the C implementation can be changed to match, and it
XXX will work for all three protocols, in both Python versions.
XXX Fingers crossed. Goodnight.
Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.152
retrieving revision 1.153
diff -C2 -d -r1.152 -r1.153
*** datetime.py 24 Jan 2003 18:56:35 -0000 1.152
--- datetime.py 30 Jan 2003 06:01:06 -0000 1.153
***************
*** 403,409 ****
"""
! def __init__(self, days=0, seconds=0, microseconds=0,
! # XXX The following should only be used as keyword args:
! milliseconds=0, minutes=0, hours=0, weeks=0):
# Doing this efficiently and accurately in C is going to be difficult
# and error-prone, due to ubiquitous overflow possibilities, and that
--- 403,409 ----
"""
! def __new__(cls, days=0, seconds=0, microseconds=0,
! # XXX The following should only be used as keyword args:
! milliseconds=0, minutes=0, hours=0, weeks=0):
# Doing this efficiently and accurately in C is going to be difficult
# and error-prone, due to ubiquitous overflow possibilities, and that
***************
*** 506,509 ****
--- 506,512 ----
assert isinstance(s, int) and 0 <= s < 24*3600
assert isinstance(us, int) and 0 <= us < 1000000
+
+ self = object.__new__(cls)
+
self.__days = d
self.__seconds = s
***************
*** 512,515 ****
--- 515,520 ----
raise OverflowError("timedelta # of days is too large: %d" % d)
+ return self
+
def __repr__(self):
if self.__microseconds:
***************
*** 611,619 ****
__safe_for_unpickling__ = True
- def __reduce__(self):
- return type(self), (), self.__getstate__()
-
def __getstate__(self):
return (self.__days, self.__seconds, self.__microseconds)
def __setstate__(self, tup):
--- 616,622 ----
__safe_for_unpickling__ = True
def __getstate__(self):
return (self.__days, self.__seconds, self.__microseconds)
+ __getnewargs__ = __getstate__
def __setstate__(self, tup):
***************
*** 630,634 ****
Constructors:
! __init__()
fromtimestamp()
today()
--- 633,637 ----
Constructors:
! __new__()
fromtimestamp()
today()
***************
*** 654,658 ****
"""
! def __init__(self, year, month, day):
"""Constructor.
--- 657,661 ----
"""
! def __new__(cls, year, month=None, day=None):
"""Constructor.
***************
*** 661,668 ****
--- 664,678 ----
year, month, day (required, base 1)
"""
+ if isinstance(year, str):
+ # From pickle __getstate__
+ self = object.__new__(cls)
+ self.__setstate__((year,))
+ return self
_check_date_fields(year, month, day)
+ self = object.__new__(cls)
self.__year = year
self.__month = month
self.__day = day
+ return self
# Additional constructors
***************
*** 845,851 ****
def __getstate__(self):
yhi, ylo = divmod(self.__year, 256)
! return "%c%c%c%c" % (yhi, ylo, self.__month, self.__day)
! def __setstate__(self, string):
assert len(string) == 4
yhi, ylo, self.__month, self.__day = map(ord, string)
--- 855,864 ----
def __getstate__(self):
yhi, ylo = divmod(self.__year, 256)
! return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), )
! __getnewargs__ = __getstate__
! def __setstate__(self, t):
! assert isinstance(t, tuple) and len(t) == 1, `t`
! string = t[0]
assert len(string) == 4
yhi, ylo, self.__month, self.__day = map(ord, string)
***************
*** 911,914 ****
--- 924,928 ----
# pickle support
+ # XXX Should do something with __new__ instead
__safe_for_unpickling__ = True
***************
*** 917,920 ****
--- 931,936 ----
return type(self), (), self.__dict__
+ _tzinfo_class = tzinfo # so functions w/ args named "tinfo" can get at it
+
class time(object):
"""Time with time zone.
***************
*** 922,926 ****
Constructors:
! __init__()
Operators:
--- 938,942 ----
Constructors:
! __new__()
Operators:
***************
*** 941,945 ****
"""
! def __init__(self, hour=0, minute=0, second=0, microsecond=0, tzinfo=None):
"""Constructor.
--- 957,961 ----
"""
! def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None):
"""Constructor.
***************
*** 950,953 ****
--- 966,979 ----
tzinfo (default to None)
"""
+ self = object.__new__(cls)
+ if isinstance(hour, str):
+ # Call from protocol 2 unpickling
+ assert len(hour) == 6
+ assert minute == 0 or isinstance(minute, _tzinfo_class), `minute`
+ self.__hour, self.__minute, self.__second, us1, us2, us3 = \
+ map(ord, hour)
+ self.__microsecond = (((us1 << 8) | us2) << 8) | us3
+ self._tzinfo = minute or None
+ return self
_check_tzinfo_arg(tzinfo)
_check_time_fields(hour, minute, second, microsecond)
***************
*** 957,960 ****
--- 983,987 ----
self.__microsecond = microsecond
self._tzinfo = tzinfo
+ return self
# Read-only field accessors
***************
*** 1148,1151 ****
--- 1175,1179 ----
else:
return (basestate, self._tzinfo)
+ __getnewargs__ = __getstate__
def __setstate__(self, state):
***************
*** 1176,1184 ****
# See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo
! def __init__(self, year, month, day, hour=0, minute=0, second=0,
! microsecond=0, tzinfo=None):
_check_tzinfo_arg(tzinfo)
_check_time_fields(hour, minute, second, microsecond)
! date.__init__(self, year, month, day)
# XXX This duplicates __year, __month, __day for convenience :-(
self.__year = year
--- 1204,1217 ----
# See http://www.zope.org/Members/fdrake/DateTimeWiki/TimeZoneInfo
! def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,
! microsecond=0, tzinfo=None):
! if isinstance(year, str):
! # Pickle support
! self = date.__new__(cls, 1, 1, 1)
! self.__setstate__((year, month))
! return self
_check_tzinfo_arg(tzinfo)
_check_time_fields(hour, minute, second, microsecond)
! self = date.__new__(cls, year, month, day)
# XXX This duplicates __year, __month, __day for convenience :-(
self.__year = year
***************
*** 1190,1193 ****
--- 1223,1227 ----
self.__microsecond = microsecond
self._tzinfo = tzinfo
+ return self
# Read-only field accessors
***************
*** 1533,1536 ****
--- 1567,1571 ----
else:
return (basestate, self._tzinfo)
+ __getnewargs__ = __getstate__
def __setstate__(self, state):
***************
*** 1607,1618 ****
self.__setstate__(state)
return self
-
- # Register pickle/unpickle functions.
- from copy_reg import pickle
- pickle(date, _date_pickler, _date_unpickler)
- pickle(tzinfo, _tzinfo_pickler, _tzinfo_unpickler)
- pickle(time, _time_pickler, _time_unpickler)
- pickle(datetime, _datetime_pickler, _datetime_unpickler)
- del pickle
"""
--- 1642,1645 ----
Index: test_datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/test_datetime.py,v
retrieving revision 1.106
retrieving revision 1.107
diff -C2 -d -r1.106 -r1.107
*** test_datetime.py 24 Jan 2003 22:32:27 -0000 1.106
--- test_datetime.py 30 Jan 2003 06:01:07 -0000 1.107
***************
*** 107,112 ****
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)
self.failUnless(type(derived) is tzinfo)
--- 107,112 ----
self.failUnless(type(orig) is tzinfo)
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.failUnless(type(derived) is tzinfo)
***************
*** 123,128 ****
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)
self.failUnless(isinstance(derived, tzinfo))
--- 123,128 ----
self.assertEqual(orig.tzname(None), 'cookie')
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.failUnless(isinstance(derived, tzinfo))
***************
*** 272,277 ****
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for binary in 0, 1:
! green = pickler.dumps(orig, binary)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
--- 272,277 ----
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
***************
*** 826,836 ****
orig = self.theclass(*args)
state = orig.__getstate__()
! self.assertEqual(state, '\x00\x06\x07\x17')
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)
self.assertEqual(orig, derived)
--- 826,836 ----
orig = self.theclass(*args)
state = orig.__getstate__()
! self.assertEqual(state, ('\x00\x06\x07\x17',))
derived = self.theclass(1, 1, 1)
derived.__setstate__(state)
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
***************
*** 1190,1195 ****
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for binary in 0, 1:
! green = pickler.dumps(orig, binary)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
--- 1190,1195 ----
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
***************
*** 1576,1581 ****
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for binary in 0, 1:
! green = pickler.dumps(orig, binary)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
--- 1576,1581 ----
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
***************
*** 1892,1897 ****
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for binary in 0, 1:
! green = pickler.dumps(orig, binary)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
--- 1892,1897 ----
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
***************
*** 1909,1914 ****
for pickler in pickle, cPickle:
! for binary in 0, 1:
! green = pickler.dumps(orig, binary)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
--- 1909,1914 ----
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
***************
*** 2111,2116 ****
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for binary in 0, 1:
! green = pickler.dumps(orig, binary)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
--- 2111,2116 ----
self.assertEqual(orig, derived)
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
***************
*** 2128,2133 ****
for pickler in pickle, cPickle:
! for binary in 0, 1:
! green = pickler.dumps(orig, binary)
derived = pickler.loads(green)
self.assertEqual(orig, derived)
--- 2128,2133 ----
for pickler in pickle, cPickle:
! for proto in 0, 1, 2:
! green = pickler.dumps(orig, proto)
derived = pickler.loads(green)
self.assertEqual(orig, derived)