Skip to content

fix: validate the amount in Interval.range (zero/negative hang or run away) - #1090

Open
rahul05ranjan wants to merge 1 commit into
python-pendulum:masterfrom
rahul05ranjan:fix/interval-range-amount-validation
Open

rahul05ranjan wants to merge 1 commit into
python-pendulum:masterfrom
rahul05ranjan:fix/interval-range-amount-validation

Conversation

@rahul05ranjan

Copy link
Copy Markdown

Interval.range(unit, amount) accepts any integer amount, including 0 — which produces a generator that yields the same starting value forever and never reaches its stated end:

it = pendulum.interval(pendulum.datetime(2026, 1, 1), pendulum.datetime(2026, 2, 1)).range("days", 0)
# next(it) -> 2026-01-01
# next(it) -> 2026-01-01   (forever; start = self.start.add(days=0) never moves)

The loop's advance step (add(**{unit: i}) with i stuck at 0) and its termination check (start <= end) both depend on amount, so any caller that consumes the generator without an independent bound — a plain for loop, list(...) — hangs at full CPU with no way to recover. A caller that builds the step from user/config input can be made to hang a worker indefinitely.

A related case, a wrong-sign amount (e.g. -1 on a forward interval), does not hang but runs away unbounded in the opposite direction from the stated end — the same missing validation.

Fix: reject non-positive amounts with ValueError. The direction is already applied internally (add/le vs subtract/ge per the interval's orientation), so the step magnitude must be positive in both directions.

>>> list(p.range("days", 0))
ValueError: amount must be a positive integer, got 0

Fixes #1080.

Verification (system Python 3.13, wheels on the path, nothing installed):

  • Both failure modes demonstrated on unpatched master@e06dace: amount=0 repeats the start indefinitely (islice of an infinite generator), amount=-1 yields 2026-01-01, 2025-12-31, 2025-12-30 … running backward, never reaching the end.
  • New tests in tests/interval/test_range.py (zero and negative amount → ValueError): both fail with the infinite/escaping behavior on unpatched master, pass with this change.
  • tests/interval, tests/datetime, tests/parsing, tests/formatting, tests/date, tests/time: 1104 passed, zero regressions.

A zero amount made range() yield the same start value forever: the
advance step add(**{unit: i}) with i == 0 never moves, so the loop
condition start <= end never turns false and any consuming for-loop
hangs. A negative amount runs away from the stated end in the opposite
direction, unbounded, for the same missing-validation reason.

Reject non-positive amounts with ValueError, matching the documented
direction handling (the direction itself is applied via add/subtract
and le/ge, so the step magnitude must be positive in both directions).

Fixes python-pendulum#1080

Co-authored-by: rahul05ranjan <11793455+rahul05ranjan@users.noreply.github.com>

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.

Interval.range() hangs forever on a zero (or wrong-sign) step

1 participant