Skip to content

Commit f9762d8

Browse files
authored
BUG: Timedelta(td64, unit=foo) silent overflow (pandas-dev#46827)
* BUG: Timedelta(td64, unit=foo) silent overflow * GH ref
1 parent e6fd3db commit f9762d8

File tree

4 files changed

+27
-2
lines changed

4 files changed

+27
-2
lines changed

doc/source/whatsnew/v1.5.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,8 @@ Datetimelike
479479
Timedelta
480480
^^^^^^^^^
481481
- Bug in :func:`astype_nansafe` astype("timedelta64[ns]") fails when np.nan is included (:issue:`45798`)
482+
- Bug in constructing a :class:`Timedelta` with a ``np.timedelta64`` object and a ``unit`` sometimes silently overflowing and returning incorrect results instead of raising ``OutOfBoundsTimedelta`` (:issue:`46827`)
483+
-
482484

483485
Time Zones
484486
^^^^^^^^^^

pandas/_libs/tslibs/dtypes.pyx

+10
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ cdef str npy_unit_to_abbrev(NPY_DATETIMEUNIT unit):
277277
return "M"
278278
elif unit == NPY_DATETIMEUNIT.NPY_FR_Y:
279279
return "Y"
280+
281+
# Checks for not-really-supported units go at the end, as we don't expect
282+
# to see these often
283+
elif unit == NPY_DATETIMEUNIT.NPY_FR_ps:
284+
return "ps"
285+
elif unit == NPY_DATETIMEUNIT.NPY_FR_fs:
286+
return "fs"
287+
elif unit == NPY_DATETIMEUNIT.NPY_FR_as:
288+
return "as"
289+
280290
else:
281291
raise NotImplementedError(unit)
282292

pandas/_libs/tslibs/timedeltas.pyx

-2
Original file line numberDiff line numberDiff line change
@@ -1487,8 +1487,6 @@ class Timedelta(_Timedelta):
14871487
elif PyDelta_Check(value):
14881488
value = convert_to_timedelta64(value, 'ns')
14891489
elif is_timedelta64_object(value):
1490-
if unit is not None:
1491-
value = value.astype(f'timedelta64[{unit}]')
14921490
value = ensure_td64ns(value)
14931491
elif is_tick_object(value):
14941492
value = np.timedelta64(value.nanos, 'ns')

pandas/tests/scalar/timedelta/test_constructors.py

+15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@
1313
)
1414

1515

16+
def test_construct_from_td64_with_unit():
17+
# ignore the unit, as it may cause silently overflows leading to incorrect
18+
# results, and in non-overflow cases is irrelevant GH#46827
19+
obj = np.timedelta64(123456789, "h")
20+
21+
with pytest.raises(OutOfBoundsTimedelta, match="123456789 hours"):
22+
Timedelta(obj, unit="ps")
23+
24+
with pytest.raises(OutOfBoundsTimedelta, match="123456789 hours"):
25+
Timedelta(obj, unit="ns")
26+
27+
with pytest.raises(OutOfBoundsTimedelta, match="123456789 hours"):
28+
Timedelta(obj)
29+
30+
1631
def test_construction():
1732
expected = np.timedelta64(10, "D").astype("m8[ns]").view("i8")
1833
assert Timedelta(10, unit="d").value == expected

0 commit comments

Comments
 (0)