Skip to content

BUG: overflow on Timedelta construction & arithmetic now raises #17640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ Conversion
- Bug in :func:`Series.fillna` returns frame when ``inplace=True`` and ``value`` is dict (:issue:`16156`)
- Bug in :attr:`Timestamp.weekday_name` returning a UTC-based weekday name when localized to a timezone (:issue:`17354`)
- Bug in ``Timestamp.replace`` when replacing ``tzinfo`` around DST changes (:issue:`15683`)
- Bug in ``Timedelta`` construction and arithmetic that would not propagate the ``Overflow`` exception (:issue:`17367`)

Indexing
^^^^^^^^
Expand Down
6 changes: 3 additions & 3 deletions pandas/_libs/tslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -3514,7 +3514,7 @@ cpdef convert_to_timedelta64(object ts, object unit):
ts = np.timedelta64(_delta_to_nanoseconds(ts), 'ns')

if isinstance(ts, timedelta):
ts = np.timedelta64(ts)
ts = np.timedelta64(_delta_to_nanoseconds(ts), 'ns')
elif not isinstance(ts, np.timedelta64):
raise ValueError("Invalid type for timedelta "
"scalar: %s" % type(ts))
Expand Down Expand Up @@ -3891,8 +3891,7 @@ for _maybe_method_name in dir(NaTType):
#----------------------------------------------------------------------
# Conversion routines


cpdef int64_t _delta_to_nanoseconds(delta):
cpdef int64_t _delta_to_nanoseconds(delta) except? -1:
if isinstance(delta, np.ndarray):
return delta.astype('m8[ns]').astype('int64')
if hasattr(delta, 'nanos'):
Expand All @@ -3903,6 +3902,7 @@ cpdef int64_t _delta_to_nanoseconds(delta):
return delta.astype("timedelta64[ns]").item()
if is_integer_object(delta):
return delta

return (delta.days * 24 * 60 * 60 * 1000000
+ delta.seconds * 1000000
+ delta.microseconds) * 1000
Expand Down
7 changes: 7 additions & 0 deletions pandas/tests/indexes/datetimes/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,13 @@ def test_to_datetime_freq(self):
assert xp.freq == rs.freq
assert xp.tzinfo == rs.tzinfo

def test_to_datetime_overflow(self):
# gh-17637
# we are overflowing Timedelta range here

with pytest.raises(OverflowError):
date_range(start='1/1/1700', freq='B', periods=100000)

def test_string_na_nat_conversion(self):
# GH #999, #858

Expand Down
15 changes: 15 additions & 0 deletions pandas/tests/scalar/test_timedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ def test_overflow_on_construction(self):
value = pd.Timedelta('1day').value * 20169940
pytest.raises(OverflowError, pd.Timedelta, value)

# xref gh-17637
with pytest.raises(OverflowError):
pd.Timedelta(7 * 19999, unit='D')

with pytest.raises(OverflowError):
pd.Timedelta(timedelta(days=13 * 19999))

def test_total_seconds_scalar(self):
# see gh-10939
rng = Timedelta('1 days, 10:11:12.100123456')
Expand Down Expand Up @@ -612,6 +619,14 @@ def test_timedelta_arithmetic(self):
tm.assert_series_equal(result_operator, expected)
tm.assert_series_equal(result_method, expected)

def test_arithmetic_overflow(self):

with pytest.raises(OverflowError):
pd.Timestamp('1700-01-01') + pd.Timedelta(13 * 19999, unit='D')

with pytest.raises(OverflowError):
pd.Timestamp('1700-01-01') + timedelta(days=13 * 19999)

def test_apply_to_timedelta(self):
timedelta_NaT = pd.to_timedelta('NaT')

Expand Down