Skip to content

Commit 76d1744

Browse files
authored
BUG: overflow on Timedelta construction & arithmetic now raises (#17640)
closes #17637
1 parent 4004367 commit 76d1744

File tree

4 files changed

+26
-3
lines changed

4 files changed

+26
-3
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -498,6 +498,7 @@ Conversion
498
- Bug in :func:`Series.fillna` returns frame when ``inplace=True`` and ``value`` is dict (:issue:`16156`)
498
- Bug in :func:`Series.fillna` returns frame when ``inplace=True`` and ``value`` is dict (:issue:`16156`)
499
- Bug in :attr:`Timestamp.weekday_name` returning a UTC-based weekday name when localized to a timezone (:issue:`17354`)
499
- Bug in :attr:`Timestamp.weekday_name` returning a UTC-based weekday name when localized to a timezone (:issue:`17354`)
500
- Bug in ``Timestamp.replace`` when replacing ``tzinfo`` around DST changes (:issue:`15683`)
500
- Bug in ``Timestamp.replace`` when replacing ``tzinfo`` around DST changes (:issue:`15683`)
501+
- Bug in ``Timedelta`` construction and arithmetic that would not propagate the ``Overflow`` exception (:issue:`17367`)
501

502

502
Indexing
503
Indexing
503
^^^^^^^^
504
^^^^^^^^

pandas/_libs/tslib.pyx

+3-3
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -3514,7 +3514,7 @@ cpdef convert_to_timedelta64(object ts, object unit):
3514
ts = np.timedelta64(_delta_to_nanoseconds(ts), 'ns')
3514
ts = np.timedelta64(_delta_to_nanoseconds(ts), 'ns')
3515

3515

3516
if isinstance(ts, timedelta):
3516
if isinstance(ts, timedelta):
3517-
ts = np.timedelta64(ts)
3517+
ts = np.timedelta64(_delta_to_nanoseconds(ts), 'ns')
3518
elif not isinstance(ts, np.timedelta64):
3518
elif not isinstance(ts, np.timedelta64):
3519
raise ValueError("Invalid type for timedelta "
3519
raise ValueError("Invalid type for timedelta "
3520
"scalar: %s" % type(ts))
3520
"scalar: %s" % type(ts))
@@ -3891,8 +3891,7 @@ for _maybe_method_name in dir(NaTType):
3891
#----------------------------------------------------------------------
3891
#----------------------------------------------------------------------
3892
# Conversion routines
3892
# Conversion routines
3893

3893

3894-
3894+
cpdef int64_t _delta_to_nanoseconds(delta) except? -1:
3895-
cpdef int64_t _delta_to_nanoseconds(delta):
3896
if isinstance(delta, np.ndarray):
3895
if isinstance(delta, np.ndarray):
3897
return delta.astype('m8[ns]').astype('int64')
3896
return delta.astype('m8[ns]').astype('int64')
3898
if hasattr(delta, 'nanos'):
3897
if hasattr(delta, 'nanos'):
@@ -3903,6 +3902,7 @@ cpdef int64_t _delta_to_nanoseconds(delta):
3903
return delta.astype("timedelta64[ns]").item()
3902
return delta.astype("timedelta64[ns]").item()
3904
if is_integer_object(delta):
3903
if is_integer_object(delta):
3905
return delta
3904
return delta
3905+
3906
return (delta.days * 24 * 60 * 60 * 1000000
3906
return (delta.days * 24 * 60 * 60 * 1000000
3907
+ delta.seconds * 1000000
3907
+ delta.seconds * 1000000
3908
+ delta.microseconds) * 1000
3908
+ delta.microseconds) * 1000

pandas/tests/indexes/datetimes/test_tools.py

+7
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -787,6 +787,13 @@ def test_to_datetime_freq(self):
787
assert xp.freq == rs.freq
787
assert xp.freq == rs.freq
788
assert xp.tzinfo == rs.tzinfo
788
assert xp.tzinfo == rs.tzinfo
789

789

790+
def test_to_datetime_overflow(self):
791+
# gh-17637
792+
# we are overflowing Timedelta range here
793+
794+
with pytest.raises(OverflowError):
795+
date_range(start='1/1/1700', freq='B', periods=100000)
796+
790
def test_string_na_nat_conversion(self):
797
def test_string_na_nat_conversion(self):
791
# GH #999, #858
798
# GH #999, #858
792

799

pandas/tests/scalar/test_timedelta.py

+15
Original file line numberOriginal file lineDiff line numberDiff line change
@@ -166,6 +166,13 @@ def test_overflow_on_construction(self):
166
value = pd.Timedelta('1day').value * 20169940
166
value = pd.Timedelta('1day').value * 20169940
167
pytest.raises(OverflowError, pd.Timedelta, value)
167
pytest.raises(OverflowError, pd.Timedelta, value)
168

168

169+
# xref gh-17637
170+
with pytest.raises(OverflowError):
171+
pd.Timedelta(7 * 19999, unit='D')
172+
173+
with pytest.raises(OverflowError):
174+
pd.Timedelta(timedelta(days=13 * 19999))
175+
169
def test_total_seconds_scalar(self):
176
def test_total_seconds_scalar(self):
170
# see gh-10939
177
# see gh-10939
171
rng = Timedelta('1 days, 10:11:12.100123456')
178
rng = Timedelta('1 days, 10:11:12.100123456')
@@ -612,6 +619,14 @@ def test_timedelta_arithmetic(self):
612
tm.assert_series_equal(result_operator, expected)
619
tm.assert_series_equal(result_operator, expected)
613
tm.assert_series_equal(result_method, expected)
620
tm.assert_series_equal(result_method, expected)
614

621

622+
def test_arithmetic_overflow(self):
623+
624+
with pytest.raises(OverflowError):
625+
pd.Timestamp('1700-01-01') + pd.Timedelta(13 * 19999, unit='D')
626+
627+
with pytest.raises(OverflowError):
628+
pd.Timestamp('1700-01-01') + timedelta(days=13 * 19999)
629+
615
def test_apply_to_timedelta(self):
630
def test_apply_to_timedelta(self):
616
timedelta_NaT = pd.to_timedelta('NaT')
631
timedelta_NaT = pd.to_timedelta('NaT')
617

632

0 commit comments

Comments
 (0)