diff --git a/src/humanize/time.py b/src/humanize/time.py index 4a07d52..37f930d 100644 --- a/src/humanize/time.py +++ b/src/humanize/time.py @@ -89,7 +89,7 @@ def _date_and_delta( value = value if precise else round(value) delta = dt.timedelta(seconds=value) date = now - delta - except (ValueError, TypeError): + except (ValueError, TypeError, OverflowError): return None, value return date, _abs_timedelta(delta) @@ -114,11 +114,9 @@ def naturaldelta( Returns: 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()`). Examples: Compare two timestamps in a custom local timezone:: @@ -151,7 +149,7 @@ def naturaldelta( int(value) # Explicitly don't support string such as "NaN" or "inf" value = float(value) delta = dt.timedelta(seconds=value) - except (ValueError, TypeError): + except (ValueError, TypeError, OverflowError): return str(value) use_months = months diff --git a/tests/test_time.py b/tests/test_time.py index 7699770..033a4e5 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -837,6 +837,45 @@ def test_time_unit() -> None: _ = years < "foo" +@pytest.mark.parametrize( + "value, expected", + [ + (float("inf"), "inf"), + (float("-inf"), "-inf"), + (float("nan"), "nan"), + ], +) +def test_naturaldelta_non_finite(value: float, expected: str) -> None: + # 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. + assert humanize.naturaldelta(value) == expected + + +@pytest.mark.parametrize( + "value, expected", + [ + (float("inf"), "inf"), + (float("-inf"), "-inf"), + (float("nan"), "nan"), + ], +) +def test_naturaltime_non_finite(value: float, expected: str) -> None: + assert humanize.naturaltime(value) == expected + + +@pytest.mark.parametrize( + "value, expected", + [ + (float("inf"), "inf"), + (float("-inf"), "-inf"), + (float("nan"), "nan"), + ], +) +def test_precisedelta_non_finite(value: float, expected: str) -> None: + assert humanize.precisedelta(value) == expected + + @pytest.mark.parametrize( "fmt, value, expected", [