fix: catch OverflowError for non-finite floats in time functions - #375
fix: catch OverflowError for non-finite floats in time functions#375Manushprajwal7 wants to merge 1 commit into
Conversation
naturaldelta(), naturaltime(), and precisedelta() all raised an uncaught
OverflowError for float('inf') / float('-inf') instead of returning the
value unchanged, unlike every other numeric humanize function (which
already treat non-finite input this way) and unlike how these same
functions already handle float('nan').
The root cause is that int()/round() raise OverflowError (not ValueError
or TypeError) for infinite floats, and that exception wasn't in the
except clauses guarding the timedelta conversion in naturaldelta() and
the shared _date_and_delta() helper used by naturaltime() and
precisedelta().
Fixes python-humanize#333.
There was a problem hiding this comment.
Pull request overview
Fixes an inconsistency in the time humanizing APIs where non-finite floats (inf/-inf) could raise an uncaught OverflowError. The change aligns naturaldelta(), naturaltime(), and precisedelta() with other humanize numeric functions by returning a string representation for non-finite/invalid inputs rather than raising.
Changes:
- Catch
OverflowErrorinnaturaldelta()and the shared_date_and_delta()helper. - Update
naturaldelta()docstring to describe the intended behavior (no longer documenting the crash as an expected exception). - Add regression tests covering
inf/-inf/nanfornaturaldelta,naturaltime, andprecisedelta.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/humanize/time.py |
Extends conversion guards to include OverflowError and adjusts documentation around non-finite/too-large values. |
tests/test_time.py |
Adds regression coverage for non-finite float inputs across the affected public time functions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| str (str or `value`): A natural representation of the amount of time | ||
| elapsed unless `value` is not datetime.timedelta or cannot be | ||
| converted to int (cannot be float due to 'inf' or 'nan'). | ||
| In that case, a `value` is returned unchanged. | ||
|
|
||
| Raises: | ||
| OverflowError: If `value` is too large to convert to datetime.timedelta. | ||
| converted to int (cannot be float due to 'inf' or 'nan', or too | ||
| large to fit in a `datetime.timedelta`). In that case, `value` is | ||
| returned unchanged (via `str()`). |
| @@ -151,7 +149,7 @@ def naturaldelta( | |||
| int(value) # Explicitly don't support string such as "NaN" or "inf" | |||
| # Regression test for #333: non-finite floats used to raise an uncaught | ||
| # OverflowError (or, for nan, were only handled when passed as a string) | ||
| # instead of being returned unchanged like other non-numeric input. |
|
Heads-up for maintainers: this PR and #375 fix the same OverflowError-on-non-finite issue (#333) but with opposite semantics for finite too-large values:
These will behave differently for e.g. (Also noting for completeness that I reviewed #374 separately; unrelated.) |
Summary
Fixes #333.
naturaldelta(),naturaltime(), andprecisedelta()all raise an uncaughtOverflowErrorforfloat('inf')/float('-inf')instead of returning the value unchanged — inconsistent with every other numeric humanize function (ordinal,intcomma,intword, etc.), which already treat non-finite input this way, and inconsistent with how these same three functions already handlefloat('nan').Root cause:
int()/round()raiseOverflowError(notValueErrororTypeError) for infinite floats. That exception wasn't included in theexceptclauses guarding thetimedeltaconversion innaturaldelta(), nor in the shared_date_and_delta()helper used bynaturaltime()andprecisedelta(). Since both call sites share the same root cause, this fixes all three functions rather than just the one named in the issue.Changes
src/humanize/time.py: addOverflowErrorto the two relevantexceptclauses (innaturaldelta()and_date_and_delta()).naturaldelta()'s docstring, which documented the crash as aRaises: OverflowError— that was describing the bug, not an intentional design.inf/-inf/nanacrossnaturaldelta,naturaltime, andprecisedelta.Test plan
pytest tests/test_time.py -q— 392 passedpytest -q— 724 passed, 74 skipped, 0 failedruff checkon changed files — cleannaturaldelta/naturaltime/precisedeltano longer raise forinf/-inf, and behavior for genuinely-too-large-but-finite values (e.g.1e300) is now consistent (returned unchanged rather than raising)