gh-151770: Fix datetime.fromisoformat() assertion on an out-of-range month with a 24:00 time#151771
Conversation
…range month with a 24:00 time The 24:00 midnight-rollover path validated only the upper month bound before calling days_in_month(), so a month below 1 reached assert(month >= 1) on a debug build (and AssertionError in the pure Python implementation). Add the missing lower bound to both so an out-of-range month consistently raises ValueError.
StanFromIreland
left a comment
There was a problem hiding this comment.
Just a few little nits, the core change is correct.
While we're dealing with this assert, can you please update it (on L58) like so:
- assert 1 <= month <= 12, month
+ assert 1 <= month <= 12, f"month must be in 1..12, not {month}"| Fix :meth:`datetime.datetime.fromisoformat` raising an unexpected error on an | ||
| out-of-range month combined with a ``24:00`` time, such as | ||
| ``"2009-00-01T24:00:00"``. It now consistently raises :exc:`ValueError`. |
There was a problem hiding this comment.
| Fix :meth:`datetime.datetime.fromisoformat` raising an unexpected error on an | |
| out-of-range month combined with a ``24:00`` time, such as | |
| ``"2009-00-01T24:00:00"``. It now consistently raises :exc:`ValueError`. | |
| Fix :meth:`datetime.datetime.fromisoformat` raising :exc:`AssertionError` | |
| instead of :exc:`ValueError` for an out-of-range month combined with a | |
| ``24:00`` time. |
| "2009-04-01T12:30:90", # Second out of range | ||
| "2009-04-01T12:90:45", # Minute out of range | ||
| "2009-04-01T25:30:45", # Hour out of range | ||
| "2009-00-01T24:00:00", # Month out of range (below) |
There was a problem hiding this comment.
| "2009-00-01T24:00:00", # Month out of range (below) | |
| "2009-00-01T24:00:00", # Month below range |
|
Thanks @StanFromIreland — applied all three. |
|
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. |
|
GH-151809 is a backport of this pull request to the 3.15 branch. |
|
Sorry, @tonghuaroot and @StanFromIreland, I could not cleanly backport this to |
|
GH-151810 is a backport of this pull request to the 3.14 branch. |
|
@tonghuaroot are you able to do the backport (see bot comment above)? |
…onth w/ a 24:00 time (GH-151771) (#151810) (cherry picked from commit 1fb874c) Co-authored-by: tonghuaroot (童话) <[email protected]> Co-authored-by: Stan Ulbrych <[email protected]>
…onth w/ a 24:00 time (GH-151771) (#151809) (cherry picked from commit 1fb874c) Co-authored-by: tonghuaroot (童话) <[email protected]> Co-authored-by: Stan Ulbrych <[email protected]>
datetime.fromisoformat()reacheddays_in_month()withmonth == 0when the input combined an out-of-range (below 1) month with a24:00time, for example"2009-00-01T24:00:00". On a--with-pydebugbuild this trippedassert(month >= 1)indays_in_month(Modules/_datetimemodule.c); the pure-Python implementation inLib/_pydatetime.pyraisedAssertionErroron the same input. On a release build both already raisedValueError.The
24:00midnight-rollover guard validated only the upper month bound (month <= 12) before thedays_in_month()call, and the parser does not range-check the month before that point, so a month below 1 slipped through. The matching upper-bound input"2009-13-01T24:00:00"was already rejected by themonth <= 12check.This adds the missing
month >= 1lower bound to the guard in both implementations (mirroring the existingcheck_date_argsvalidation), so an out-of-range month consistently raisesValueError. A regression test is added next to the existing out-of-range-month case indatetimetester.py.