Kaydet (Commit) 21f58935 authored tarafından Victor Stinner's avatar Victor Stinner

Issue #14180: datetime.date.fromtimestamp(), datetime.datetime.fromtimestamp()

and datetime.datetime.utcfromtimestamp() now raise an OSError instead of
ValueError if localtime() or gmtime() failed.
üst 910df329
...@@ -404,7 +404,8 @@ Other constructors, all class methods: ...@@ -404,7 +404,8 @@ Other constructors, all class methods:
.. versionchanged:: 3.3 .. versionchanged:: 3.3
Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp
is out of the range of values supported by the platform C is out of the range of values supported by the platform C
:c:func:`localtime` function. :c:func:`localtime` function. Raise :exc:`OSError` instead of
:exc:`ValueError` on :c:func:`localtime` failure.
.. classmethod:: date.fromordinal(ordinal) .. classmethod:: date.fromordinal(ordinal)
...@@ -720,7 +721,9 @@ Other constructors, all class methods: ...@@ -720,7 +721,9 @@ Other constructors, all class methods:
.. versionchanged:: 3.3 .. versionchanged:: 3.3
Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp
is out of the range of values supported by the platform C is out of the range of values supported by the platform C
:c:func:`localtime` or :c:func:`gmtime` functions :c:func:`localtime` or :c:func:`gmtime` functions. Raise :exc:`OSError`
instead of :exc:`ValueError` on :c:func:`localtime` or :c:func:`gmtime`
failure.
.. classmethod:: datetime.utcfromtimestamp(timestamp) .. classmethod:: datetime.utcfromtimestamp(timestamp)
...@@ -750,7 +753,8 @@ Other constructors, all class methods: ...@@ -750,7 +753,8 @@ Other constructors, all class methods:
.. versionchanged:: 3.3 .. versionchanged:: 3.3
Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp
is out of the range of values supported by the platform C is out of the range of values supported by the platform C
:c:func:`gmtime` function. :c:func:`gmtime` function. Raise :exc:`OSError` instead of
:exc:`ValueError` on :c:func:`gmtime` failure.
.. classmethod:: datetime.fromordinal(ordinal) .. classmethod:: datetime.fromordinal(ordinal)
......
...@@ -33,6 +33,10 @@ Library ...@@ -33,6 +33,10 @@ Library
- Issue #14184: Increase the default stack size for secondary threads on - Issue #14184: Increase the default stack size for secondary threads on
Mac OS X to avoid interpreter crashes when using threads on 10.7. Mac OS X to avoid interpreter crashes when using threads on 10.7.
- Issue #14180: datetime.date.fromtimestamp(),
datetime.datetime.fromtimestamp() and datetime.datetime.utcfromtimestamp()
now raise an OSError instead of ValueError if localtime() or gmtime() failed.
- Issue #14180: time.ctime(), gmtime(), time.localtime(), - Issue #14180: time.ctime(), gmtime(), time.localtime(),
datetime.date.fromtimestamp(), datetime.datetime.fromtimestamp() and datetime.date.fromtimestamp(), datetime.datetime.fromtimestamp() and
datetime.datetime.utcfromtimestamp() now raises an OverflowError, instead of datetime.datetime.utcfromtimestamp() now raises an OverflowError, instead of
......
...@@ -2443,22 +2443,25 @@ date_local_from_object(PyObject *cls, PyObject *obj) ...@@ -2443,22 +2443,25 @@ date_local_from_object(PyObject *cls, PyObject *obj)
{ {
struct tm *tm; struct tm *tm;
time_t t; time_t t;
PyObject *result = NULL;
if (_PyTime_ObjectToTime_t(obj, &t) == -1) if (_PyTime_ObjectToTime_t(obj, &t) == -1)
return NULL; return NULL;
tm = localtime(&t); tm = localtime(&t);
if (tm) if (tm == NULL) {
result = PyObject_CallFunction(cls, "iii", /* unconvertible time */
#ifdef EINVAL
if (errno == 0)
errno = EINVAL;
#endif
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
return PyObject_CallFunction(cls, "iii",
tm->tm_year + 1900, tm->tm_year + 1900,
tm->tm_mon + 1, tm->tm_mon + 1,
tm->tm_mday); tm->tm_mday);
else
PyErr_SetString(PyExc_ValueError,
"timestamp out of range for "
"platform localtime() function");
return result;
} }
/* Return new date from current time. /* Return new date from current time.
...@@ -4057,10 +4060,16 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, ...@@ -4057,10 +4060,16 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
PyObject *tzinfo) PyObject *tzinfo)
{ {
struct tm *tm; struct tm *tm;
PyObject *result = NULL;
tm = f(&timet); tm = f(&timet);
if (tm) { if (tm == NULL) {
#ifdef EINVAL
if (errno == 0)
errno = EINVAL;
#endif
return PyErr_SetFromErrno(PyExc_OSError);
}
/* The platform localtime/gmtime may insert leap seconds, /* The platform localtime/gmtime may insert leap seconds,
* indicated by tm->tm_sec > 59. We don't care about them, * indicated by tm->tm_sec > 59. We don't care about them,
* except to the extent that passing them on to the datetime * except to the extent that passing them on to the datetime
...@@ -4069,7 +4078,7 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, ...@@ -4069,7 +4078,7 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
*/ */
if (tm->tm_sec > 59) if (tm->tm_sec > 59)
tm->tm_sec = 59; tm->tm_sec = 59;
result = PyObject_CallFunction(cls, "iiiiiiiO", return PyObject_CallFunction(cls, "iiiiiiiO",
tm->tm_year + 1900, tm->tm_year + 1900,
tm->tm_mon + 1, tm->tm_mon + 1,
tm->tm_mday, tm->tm_mday,
...@@ -4078,12 +4087,6 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us, ...@@ -4078,12 +4087,6 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
tm->tm_sec, tm->tm_sec,
us, us,
tzinfo); tzinfo);
}
else
PyErr_SetString(PyExc_ValueError,
"timestamp out of range for "
"platform localtime()/gmtime() function");
return result;
} }
/* Internal helper. /* Internal helper.
...@@ -4102,7 +4105,7 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, ...@@ -4102,7 +4105,7 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1) if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1)
return NULL; return NULL;
return datetime_from_timet_and_us(cls, f, timet, us, tzinfo); return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
} }
/* Internal helper. /* Internal helper.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment