summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2012-03-13 23:15:40 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2012-03-13 23:15:40 (GMT)
commit21f5893571e953aa6042ef686bc2ea539acf39d1 (patch)
tree5fd9b7b5e3e4b696156ecd9213501021fe25be94
parent910df329fd4f4206966e98ddf81ae169e0ca4d1d (diff)
downloadcpython-21f5893571e953aa6042ef686bc2ea539acf39d1.zip
cpython-21f5893571e953aa6042ef686bc2ea539acf39d1.tar.gz
cpython-21f5893571e953aa6042ef686bc2ea539acf39d1.tar.bz2
Issue #14180: datetime.date.fromtimestamp(), datetime.datetime.fromtimestamp()
and datetime.datetime.utcfromtimestamp() now raise an OSError instead of ValueError if localtime() or gmtime() failed.
-rw-r--r--Doc/library/datetime.rst10
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/_datetimemodule.c75
3 files changed, 50 insertions, 39 deletions
diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst
index d16551e..c8dcbc1 100644
--- a/Doc/library/datetime.rst
+++ b/Doc/library/datetime.rst
@@ -404,7 +404,8 @@ Other constructors, all class methods:
.. versionchanged:: 3.3
Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp
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)
@@ -720,7 +721,9 @@ Other constructors, all class methods:
.. versionchanged:: 3.3
Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp
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)
@@ -750,7 +753,8 @@ Other constructors, all class methods:
.. versionchanged:: 3.3
Raise :exc:`OverflowError` instead of :exc:`ValueError` if the timestamp
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)
diff --git a/Misc/NEWS b/Misc/NEWS
index b0dab74..aee1ad8 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -33,6 +33,10 @@ Library
- Issue #14184: Increase the default stack size for secondary threads on
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(),
datetime.date.fromtimestamp(), datetime.datetime.fromtimestamp() and
datetime.datetime.utcfromtimestamp() now raises an OverflowError, instead of
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 669170a..963a1ac 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -2443,22 +2443,25 @@ date_local_from_object(PyObject *cls, PyObject *obj)
{
struct tm *tm;
time_t t;
- PyObject *result = NULL;
if (_PyTime_ObjectToTime_t(obj, &t) == -1)
return NULL;
tm = localtime(&t);
- if (tm)
- result = PyObject_CallFunction(cls, "iii",
- tm->tm_year + 1900,
- tm->tm_mon + 1,
- tm->tm_mday);
- else
- PyErr_SetString(PyExc_ValueError,
- "timestamp out of range for "
- "platform localtime() function");
- return result;
+ if (tm == NULL) {
+ /* 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_mon + 1,
+ tm->tm_mday);
}
/* Return new date from current time.
@@ -4057,33 +4060,33 @@ datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, int us,
PyObject *tzinfo)
{
struct tm *tm;
- PyObject *result = NULL;
tm = f(&timet);
- if (tm) {
- /* The platform localtime/gmtime may insert leap seconds,
- * indicated by tm->tm_sec > 59. We don't care about them,
- * except to the extent that passing them on to the datetime
- * constructor would raise ValueError for a reason that
- * made no sense to the user.
- */
- if (tm->tm_sec > 59)
- tm->tm_sec = 59;
- result = PyObject_CallFunction(cls, "iiiiiiiO",
- tm->tm_year + 1900,
- tm->tm_mon + 1,
- tm->tm_mday,
- tm->tm_hour,
- tm->tm_min,
- tm->tm_sec,
- us,
- tzinfo);
+ if (tm == NULL) {
+#ifdef EINVAL
+ if (errno == 0)
+ errno = EINVAL;
+#endif
+ return PyErr_SetFromErrno(PyExc_OSError);
}
- else
- PyErr_SetString(PyExc_ValueError,
- "timestamp out of range for "
- "platform localtime()/gmtime() function");
- return result;
+
+ /* The platform localtime/gmtime may insert leap seconds,
+ * indicated by tm->tm_sec > 59. We don't care about them,
+ * except to the extent that passing them on to the datetime
+ * constructor would raise ValueError for a reason that
+ * made no sense to the user.
+ */
+ if (tm->tm_sec > 59)
+ tm->tm_sec = 59;
+ return PyObject_CallFunction(cls, "iiiiiiiO",
+ tm->tm_year + 1900,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ us,
+ tzinfo);
}
/* Internal helper.
@@ -4102,7 +4105,7 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
if (_PyTime_ObjectToTimeval(timestamp, &timet, &us) == -1)
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.