mirror of https://github.com/python/cpython
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).
This commit is contained in:
parent
21dfffa218
commit
13019fdef3
|
@ -66,7 +66,10 @@ PyAPI_FUNC(int) _PyTime_ObjectToTimespec(
|
||||||
_PyTime_round_t);
|
_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);
|
PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(PY_LONG_LONG ns);
|
||||||
|
|
||||||
/* Convert a number of seconds (Python float or int) to a timetamp.
|
/* Convert a number of seconds (Python float or int) to a timetamp.
|
||||||
|
|
|
@ -731,6 +731,13 @@ class TestPytime(unittest.TestCase):
|
||||||
@unittest.skipUnless(_testcapi is not None,
|
@unittest.skipUnless(_testcapi is not None,
|
||||||
'need the _testcapi module')
|
'need the _testcapi module')
|
||||||
class TestPyTime_t(unittest.TestCase):
|
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):
|
def test_FromSecondsObject(self):
|
||||||
from _testcapi import PyTime_FromSecondsObject
|
from _testcapi import PyTime_FromSecondsObject
|
||||||
|
|
||||||
|
|
|
@ -3382,6 +3382,18 @@ return_result_with_error(PyObject *self, PyObject *args)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 *
|
static PyObject *
|
||||||
test_pytime_fromsecondsobject(PyObject *self, PyObject *args)
|
test_pytime_fromsecondsobject(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -3651,6 +3663,7 @@ static PyMethodDef TestMethods[] = {
|
||||||
return_null_without_error, METH_NOARGS},
|
return_null_without_error, METH_NOARGS},
|
||||||
{"return_result_with_error",
|
{"return_result_with_error",
|
||||||
return_result_with_error, METH_NOARGS},
|
return_result_with_error, METH_NOARGS},
|
||||||
|
{"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS},
|
||||||
{"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS},
|
{"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS},
|
||||||
{"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS},
|
{"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS},
|
||||||
{"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS},
|
{"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS},
|
||||||
|
|
|
@ -101,7 +101,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds,
|
||||||
char *kwlist[] = {"blocking", "timeout", NULL};
|
char *kwlist[] = {"blocking", "timeout", NULL};
|
||||||
int blocking = 1;
|
int blocking = 1;
|
||||||
PyObject *timeout_obj = NULL;
|
PyObject *timeout_obj = NULL;
|
||||||
const _PyTime_t unset_timeout = _PyTime_FromNanoseconds(-1000000000);
|
const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
|
||||||
|
|
||||||
*timeout = unset_timeout ;
|
*timeout = unset_timeout ;
|
||||||
|
|
||||||
|
|
|
@ -405,15 +405,15 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib)
|
||||||
if (!install_importlib)
|
if (!install_importlib)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (_PyTime_Init() < 0)
|
||||||
|
Py_FatalError("Py_Initialize: can't initialize time");
|
||||||
|
|
||||||
import_init(interp, sysmod);
|
import_init(interp, sysmod);
|
||||||
|
|
||||||
/* initialize the faulthandler module */
|
/* initialize the faulthandler module */
|
||||||
if (_PyFaulthandler_Init())
|
if (_PyFaulthandler_Init())
|
||||||
Py_FatalError("Py_Initialize: can't initialize faulthandler");
|
Py_FatalError("Py_Initialize: can't initialize faulthandler");
|
||||||
|
|
||||||
if (_PyTime_Init() < 0)
|
|
||||||
Py_FatalError("Py_Initialize: can't initialize time");
|
|
||||||
|
|
||||||
if (initfsencoding(interp) < 0)
|
if (initfsencoding(interp) < 0)
|
||||||
Py_FatalError("Py_Initialize: unable to load the file system codec");
|
Py_FatalError("Py_Initialize: unable to load the file system codec");
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,19 @@ _PyTime_overflow(void)
|
||||||
"timestamp too large to convert to C _PyTime_t");
|
"timestamp too large to convert to C _PyTime_t");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_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_t
|
||||||
_PyTime_FromNanoseconds(PY_LONG_LONG ns)
|
_PyTime_FromNanoseconds(PY_LONG_LONG ns)
|
||||||
{
|
{
|
||||||
|
@ -657,5 +670,9 @@ _PyTime_Init(void)
|
||||||
/* ensure that the operating system provides a monotonic clock */
|
/* ensure that the operating system provides a monotonic clock */
|
||||||
if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
|
if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0)
|
||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue