diff --git a/pandas/_libs/src/util.pxd b/pandas/_libs/src/util.pxd index d8249ec130f4d..2c1876fad95d2 100644 --- a/pandas/_libs/src/util.pxd +++ b/pandas/_libs/src/util.pxd @@ -161,3 +161,18 @@ cdef inline bint _checknull(object val): cdef inline bint is_period_object(object val): return getattr(val, '_typ', '_typ') == 'period' + + +cdef inline bint is_offset_object(object val): + """ + Check if an object is a DateOffset object. + + Parameters + ---------- + val : object + + Returns + ------- + is_date_offset : bool + """ + return getattr(val, '_typ', None) == "dateoffset" diff --git a/pandas/_libs/tslib.pyx b/pandas/_libs/tslib.pyx index 4f73f196b0d9d..6588b5476e2b9 100644 --- a/pandas/_libs/tslib.pyx +++ b/pandas/_libs/tslib.pyx @@ -125,7 +125,7 @@ def ints_to_pydatetime(ndarray[int64_t] arr, tz=None, freq=None, elif box == "datetime": func_create = create_datetime_from_ts else: - raise ValueError("box must be one of 'datetime', 'date', 'time' or" + + raise ValueError("box must be one of 'datetime', 'date', 'time' or" " 'timestamp'") if tz is not None: diff --git a/pandas/_libs/tslibs/period.pyx b/pandas/_libs/tslibs/period.pyx index 008747c0a9e78..cc2fb6e0617cb 100644 --- a/pandas/_libs/tslibs/period.pyx +++ b/pandas/_libs/tslibs/period.pyx @@ -19,7 +19,8 @@ from pandas.compat import PY2 cimport cython -from cpython.datetime cimport PyDateTime_Check, PyDateTime_IMPORT +from cpython.datetime cimport (PyDateTime_Check, PyDelta_Check, + PyDateTime_IMPORT) # import datetime C API PyDateTime_IMPORT @@ -1058,18 +1059,21 @@ cdef class _Period(object): return hash((self.ordinal, self.freqstr)) def _add_delta(self, other): - if isinstance(other, (timedelta, np.timedelta64, offsets.Tick)): + cdef: + int64_t nanos, offset_nanos + + if (PyDelta_Check(other) or util.is_timedelta64_object(other) or + isinstance(other, offsets.Tick)): offset = frequencies.to_offset(self.freq.rule_code) if isinstance(offset, offsets.Tick): nanos = delta_to_nanoseconds(other) offset_nanos = delta_to_nanoseconds(offset) - if nanos % offset_nanos == 0: ordinal = self.ordinal + (nanos // offset_nanos) return Period(ordinal=ordinal, freq=self.freq) msg = 'Input cannot be converted to Period(freq={0})' raise IncompatibleFrequency(msg.format(self.freqstr)) - elif isinstance(other, offsets.DateOffset): + elif util.is_offset_object(other): freqstr = other.rule_code base = get_base_alias(freqstr) if base == self.freq.rule_code: @@ -1082,8 +1086,8 @@ cdef class _Period(object): def __add__(self, other): if is_period_object(self): - if isinstance(other, (timedelta, np.timedelta64, - offsets.DateOffset)): + if (PyDelta_Check(other) or util.is_timedelta64_object(other) or + util.is_offset_object(other)): return self._add_delta(other) elif other is NaT: return NaT @@ -1109,8 +1113,8 @@ cdef class _Period(object): def __sub__(self, other): if is_period_object(self): - if isinstance(other, (timedelta, np.timedelta64, - offsets.DateOffset)): + if (PyDelta_Check(other) or util.is_timedelta64_object(other) or + util.is_offset_object(other)): neg_other = -other return self + neg_other elif util.is_integer_object(other):