Skip to content

naturaltime and precisedelta: return non-finite floats unchanged#348

Open
HrachShah wants to merge 2 commits into
python-humanize:mainfrom
HrachShah:fix/nonfinite-naturaltime-precisedelta
Open

naturaltime and precisedelta: return non-finite floats unchanged#348
HrachShah wants to merge 2 commits into
python-humanize:mainfrom
HrachShah:fix/nonfinite-naturaltime-precisedelta

Conversation

@HrachShah

Copy link
Copy Markdown

naturaltime and precisedelta both routed their float input through _date_and_delta, which fed it straight to round() (or skipped round in precise mode) and then dt.timedelta(seconds=...). For a non-finite float like inf or -inf, round(float("inf")) raises OverflowError and dt.timedelta(seconds=float("inf")) raises OverflowError too. NaN happened to work because round(float("nan")) raises ValueError which the except clause caught, but inf/-inf slipped past.

The naturaldelta path catches inf/-inf via a different probe (it calls int(value) first, which raises OverflowError for inf) and that case is fixed in the still-open PR #342 -- this PR leaves that probe alone and adds the equivalent isfinite guard inside _date_and_delta, which is what both naturaltime and precisedelta go through. Adding OverflowError to the except tuple covers the last remaining case where a finite but oversized number (> ~3e9 days in seconds) would otherwise crash.

Three new parametrized test functions in tests/test_time.py cover naturaltime, precisedelta, and the internal _date_and_delta contract for inf/-inf/nan. The inf and -inf cases fail on the pre-fix code with OverflowError; the nan case already worked and is included as a regression guard. Full suite: 724 passed, 69 skipped.

Zo Bot and others added 2 commits July 4, 2026 23:35
naturaltime and precisedelta both routed their float input through
_date_and_delta, which fed it straight to round() (or skipped round
in precise mode) and then dt.timedelta(seconds=...). For a non-finite
float like inf or -inf, round(float("inf")) raises OverflowError
and dt.timedelta(seconds=float("inf")) raises OverflowError too.
NaN happened to work because round(float("nan")) raises ValueError
which the except clause caught, but inf/-inf slipped past.

The naturaldelta path caught inf/-inf via a different probe (it
calls int(value) first, which raises OverflowError for inf) and
that case is fixed in the still-open PR python-humanize#342 -- this commit leaves
that probe alone and adds the equivalent isfinite guard inside
_date_and_delta, which is what both naturaltime and precisedelta
go through. Adding OverflowError to the except tuple covers the
last remaining case where a finite but oversized number
(> ~3e9 days in seconds) would otherwise crash.

Three new parametrized test functions in tests/test_time.py cover
naturaltime, precisedelta, and the internal _date_and_delta
contract for inf/-inf/nan. The inf and -inf cases fail on the
pre-fix code with OverflowError; the nan case already worked and
is included as a regression guard. Full suite: 724 passed,
69 skipped.
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.

1 participant