Skip to content

Commit d2feb60

Browse files
fix(time): catch OverflowError for non-finite floats in naturaldelta and naturaltime (#333)
1 parent ce4147b commit d2feb60

2 files changed

Lines changed: 12 additions & 6 deletions

File tree

src/humanize/time.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def _date_and_delta(
8989
value = value if precise else round(value)
9090
delta = dt.timedelta(seconds=value)
9191
date = now - delta
92-
except (ValueError, TypeError):
92+
except (ValueError, TypeError, OverflowError):
9393
return None, value
9494
return date, _abs_timedelta(delta)
9595

@@ -117,9 +117,6 @@ def naturaldelta(
117117
converted to int (cannot be float due to 'inf' or 'nan').
118118
In that case, a `value` is returned unchanged.
119119
120-
Raises:
121-
OverflowError: If `value` is too large to convert to datetime.timedelta.
122-
123120
Examples:
124121
Compare two timestamps in a custom local timezone::
125122
@@ -151,7 +148,7 @@ def naturaldelta(
151148
int(value) # Explicitly don't support string such as "NaN" or "inf"
152149
value = float(value)
153150
delta = dt.timedelta(seconds=value)
154-
except (ValueError, TypeError):
151+
except (ValueError, TypeError, OverflowError):
155152
return str(value)
156153

157154
use_months = months

tests/test_time.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from __future__ import annotations
44

55
import datetime as dt
6+
import math
67
import typing
78

89
import pytest
@@ -71,6 +72,8 @@ def test_date_and_delta() -> None:
7172
assert_equal_datetime(date, result[0])
7273
assert_equal_timedelta(d, result[1])
7374
assert time._date_and_delta("NaN") == (None, "NaN")
75+
assert time._date_and_delta(float("inf")) == (None, float("inf"))
76+
assert time._date_and_delta(float("-inf")) == (None, float("-inf"))
7477

7578

7679
# Tests for the public interface of humanize.time
@@ -128,13 +131,15 @@ def test_naturaldelta_nomonths(test_input: dt.timedelta, expected: str) -> None:
128131
(dt.timedelta(days=365), "a year"),
129132
(dt.timedelta(days=365 * 1_141), "1,141 years"),
130133
("NaN", "NaN"), # Returns non-numbers unchanged.
134+
(float("inf"), "inf"),
135+
(float("-inf"), "-inf"),
131136
# largest possible timedelta
132137
(dt.timedelta(days=999_999_999), "2,739,726 years"),
133138
],
134139
)
135140
def test_naturaldelta(test_input: float | dt.timedelta, expected: str) -> None:
136141
assert humanize.naturaldelta(test_input) == expected
137-
if not isinstance(test_input, str):
142+
if not isinstance(test_input, str) and not (isinstance(test_input, float) and math.isinf(test_input)):
138143
assert humanize.naturaldelta(-test_input) == expected
139144

140145

@@ -179,6 +184,8 @@ def test_naturaldelta(test_input: float | dt.timedelta, expected: str) -> None:
179184
(NOW - dt.timedelta(days=365 * 2 + 65), "2 years ago"),
180185
(NOW - dt.timedelta(days=365 + 4), "1 year, 4 days ago"),
181186
("NaN", "NaN"),
187+
(float("inf"), "inf"),
188+
(float("-inf"), "-inf"),
182189
],
183190
)
184191
def test_naturaltime(
@@ -817,6 +824,8 @@ def test_precisedelta_suppress_units(
817824

818825
def test_precisedelta_bogus_call() -> None:
819826
assert humanize.precisedelta(None) == "None"
827+
assert humanize.precisedelta(float("inf")) == "inf"
828+
assert humanize.precisedelta(float("-inf")) == "-inf"
820829

821830
with pytest.raises(
822831
ValueError,

0 commit comments

Comments
 (0)