Skip to content

Reject impossible calendar dates in parse_date - #98

Open
Dcastroro wants to merge 1 commit into
xolox:masterfrom
Dcastroro:fix/reject-impossible-calendar-dates
Open

Dcastroro wants to merge 1 commit into
xolox:masterfrom
Dcastroro:fix/reject-impossible-calendar-dates

Conversation

@Dcastroro

Copy link
Copy Markdown

parse_date('2023-02-29') and parse_date('2024-04-31 12:34:56') currently return tuples describing impossible calendar dates. A caller following the documented datetime(*parse_date(...)) example then receives a separate ValueError, while time.mktime can silently normalize those dates into a different month.

Validate the parsed year/month/day with datetime.date before returning the tuple, using the existing InvalidDate error path for failures. Document that calendar validity is checked. The parsing formats, partial-date defaults and time-component handling are otherwise preserved. This intentionally rejects previously accepted impossible dates.

Tests cover seven invalid calendar dates in both date-only and date/time forms, along with leap-year, month-end and partial-date controls.

Validation (Linux/WSL, CPython 3.12.3):

  • Before the fix: the new invalid-date regression fails with InvalidDate not raised; the existing date test and new calendar-boundary controls pass (1 failed, 2 passed).
  • After the fix: complete test suite 71 passed, coverage 91%; changed-file Flake8, including configured docstring checks, passes.
  • git diff --check passes.
  • The existing CLI import emits the Python 3.12 pipes deprecation warning. Python 3.13 test collection is blocked by that existing import; this patch does not change CLI imports. Other Python/OS combinations were not validated.

No overlapping issue or PR was found in the repository searches. Found through source inspection and prepared with OpenAI Codex assistance; no production incident or human manual review is claimed.

Copilot AI balanced review requested due to automatic review settings October 27, 2026 08:25

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.

🔵 Needs a closer look

It is a behavioral change that rejects dates parse_date() previously accepted, which could affect downstream callers and warrants final human sign-off.

No open issues 🎉

What changed in this PR

This PR makes humanfriendly.parse_date() reject impossible calendar dates (e.g. 2023-02-29, 2024-04-31) instead of silently returning a tuple describing a non-existent date. After parsing the string into a (year, month, day, hour, minute, second) tuple, it now validates the date portion by constructing a datetime.date object, which raises ValueError for invalid dates and is converted into the existing InvalidDate error. This tightens an edge case that previously pushed validation failures onto callers (via datetime(*parse_date(...))) or allowed time.mktime to silently normalize into a different month.

Changes:

  • Validate the parsed year/month/day with datetime.date(*result[:3]) before returning, reusing the existing InvalidDate error path.
  • Update the docstring to note that calendar validity is now checked.
  • Add two tests covering rejected impossible dates and preserved leap-day/month-end/partial-date behavior.
File Description
humanfriendly/​__init__.py Adds calendar-date validation in parse_date() and documents the new InvalidDate condition.
humanfriendly/​tests.py Adds test_parse_date_invalid_calendar_dates and test_parse_date_calendar_boundaries covering rejection and boundary cases.

Review effort: Balanced

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