Skip to content

Commit ca191f1

Browse files
authored
BUG: Timedelta.__new__ (#48898)
* BUG: Timedelta.__new__ * remove assertion * GH refs * put passed kwargs in exception message
1 parent 39fc318 commit ca191f1

File tree

3 files changed

+32
-3
lines changed

3 files changed

+32
-3
lines changed

doc/source/whatsnew/v1.6.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ Datetimelike
172172
Timedelta
173173
^^^^^^^^^
174174
- Bug in :func:`to_timedelta` raising error when input has nullable dtype ``Float64`` (:issue:`48796`)
175+
- Bug in :class:`Timedelta` constructor incorrectly raising instead of returning ``NaT`` when given a ``np.timedelta64("nat")`` (:issue:`48898`)
176+
- Bug in :class:`Timedelta` constructor failing to raise when passed both a :class:`Timedelta` object and keywords (e.g. days, seconds) (:issue:`48898`)
175177
-
176178

177179
Timezones

pandas/_libs/tslibs/timedeltas.pyx

+12-3
Original file line numberDiff line numberDiff line change
@@ -1662,10 +1662,16 @@ class Timedelta(_Timedelta):
16621662

16631663
# GH 30543 if pd.Timedelta already passed, return it
16641664
# check that only value is passed
1665-
if isinstance(value, _Timedelta) and unit is None and len(kwargs) == 0:
1665+
if isinstance(value, _Timedelta):
1666+
# 'unit' is benign in this case, but e.g. days or seconds
1667+
# doesn't make sense here.
1668+
if len(kwargs):
1669+
# GH#48898
1670+
raise ValueError(
1671+
"Cannot pass both a Timedelta input and timedelta keyword arguments, got "
1672+
f"{list(kwargs.keys())}"
1673+
)
16661674
return value
1667-
elif isinstance(value, _Timedelta):
1668-
value = value.value
16691675
elif isinstance(value, str):
16701676
if unit is not None:
16711677
raise ValueError("unit must not be specified if the value is a str")
@@ -1679,6 +1685,9 @@ class Timedelta(_Timedelta):
16791685
elif PyDelta_Check(value):
16801686
value = convert_to_timedelta64(value, 'ns')
16811687
elif is_timedelta64_object(value):
1688+
if get_timedelta64_value(value) == NPY_NAT:
1689+
# i.e. np.timedelta64("NaT")
1690+
return NaT
16821691
value = ensure_td64ns(value)
16831692
elif is_tick_object(value):
16841693
value = np.timedelta64(value.nanos, 'ns')

pandas/tests/scalar/timedelta/test_constructors.py

+18
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pandas._libs.tslibs import OutOfBoundsTimedelta
88

99
from pandas import (
10+
NaT,
1011
Timedelta,
1112
offsets,
1213
to_timedelta,
@@ -371,6 +372,17 @@ def test_timedelta_constructor_identity():
371372
assert result is expected
372373

373374

375+
def test_timedelta_pass_td_and_kwargs_raises():
376+
# don't silently ignore the kwargs GH#48898
377+
td = Timedelta(days=1)
378+
msg = (
379+
"Cannot pass both a Timedelta input and timedelta keyword arguments, "
380+
r"got \['days'\]"
381+
)
382+
with pytest.raises(ValueError, match=msg):
383+
Timedelta(td, days=2)
384+
385+
374386
@pytest.mark.parametrize(
375387
"constructor, value, unit, expectation",
376388
[
@@ -402,3 +414,9 @@ def test_string_without_numbers(value):
402414
)
403415
with pytest.raises(ValueError, match=msg):
404416
Timedelta(value)
417+
418+
419+
def test_timedelta_new_npnat():
420+
# GH#48898
421+
nat = np.timedelta64("NaT", "h")
422+
assert Timedelta(nat) is NaT

0 commit comments

Comments
 (0)