]> granicus.if.org Git - python/commitdiff
Issue #10278: Add an optional strict argument to time.steady(), False by default
authorVictor Stinner <victor.stinner@gmail.com>
Thu, 15 Mar 2012 00:17:09 +0000 (01:17 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Thu, 15 Mar 2012 00:17:09 +0000 (01:17 +0100)
Doc/library/time.rst
Lib/test/test_time.py
Modules/timemodule.c

index 63d45fd0402fab5c37510d80032bf49d30de281d..fcee5513893f85e98b3331778344611644bb1083 100644 (file)
@@ -226,7 +226,7 @@ The module defines the following functions and data items:
    The earliest date for which it can generate a time is platform-dependent.
 
 
-.. function:: steady()
+.. function:: steady(strict=False)
 
    .. index::
       single: benchmarking
@@ -236,6 +236,11 @@ The module defines the following functions and data items:
    adjusted. The reference point of the returned value is undefined so only the
    difference of consecutive calls is valid.
 
+   If available, a monotonic clock is used. By default, if *strict* is False,
+   the function falls back to another clock if the monotonic clock failed or is
+   not available. If *strict* is True, raise an :exc:`OSError` on error or
+   :exc:`NotImplementedError` if no monotonic clock is available.
+
    .. versionadded:: 3.3
 
 
index 2baf066820b6e21c25e654e7c4c13c929bf05b47..28d018afe7a3c6a2faf4ffe42e9d195d2bc4597c 100644 (file)
@@ -340,6 +340,16 @@ class TimeTestCase(unittest.TestCase):
         self.assertGreater(t2, t1)
         self.assertAlmostEqual(dt, 0.1, delta=0.2)
 
+    def test_steady_strict(self):
+        try:
+            t1 = time.steady(strict=True)
+        except OSError as err:
+            self.skipTest("the monotonic clock failed: %s" % err)
+        except NotImplementedError:
+            self.skipTest("no monotonic clock available")
+        t2 = time.steady(strict=True)
+        self.assertGreaterEqual(t2, t1)
+
     def test_localtime_failure(self):
         # Issue #13847: check for localtime() failure
         invalid_time_t = None
index c7efce681a6177988ae65cfcceb002d9dd9be222..e6e1ff400ef9aeef269679b6937828bf8f3572c3 100644 (file)
 
 /* Forward declarations */
 static int floatsleep(double);
-static double floattime(void);
+static PyObject* floattime(void);
 
 static PyObject *
 time_time(PyObject *self, PyObject *unused)
 {
-    double secs;
-    secs = floattime();
-    if (secs == 0.0) {
-        PyErr_SetFromErrno(PyExc_IOError);
-        return NULL;
-    }
-    return PyFloat_FromDouble(secs);
+    return floattime();
 }
 
 PyDoc_STRVAR(time_doc,
@@ -768,11 +762,11 @@ the local timezone used by methods such as localtime, but this behaviour\n\
 should not be relied on.");
 #endif /* HAVE_WORKING_TZSET */
 
-static PyObject *
-time_steady(PyObject *self, PyObject *unused)
+static PyObject*
+steady_clock(int strict)
 {
 #if defined(MS_WINDOWS) && !defined(__BORLANDC__)
-    return win32_clock(1);
+    return win32_clock(!strict);
 #elif defined(__APPLE__)
     uint64_t time = mach_absolute_time();
     double secs;
@@ -806,14 +800,37 @@ time_steady(PyObject *self, PyObject *unused)
         if (Py_ARRAY_LENGTH(clk_ids) <= clk_index)
             clk_index = -1;
     }
-    return time_time(self, NULL);
+    if (strict) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    return floattime();
 #else
-    return time_time(self, NULL);
+    if (strict) {
+        PyErr_SetString(PyExc_NotImplementedError,
+                        "no steady clock available on your platform");
+        return NULL;
+    }
+    return floattime();
 #endif
 }
 
+static PyObject *
+time_steady(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = {"strict", NULL};
+    int strict = 0;
+
+    if (!PyArg_ParseTupleAndKeywords(
+            args, kwargs, "|i:steady", kwlist,
+            &strict))
+        return NULL;
+
+    return steady_clock(strict);
+}
+
 PyDoc_STRVAR(steady_doc,
-"steady() -> float\n\
+"steady(strict=False) -> float\n\
 \n\
 Return the current time as a floating point number expressed in seconds.\n\
 This clock advances at a steady rate relative to real time and it may not\n\
@@ -949,7 +966,8 @@ static PyMethodDef time_methods[] = {
 #ifdef HAVE_MKTIME
     {"mktime",          time_mktime, METH_O, mktime_doc},
 #endif
-    {"steady",          time_steady, METH_NOARGS, steady_doc},
+    {"steady",          (PyCFunction)time_steady, METH_VARARGS|METH_KEYWORDS,
+                        steady_doc},
 #ifdef HAVE_STRFTIME
     {"strftime",        time_strftime, METH_VARARGS, strftime_doc},
 #endif
@@ -1041,12 +1059,18 @@ PyInit_time(void)
     return m;
 }
 
-static double
+static PyObject*
 floattime(void)
 {
     _PyTime_timeval t;
+    double secs;
     _PyTime_gettimeofday(&t);
-    return (double)t.tv_sec + t.tv_usec*0.000001;
+    secs = (double)t.tv_sec + t.tv_usec*0.000001;
+    if (secs == 0.0) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    return PyFloat_FromDouble(secs);
 }