Skip to content

REF: make CustomMixin a cdef class #34345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions doc/source/reference/offset_frequency.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ Properties
BusinessDay.normalize
BusinessDay.rule_code
BusinessDay.n
BusinessDay.weekmask
BusinessDay.holidays
BusinessDay.calendar

Methods
~~~~~~~
Expand Down Expand Up @@ -95,6 +98,9 @@ Properties
BusinessHour.n
BusinessHour.start
BusinessHour.end
BusinessHour.weekmask
BusinessHour.holidays
BusinessHour.calendar

Methods
~~~~~~~
Expand Down Expand Up @@ -128,6 +134,9 @@ Properties
CustomBusinessDay.normalize
CustomBusinessDay.rule_code
CustomBusinessDay.n
CustomBusinessDay.weekmask
CustomBusinessDay.calendar
CustomBusinessDay.holidays

Methods
~~~~~~~
Expand Down Expand Up @@ -162,6 +171,9 @@ Properties
CustomBusinessHour.normalize
CustomBusinessHour.rule_code
CustomBusinessHour.n
CustomBusinessHour.weekmask
CustomBusinessHour.calendar
CustomBusinessHour.holidays
CustomBusinessHour.start
CustomBusinessHour.end

Expand Down Expand Up @@ -334,6 +346,9 @@ Properties
CustomBusinessMonthEnd.normalize
CustomBusinessMonthEnd.rule_code
CustomBusinessMonthEnd.n
CustomBusinessMonthEnd.weekmask
CustomBusinessMonthEnd.calendar
CustomBusinessMonthEnd.holidays

Methods
~~~~~~~
Expand Down Expand Up @@ -368,6 +383,9 @@ Properties
CustomBusinessMonthBegin.normalize
CustomBusinessMonthBegin.rule_code
CustomBusinessMonthBegin.n
CustomBusinessMonthBegin.weekmask
CustomBusinessMonthBegin.calendar
CustomBusinessMonthBegin.holidays

Methods
~~~~~~~
Expand Down Expand Up @@ -1241,6 +1259,9 @@ Properties
BDay.offset
BDay.rule_code
BDay.n
BDay.weekmask
BDay.holidays
BDay.calendar

Methods
~~~~~~~
Expand Down Expand Up @@ -1356,6 +1377,9 @@ Properties
CBMonthEnd.offset
CBMonthEnd.rule_code
CBMonthEnd.n
CBMonthEnd.weekmask
CBMonthEnd.holidays
CBMonthEnd.calendar

Methods
~~~~~~~
Expand Down Expand Up @@ -1397,6 +1421,9 @@ Properties
CBMonthBegin.offset
CBMonthBegin.rule_code
CBMonthBegin.n
CBMonthBegin.weekmask
CBMonthBegin.holidays
CBMonthBegin.calendar

Methods
~~~~~~~
Expand Down Expand Up @@ -1435,6 +1462,9 @@ Properties
CDay.offset
CDay.rule_code
CDay.n
CDay.weekmask
CDay.calendar
CDay.holidays

Methods
~~~~~~~
Expand All @@ -1452,6 +1482,7 @@ Methods
CDay.rollforward
CDay.__call__


.. _api.frequencies:

===========
Expand Down
63 changes: 36 additions & 27 deletions pandas/_libs/tslibs/offsets.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1247,11 +1247,27 @@ cdef class BusinessMixin(SingleConstructorOffset):

cdef readonly:
timedelta _offset
# Only Custom subclasses use weekmask, holiday, calendar
object weekmask, holidays, calendar

def __init__(self, n=1, normalize=False, offset=timedelta(0)):
BaseOffset.__init__(self, n, normalize)
self._offset = offset

cpdef _init_custom(self, weekmask, holidays, calendar):
"""
Additional __init__ for Custom subclasses.
"""
calendar, holidays = _get_calendar(
weekmask=weekmask, holidays=holidays, calendar=calendar
)
# Custom offset instances are identified by the
# following two attributes. See DateOffset._params()
# holidays, weekmask
self.weekmask = weekmask
self.holidays = holidays
self.calendar = calendar

@property
def offset(self):
"""
Expand All @@ -1276,6 +1292,18 @@ cdef class BusinessMixin(SingleConstructorOffset):
self._offset = state.pop("_offset")
elif "offset" in state:
self._offset = state.pop("offset")

if self._prefix.startswith("C"):
# i.e. this is a Custom class
weekmask = state.pop("weekmask")
holidays = state.pop("holidays")
calendar, holidays = _get_calendar(weekmask=weekmask,
holidays=holidays,
calendar=None)
self.weekmask = weekmask
self.calendar = calendar
self.holidays = holidays

BaseOffset.__setstate__(self, state)


Expand Down Expand Up @@ -1785,25 +1813,6 @@ cdef class BusinessHour(BusinessMixin):
return False


class CustomMixin:
"""
Mixin for classes that define and validate calendar, holidays,
and weekdays attributes.
"""

def __init__(self, weekmask, holidays, calendar):
calendar, holidays = _get_calendar(
weekmask=weekmask, holidays=holidays, calendar=calendar
)
# Custom offset instances are identified by the
# following two attributes. See DateOffset._params()
# holidays, weekmask

object.__setattr__(self, "weekmask", weekmask)
object.__setattr__(self, "holidays", holidays)
object.__setattr__(self, "calendar", calendar)


cdef class WeekOfMonthMixin(SingleConstructorOffset):
"""
Mixin for methods common to WeekOfMonth and LastWeekOfMonth.
Expand Down Expand Up @@ -3252,7 +3261,7 @@ cdef class Easter(SingleConstructorOffset):
# Custom Offset classes


class CustomBusinessDay(CustomMixin, BusinessDay):
cdef class CustomBusinessDay(BusinessDay):
"""
DateOffset subclass representing custom business days excluding holidays.

Expand Down Expand Up @@ -3291,12 +3300,12 @@ class CustomBusinessDay(CustomMixin, BusinessDay):
offset=timedelta(0),
):
BusinessDay.__init__(self, n, normalize, offset)
CustomMixin.__init__(self, weekmask, holidays, calendar)
self._init_custom(weekmask, holidays, calendar)

def __setstate__(self, state):
cpdef __setstate__(self, state):
self.holidays = state.pop("holidays")
self.weekmask = state.pop("weekmask")
super().__setstate__(state)
BusinessDay.__setstate__(self, state)

@apply_wraps
def apply(self, other):
Expand Down Expand Up @@ -3338,7 +3347,7 @@ class CustomBusinessDay(CustomMixin, BusinessDay):
return np.is_busday(day64, busdaycal=self.calendar)


class CustomBusinessHour(CustomMixin, BusinessHour):
class CustomBusinessHour(BusinessHour):
"""
DateOffset subclass representing possibly n custom business days.
"""
Expand All @@ -3361,7 +3370,7 @@ class CustomBusinessHour(CustomMixin, BusinessHour):
offset=timedelta(0),
):
BusinessHour.__init__(self, n, normalize, start=start, end=end, offset=offset)
CustomMixin.__init__(self, weekmask, holidays, calendar)
self._init_custom(weekmask, holidays, calendar)

def __reduce__(self):
# None for self.calendar bc np.busdaycalendar doesnt pickle nicely
Expand All @@ -3380,7 +3389,7 @@ class CustomBusinessHour(CustomMixin, BusinessHour):
)


class _CustomBusinessMonth(CustomMixin, BusinessMixin, MonthOffset):
class _CustomBusinessMonth(BusinessMixin, MonthOffset):
"""
DateOffset subclass representing custom business month(s).

Expand Down Expand Up @@ -3420,7 +3429,7 @@ class _CustomBusinessMonth(CustomMixin, BusinessMixin, MonthOffset):
offset=timedelta(0),
):
BusinessMixin.__init__(self, n, normalize, offset)
CustomMixin.__init__(self, weekmask, holidays, calendar)
self._init_custom(weekmask, holidays, calendar)

def __reduce__(self):
# None for self.calendar bc np.busdaycalendar doesnt pickle nicely
Expand Down