[Python-checkins] r82065 - sandbox/branches/py3k-datetime/datetime.py
alexander.belopolsky
python-checkins at python.org
Fri Jun 18 03:18:47 CEST 2010
Author: alexander.belopolsky
Date: Fri Jun 18 03:18:47 2010
New Revision: 82065
Log:
Applied changes from PyPy. The result passes original tests.
See http://codespeak.net/pypy/dist/pypy/lib/datetime.py
Modified:
sandbox/branches/py3k-datetime/datetime.py
Modified: sandbox/branches/py3k-datetime/datetime.py
==============================================================================
--- sandbox/branches/py3k-datetime/datetime.py (original)
+++ sandbox/branches/py3k-datetime/datetime.py Fri Jun 18 03:18:47 2010
@@ -12,6 +12,8 @@
Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm
+This was originally copied from the sandbox of the CPython CVS repository.
+Thanks to Tim Peters for suggesting using it.
"""
import time as _time
@@ -575,9 +577,11 @@
def __add__(self, other):
if isinstance(other, timedelta):
- return self.__class__(self.__days + other.__days,
- self.__seconds + other.__seconds,
- self.__microseconds + other.__microseconds)
+ # for CPython compatibility, we cannot use
+ # our __class__ here, but need a real timedelta
+ return timedelta(self.__days + other.__days,
+ self.__seconds + other.__seconds,
+ self.__microseconds + other.__microseconds)
return NotImplemented
__radd__ = __add__
@@ -593,9 +597,11 @@
return NotImplemented
def __neg__(self):
- return self.__class__(-self.__days,
- -self.__seconds,
- -self.__microseconds)
+ # for CPython compatibility, we cannot use
+ # our __class__ here, but need a real timedelta
+ return timedelta(-self.__days,
+ -self.__seconds,
+ -self.__microseconds)
def __pos__(self):
return self
@@ -608,9 +614,11 @@
def __mul__(self, other):
if isinstance(other, (int, long)):
- return self.__class__(self.__days * other,
- self.__seconds * other,
- self.__microseconds * other)
+ # for CPython compatibility, we cannot use
+ # our __class__ here, but need a real timedelta
+ return timedelta(self.__days * other,
+ self.__seconds * other,
+ self.__microseconds * other)
return NotImplemented
__rmul__ = __mul__
@@ -619,7 +627,7 @@
if isinstance(other, (int, long)):
usec = ((self.__days * (24*3600L) + self.__seconds) * 1000000 +
self.__microseconds)
- return self.__class__(0, 0, usec // other)
+ return timedelta(0, 0, usec // other)
return NotImplemented
__floordiv__ = __div__
@@ -728,7 +736,7 @@
if isinstance(year, str):
# Pickle support
self = object.__new__(cls)
- self.__setstate((year,))
+ self.__setstate(year)
return self
_check_date_fields(year, month, day)
self = object.__new__(cls)
@@ -901,7 +909,7 @@
self.__month,
self.__day + other.days)
self._checkOverflow(t.year)
- result = self.__class__(t.year, t.month, t.day)
+ result = date(t.year, t.month, t.day)
return result
raise TypeError
# XXX Should be 'return NotImplemented', but there's a bug in 2.2...
@@ -964,10 +972,9 @@
yhi, ylo = divmod(self.__year, 256)
return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), )
- def __setstate(self, t):
- assert isinstance(t, tuple) and len(t) == 1, `t`
- string = t[0]
- assert len(string) == 4
+ def __setstate(self, string):
+ if len(string) != 4 or not (1 <= ord(string[2]) <= 12):
+ raise TypeError("not enough arguments")
yhi, ylo, self.__month, self.__day = map(ord, string)
self.__year = yhi * 256 + ylo
@@ -1090,7 +1097,7 @@
self = object.__new__(cls)
if isinstance(hour, str):
# Pickle support
- self.__setstate((hour, minute or None))
+ self.__setstate(hour, minute or None)
return self
_check_tzinfo_arg(tzinfo)
_check_time_fields(hour, minute, second, microsecond)
@@ -1328,21 +1335,16 @@
else:
return (basestate, self._tzinfo)
- def __setstate(self, state):
- assert isinstance(state, tuple)
- assert 1 <= len(state) <= 2
- string = state[0]
- assert len(string) == 6
+ def __setstate(self, string, tzinfo):
+ if len(string) != 6 or ord(string[0]) >= 24:
+ raise TypeError("an integer is required")
self.__hour, self.__minute, self.__second, us1, us2, us3 = \
map(ord, string)
self.__microsecond = (((us1 << 8) | us2) << 8) | us3
- if len(state) == 1:
- self._tzinfo = None
- else:
- self._tzinfo = state[1]
+ self._tzinfo = tzinfo
def __reduce__(self):
- return (self.__class__, self.__getstate())
+ return (time, self.__getstate())
_time_class = time # so functions w/ args named "time" can get at the class
@@ -1360,7 +1362,7 @@
if isinstance(year, str):
# Pickle support
self = date.__new__(cls, year[:4])
- self.__setstate((year, month))
+ self.__setstate(year, month)
return self
_check_tzinfo_arg(tzinfo)
_check_time_fields(hour, minute, second, microsecond)
@@ -1395,6 +1397,10 @@
converter = _time.localtime
else:
converter = _time.gmtime
+ if 1 - (t % 1.0) < 0.000001:
+ t = float(int(t)) + 1
+ if t < 0:
+ t -= 1
y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
us = int((t % 1.0) * 1000000)
ss = min(ss, 59) # clamp out leap seconds if the platform has them
@@ -1406,6 +1412,10 @@
def utcfromtimestamp(cls, t):
"Construct a UTC datetime from a POSIX timestamp (like time.time())."
+ if 1 - (t % 1.0) < 0.000001:
+ t = float(int(t)) + 1
+ if t < 0:
+ t -= 1
y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t)
us = int((t % 1.0) * 1000000)
ss = min(ss, 59) # clamp out leap seconds if the platform has them
@@ -1559,8 +1569,10 @@
"Convert to formal string, for repr()."
L = [self.__year, self.__month, self.__day, # These are never zero
self.__hour, self.__minute, self.__second, self.__microsecond]
- while L[-1] == 0:
+ if L[-1] == 0:
del L[-1]
+ if L[-1] == 0:
+ del L[-1]
s = ", ".join(map(str, L))
s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s)
if self._tzinfo is not None:
@@ -1572,6 +1584,11 @@
"Convert to string, for str()."
return self.isoformat(sep=' ')
+ @classmethod
+ def strptime(cls, date_string, format):
+ 'string, format -> new datetime parsed from a string (like time.strptime()).'
+ return cls(*_time.strptime(date_string, format)[0:6])
+
def utcoffset(self):
"""Return the timezone offset in minutes east of UTC (negative west of
UTC)."""
@@ -1624,7 +1641,7 @@
def __eq__(self, other):
if isinstance(other, datetime):
return self.__cmp(other) == 0
- elif hasattr(other, "timetuple"):
+ elif hasattr(other, "timetuple") and not isinstance(other, date):
return NotImplemented
else:
return False
@@ -1632,7 +1649,7 @@
def __ne__(self, other):
if isinstance(other, datetime):
return self.__cmp(other) != 0
- elif hasattr(other, "timetuple"):
+ elif hasattr(other, "timetuple") and not isinstance(other, date):
return NotImplemented
else:
return True
@@ -1640,7 +1657,7 @@
def __le__(self, other):
if isinstance(other, datetime):
return self.__cmp(other) <= 0
- elif hasattr(other, "timetuple"):
+ elif hasattr(other, "timetuple") and not isinstance(other, date):
return NotImplemented
else:
_cmperror(self, other)
@@ -1648,7 +1665,7 @@
def __lt__(self, other):
if isinstance(other, datetime):
return self.__cmp(other) < 0
- elif hasattr(other, "timetuple"):
+ elif hasattr(other, "timetuple") and not isinstance(other, date):
return NotImplemented
else:
_cmperror(self, other)
@@ -1656,7 +1673,7 @@
def __ge__(self, other):
if isinstance(other, datetime):
return self.__cmp(other) >= 0
- elif hasattr(other, "timetuple"):
+ elif hasattr(other, "timetuple") and not isinstance(other, date):
return NotImplemented
else:
_cmperror(self, other)
@@ -1664,7 +1681,7 @@
def __gt__(self, other):
if isinstance(other, datetime):
return self.__cmp(other) > 0
- elif hasattr(other, "timetuple"):
+ elif hasattr(other, "timetuple") and not isinstance(other, date):
return NotImplemented
else:
_cmperror(self, other)
@@ -1712,7 +1729,7 @@
self.__second + other.seconds,
self.__microsecond + other.microseconds)
self._checkOverflow(t.year)
- result = self.__class__(t.year, t.month, t.day,
+ result = datetime(t.year, t.month, t.day,
t.hour, t.minute, t.second,
t.microsecond, tzinfo=self._tzinfo)
return result
@@ -1767,19 +1784,12 @@
else:
return (basestate, self._tzinfo)
- def __setstate(self, state):
- assert isinstance(state, tuple)
- assert 1 <= len(state) <= 2
- string = state[0]
- assert len(string) == 10
+ def __setstate(self, string, tzinfo):
(yhi, ylo, self.__month, self.__day, self.__hour,
self.__minute, self.__second, us1, us2, us3) = map(ord, string)
self.__year = yhi * 256 + ylo
self.__microsecond = (((us1 << 8) | us2) << 8) | us3
- if len(state) == 1:
- self._tzinfo = None
- else:
- self._tzinfo = state[1]
+ self._tzinfo = tzinfo
def __reduce__(self):
return (self.__class__, self.__getstate())
@@ -1999,9 +2009,3 @@
pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
"""
-def _test():
- import test_datetime
- test_datetime.test_main()
-
-if __name__ == "__main__":
- _test()
More information about the Python-checkins
mailing list