[pypy-commit] pypy default: clean up datetime argument handling, improve tests
bdkearns
noreply at buildbot.pypy.org
Sat Feb 9 01:54:15 CET 2013
Author: Brian Kearns <bdkearns at gmail.com>
Branch:
Changeset: r60995:72e79a8305c7
Date: 2013-02-08 19:52 -0500
http://bitbucket.org/pypy/pypy/changeset/72e79a8305c7/
Log: clean up datetime argument handling, improve tests
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -18,6 +18,7 @@
import time as _time
import math as _math
+import decimal as _decimal
MINYEAR = 1
MAXYEAR = 9999
@@ -270,10 +271,15 @@
return offset
raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))
+def _check_int_field(value):
+ if not isinstance(value, (int, long, _decimal.Decimal)):
+ raise TypeError('integer argument expected')
+ return int(value)
+
def _check_date_fields(year, month, day):
- for value in [year, day]:
- if not isinstance(value, (int, long)):
- raise TypeError('int expected')
+ year = _check_int_field(year)
+ month = _check_int_field(month)
+ day = _check_int_field(day)
if not MINYEAR <= year <= MAXYEAR:
raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
if not 1 <= month <= 12:
@@ -281,11 +287,13 @@
dim = _days_in_month(year, month)
if not 1 <= day <= dim:
raise ValueError('day must be in 1..%d' % dim, day)
+ return year, month, day
def _check_time_fields(hour, minute, second, microsecond):
- for value in [hour, minute, second, microsecond]:
- if not isinstance(value, (int, long)):
- raise TypeError('int expected')
+ hour = _check_int_field(hour)
+ minute = _check_int_field(minute)
+ second = _check_int_field(second)
+ microsecond = _check_int_field(microsecond)
if not 0 <= hour <= 23:
raise ValueError('hour must be in 0..23', hour)
if not 0 <= minute <= 59:
@@ -294,6 +302,7 @@
raise ValueError('second must be in 0..59', second)
if not 0 <= microsecond <= 999999:
raise ValueError('microsecond must be in 0..999999', microsecond)
+ return hour, minute, second, microsecond
def _check_tzinfo_arg(tz):
if tz is not None and not isinstance(tz, tzinfo):
@@ -768,7 +777,7 @@
self = object.__new__(cls)
self.__setstate(year)
return self
- _check_date_fields(year, month, day)
+ year, month, day = _check_date_fields(year, month, day)
self = object.__new__(cls)
self._year = year
self._month = month
@@ -889,7 +898,7 @@
month = self._month
if day is None:
day = self._day
- _check_date_fields(year, month, day)
+ year, month, day = _check_date_fields(year, month, day)
return date(year, month, day)
# Comparisons of date objects with other.
@@ -1150,13 +1159,14 @@
second, microsecond (default to zero)
tzinfo (default to None)
"""
- self = object.__new__(cls)
if isinstance(hour, str):
# Pickle support
+ self = object.__new__(cls)
self.__setstate(hour, minute or None)
return self
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_check_tzinfo_arg(tzinfo)
- _check_time_fields(hour, minute, second, microsecond)
+ self = object.__new__(cls)
self._hour = hour
self._minute = minute
self._second = second
@@ -1387,7 +1397,7 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- _check_time_fields(hour, minute, second, microsecond)
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_check_tzinfo_arg(tzinfo)
return time(hour, minute, second, microsecond, tzinfo)
@@ -1449,10 +1459,10 @@
self = date.__new__(cls, year[:4])
self.__setstate(year, month)
return self
+ year, month, day = _check_date_fields(year, month, day)
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_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 = object.__new__(cls)
self._year = year
self._month = month
self._day = day
@@ -1617,8 +1627,8 @@
microsecond = self.microsecond
if tzinfo is True:
tzinfo = self.tzinfo
- _check_date_fields(year, month, day)
- _check_time_fields(hour, minute, second, microsecond)
+ year, month, day = _check_date_fields(year, month, day)
+ hour, minute, second, microsecond = _check_time_fields(hour, minute, second, microsecond)
_check_tzinfo_arg(tzinfo)
return datetime(year, month, day, hour, minute, second,
microsecond, tzinfo)
diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py
--- a/pypy/module/test_lib_pypy/test_datetime.py
+++ b/pypy/module/test_lib_pypy/test_datetime.py
@@ -30,14 +30,40 @@
dt = datetime.datetime.utcfromtimestamp(0)
assert isinstance(dt.microsecond, int)
+def test_default_args():
+ with py.test.raises(TypeError):
+ datetime.datetime()
+ with py.test.raises(TypeError):
+ datetime.datetime(10)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10)
+ datetime.datetime(10, 10, 10)
-def test_integer_args():
+def test_check_arg_types():
+ import decimal
+ i10 = 10
+ l10 = 10L
+ d10 = decimal.Decimal(10)
+ d11 = decimal.Decimal(10.9)
+ assert datetime.datetime(i10, i10, i10, i10, i10, i10, i10) == \
+ datetime.datetime(l10, l10, l10, l10, l10, l10, l10) == \
+ datetime.datetime(d10, d10, d10, d10, d10, d10, d10) == \
+ datetime.datetime(d11, d11, d11, d11, d11, d11, d11)
+
+ with py.test.raises(TypeError):
+ datetime.datetime(10., 10, 10)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10., 10)
with py.test.raises(TypeError):
datetime.datetime(10, 10, 10.)
with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10.)
+ with py.test.raises(TypeError):
datetime.datetime(10, 10, 10, 10, 10.)
with py.test.raises(TypeError):
datetime.datetime(10, 10, 10, 10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10, 10, 10, 10.)
def test_utcnow_microsecond():
dt = datetime.datetime.utcnow()
More information about the pypy-commit
mailing list