From e1d36a5e7f0a4a68967e6ffc68246930297365f4 Mon Sep 17 00:00:00 2001 From: Aaron Thomas <84493696+arxhr007@users.noreply.github.com> Date: Sat, 31 Oct 2026 16:37:57 +0000 Subject: [PATCH] gh-161017: Reject a fraction without a decimal mark in fromisoformat() time.fromisoformat() and datetime.fromisoformat() read digits after the seconds of a basic-format time as a fractional second even without a decimal mark, so "12304512" was accepted by the C implementation but rejected by the pure-Python one. --- Lib/test/datetimetester.py | 5 +++++ .../Library/2026-10-31-16-45-00.gh-issue-161017.Vb4mQz.rst | 5 +++++ Modules/_datetimemodule.c | 3 +++ 3 files changed, 13 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-10-31-16-45-00.gh-issue-161017.Vb4mQz.rst diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 92607e381db20c7..6e936ab7b7f2a37 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3959,6 +3959,8 @@ def test_fromisoformat_fails_datetime(self): '9999-12-31T24:00:00.000000', # Year is invalid after wrapping due to 24:00 '2009-04-19T12:30Z12:00', # Extra time zone info after Z '2009-04-19T12:30:45:334034', # Invalid microsecond separator + '20090419T12304512', # Fraction without decimal mark (basic format) + '2009-04-19T12304512', # Fraction without decimal mark (basic format) '2009-04-19T12:30:45.400 +02:30', # Space between ms and timezone (gh-130959) '2009-04-19T12:30:45.400 ', # Trailing space (gh-130959) '2009-04-19T12:30:45. 400', # Space before fraction (gh-130959) @@ -5306,6 +5308,9 @@ def test_fromisoformat_fails(self): '12:30,5', # Decimal mark at end of minute '12:30:45.123456Z12:00', # Extra time zone info after Z '12:30:45:334034', # Invalid microsecond separator + '12304512', # Fraction without decimal mark (basic format) + '123045123456', # Fraction without decimal mark (basic format) + 'T12304512', # Fraction without decimal mark (basic format) '12:30:45.400 +02:30', # Space between ms and timezone (gh-130959) '12:30:45.400 ', # Trailing space (gh-130959) '12:30:45. 400', # Space before fraction (gh-130959) diff --git a/Misc/NEWS.d/next/Library/2026-10-31-16-45-00.gh-issue-161017.Vb4mQz.rst b/Misc/NEWS.d/next/Library/2026-10-31-16-45-00.gh-issue-161017.Vb4mQz.rst new file mode 100644 index 000000000000000..98db568d2ec4426 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-31-16-45-00.gh-issue-161017.Vb4mQz.rst @@ -0,0 +1,5 @@ +:meth:`datetime.time.fromisoformat` and +:meth:`datetime.datetime.fromisoformat` now reject digits after the seconds +of a time in the basic format when there is no decimal mark, such as +``"12304512"``. The C implementation previously read them as a fractional +second, while the pure-Python implementation rejected them. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 959abcf5e421cf5..790e6decd59a04c 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1045,6 +1045,9 @@ parse_hh_mm_ss_ff(const char *tstr, const char *tstr_end, int *hour, continue; } else if (!has_separator) { + if (i == 2) { + return -4; // Malformed microsecond separator + } --p; } else {