]> granicus.if.org Git - python/commitdiff
Issue #14180: datetime.date.fromtimestamp(), datetime.datetime.fromtimestamp()
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 13 Mar 2012 23:15:40 +0000 (00:15 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 13 Mar 2012 23:15:40 +0000 (00:15 +0100)
and datetime.datetime.utcfromtimestamp() now raise an OSError instead of
ValueError if localtime() or gmtime() failed.

Doc/library/datetime.rst
Misc/NEWS
Modules/_datetimemodule.c

index d16551e713ac2e070b3269f5dd95fe75a7a08c5e..c8dcbc1596963a0e9440fb9aae33b073c768aae3 100644 (file)
@@ -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)
index b0dab745235eec3f9ad82e81892e07bba02970c9..aee1ad8b3db88097638a1aad834ce9becf313530 100644 (file)
--- 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
index 669170add7d70467ed33c14a64302eb782986013..963a1acdf02421d968fb0432aecf4a4be925a953 100644 (file)
@@ -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.