diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 660cd3af1b35e..baf8889b415fb 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -1325,7 +1325,7 @@ cdef class BusinessDay(BusinessMixin): off_str += str(td.microseconds) + "us" return off_str - if isinstance(self.offset, timedelta): + if PyDelta_Check(self.offset): zero = timedelta(0, 0, 0) if self.offset >= zero: off_str = "+" + get_str(self.offset) @@ -1337,7 +1337,7 @@ cdef class BusinessDay(BusinessMixin): @apply_wraps def apply(self, other): - if isinstance(other, datetime): + if PyDateTime_Check(other): n = self.n wday = other.weekday() @@ -1368,7 +1368,7 @@ cdef class BusinessDay(BusinessMixin): result = result + self.offset return result - elif isinstance(other, (timedelta, Tick)): + elif PyDelta_Check(other) or isinstance(other, Tick): return BusinessDay( self.n, offset=self.offset + other, normalize=self.normalize ) @@ -1649,7 +1649,7 @@ cdef class BusinessHour(BusinessMixin): @apply_wraps def apply(self, other): - if isinstance(other, datetime): + if PyDateTime_Check(other): # used for detecting edge condition nanosecond = getattr(other, "nanosecond", 0) # reset timezone and nanosecond @@ -2511,7 +2511,7 @@ cdef class Week(SingleConstructorOffset): if self.weekday is None: return other + self.n * self._inc - if not isinstance(other, datetime): + if not PyDateTime_Check(other): raise TypeError( f"Cannot add {type(other).__name__} to {type(self).__name__}" ) @@ -3305,7 +3305,7 @@ class CustomBusinessDay(CustomMixin, BusinessDay): else: roll = "backward" - if isinstance(other, datetime): + if PyDateTime_Check(other): date_in = other np_dt = np.datetime64(date_in.date()) @@ -3320,7 +3320,7 @@ class CustomBusinessDay(CustomMixin, BusinessDay): result = result + self.offset return result - elif isinstance(other, (timedelta, Tick)): + elif PyDelta_Check(other) or isinstance(other, Tick): return BDay(self.n, offset=self.offset + other, normalize=self.normalize) else: raise ApplyTypeError( diff --git a/pandas/_libs/tslibs/period.pyx b/pandas/_libs/tslibs/period.pyx index ec6f8de159dae..9757c4d36d5fa 100644 --- a/pandas/_libs/tslibs/period.pyx +++ b/pandas/_libs/tslibs/period.pyx @@ -40,7 +40,10 @@ cimport pandas._libs.tslibs.util as util from pandas._libs.tslibs.timestamps import Timestamp from pandas._libs.tslibs.timezones cimport is_utc, is_tzlocal, get_dst_info from pandas._libs.tslibs.timedeltas import Timedelta -from pandas._libs.tslibs.timedeltas cimport delta_to_nanoseconds +from pandas._libs.tslibs.timedeltas cimport ( + delta_to_nanoseconds, + is_any_td_scalar, +) from pandas._libs.tslibs.ccalendar cimport ( dayofweek, @@ -1591,7 +1594,7 @@ cdef class _Period: return NaT return other.__add__(self) - if is_any_tdlike_scalar(other): + if is_any_td_scalar(other): return self._add_delta(other) elif is_offset_object(other): return self._add_offset(other) @@ -1618,7 +1621,7 @@ cdef class _Period: return NaT return NotImplemented - elif is_any_tdlike_scalar(other): + elif is_any_td_scalar(other): neg_other = -other return self + neg_other elif is_offset_object(other): @@ -2494,18 +2497,3 @@ def validate_end_alias(how): if how not in {'S', 'E'}: raise ValueError('How must be one of S or E') return how - - -cpdef is_any_tdlike_scalar(object obj): - """ - Cython equivalent for `isinstance(obj, (timedelta, np.timedelta64, Tick))` - - Parameters - ---------- - obj : object - - Returns - ------- - bool - """ - return util.is_timedelta64_object(obj) or PyDelta_Check(obj) or is_tick_object(obj) diff --git a/pandas/_libs/tslibs/timedeltas.pxd b/pandas/_libs/tslibs/timedeltas.pxd index 8f9c1b190b021..95ddf8840e65d 100644 --- a/pandas/_libs/tslibs/timedeltas.pxd +++ b/pandas/_libs/tslibs/timedeltas.pxd @@ -3,3 +3,4 @@ from numpy cimport int64_t # Exposed for tslib, not intended for outside use. cpdef int64_t delta_to_nanoseconds(delta) except? -1 cdef convert_to_timedelta64(object ts, object unit) +cdef bint is_any_td_scalar(object obj) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 5bc3694cf8dad..f7f8b86359732 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -446,7 +446,8 @@ cdef inline timedelta_from_spec(object number, object frac, object unit): frac : a list of frac digits unit : a list of unit characters """ - cdef object n + cdef: + str n try: unit = ''.join(unit) @@ -1376,6 +1377,17 @@ class Timedelta(_Timedelta): cdef bint is_any_td_scalar(object obj): + """ + Cython equivalent for `isinstance(obj, (timedelta, np.timedelta64, Tick))` + + Parameters + ---------- + obj : object + + Returns + ------- + bool + """ return ( PyDelta_Check(obj) or is_timedelta64_object(obj) or is_tick_object(obj) ) diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 9fd62e5e25c54..48c4afe7d4c1b 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -808,7 +808,7 @@ class Timestamp(_Timestamp): # check that only ts_input is passed # checking verbosely, because cython doesn't optimize # list comprehensions (as of cython 0.29.x) - if (isinstance(ts_input, Timestamp) and freq is None and + if (isinstance(ts_input, _Timestamp) and freq is None and tz is None and unit is None and year is None and month is None and day is None and hour is None and minute is None and second is None and