Skip to content

gh-152060: Fix datetime.fromisoformat() raising AssertionError in pure Python#152061

Merged
StanFromIreland merged 2 commits into
python:mainfrom
tonghuaroot:fix-pydatetime-fromisoformat-assertionerror
Jun 24, 2026
Merged

gh-152060: Fix datetime.fromisoformat() raising AssertionError in pure Python#152061
StanFromIreland merged 2 commits into
python:mainfrom
tonghuaroot:fix-pydatetime-fromisoformat-assertionerror

Conversation

@tonghuaroot

@tonghuaroot tonghuaroot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Fixes #152060.

_pydatetime._parse_isoformat_date() asserted that the date portion has length 7, 8 or
10. For some malformed inputs (e.g. '2020-2020', '2020-1234') the separator finder
yields a 9-character date portion, so the assert fires and a bare AssertionError escapes
datetime.fromisoformat(), which is documented to raise only ValueError. The C
accelerator already raises ValueError. Because the check is an assert, the input also
raises ValueError instead under python -O, so the behaviour differed by build flag.

This replaces the assert with an explicit ValueError whose message matches the C
implementation, so both implementations agree on every build. This is the sibling assert
site to the one fixed in #151771 (gh-151770).

date.fromisoformat() already validates the length before calling
_parse_isoformat_date(), so it is unaffected.

A regression test is added to test_fromisoformat_fails_datetime, which runs under both
the C (_Fast) and pure-Python (_Pure) test classes.

…in pure Python

_pydatetime._parse_isoformat_date() asserted the date portion length, leaking
a bare AssertionError out of datetime.fromisoformat() for some malformed
strings (e.g. '2020-2020'), and behaving differently under -O. The C
accelerator already raises ValueError. Replace the assert with an explicit
ValueError so both implementations agree on all builds.
Comment thread Lib/_pydatetime.py Outdated
# 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(f"Invalid isoformat string: {dtstr!r}")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{dtstr!r} won't match the C impl, but it doesn’t matter as fromisoformat re-raises anyway.

Suggested change
raise ValueError(f"Invalid isoformat string: {dtstr!r}")
raise ValueError(f"Invalid isoformat string")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks!

Comment thread Lib/test/datetimetester.py Outdated
'2009-04-19T12:30:45-00:90:00', # Time zone field out from range
'2009-04-19T12:30:45-00:00:90', # Time zone field out from range
'2020-2020', # Ambiguous 9-char date portion
'2020-1234', # Ambiguous 9-char date portion

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'2020-1234', # Ambiguous 9-char date portion

These cases are identical.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks!

@StanFromIreland StanFromIreland added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes labels Jun 24, 2026
@StanFromIreland StanFromIreland merged commit ff781d5 into python:main Jun 24, 2026
103 of 105 checks passed
@miss-islington-app

Copy link
Copy Markdown

Thanks @tonghuaroot for the PR, and @StanFromIreland for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15.
🐍🍒⛏🤖

@bedevere-app

bedevere-app Bot commented Jun 24, 2026

Copy link
Copy Markdown

GH-152081 is a backport of this pull request to the 3.15 branch.

@miss-islington-app

Copy link
Copy Markdown

Sorry, @tonghuaroot and @StanFromIreland, I could not cleanly backport this to 3.14 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker ff781d52d451db56e154aac35ae7f2c41b1695a4 3.14

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Jun 24, 2026
@miss-islington-app

Copy link
Copy Markdown

Sorry, @tonghuaroot and @StanFromIreland, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker ff781d52d451db56e154aac35ae7f2c41b1695a4 3.13

@StanFromIreland

Copy link
Copy Markdown
Member

@tonghuaroot are you able to do the backports?

StanFromIreland pushed a commit that referenced this pull request Jun 24, 2026
…nError` on invalid lengths (GH-152061) (#152081)

(cherry picked from commit ff781d5)

Co-authored-by: tonghuaroot (童话) <tonghuaroot@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

datetime.fromisoformat() raises AssertionError instead of ValueError in the pure-Python implementation

2 participants