Skip to content

Clamp day-of-month when a daterange step overflows into a shorter month - #507

Open
afonsojanu wants to merge 1 commit into
mahmoud:masterfrom
afonsojanu:fix/daterange-month-step-day-overflow
Open

afonsojanu wants to merge 1 commit into
mahmoud:masterfrom
afonsojanu:fix/daterange-month-step-day-overflow

Conversation

@afonsojanu

Copy link
Copy Markdown

The change

daterange() with a month/year step crashes whenever advancing lands the
anchor day on a day that doesn't exist in the target month, e.g.:

list(daterange(date(2020, 1, 31), date(2020, 6, 30), step=(0, 1, 0), inclusive=True))
# ValueError: day is out of range for month

_advance() carried the day over unchanged into date.replace(), so Jan 31
advancing by one month tried to build Feb 31 and blew up. A monthly sequence
anchored on a month-end date is ordinary input, not an edge case, so this
fixes it by clamping the day to the last valid day of the target month
(the same convention dateutil.relativedelta uses) instead of raising.
Closes #500.

The backstory

Went looking through the open timeutils issues for something concrete to
fix. #500 already had a full repro, root cause, and a menu of possible
fixes from the reporter, so I reproduced the crash locally first rather than
taking that at face value, then picked the clamp-to-last-day option since
it never raises and matches existing precedent elsewhere. Added a test that
covers both the leap and non-leap February case plus stepping backwards.

AI assistance

  • Harness/tooling: Claude Code
  • Model(s): Claude Sonnet 5
  • Original prompt(s), as close to verbatim as I can manage: this runs as part of a standing task where the model looks through open-source Python repos for a genuine correctness bug, verifies it itself rather than trusting an issue's own diagnosis, fixes it with a regression test, and opens a PR under my account. For this repo specifically, it was told to reproduce issue daterange with a month step raises 'day is out of range for month' when start is on the 29th-31st聽#500 (daterange crashing on month-step day overflow) locally, confirm it's real, implement a fix, and add tests before opening the PR.

daterange()'s month/year stepping kept the anchor day fixed and passed
it straight to date.replace(), so any step that landed on a day past
the end of the target month (day 29 to 31 into February, or 31 into a
30-day month) raised ValueError instead of yielding. A monthly walk
anchored on a month-end date is a normal thing to build, so this is a
crash on ordinary input rather than an edge case.

Clamp the day to the last valid day of the target month instead,
following the same convention dateutil's relativedelta uses. Added a
test covering the leap/non-leap February case and stepping backwards.
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.

daterange with a month step raises 'day is out of range for month' when start is on the 29th-31st

1 participant