Closes #27710: Disallow fold not in [0, 1] in time and datetime constructors.
This commit is contained in:
parent
95e0df8389
commit
47649ab1f1
|
@ -288,7 +288,7 @@ def _check_date_fields(year, month, day):
|
||||||
raise ValueError('day must be in 1..%d' % dim, day)
|
raise ValueError('day must be in 1..%d' % dim, day)
|
||||||
return year, month, day
|
return year, month, day
|
||||||
|
|
||||||
def _check_time_fields(hour, minute, second, microsecond):
|
def _check_time_fields(hour, minute, second, microsecond, fold):
|
||||||
hour = _check_int_field(hour)
|
hour = _check_int_field(hour)
|
||||||
minute = _check_int_field(minute)
|
minute = _check_int_field(minute)
|
||||||
second = _check_int_field(second)
|
second = _check_int_field(second)
|
||||||
|
@ -301,7 +301,9 @@ def _check_time_fields(hour, minute, second, microsecond):
|
||||||
raise ValueError('second must be in 0..59', second)
|
raise ValueError('second must be in 0..59', second)
|
||||||
if not 0 <= microsecond <= 999999:
|
if not 0 <= microsecond <= 999999:
|
||||||
raise ValueError('microsecond must be in 0..999999', microsecond)
|
raise ValueError('microsecond must be in 0..999999', microsecond)
|
||||||
return hour, minute, second, microsecond
|
if fold not in (0, 1):
|
||||||
|
raise ValueError('fold must be either 0 or 1', fold)
|
||||||
|
return hour, minute, second, microsecond, fold
|
||||||
|
|
||||||
def _check_tzinfo_arg(tz):
|
def _check_tzinfo_arg(tz):
|
||||||
if tz is not None and not isinstance(tz, tzinfo):
|
if tz is not None and not isinstance(tz, tzinfo):
|
||||||
|
@ -1059,8 +1061,8 @@ class time:
|
||||||
self.__setstate(hour, minute or None)
|
self.__setstate(hour, minute or None)
|
||||||
self._hashcode = -1
|
self._hashcode = -1
|
||||||
return self
|
return self
|
||||||
hour, minute, second, microsecond = _check_time_fields(
|
hour, minute, second, microsecond, fold = _check_time_fields(
|
||||||
hour, minute, second, microsecond)
|
hour, minute, second, microsecond, fold)
|
||||||
_check_tzinfo_arg(tzinfo)
|
_check_tzinfo_arg(tzinfo)
|
||||||
self = object.__new__(cls)
|
self = object.__new__(cls)
|
||||||
self._hour = hour
|
self._hour = hour
|
||||||
|
@ -1369,8 +1371,8 @@ class datetime(date):
|
||||||
self._hashcode = -1
|
self._hashcode = -1
|
||||||
return self
|
return self
|
||||||
year, month, day = _check_date_fields(year, month, day)
|
year, month, day = _check_date_fields(year, month, day)
|
||||||
hour, minute, second, microsecond = _check_time_fields(
|
hour, minute, second, microsecond, fold = _check_time_fields(
|
||||||
hour, minute, second, microsecond)
|
hour, minute, second, microsecond, fold)
|
||||||
_check_tzinfo_arg(tzinfo)
|
_check_tzinfo_arg(tzinfo)
|
||||||
self = object.__new__(cls)
|
self = object.__new__(cls)
|
||||||
self._year = year
|
self._year = year
|
||||||
|
|
|
@ -1724,6 +1724,11 @@ class TestDateTime(TestDate):
|
||||||
self.assertRaises(ValueError, self.theclass,
|
self.assertRaises(ValueError, self.theclass,
|
||||||
2000, 1, 31, 23, 59, 59,
|
2000, 1, 31, 23, 59, 59,
|
||||||
1000000)
|
1000000)
|
||||||
|
# bad fold
|
||||||
|
self.assertRaises(ValueError, self.theclass,
|
||||||
|
2000, 1, 31, fold=-1)
|
||||||
|
self.assertRaises(ValueError, self.theclass,
|
||||||
|
2000, 1, 31, fold=2)
|
||||||
# Positional fold:
|
# Positional fold:
|
||||||
self.assertRaises(TypeError, self.theclass,
|
self.assertRaises(TypeError, self.theclass,
|
||||||
2000, 1, 31, 23, 59, 59, 0, None, 1)
|
2000, 1, 31, 23, 59, 59, 0, None, 1)
|
||||||
|
|
|
@ -427,7 +427,7 @@ check_date_args(int year, int month, int day)
|
||||||
* aren't, raise ValueError and return -1.
|
* aren't, raise ValueError and return -1.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
check_time_args(int h, int m, int s, int us)
|
check_time_args(int h, int m, int s, int us, int fold)
|
||||||
{
|
{
|
||||||
if (h < 0 || h > 23) {
|
if (h < 0 || h > 23) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
@ -449,6 +449,11 @@ check_time_args(int h, int m, int s, int us)
|
||||||
"microsecond must be in 0..999999");
|
"microsecond must be in 0..999999");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if (fold != 0 && fold != 1) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"fold must be either 0 or 1");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3598,7 +3603,7 @@ time_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
||||||
if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
|
if (PyArg_ParseTupleAndKeywords(args, kw, "|iiiiO$i", time_kws,
|
||||||
&hour, &minute, &second, &usecond,
|
&hour, &minute, &second, &usecond,
|
||||||
&tzinfo, &fold)) {
|
&tzinfo, &fold)) {
|
||||||
if (check_time_args(hour, minute, second, usecond) < 0)
|
if (check_time_args(hour, minute, second, usecond, fold) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (check_tzinfo_subclass(tzinfo) < 0)
|
if (check_tzinfo_subclass(tzinfo) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3926,8 +3931,14 @@ time_replace(PyDateTime_Time *self, PyObject *args, PyObject *kw)
|
||||||
if (tuple == NULL)
|
if (tuple == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
clone = time_new(Py_TYPE(self), tuple, NULL);
|
clone = time_new(Py_TYPE(self), tuple, NULL);
|
||||||
if (clone != NULL)
|
if (clone != NULL) {
|
||||||
|
if (fold != 0 && fold != 1) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"fold must be either 0 or 1");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
TIME_SET_FOLD(clone, fold);
|
TIME_SET_FOLD(clone, fold);
|
||||||
|
}
|
||||||
Py_DECREF(tuple);
|
Py_DECREF(tuple);
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
@ -4175,7 +4186,7 @@ datetime_new(PyTypeObject *type, PyObject *args, PyObject *kw)
|
||||||
&second, &usecond, &tzinfo, &fold)) {
|
&second, &usecond, &tzinfo, &fold)) {
|
||||||
if (check_date_args(year, month, day) < 0)
|
if (check_date_args(year, month, day) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (check_time_args(hour, minute, second, usecond) < 0)
|
if (check_time_args(hour, minute, second, usecond, fold) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (check_tzinfo_subclass(tzinfo) < 0)
|
if (check_tzinfo_subclass(tzinfo) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -5006,8 +5017,15 @@ datetime_replace(PyDateTime_DateTime *self, PyObject *args, PyObject *kw)
|
||||||
if (tuple == NULL)
|
if (tuple == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
clone = datetime_new(Py_TYPE(self), tuple, NULL);
|
clone = datetime_new(Py_TYPE(self), tuple, NULL);
|
||||||
if (clone != NULL)
|
|
||||||
|
if (clone != NULL) {
|
||||||
|
if (fold != 0 && fold != 1) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"fold must be either 0 or 1");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
DATE_SET_FOLD(clone, fold);
|
DATE_SET_FOLD(clone, fold);
|
||||||
|
}
|
||||||
Py_DECREF(tuple);
|
Py_DECREF(tuple);
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue