pandas-dev/pandas · error · TypeError

Cannot multiply ' ' by bool, explicitly cast to integers…

Error message

Cannot multiply '{self.dtype}' by bool, explicitly cast to integers instead

What it means

Raised in TimedeltaArray.__mul__ when the scalar operand is a Python/numpy bool. Because multiplying a duration by a boolean is ambiguous (and numpy's silent true->1 promotion was deemed error-prone), pandas explicitly forbids it and directs the caller to cast the bool to integers first. This is the scalar entry; the array-bool case has its own message (GH#58054).

Solutions

  1. Cast the bool to int explicitly: `int(my_bool)` or `.astype(int)` for arrays.
  2. Use a genuine integer/float scalar if a multiplier was intended.

Example fix

# before
pd.to_timedelta([1, 2], unit='D') * True  # TypeError

# after
pd.to_timedelta([1, 2], unit='D') * int(True)
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np

def as_numeric_multiplier(x):
    if isinstance(x, (bool, np.bool_)):
        return int(x)
    return x

Type guard

import numpy as np

def is_valid_td_multiplier(x) -> bool:
    return not isinstance(x, (bool, np.bool_))

Try / catch

try:
    result = td * other
except TypeError as e:
    if 'by bool' in str(e):
        result = td * int(other)
    else:
        raise

Prevention

When it happens

Trigger: `pd.Timedelta('1D') * True`, `pd.to_timedelta([1, 2], unit='D') * np.bool_(True)`, or passing a boolean mask/scalar where an integer was intended.

Common situations: Using a boolean condition or mask result directly as a timedelta multiplier; passing a `np.bool_` from a comparison into arithmetic.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/e75367a212290305. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/timedeltas.py:519

            i8_result[nat_out] = iNaT
        result = i8_result.view(self._ndarray.dtype)
        return type(self)._simple_new(result, dtype=result.dtype)

    def _mul_int_overflowsafe(self, i8_other: npt.NDArray[np.int64]) -> Self:
        # GH#43178: mul_overflowsafe raises the low-level OverflowError; surface
        #  it as OutOfBoundsTimedelta to match pandas' other td64 overflow paths.
        try:
            i8_result = mul_overflowsafe(self.asi8, i8_other)
        except OverflowError as err:
            raise OutOfBoundsTimedelta("Overflow in int64 multiplication") from err
        result = i8_result.view(self._ndarray.dtype)
        return type(self)._simple_new(result, dtype=result.dtype)

    @unpack_zerodim_and_defer("__mul__")
    def __mul__(self, other) -> Self:
        if is_scalar(other):
            if lib.is_bool(other):
                raise TypeError(
                    f"Cannot multiply '{self.dtype}' by bool, explicitly cast to "
                    "integers instead"
                )
            other = _exact_if_integral(other)
            if lib.is_integer(other):
                # GH#43178: detect int64 overflow rather than silently wrapping
                #  in the i8 cast below (e.g. a multiplier outside int64 bounds).
                # TODO(numpy>=2.5): numpy detects this natively (numpy GH-31378)
                #  but raises OverflowError; once the numpy floor is >= 2.5, drop
                #  mul_overflowsafe and re-wrap numpy's error as
                #  OutOfBoundsTimedelta. The non-integral float path isn't
                #  covered and stays.
                other = int(other)
                if other > lib.i8max or other < -lib.i8max - 1:
                    raise OutOfBoundsTimedelta("Overflow in int64 multiplication")
                i8_vals = self.asi8
                if other != 0 and i8_vals.size:
                    # The extreme elements bound all products, so checking them

View on GitHub (pinned to 3b7651241d)