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.
|
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 |
|
@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. |
…misoformat` (GH-152161) (#152761) (cherry picked from commit 112c69a) Co-authored-by: tonghuaroot (童话) <[email protected]> Co-authored-by: Stan Ulbrych <[email protected]>
|
We need to backport #152061 first, can you do those please? |
…misoformat` (GH-152161) (#152765) (cherry picked from commit 112c69a) Co-authored-by: tonghuaroot (童话) <[email protected]> Co-authored-by: Stan Ulbrych <[email protected]>
…misoformat` (GH-152161) (#152766) (cherry picked from commit 112c69a) Co-authored-by: Stan Ulbrych <[email protected]>
Fixes gh-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.