diff --git a/src/humanize/number.py b/src/humanize/number.py index 2fb22c6..593b408 100644 --- a/src/humanize/number.py +++ b/src/humanize/number.py @@ -109,7 +109,8 @@ def ordinal(value: NumberOrString, gender: str = "male") -> str: except (TypeError, ValueError): return str(value) gender = "male" if gender == "male" else "female" - digit = 0 if value % 100 in (11, 12, 13) else value % 10 + abs_value = abs(value) + digit = 0 if abs_value % 100 in (11, 12, 13) else abs_value % 10 return f"{value}{P_(f'{digit} ({gender})', _ORDINAL_SUFFIXES[digit])}" diff --git a/src/humanize/time.py b/src/humanize/time.py index 4a07d52..41e5677 100644 --- a/src/humanize/time.py +++ b/src/humanize/time.py @@ -151,7 +151,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_number.py b/tests/test_number.py index 78639c3..204d172 100644 --- a/tests/test_number.py +++ b/tests/test_number.py @@ -25,6 +25,16 @@ ("102", "102nd"), ("103", "103rd"), ("111", "111th"), + (-1, "-1st"), + (-2, "-2nd"), + (-3, "-3rd"), + (-4, "-4th"), + (-11, "-11th"), + (-12, "-12th"), + (-13, "-13th"), + (-21, "-21st"), + (-101, "-101st"), + (-111, "-111th"), ("something else", "something else"), (None, "None"), (math.nan, "NaN"), diff --git a/tests/test_time.py b/tests/test_time.py index 7699770..771e763 100644 --- a/tests/test_time.py +++ b/tests/test_time.py @@ -3,6 +3,7 @@ from __future__ import annotations import datetime as dt +import math import typing import pytest @@ -128,6 +129,8 @@ def test_naturaldelta_nomonths(test_input: dt.timedelta, expected: str) -> None: (dt.timedelta(days=365), "a year"), (dt.timedelta(days=365 * 1_141), "1,141 years"), ("NaN", "NaN"), # Returns non-numbers unchanged. + (float("inf"), "inf"), + (float("-inf"), "-inf"), # largest possible timedelta (dt.timedelta(days=999_999_999), "2,739,726 years"), ], @@ -135,7 +138,8 @@ def test_naturaldelta_nomonths(test_input: dt.timedelta, expected: str) -> None: def test_naturaldelta(test_input: float | dt.timedelta, expected: str) -> None: assert humanize.naturaldelta(test_input) == expected if not isinstance(test_input, str): - assert humanize.naturaldelta(-test_input) == expected + if isinstance(test_input, dt.timedelta) or math.isfinite(test_input): + assert humanize.naturaldelta(-test_input) == expected @freeze_time(FROZEN_DATE)