cpython: 65ac8e587bb0 (original) (raw)
--- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -21,6 +21,8 @@ SIZEOF_INT = sysconfig.get_config_var('S TIME_MAXYEAR = (1 << 8 * SIZEOF_INT - 1) - 1 TIME_MINYEAR = -TIME_MAXYEAR - 1 +US_TO_NS = 10 ** 3 +MS_TO_NS = 10 ** 6 SEC_TO_NS = 10 ** 9 class _PyTime(enum.IntEnum): @@ -867,10 +869,6 @@ class TestPyTime_t(unittest.TestCase): # seconds (2 * SEC_TO_NS, (2, 0)), (-3 * SEC_TO_NS, (-3, 0)), -
# seconds + nanoseconds[](#l1.17)
(1234567000, (1, 234567)),[](#l1.18)
(-1234567000, (-2, 765433)),[](#l1.19) ):[](#l1.20) with self.subTest(nanoseconds=ns, timeval=tv, round=rnd):[](#l1.21) self.assertEqual(PyTime_AsTimeval(ns, rnd), tv)[](#l1.22)
@@ -914,6 +912,76 @@ class TestPyTime_t(unittest.TestCase): with self.subTest(nanoseconds=ns, timespec=ts): self.assertEqual(PyTime_AsTimespec(ns), ts)
- def test_milliseconds(self):
from _testcapi import PyTime_AsMilliseconds[](#l1.28)
for rnd in ALL_ROUNDING_METHODS:[](#l1.29)
for ns, tv in ([](#l1.30)
# milliseconds[](#l1.31)
(1 * MS_TO_NS, 1),[](#l1.32)
(-2 * MS_TO_NS, -2),[](#l1.33)
# seconds[](#l1.35)
(2 * SEC_TO_NS, 2000),[](#l1.36)
(-3 * SEC_TO_NS, -3000),[](#l1.37)
):[](#l1.38)
with self.subTest(nanoseconds=ns, timeval=tv, round=rnd):[](#l1.39)
self.assertEqual(PyTime_AsMilliseconds(ns, rnd), tv)[](#l1.40)
FLOOR = _PyTime.ROUND_FLOOR[](#l1.42)
CEILING = _PyTime.ROUND_CEILING[](#l1.43)
for ns, ms, rnd in ([](#l1.44)
# nanoseconds[](#l1.45)
(1, 0, FLOOR),[](#l1.46)
(1, 1, CEILING),[](#l1.47)
(-1, 0, FLOOR),[](#l1.48)
(-1, -1, CEILING),[](#l1.49)
# seconds + nanoseconds[](#l1.51)
(1234 * MS_TO_NS + 1, 1234, FLOOR),[](#l1.52)
(1234 * MS_TO_NS + 1, 1235, CEILING),[](#l1.53)
(-1234 * MS_TO_NS - 1, -1234, FLOOR),[](#l1.54)
(-1234 * MS_TO_NS - 1, -1235, CEILING),[](#l1.55)
):[](#l1.56)
with self.subTest(nanoseconds=ns, milliseconds=ms, round=rnd):[](#l1.57)
self.assertEqual(PyTime_AsMilliseconds(ns, rnd), ms)[](#l1.58)
- def test_microseconds(self):
from _testcapi import PyTime_AsMicroseconds[](#l1.61)
for rnd in ALL_ROUNDING_METHODS:[](#l1.62)
for ns, tv in ([](#l1.63)
# microseconds[](#l1.64)
(1 * US_TO_NS, 1),[](#l1.65)
(-2 * US_TO_NS, -2),[](#l1.66)
# milliseconds[](#l1.68)
(1 * MS_TO_NS, 1000),[](#l1.69)
(-2 * MS_TO_NS, -2000),[](#l1.70)
# seconds[](#l1.72)
(2 * SEC_TO_NS, 2000000),[](#l1.73)
(-3 * SEC_TO_NS, -3000000),[](#l1.74)
):[](#l1.75)
with self.subTest(nanoseconds=ns, timeval=tv, round=rnd):[](#l1.76)
self.assertEqual(PyTime_AsMicroseconds(ns, rnd), tv)[](#l1.77)
FLOOR = _PyTime.ROUND_FLOOR[](#l1.79)
CEILING = _PyTime.ROUND_CEILING[](#l1.80)
for ns, ms, rnd in ([](#l1.81)
# nanoseconds[](#l1.82)
(1, 0, FLOOR),[](#l1.83)
(1, 1, CEILING),[](#l1.84)
(-1, 0, FLOOR),[](#l1.85)
(-1, -1, CEILING),[](#l1.86)
# seconds + nanoseconds[](#l1.88)
(1234 * US_TO_NS + 1, 1234, FLOOR),[](#l1.89)
(1234 * US_TO_NS + 1, 1235, CEILING),[](#l1.90)
(-1234 * US_TO_NS - 1, -1234, FLOOR),[](#l1.91)
(-1234 * US_TO_NS - 1, -1235, CEILING),[](#l1.92)
):[](#l1.93)
with self.subTest(nanoseconds=ns, milliseconds=ms, round=rnd):[](#l1.94)
self.assertEqual(PyTime_AsMicroseconds(ns, rnd), ms)[](#l1.95)
+ if name == "main": unittest.main()
--- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3452,6 +3452,42 @@ test_PyTime_AsTimespec(PyObject *self, P } #endif +static PyObject * +test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) +{
- if (!PyArg_ParseTuple(args, "Li", &ns, &round))
return NULL;[](#l2.15)
- if (check_time_rounding(round) < 0)
return NULL;[](#l2.17)
- t = _PyTime_FromNanoseconds(ns);
- ms = _PyTime_AsMilliseconds(t, round);
- /* This conversion rely on the fact that _PyTime_t is a number of
nanoseconds */[](#l2.21)
- return _PyTime_AsNanosecondsObject(ms);
+} + +static PyObject * +test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) +{
- if (!PyArg_ParseTuple(args, "Li", &ns, &round))
return NULL;[](#l2.33)
- if (check_time_rounding(round) < 0)
return NULL;[](#l2.35)
- t = _PyTime_FromNanoseconds(ns);
- ms = _PyTime_AsMicroseconds(t, round);
- /* This conversion rely on the fact that _PyTime_t is a number of
nanoseconds */[](#l2.39)
- return _PyTime_AsNanosecondsObject(ms);
+} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, @@ -3621,6 +3657,8 @@ static PyMethodDef TestMethods[] = { #ifdef HAVE_CLOCK_GETTIME {"PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, #endif
- {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS},
- {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, {NULL, NULL} /* sentinel */ };
--- a/Python/pytime.c +++ b/Python/pytime.c @@ -19,6 +19,10 @@ #define MS_TO_NS (MS_TO_US * US_TO_NS) #define SEC_TO_NS (SEC_TO_MS * MS_TO_NS) +/* Conversion from nanoseconds */ +#define NS_TO_MS (1000 * 1000) +#define NS_TO_US (1000) + static void error_time_t_overflow(void) { @@ -288,33 +292,29 @@ PyObject * } static _PyTime_t -_PyTime_Multiply(_PyTime_t t, unsigned int multiply, _PyTime_round_t round) +_PyTime_Divide(_PyTime_t t, _PyTime_t k, _PyTime_round_t round) {
- _PyTime_t k;
- if (multiply < SEC_TO_NS) {
k = SEC_TO_NS / multiply;[](#l3.23)
if (round == _PyTime_ROUND_CEILING)[](#l3.24)
- assert(k > 1);
- if (round == _PyTime_ROUND_CEILING) {
if (t >= 0)[](#l3.27) return (t + k - 1) / k;[](#l3.28) else[](#l3.29)
return t / k;[](#l3.30)
} _PyTime_t _PyTime_AsMilliseconds(_PyTime_t t, _PyTime_round_t round) {
} -/* FIXME: write unit tests */ _PyTime_t _PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round) {