Uh oh!
There was an error while loading. Please reload this page.
gh-152157: Reject empty fraction before timezone in C fromisoformat - #152161
Conversation
…rmat The C accelerator for datetime.fromisoformat() and time.fromisoformat() accepted a decimal separator (. or ,) with no following digit when a timezone designator came next, e.g. '12:34:56.+05:00', while the pure-Python implementation correctly raised ValueError. Handle the decimal-separator case before the generic end-of-substring check so an empty fraction is rejected.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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. |
Sorry, @tonghuaroot and @StanFromIreland, I could not cleanly backport this to |
GH-152761 is a backport of this pull request to the 3.15 branch. |
Sorry, @tonghuaroot and @StanFromIreland, I could not cleanly backport this to |
StanFromIreland
commented
Jul 1, 2026
@tonghuaroot can you please do the backports? |
GH-152765 is a backport of this pull request to the 3.14 branch. |
GH-152766 is a backport of this pull request to the 3.13 branch. |
tonghuaroot
commented
Jul 1, 2026
StanFromIreland
commented
Jul 1, 2026
We need to backport #152061 first, can you do those please? |
Fixesgh-152157
datetime.fromisoformat()andtime.fromisoformat()accepted, in the C accelerator, adecimal separator (
.or,) followed by zero fractional digits when a timezonedesignator (
+/-/Z) came next, e.g.'2020-01-01T12:34:56.+05:00'or'12:34:56.Z'.The pure-Python implementation already raised
ValueErrorfor these. ISO 8601 §4.2.2.4 andRFC 3339 §5.6 require at least one digit after the decimal sign, so the C side was the
lenient/incorrect one.
Divergence (before this PR)
'2020-01-01T12:34:56.+05:00'ValueError'2020-01-01T12:34:56.Z'ValueError'2020-01-01T12:34:56,+05:00'ValueError'12:34:56.+05:00'ValueError'12:34:56,+05:00'ValueError'12:34:56.Z'ValueErrorAfter this PR both implementations raise
ValueErrorfor all of the above, and allpreviously-accepted valid strings (
.5,.123456, comma fractions, no-fraction +offset,Z) parse identically on both.Fix
In
parse_hh_mm_ss_ff()the decimal-separator case is now handled before the genericend-of-substring check, so a separator with no following digit is rejected instead of being
treated as trailing content. The standalone trailing separator (
'12:34:56.') remainsrejected. No change to the valid-fraction or no-fraction paths.
Note for reviewers
The spec requires ≥1 digit after the decimal sign, and the C implementation already rejects
a standalone trailing separator, so this PR fixes C to reject. The alternative direction
(making pure-Python lenient) is possible but contradicts both the spec and C's own
end-of-string behavior; happy to flip the approach if you'd rather standardize on lenient.
Tests
Added the four empty-fraction-before-tz inputs (offset, negative offset,
Z, comma) to thedatetimeandtimefromisoformatfailure tests, which run against both the C andpure-Python implementations. Positive parity (valid fractions, comma fractions, and
no-fraction-with-offset) is already covered by the existing
*_examplestests, which alsorun on both implementations.
./python.exe -m test test_datetimepasses (both impls), with no refleaks for the touchedtests.