From d4764cd4bd004b7f647c92f00fbd24697636f838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?tonghuaroot=20=28=E7=AB=A5=E8=AF=9D=29?= Date: Thu, 2 Jul 2026 13:17:29 +0800 Subject: [PATCH 1/4] gh-152849: Fix OverflowError message for out-of-range float timestamps pytime_from_double() converts a float number of seconds to a PyTime_t (nanoseconds) but reported overflow with pytime_time_t_overflow() ("out of range for platform time_t"), naming a type it never uses. The integer path already uses pytime_overflow(); switch the float path to it so both conversion paths report the same PyTime_t overflow. --- Lib/test/test_time.py | 8 ++++++++ .../2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst | 4 ++++ Python/pytime.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 1850f053aaffd6..277d4327616690 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -1013,6 +1013,14 @@ def test_FromSecondsObject(self): with self.assertRaises(ValueError): _PyTime_FromSecondsObject(float('nan'), time_rnd) + def test_FromSecondsObject_float_overflow_message(self): + # Float path must report a PyTime_t overflow, like the integer path. + from _testinternalcapi import _PyTime_FromSecondsObject + for value in (2.0 ** 63, -(2.0 ** 63)): + for time_rnd, _ in ROUNDING_MODES: + with self.assertRaisesRegex(OverflowError, "to C PyTime_t"): + _PyTime_FromSecondsObject(value, time_rnd) + def test_AsSecondsDouble(self): from _testcapi import PyTime_AsSecondsDouble diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst new file mode 100644 index 00000000000000..d06528b68aaf9c --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst @@ -0,0 +1,4 @@ +Fix the :exc:`OverflowError` message raised for an out-of-range float +timestamp (such as a very large :func:`time.sleep` argument): it now reports +the internal ``PyTime_t`` overflow, matching the integer path, instead of a +spurious ``time_t`` overflow. Patch by tonghuaroot. diff --git a/Python/pytime.c b/Python/pytime.c index 399ff59ad01ab6..c6cbdfc2da37fa 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -636,7 +636,7 @@ pytime_from_double(PyTime_t *tp, double value, _PyTime_round_t round, /* See comments in pytime_double_to_denominator */ if (!((double)PyTime_MIN <= d && d < -(double)PyTime_MIN)) { - pytime_time_t_overflow(); + pytime_overflow(); *tp = 0; return -1; } From 453a2bb587312c64f0c83f66b9600f4d879d331f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?tonghuaroot=20=28=E7=AB=A5=E8=AF=9D=29?= Date: Thu, 2 Jul 2026 13:19:58 +0800 Subject: [PATCH 2/4] gh-152849: Trim the NEWS entry --- .../2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst index d06528b68aaf9c..b2f1ab1426ce50 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst @@ -1,4 +1,2 @@ -Fix the :exc:`OverflowError` message raised for an out-of-range float -timestamp (such as a very large :func:`time.sleep` argument): it now reports -the internal ``PyTime_t`` overflow, matching the integer path, instead of a -spurious ``time_t`` overflow. Patch by tonghuaroot. +Fix the :exc:`OverflowError` message for out-of-range float timestamps: it +now names ``PyTime_t`` instead of ``time_t``. Patch by tonghuaroot. From a23c23f966566a8d301a491d2c95213051accf8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?tonghuaroot=20=28=E7=AB=A5=E8=AF=9D=29?= Date: Thu, 2 Jul 2026 15:55:41 +0800 Subject: [PATCH 3/4] gh-152849: Address review comments --- Lib/test/test_time.py | 7 +++++-- .../2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst | 0 Python/pytime.c | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) rename Misc/NEWS.d/next/{Core_and_Builtins => Library}/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst (100%) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 277d4327616690..900a7ef10f79b9 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -1015,10 +1015,13 @@ def test_FromSecondsObject(self): def test_FromSecondsObject_float_overflow_message(self): # Float path must report a PyTime_t overflow, like the integer path. + from _testcapi import PyTime_MIN, PyTime_MAX from _testinternalcapi import _PyTime_FromSecondsObject - for value in (2.0 ** 63, -(2.0 ** 63)): + for value in (float(PyTime_MAX), float(PyTime_MIN)): for time_rnd, _ in ROUNDING_MODES: - with self.assertRaisesRegex(OverflowError, "to C PyTime_t"): + with self.assertRaisesRegex( + OverflowError, + "timestamp out of range for C PyTime_t"): _PyTime_FromSecondsObject(value, time_rnd) def test_AsSecondsDouble(self): diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst b/Misc/NEWS.d/next/Library/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst similarity index 100% rename from Misc/NEWS.d/next/Core_and_Builtins/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst rename to Misc/NEWS.d/next/Library/2026-07-02-13-30-00.gh-issue-152849.K9dRvP.rst diff --git a/Python/pytime.c b/Python/pytime.c index c6cbdfc2da37fa..53c82736137a16 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -107,7 +107,7 @@ static void pytime_overflow(void) { PyErr_SetString(PyExc_OverflowError, - "timestamp too large to convert to C PyTime_t"); + "timestamp out of range for C PyTime_t"); } From 6840090cb96494927945cb8d285efeb556abc58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?tonghuaroot=20=28=E7=AB=A5=E8=AF=9D=29?= Date: Thu, 2 Jul 2026 16:19:26 +0800 Subject: [PATCH 4/4] gh-152849: Use subTest in the overflow message test --- Lib/test/test_time.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 900a7ef10f79b9..5e068c2c02dfd2 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -1019,10 +1019,11 @@ def test_FromSecondsObject_float_overflow_message(self): from _testinternalcapi import _PyTime_FromSecondsObject for value in (float(PyTime_MAX), float(PyTime_MIN)): for time_rnd, _ in ROUNDING_MODES: - with self.assertRaisesRegex( - OverflowError, - "timestamp out of range for C PyTime_t"): - _PyTime_FromSecondsObject(value, time_rnd) + with self.subTest(value=value, time_rnd=time_rnd): + with self.assertRaisesRegex( + OverflowError, + "timestamp out of range for C PyTime_t"): + _PyTime_FromSecondsObject(value, time_rnd) def test_AsSecondsDouble(self): from _testcapi import PyTime_AsSecondsDouble