diff --git a/src/humanize/time.py b/src/humanize/time.py index 8651a98..be73bd7 100644 --- a/src/humanize/time.py +++ b/src/humanize/time.py @@ -5,6 +5,7 @@ from __future__ import annotations +import math from enum import Enum from functools import total_ordering @@ -151,6 +152,14 @@ def naturaldelta( delta = dt.timedelta(seconds=value) except (ValueError, TypeError): return str(value) + except OverflowError: + # `int(value)` raises OverflowError for non-finite floats (inf/-inf), + # which, like NaN, are returned unchanged. A too-large *finite* value + # (whose OverflowError comes from `timedelta`) is still raised, per + # the documented `OverflowError` contract. + if not math.isfinite(value): + return str(value) + raise use_months = months diff --git a/tests/test_time.py b/tests/test_time.py index 7699770..b3f448c 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -138,6 +138,19 @@ def test_naturaldelta(test_input: float | dt.timedelta, expected: str) -> None: assert humanize.naturaldelta(-test_input) == expected +def test_naturaldelta_non_finite() -> None: + """Non-finite floats are returned unchanged instead of raising (#333).""" + assert humanize.naturaldelta(float("nan")) == "nan" + assert humanize.naturaldelta(float("inf")) == "inf" + assert humanize.naturaldelta(float("-inf")) == "-inf" + + +def test_naturaldelta_too_large_value_raises() -> None: + """A too-large *finite* value still raises OverflowError (unlike inf).""" + with pytest.raises(OverflowError): + humanize.naturaldelta(1e30) + + @freeze_time(FROZEN_DATE) @pytest.mark.parametrize( "test_input, expected",