{"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        # GH#66552 the difference is a count of periods, not an ordinal, so\n        #  INT64_MIN is a legitimate answer here and not the NaT sentinel.\n        new_i8_data = add_overflowsafe(\n            self.asi8, np.asarray(-other_i8, dtype=\"i8\"), sentinel_ok=True\n        )\n        # multiply by python ints: numpy's scalar multiply spuriously reports\n        #  overflow for a np.int64 count of INT64_MIN on Windows\n        counts = new_i8_data.ravel().tolist()\n        new_data = np.array([self.freq.base * count for count in counts]).reshape(\n            new_i8_data.shape\n        )","sourceCodeStart":1223,"sourceCodeEnd":1259,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/datetimelike.py#L1223-L1259","documentation":"Raised by _sub_periodlike when self.dtype is not PeriodDtype. Subtracting a Period or PeriodArray to yield a frequency count (object-dtype ndarray of DateOffsets) is only defined when self is itself a PeriodArray; subtracting a Period from a DatetimeArray or TimedeltaArray is rejected.","triggerScenarios":"DatetimeArray - Period(...); TimedeltaArray - PeriodArray; non-Period datetimelike array minus a Period operand.","commonSituations":"Period vs datetime confusion in calendar/difference code; assuming Period can be subtracted from a Timestamp column to give a duration.","solutions":["Convert self to a PeriodArray (via .to_period(freq)) before subtracting a Period.","If you want point-in-time differences, convert the Period to a Timestamp via .to_timestamp() and subtract Timestamps.","Confirm dtype: only PeriodDtype - Period/PeriodArray is permitted in this path."],"exampleFix":"// before\nres = dta - pd.Period('2020', freq='D')  # TypeError\n\n// after\nres = dta.to_period('D') - pd.Period('2020', freq='D')","handlingStrategy":"type-guard","validationCode":"import pandas as pd\n\ndef sub_period(arr, period):\n    if not isinstance(arr.dtype, pd.PeriodDtype):\n        raise TypeError('self must be a PeriodArray to subtract a Period')\n    return arr - period","typeGuard":"import pandas as pd\n\ndef is_period_array(a) -> bool:\n    return isinstance(getattr(a, 'dtype', None), pd.PeriodDtype)","tryCatchPattern":"try:\n    res = arr - other\nexcept TypeError as e:\n    if 'cannot subtract' in str(e) and 'Period' in str(e):\n        res = arr.to_period(other.freq) - other\n    else:\n        raise","preventionTips":["Only subtract Period/PeriodArray from a PeriodArray.","Convert datetimes via .to_period(freq) before Period subtraction.","For datetime differences, use .to_timestamp() on the Period operand."],"tags":["datetime","arithmetic","period","subtraction","type-error"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}