Skip to content

Commit ade778e

Browse files
authored
BUG: timedelta64 * bool failing to raise (#62248)
1 parent 4e474f4 commit ade778e

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,7 @@ Timedelta
895895
- Accuracy improvement in :meth:`Timedelta.to_pytimedelta` to round microseconds consistently for large nanosecond based Timedelta (:issue:`57841`)
896896
- Bug in :class:`Timedelta` constructor failing to raise when passed an invalid keyword (:issue:`53801`)
897897
- Bug in :meth:`DataFrame.cumsum` which was raising ``IndexError`` if dtype is ``timedelta64[ns]`` (:issue:`57956`)
898+
- Bug in multiplication operations with ``timedelta64`` dtype failing to raise ``TypeError`` when multiplying by ``bool`` objects or dtypes (:issue:`58054`)
898899

899900
Timezones
900901
^^^^^^^^^

pandas/core/arrays/timedeltas.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,11 @@ def _add_offset(self, other):
472472
@unpack_zerodim_and_defer("__mul__")
473473
def __mul__(self, other) -> Self:
474474
if is_scalar(other):
475+
if lib.is_bool(other):
476+
raise TypeError(
477+
f"Cannot multiply '{self.dtype}' by bool, explicitly cast to "
478+
"integers instead"
479+
)
475480
# numpy will accept float and int, raise TypeError for others
476481
result = self._ndarray * other
477482
if result.dtype.kind != "m":
@@ -489,6 +494,13 @@ def __mul__(self, other) -> Self:
489494
if not hasattr(other, "dtype"):
490495
# list, tuple
491496
other = np.array(other)
497+
498+
if other.dtype.kind == "b":
499+
# GH#58054
500+
raise TypeError(
501+
f"Cannot multiply '{self.dtype}' by bool, explicitly cast to "
502+
"integers instead"
503+
)
492504
if len(other) != len(self) and not lib.is_np_dtype(other.dtype, "m"):
493505
# Exclude timedelta64 here so we correctly raise TypeError
494506
# for that instead of ValueError

pandas/tests/arithmetic/test_timedelta64.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from pandas._libs.tslibs import timezones
1212
from pandas.compat import WASM
1313
from pandas.errors import OutOfBoundsDatetime
14+
import pandas.util._test_decorators as td
1415

1516
import pandas as pd
1617
from pandas import (
@@ -1556,6 +1557,51 @@ def test_tdi_rmul_arraylike(self, other, box_with_array):
15561557
commute = tdi * other
15571558
tm.assert_equal(commute, expected)
15581559

1560+
def test_td64arr_mul_bool_scalar_raises(self, box_with_array):
1561+
# GH#58054
1562+
ser = Series(np.arange(5) * timedelta(hours=1))
1563+
obj = tm.box_expected(ser, box_with_array)
1564+
1565+
msg = r"Cannot multiply 'timedelta64\[ns\]' by bool"
1566+
with pytest.raises(TypeError, match=msg):
1567+
True * obj
1568+
with pytest.raises(TypeError, match=msg):
1569+
obj * True
1570+
with pytest.raises(TypeError, match=msg):
1571+
np.True_ * obj
1572+
with pytest.raises(TypeError, match=msg):
1573+
obj * np.True_
1574+
1575+
@pytest.mark.parametrize(
1576+
"dtype",
1577+
[
1578+
bool,
1579+
"boolean",
1580+
pytest.param("bool[pyarrow]", marks=td.skip_if_no("pyarrow")),
1581+
],
1582+
)
1583+
def test_td64arr_mul_bool_raises(self, dtype, box_with_array):
1584+
# GH#58054
1585+
ser = Series(np.arange(5) * timedelta(hours=1))
1586+
obj = tm.box_expected(ser, box_with_array)
1587+
1588+
other = Series(np.arange(5) < 0.5, dtype=dtype)
1589+
other = tm.box_expected(other, box_with_array)
1590+
1591+
msg = r"Cannot multiply 'timedelta64\[ns\]' by bool"
1592+
with pytest.raises(TypeError, match=msg):
1593+
obj * other
1594+
1595+
msg2 = msg.replace("rmul", "mul")
1596+
if dtype == "bool[pyarrow]":
1597+
# We go through ArrowEA.__mul__ which gives a different message
1598+
msg2 = (
1599+
r"operation 'mul' not supported for dtype 'bool\[pyarrow\]' "
1600+
r"with dtype 'timedelta64\[ns\]'"
1601+
)
1602+
with pytest.raises(TypeError, match=msg2):
1603+
other * obj
1604+
15591605
# ------------------------------------------------------------------
15601606
# __div__, __rdiv__
15611607

0 commit comments

Comments
 (0)