From 1b6348a85acfbf00d0c1915a0199449d0e2bb0ca Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Mon, 10 Mar 2025 20:22:37 +0000 Subject: [PATCH 1/7] Initial --- Lib/test/test_time.py | 6 ++++++ .../Library/2025-03-10-20-23-00.gh-issue-81267.a39381.rst | 2 ++ Modules/timemodule.c | 8 +++++++- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-03-10-20-23-00.gh-issue-81267.a39381.rst diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 1147997d8d86bf..f8406ea097c9cd 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -167,6 +167,12 @@ def test_sleep_exceptions(self): self.assertRaises(ValueError, time.sleep, -1) self.assertRaises(ValueError, time.sleep, -0.1) + # Improved exception #81267 + with self.assertRaises(TypeError) as errmsg: + time.sleep([]) + self.assertIn("integer or float", str(errmsg.exception)) + + def test_sleep(self): for value in [-0.0, 0, 0.0, 1e-100, 1e-9, 1e-6, 1, 1.2]: with self.subTest(value=value): diff --git a/Misc/NEWS.d/next/Library/2025-03-10-20-23-00.gh-issue-81267.a39381.rst b/Misc/NEWS.d/next/Library/2025-03-10-20-23-00.gh-issue-81267.a39381.rst new file mode 100644 index 00000000000000..9c9a86d30e2450 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-03-10-20-23-00.gh-issue-81267.a39381.rst @@ -0,0 +1,2 @@ +Correct :func:`time.sleep` error message when an object that cannot be interpreted +as an integer or float is provided. diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 1bfbf3f6a0b991..74408f57c3365c 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -398,8 +398,14 @@ time_sleep(PyObject *self, PyObject *timeout_obj) } PyTime_t timeout; - if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) + if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + const char *type_name = Py_TYPE(timeout_obj)->tp_name; + PyObject* msg = PyUnicode_FromFormat("'%s' object cannot be interpreted as an integer or float", type_name); + PyErr_SetString(PyExc_TypeError, PyUnicode_AsUTF8(msg)); + } return NULL; + } if (timeout < 0) { PyErr_SetString(PyExc_ValueError, "sleep length must be non-negative"); From 7b99519365c5a8c1f79c132daa434b90987d1f05 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Tue, 11 Mar 2025 16:32:16 +0000 Subject: [PATCH 2/7] Update Modules/timemodule.c Co-authored-by: Victor Stinner --- Modules/timemodule.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 74408f57c3365c..33aad7142fff62 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -400,9 +400,9 @@ time_sleep(PyObject *self, PyObject *timeout_obj) PyTime_t timeout; if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { - const char *type_name = Py_TYPE(timeout_obj)->tp_name; - PyObject* msg = PyUnicode_FromFormat("'%s' object cannot be interpreted as an integer or float", type_name); - PyErr_SetString(PyExc_TypeError, PyUnicode_AsUTF8(msg)); + PyErr_Format(PyExc_TypeError, + "'%T' object cannot be interpreted as an integer or float", + timeout_obj); } return NULL; } From 8ba9ffd0d4e3c01ebd9161c899aa317659753b74 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 11 Mar 2025 16:45:35 +0000 Subject: [PATCH 3/7] Move implementation to pytime --- Modules/timemodule.c | 5 ----- Python/pytime.c | 34 +++++++++++++++++++--------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 33aad7142fff62..788e9af18adc27 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -399,11 +399,6 @@ time_sleep(PyObject *self, PyObject *timeout_obj) PyTime_t timeout; if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) { - if (PyErr_ExceptionMatches(PyExc_TypeError)) { - PyErr_Format(PyExc_TypeError, - "'%T' object cannot be interpreted as an integer or float", - timeout_obj); - } return NULL; } if (timeout < 0) { diff --git a/Python/pytime.c b/Python/pytime.c index b10d5cf927b7e1..9578488d4bef70 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -594,26 +594,30 @@ pytime_from_object(PyTime_t *tp, PyObject *obj, _PyTime_round_t round, } return pytime_from_double(tp, d, round, unit_to_ns); } - else { - long long sec = PyLong_AsLongLong(obj); - if (sec == -1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - pytime_overflow(); - } - return -1; - } - static_assert(sizeof(long long) <= sizeof(PyTime_t), - "PyTime_t is smaller than long long"); - PyTime_t ns = (PyTime_t)sec; - if (pytime_mul(&ns, unit_to_ns) < 0) { + long long sec = PyLong_AsLongLong(obj); + if (sec == -1 && PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { pytime_overflow(); - return -1; } + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_Format(PyExc_TypeError, + "'%T' object cannot be interpreted as an integer or float", + obj); + } + return -1; + } - *tp = ns; - return 0; + static_assert(sizeof(long long) <= sizeof(PyTime_t), + "PyTime_t is smaller than long long"); + PyTime_t ns = (PyTime_t)sec; + if (pytime_mul(&ns, unit_to_ns) < 0) { + pytime_overflow(); + return -1; } + + *tp = ns; + return 0; } From d7e9e003b955914f9ee79a134143b0d4cd456933 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Wed, 12 Mar 2025 07:40:31 +0000 Subject: [PATCH 4/7] Victors suggestions --- Modules/timemodule.c | 3 +-- Python/pytime.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 788e9af18adc27..1bfbf3f6a0b991 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -398,9 +398,8 @@ time_sleep(PyObject *self, PyObject *timeout_obj) } PyTime_t timeout; - if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) { + if (_PyTime_FromSecondsObject(&timeout, timeout_obj, _PyTime_ROUND_TIMEOUT)) return NULL; - } if (timeout < 0) { PyErr_SetString(PyExc_ValueError, "sleep length must be non-negative"); diff --git a/Python/pytime.c b/Python/pytime.c index 9578488d4bef70..03ab5bc00e2de5 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -600,7 +600,7 @@ pytime_from_object(PyTime_t *tp, PyObject *obj, _PyTime_round_t round, if (PyErr_ExceptionMatches(PyExc_OverflowError)) { pytime_overflow(); } - if (PyErr_ExceptionMatches(PyExc_TypeError)) { + else if (PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Format(PyExc_TypeError, "'%T' object cannot be interpreted as an integer or float", obj); From 6848fc49d77d53b6cbb8b4373840377dba34bf58 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Mar 2025 08:45:14 +0100 Subject: [PATCH 5/7] Update Python/pytime.c --- Python/pytime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Python/pytime.c b/Python/pytime.c index 03ab5bc00e2de5..2ca92037c2e2f1 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -602,8 +602,8 @@ pytime_from_object(PyTime_t *tp, PyObject *obj, _PyTime_round_t round, } else if (PyErr_ExceptionMatches(PyExc_TypeError)) { PyErr_Format(PyExc_TypeError, - "'%T' object cannot be interpreted as an integer or float", - obj); + "'%T' object cannot be interpreted as an integer or float", + obj); } return -1; } From 1a7949092e76667d61d32c054692f4a51f7e5146 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Mar 2025 08:47:35 +0100 Subject: [PATCH 6/7] Update Lib/test/test_time.py --- Lib/test/test_time.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index f8406ea097c9cd..d676d18756c7c8 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -171,8 +171,6 @@ def test_sleep_exceptions(self): with self.assertRaises(TypeError) as errmsg: time.sleep([]) self.assertIn("integer or float", str(errmsg.exception)) - - def test_sleep(self): for value in [-0.0, 0, 0.0, 1e-100, 1e-9, 1e-6, 1, 1.2]: with self.subTest(value=value): From 3b4d0a0aff19d5cece2d3bbc9d91e9cecb84307c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 12 Mar 2025 08:48:13 +0100 Subject: [PATCH 7/7] Update Lib/test/test_time.py --- Lib/test/test_time.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index d676d18756c7c8..cd6c08f183ff95 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -171,6 +171,7 @@ def test_sleep_exceptions(self): with self.assertRaises(TypeError) as errmsg: time.sleep([]) self.assertIn("integer or float", str(errmsg.exception)) + def test_sleep(self): for value in [-0.0, 0, 0.0, 1e-100, 1e-9, 1e-6, 1, 1.2]: with self.subTest(value=value):