Skip to content

Accept ISO 8601 fractional seconds with more than 9 digits#976

Open
vineethsaivs wants to merge 1 commit into
python-pendulum:masterfrom
vineethsaivs:fix/iso8601-subsecond-beyond-nine-digits
Open

Accept ISO 8601 fractional seconds with more than 9 digits#976
vineethsaivs wants to merge 1 commit into
python-pendulum:masterfrom
vineethsaivs:fix/iso8601-subsecond-beyond-nine-digits

Conversation

@vineethsaivs

Copy link
Copy Markdown

Fixes #935.

pendulum.parse() raises a ParserError on ISO 8601 timestamps whose fractional-seconds field has more than 9 digits:

>>> pendulum.parse("2001-01-01T12:34:56.1234567890Z")  # 10 digits
pendulum.parsing.exceptions.ParserError: Invalid ISO 8601 string

This affects only the pure-Python parser (pendulum/parsing/iso8601.py). The Rust extension already drops the extra digits, and datetime.fromisoformat accepts them too, so the behavior was inconsistent depending on whether the compiled extension was installed.

Root cause

The subsecond capture group was bounded to 9 digits:

r"        (?P<subsecond>\d{1,9})"  # Subsecond

With 10 or more digits the whole pattern fails to match. The downstream code already truncates to microsecond resolution (subsecond = m.group("subsecond")[:6]), so the 9-digit cap was the only thing rejecting longer inputs.

Fix

Widen the group to \d+. The existing [:6] truncation converts any length down to microseconds, so results are unchanged for inputs that already parsed, and 10-or-more-digit inputs now parse (truncated), matching the Rust parser and the standard library.

Test

Added test_parse_iso8601_subsecond_more_than_nine_digits in tests/parsing/test_parse_iso8601.py. It imports the pure-Python parse_iso8601 directly so it always exercises this code path regardless of whether the compiled extension is installed. It fails before the change (ParserError) and passes after.

The pure-Python ISO 8601 parser capped the subsecond group at 9 digits
(\d{1,9}), so parse() raised a ParserError on timestamps with 10 or more
fractional-second digits, even though the Rust parser and
datetime.fromisoformat accept them and truncate to microsecond resolution.

Widen the group to \d+; the existing [:6] truncation already converts any
length down to microseconds, so the result is unchanged for inputs that
already parsed.

Fixes python-pendulum#935
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

parse fails with subsecond decimals with more than 9 digits

1 participant