[Python-checkins] cpython: Issue #22117: Add a new _PyTime_FromSeconds() function

victor.stinner python-checkins at python.org
Fri Apr 3 13:36:57 CEST 2015


https://hg.python.org/cpython/rev/d976683671ba
changeset: 95408:d976683671ba
user: Victor Stinner <victor.stinner at gmail.com>
date: Fri Apr 03 13:10:54 2015 +0200
summary:
 Issue #22117: Add a new _PyTime_FromSeconds() function
Fix also _Py_InitializeEx_Private(): initialize time before initializing
import, import_init() uses the _PyTime API (for thread locks).
files:
 Include/pytime.h | 5 ++++-
 Lib/test/test_time.py | 7 +++++++
 Modules/_testcapimodule.c | 13 +++++++++++++
 Modules/_threadmodule.c | 2 +-
 Python/pylifecycle.c | 6 +++---
 Python/pytime.c | 17 +++++++++++++++++
 6 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/Include/pytime.h b/Include/pytime.h
--- a/Include/pytime.h
+++ b/Include/pytime.h
@@ -66,7 +66,10 @@
 _PyTime_round_t);
 
 
-/* Create a timestamp from a number of nanoseconds (C long). */
+/* Create a timestamp from a number of seconds. */
+PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int ns);
+
+/* Create a timestamp from a number of nanoseconds. */
 PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(PY_LONG_LONG ns);
 
 /* Convert a number of seconds (Python float or int) to a timetamp.
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -731,6 +731,13 @@
 @unittest.skipUnless(_testcapi is not None,
 'need the _testcapi module')
 class TestPyTime_t(unittest.TestCase):
+ def test_FromSeconds(self):
+ from _testcapi import PyTime_FromSeconds
+ for seconds in (0, 3, -456, _testcapi.INT_MAX, _testcapi.INT_MIN):
+ with self.subTest(seconds=seconds):
+ self.assertEqual(PyTime_FromSeconds(seconds),
+ seconds * SEC_TO_NS)
+
 def test_FromSecondsObject(self):
 from _testcapi import PyTime_FromSecondsObject
 
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -3383,6 +3383,18 @@
 }
 
 static PyObject *
+test_pytime_fromseconds(PyObject *self, PyObject *args)
+{
+ int seconds;
+ _PyTime_t ts;
+
+ if (!PyArg_ParseTuple(args, "i", &seconds))
+ return NULL;
+ ts = _PyTime_FromSeconds(seconds);
+ return _PyTime_AsNanosecondsObject(ts);
+}
+
+static PyObject *
 test_pytime_fromsecondsobject(PyObject *self, PyObject *args)
 {
 PyObject *obj;
@@ -3651,6 +3663,7 @@
 return_null_without_error, METH_NOARGS},
 {"return_result_with_error",
 return_result_with_error, METH_NOARGS},
+ {"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS},
 {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS},
 {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS},
 {"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS},
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -101,7 +101,7 @@
 char *kwlist[] = {"blocking", "timeout", NULL};
 int blocking = 1;
 PyObject *timeout_obj = NULL;
- const _PyTime_t unset_timeout = _PyTime_FromNanoseconds(-1000000000);
+ const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
 
 *timeout = unset_timeout ;
 
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -405,15 +405,15 @@
 if (!install_importlib)
 return;
 
+ if (_PyTime_Init() < 0)
+ Py_FatalError("Py_Initialize: can't initialize time");
+
 import_init(interp, sysmod);
 
 /* initialize the faulthandler module */
 if (_PyFaulthandler_Init())
 Py_FatalError("Py_Initialize: can't initialize faulthandler");
 
- if (_PyTime_Init() < 0)
- Py_FatalError("Py_Initialize: can't initialize time");
-
 if (initfsencoding(interp) < 0)
 Py_FatalError("Py_Initialize: unable to load the file system codec");
 
diff --git a/Python/pytime.c b/Python/pytime.c
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -159,6 +159,19 @@
 }
 
 _PyTime_t
+_PyTime_FromSeconds(int seconds)
+{
+ _PyTime_t t;
+ /* ensure that integer overflow cannot happen, int type should have 32
+ bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30
+ bits). */
+ assert((seconds >= 0 && seconds <= _PyTime_MAX / SEC_TO_NS)
+ || (seconds < 0 && seconds >= _PyTime_MIN / SEC_TO_NS));
+ t = (_PyTime_t)seconds * SEC_TO_NS;
+ return t;
+}
+
+_PyTime_t
 _PyTime_FromNanoseconds(PY_LONG_LONG ns)
 {
 _PyTime_t t;
@@ -657,5 +670,9 @@
 /* ensure that the operating system provides a monotonic clock */
 if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
 return -1;
+
+ /* check that _PyTime_FromSeconds() cannot overflow */
+ assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS);
+ assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS);
 return 0;
 }
-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /