From d65624d88c413bb7b4cf6ed97e89a5a63ad6785b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?tonghuaroot=20=28=E7=AB=A5=E8=AF=9D=29?= Date: Wed, 1 Jul 2026 21:32:30 +0800 Subject: [PATCH 1/3] gh-152060: Fix `_pydatetime.fromisoformat()` raising `AssertionError` on invalid lengths (GH-152061) (cherry picked from commit ff781d52d451db56e154aac35ae7f2c41b1695a4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: tonghuaroot (童话) --- Lib/_pydatetime.py | 3 ++- Lib/test/datetimetester.py | 1 + .../Library/2026-06-24-10-46-35.gh-issue-152060.f2asrt.rst | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-06-24-10-46-35.gh-issue-152060.f2asrt.rst diff --git a/Lib/_pydatetime.py b/Lib/_pydatetime.py index b22aa7bd76e2d52..0f95a5750848237 100644 --- a/Lib/_pydatetime.py +++ b/Lib/_pydatetime.py @@ -358,7 +358,8 @@ def _find_isoformat_datetime_separator(dtstr): def _parse_isoformat_date(dtstr): # It is assumed that this is an ASCII-only string of lengths 7, 8 or 10, # see the comment on Modules/_datetimemodule.c:_find_isoformat_datetime_separator - assert len(dtstr) in (7, 8, 10) + if len(dtstr) not in (7, 8, 10): + raise ValueError("Invalid isoformat string") year = int(dtstr[0:4]) has_sep = dtstr[4] == '-' diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 9653a39da26cefd..c67ce5ceca2e94c 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3581,6 +3581,7 @@ def test_fromisoformat_fails_datetime(self): '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) + '2020-2020', # Ambiguous 9-char date portion ] for bad_str in bad_strs: diff --git a/Misc/NEWS.d/next/Library/2026-06-24-10-46-35.gh-issue-152060.f2asrt.rst b/Misc/NEWS.d/next/Library/2026-06-24-10-46-35.gh-issue-152060.f2asrt.rst new file mode 100644 index 000000000000000..6088a6b80829bb4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-24-10-46-35.gh-issue-152060.f2asrt.rst @@ -0,0 +1,3 @@ +Fix :meth:`datetime.datetime.fromisoformat` raising :exc:`AssertionError` +instead of :exc:`ValueError` for some malformed strings in the pure-Python +implementation, matching the C implementation. From 68974da5a2db17079f95808819db62420a2f491c Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Wed, 1 Jul 2026 20:21:05 +0200 Subject: [PATCH 2/3] Apply suggestion from @StanFromIreland --- Lib/test/datetimetester.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index c67ce5ceca2e94c..c40b4bc1f1a44fd 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3581,7 +3581,7 @@ def test_fromisoformat_fails_datetime(self): '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) - '2020-2020', # Ambiguous 9-char date portion + '2020-2020', # Ambiguous 9-char date portion ] for bad_str in bad_strs: From 6a5e81709976d1c7f0c7e54fca26a59713fd24ed Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Wed, 1 Jul 2026 20:21:51 +0200 Subject: [PATCH 3/3] oops one more space --- Lib/test/datetimetester.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index c40b4bc1f1a44fd..0792b14471b9377 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3581,7 +3581,7 @@ def test_fromisoformat_fails_datetime(self): '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) - '2020-2020', # Ambiguous 9-char date portion + '2020-2020', # Ambiguous 9-char date portion ] for bad_str in bad_strs: