{"record":{"id":"89cfe4c058eead9d","repo":"pandas-dev/pandas","slug":"cannot-subtract-type-other-name-from-type","errorCode":null,"errorMessage":"cannot subtract {type(other).__name__} from {type(self).__name__}","messagePattern":"cannot subtract (.+?) from (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimelike.py","lineNumber":1241,"sourceCode":"        # like a timedelta.\n        # For datetime64 dtypes by convention we treat NaT as a datetime, so\n        # this subtraction returns a timedelta64 dtype.\n        # For period dtype, timedelta64 is a close-enough return dtype.\n        result = np.empty(self.shape, dtype=np.int64)\n        result.fill(iNaT)\n        if self.dtype.kind in \"mM\":\n            # We can retain unit in dtype\n            self = cast(\"DatetimeArray| TimedeltaArray\", self)\n            return result.view(f\"timedelta64[{self.unit}]\")\n        else:\n            return result.view(\"timedelta64[ns]\")\n\n    @final\n    def _sub_periodlike(self, other: Period | PeriodArray) -> npt.NDArray[np.object_]:\n        # If the operation is well-defined, we return an object-dtype ndarray\n        # of DateOffsets.  Null entries are filled with pd.NaT\n        if not isinstance(self.dtype, PeriodDtype):\n            raise TypeError(\n                f\"cannot subtract {type(other).__name__} from {type(self).__name__}\"\n            )\n\n        self = cast(\"PeriodArray\", self)\n        self._check_compatible_with(other)\n\n        other_i8, o_mask = self._get_i8_values_and_mask(other)\n        new_i8_data = add_overflowsafe(self.asi8, np.asarray(-other_i8, dtype=\"i8\"))\n        new_data = np.array([self.freq.base * x for x in new_i8_data])\n\n        if o_mask is None:\n            # i.e. Period scalar\n            mask = self._isnan\n        else:\n            # i.e. PeriodArray\n            mask = self._isnan | o_mask\n        new_data[mask] = NaT\n        return new_data","sourceCodeStart":1223,"sourceCodeEnd":1259,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/datetimelike.py#L1223-L1259","documentation":"Raised by _sub_periodlike when self.dtype is not PeriodDtype. Subtracting a Period (or PeriodArray) is only defined for PeriodArray operands (yielding an object ndarray of DateOffsets); doing it against DatetimeArray or TimedeltaArray is rejected.","triggerScenarios":"DatetimeIndex - pd.Period(...) or TimedeltaIndex - PeriodArray, dispatched via __sub__ line 1398-1399 into _sub_periodlike at line 1237; the PeriodDtype check at line 1240 fires.","commonSituations":"Mixing Period and datetime columns in subtraction; assuming Period behaves like a datetime or offset.","solutions":["Convert the Period to a Timestamp first: idx - period.to_timestamp().","For PeriodIndex, use idx - other_period to get a DateOffset result.","Add the appropriate DateOffset (negative) instead of subtracting a Period from a DatetimeIndex.","Check isinstance(idx.dtype, pd.PeriodDtype) before subtracting a Period."],"exampleFix":"// before\nout = datetime_idx - pd.Period('2020-01', 'M')  # TypeError\n// after\nout = datetime_idx - pd.Period('2020-01', 'M').to_timestamp()","handlingStrategy":"type-guard","validationCode":"from pandas.api.types import is_period_dtype\nif not is_period_dtype(idx.dtype):\n    out = idx - period.to_timestamp()\nelse:\n    out = idx - period","typeGuard":"def accepts_period_subtraction(idx) -> bool:\n    from pandas.api.types import is_period_dtype\n    return is_period_dtype(idx.dtype)","tryCatchPattern":"try:\n    out = idx - period\nexcept TypeError as e:\n    if 'cannot subtract' in str(e) and 'Period' in str(e):\n        out = idx - period.to_timestamp()\n    else:\n        raise","preventionTips":["Only PeriodArray supports subtracting a Period operand.","Convert Period to Timestamp before datetime arithmetic.","Guard on isinstance(idx.dtype, pd.PeriodDtype)."],"tags":["subtraction","period","type-mismatch"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}