Skip to content

parse_date: raise ParseError instead of leaking IndexError/ValueError - #1365

Open
simpleqt wants to merge 1 commit into
python-babel:masterfrom
simpleqt:sq/r22-parse-date-parseerror
Open

simpleqt wants to merge 1 commit into
python-babel:masterfrom
simpleqt:sq/r22-parse-date-parseerror

Conversation

@simpleqt

@simpleqt simpleqt commented Oct 5, 2026

Copy link
Copy Markdown

Summary

parse_date indexes the numbers extracted from the input string by the positions of y/m/d in the locale's date pattern, but never checks how many numbers were actually found. Input with fewer than three numbers — including month-name dates like the locale's own medium/long formats — crashes with a bare IndexError:

>>> from babel.dates import parse_date
>>> parse_date('Jan 3, 2026', locale='en_US')     # en_US medium format
IndexError: list index out of range
>>> parse_date('1. Januar 2026', locale='de_DE')
IndexError: list index out of range

Out-of-range fields likewise leak datetime.date()'s ValueError, which except ParseError handlers do not catch:

>>> parse_date('01.32.2026', locale='de_DE')
ValueError: day 32 must be in range 1..31 for month 1 in year 2026

This PR raises ParseError for both cases, matching the existing No numbers were found in input behavior. parse_time already guards its indexing (len(numbers) > 1 / > 2), so this brings the two parsers in line. (Month-name support remains a separate, already-acknowledged FIXME; this only fixes the error contract.)

Verification

  • Red/green: test_parse_date_raises_parse_error_instead_of_index_error and test_parse_date_raises_parse_error_on_out_of_range_values fail on master (IndexError / ValueError raised instead of ParseError) and pass with this change.
  • pytest tests/test_dates.py: 1193 passed with this change vs 1191 on master against the same environment (5 pre-existing failures identical on master — CLDR data drift in my local setup; no regressions).
  • ruff check clean.
AI Disclosure

This PR was prepared with the assistance of an AI coding agent.

  • Tool(s): ZCode (GLM-based coding agent)
  • Used for: discovering the exception leaks via a locale matrix sweep of parse_date, implementing the guards, and running the red/green and baseline verification described above.

parse_date indexes the numbers extracted from the input by the
positions of y/m/d in the locale pattern, but never checks how many
numbers were actually found. Strings with fewer than three numbers -
including month-name dates like 'Jan 3, 2026' (en_US medium format)
or '1. Januar 2026' - crash with a bare IndexError:

    >>> parse_date('Jan 3, 2026', locale='en_US')
    IndexError: list index out of range

Out-of-range fields likewise leak datetime.date()'s ValueError, which
is not the documented ParseError, so 'except ParseError' handlers miss
it:

    >>> parse_date('01.32.2026', locale='de_DE')
    ValueError: day 32 must be in range 1..31 for month 1 in year 2026

Raise ParseError for both cases, matching the existing
'No numbers were found in input' behaviour. parse_time already guards
its indexing (len(numbers) > 1 / > 2).
Copilot AI balanced review requested due to automatic review settings October 5, 2026 13:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

This branch has not been deployed

No deployments
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.

2 participants