pandas-dev/pandas · error · TypeError

cannot add Period to a

Error message

cannot add Period to a {type(self).__name__}

What it means

Raised by _add_period when self.dtype is not timedelta64. Only TimedeltaArray + Period -> PeriodArray is defined (a duration shifts a period); adding a Period to a DatetimeArray or to another PeriodArray is rejected.

Solutions

  1. Add the Period to a TimedeltaArray/TimedeltaIndex, or use PeriodArray + Timedelta.
  2. Convert the Period to a Timestamp via .to_timestamp() if you need datetime arithmetic.
  3. For Period-on-Period differences, subtract instead of add to get an int frequency count.

Example fix

// before
res = dta + pd.Period('2020', freq='D')  # TypeError

// after
res = tda + pd.Period('2020', freq='D')   # TimedeltaArray + Period
# or
res = dta + pd.Timedelta(days=1)
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd

def add_period(arr, period):
    if not isinstance(period, pd.Period):
        raise TypeError('expected a pd.Period')
    if arr.dtype.kind != 'm':
        raise TypeError('Period can only be added to a TimedeltaArray')
    return arr + period

Type guard

import pandas as pd

def is_period(v) -> bool:
    return isinstance(v, pd.Period)

Try / catch

try:
    res = arr + other
except TypeError as e:
    if 'cannot add Period' in str(e):
        res = arr + pd.Timedelta(other.freq)  # only if a timedelta equivalent exists
    else:
        raise

Prevention

When it happens

Trigger: DatetimeArray + Period(...); PeriodArray + Period(...); adding a pd.Period scalar to a non-timedelta datetimelike array.

Common situations: Period arithmetic confusion: assuming Period + Period composes; mixing Period and Timestamp semantics in financial/calendar code.

Related errors


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

Appendix: source

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

        from pandas.core.arrays import TimedeltaArray

        try:
            self._assert_tzawareness_compat(other)
        except TypeError as err:
            new_message = str(err).replace("compare", "subtract")
            raise type(err)(new_message) from err

        other_i8, o_mask = self._get_i8_values_and_mask(other)
        res_values = add_overflowsafe(self.asi8, np.asarray(-other_i8, dtype="i8"))
        res_m8 = res_values.view(f"timedelta64[{self.unit}]")

        return TimedeltaArray._simple_new(res_m8, dtype=res_m8.dtype)

    @final
    def _add_period(self, other: Period) -> PeriodArray:
        if not lib.is_np_dtype(self.dtype, "m"):
            raise TypeError(f"cannot add Period to a {type(self).__name__}")

        # We will wrap in a PeriodArray and defer to the reversed operation
        from pandas.core.arrays.period import PeriodArray

        i8vals = np.broadcast_to(other.ordinal, self.shape)
        dtype = PeriodDtype(other.freq)
        parr = PeriodArray(i8vals, dtype=dtype)
        return parr + self

    def _add_offset(self, offset):
        raise AbstractMethodError(self)

    def _add_timedeltalike_scalar(self, other):
        """
        Add a delta of a timedeltalike

        Returns
        -------

View on GitHub (pinned to 3b7651241d)