pandas-dev/pandas · error · TypeError

cannot subtract {type(self).__name__} from {type(other).__na

Error message

cannot subtract {type(self).__name__} from {type(other).__name__}

What it means

Raised by __rsub__ as a final guard when the flipped subtraction (self - other) produces a datetime-kind result, meaning the reflected op other - self would have yielded a datetime — which is not a meaningful 'subtraction from other'. Improved message introduced in GH#59571.

Source

Thrown at pandas/core/arrays/datetimelike.py:1466

            return other - self
        elif self.dtype.kind == "M" and hasattr(other, "dtype") and not other_is_dt64:
            # GH#19959 datetime - datetime is well-defined as timedelta,
            # but any other type - datetime is not well-defined.
            raise TypeError(
                f"cannot subtract {type(self).__name__} from "
                f"{type(other).__name__}[{other.dtype}]"
            )
        elif isinstance(self.dtype, PeriodDtype) and lib.is_np_dtype(other_dtype, "m"):
            # TODO: Can we simplify/generalize these cases at all?
            raise TypeError(f"cannot subtract {type(self).__name__} from {other.dtype}")
        elif lib.is_np_dtype(self.dtype, "m"):
            self = cast("TimedeltaArray", self)
            return (-self) + other

        flipped = self - other
        if flipped.dtype.kind == "M":
            # GH#59571 give a more helpful exception message
            raise TypeError(
                f"cannot subtract {type(self).__name__} from {type(other).__name__}"
            )
        # We get here with e.g. datetime objects
        return -flipped

    def __iadd__(self, other) -> Self:
        result = self + other
        self[:] = result[:]
        return self

    def __isub__(self, other) -> Self:
        result = self - other
        self[:] = result[:]
        return self

    # --------------------------------------------------------------
    # Reductions

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Reorder the expression so the operation is direct, not reflected.
  2. Convert object-dtype operands to explicit DatetimeArray/Timestamp before subtracting.
  3. Use pd.to_datetime(other) - timedelta_idx to make the intent explicit.
  4. Inspect intermediate dtypes to ensure the result is timedelta, not datetime.

Example fix

// before
out = object_series - timedelta_idx  # TypeError: cannot subtract TimedeltaArray from Series
// after
out = pd.to_datetime(object_series) - timedelta_idx
Defensive patterns

Strategy: validation

Validate before calling

if getattr(other, 'dtype', None) == object:
    other = pd.to_datetime(other)
out = other - timedelta_idx

Type guard

def needs_datetime_conversion(other) -> bool:
    return getattr(other, 'dtype', None) == object

Try / catch

try:
    out = other - timedelta_idx
except TypeError as e:
    if 'cannot subtract' in str(e) and 'from' in str(e):
        out = pd.to_datetime(other) - timedelta_idx
    else:
        raise

Prevention

When it happens

Trigger: Subtracting a TimedeltaArray from a non-datelike operand in reflected form, where the internal flip lands back in datetime dtype; reached at line 1466 after the flip computation at line 1463.

Common situations: Generic reflected arithmetic in numpy/pandas expressions; building expressions like list_like - timedelta_idx where list_like is object dtype containing datetimes.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/c39d9da934d9a826. Report an issue: GitHub.