Skip to content

Commit d00438b

Browse files
authored
REF: make FreqGroup an Enum (#39027)
1 parent d25b169 commit d00438b

File tree

6 files changed

+29
-29
lines changed

6 files changed

+29
-29
lines changed

pandas/_libs/tslibs/dtypes.pyx

+7-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cdef class PeriodDtypeBase:
2323
return self._dtype_code == other._dtype_code
2424

2525
@property
26-
def freq_group(self) -> int:
26+
def freq_group_code(self) -> int:
2727
# See also: libperiod.get_freq_group
2828
return (self._dtype_code // 1000) * 1000
2929

@@ -37,7 +37,6 @@ cdef class PeriodDtypeBase:
3737
from .offsets import to_offset
3838

3939
freqstr = _reverse_period_code_map.get(self._dtype_code)
40-
# equiv: freqstr = libfrequencies.get_freq_str(self._dtype_code)
4140

4241
return to_offset(freqstr)
4342

@@ -134,7 +133,7 @@ cdef dict attrname_to_abbrevs = _attrname_to_abbrevs
134133
cdef dict _abbrev_to_attrnames = {v: k for k, v in attrname_to_abbrevs.items()}
135134

136135

137-
class FreqGroup:
136+
class FreqGroup(Enum):
138137
# Mirrors c_FreqGroup in the .pxd file
139138
FR_ANN = 1000
140139
FR_QTR = 2000
@@ -151,9 +150,10 @@ class FreqGroup:
151150
FR_UND = -10000 # undefined
152151

153152
@staticmethod
154-
def get_freq_group(code: int) -> int:
155-
# See also: PeriodDtypeBase.freq_group
156-
return (code // 1000) * 1000
153+
def get_freq_group(code: int) -> "FreqGroup":
154+
# See also: PeriodDtypeBase.freq_group_code
155+
code = (code // 1000) * 1000
156+
return FreqGroup(code)
157157

158158

159159
class Resolution(Enum):
@@ -178,8 +178,7 @@ class Resolution(Enum):
178178
return self.value >= other.value
179179

180180
@property
181-
def freq_group(self):
182-
# TODO: annotate as returning FreqGroup once that is an enum
181+
def freq_group(self) -> FreqGroup:
183182
if self == Resolution.RESO_NS:
184183
return FreqGroup.FR_NS
185184
elif self == Resolution.RESO_US:

pandas/core/arrays/period.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1068,11 +1068,11 @@ def _range_from_fields(
10681068
if quarter is not None:
10691069
if freq is None:
10701070
freq = to_offset("Q")
1071-
base = FreqGroup.FR_QTR
1071+
base = FreqGroup.FR_QTR.value
10721072
else:
10731073
freq = to_offset(freq)
10741074
base = libperiod.freq_to_dtype_code(freq)
1075-
if base != FreqGroup.FR_QTR:
1075+
if base != FreqGroup.FR_QTR.value:
10761076
raise AssertionError("base must equal FR_QTR")
10771077

10781078
freqstr = freq.freqstr

pandas/core/indexes/datetimes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ def _parsed_string_to_bounds(self, reso: Resolution, parsed: datetime):
571571
raise KeyError
572572

573573
grp = reso.freq_group
574-
per = Period(parsed, freq=grp)
574+
per = Period(parsed, freq=grp.value)
575575
start, end = per.start_time, per.end_time
576576

577577
# GH 24076

pandas/core/indexes/period.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,8 @@ def get_loc(self, key, method=None, tolerance=None):
506506
raise KeyError(f"Cannot interpret '{key}' as period") from err
507507

508508
reso = Resolution.from_attrname(reso)
509-
grp = reso.freq_group
510-
freqn = self.dtype.freq_group
509+
grp = reso.freq_group.value
510+
freqn = self.dtype.freq_group_code
511511

512512
# _get_string_slice will handle cases where grp < freqn
513513
assert grp >= freqn
@@ -580,15 +580,15 @@ def _maybe_cast_slice_bound(self, label, side: str, kind: str):
580580

581581
def _parsed_string_to_bounds(self, reso: Resolution, parsed: datetime):
582582
grp = reso.freq_group
583-
iv = Period(parsed, freq=grp)
583+
iv = Period(parsed, freq=grp.value)
584584
return (iv.asfreq(self.freq, how="start"), iv.asfreq(self.freq, how="end"))
585585

586586
def _validate_partial_date_slice(self, reso: Resolution):
587587
assert isinstance(reso, Resolution), (type(reso), reso)
588588
grp = reso.freq_group
589-
freqn = self.dtype.freq_group
589+
freqn = self.dtype.freq_group_code
590590

591-
if not grp < freqn:
591+
if not grp.value < freqn:
592592
# TODO: we used to also check for
593593
# reso in ["day", "hour", "minute", "second"]
594594
# why is that check not needed?

pandas/plotting/_matplotlib/converter.py

+13-12
Original file line numberDiff line numberDiff line change
@@ -510,28 +510,28 @@ def _daily_finder(vmin, vmax, freq: BaseOffset):
510510

511511
periodsperday = -1
512512

513-
if dtype_code >= FreqGroup.FR_HR:
514-
if dtype_code == FreqGroup.FR_NS:
513+
if dtype_code >= FreqGroup.FR_HR.value:
514+
if dtype_code == FreqGroup.FR_NS.value:
515515
periodsperday = 24 * 60 * 60 * 1000000000
516-
elif dtype_code == FreqGroup.FR_US:
516+
elif dtype_code == FreqGroup.FR_US.value:
517517
periodsperday = 24 * 60 * 60 * 1000000
518-
elif dtype_code == FreqGroup.FR_MS:
518+
elif dtype_code == FreqGroup.FR_MS.value:
519519
periodsperday = 24 * 60 * 60 * 1000
520-
elif dtype_code == FreqGroup.FR_SEC:
520+
elif dtype_code == FreqGroup.FR_SEC.value:
521521
periodsperday = 24 * 60 * 60
522-
elif dtype_code == FreqGroup.FR_MIN:
522+
elif dtype_code == FreqGroup.FR_MIN.value:
523523
periodsperday = 24 * 60
524-
elif dtype_code == FreqGroup.FR_HR:
524+
elif dtype_code == FreqGroup.FR_HR.value:
525525
periodsperday = 24
526526
else: # pragma: no cover
527527
raise ValueError(f"unexpected frequency: {dtype_code}")
528528
periodsperyear = 365 * periodsperday
529529
periodspermonth = 28 * periodsperday
530530

531-
elif dtype_code == FreqGroup.FR_BUS:
531+
elif dtype_code == FreqGroup.FR_BUS.value:
532532
periodsperyear = 261
533533
periodspermonth = 19
534-
elif dtype_code == FreqGroup.FR_DAY:
534+
elif dtype_code == FreqGroup.FR_DAY.value:
535535
periodsperyear = 365
536536
periodspermonth = 28
537537
elif FreqGroup.get_freq_group(dtype_code) == FreqGroup.FR_WK:
@@ -661,7 +661,7 @@ def _second_finder(label_interval):
661661
elif span <= periodsperyear // 4:
662662
month_start = period_break(dates_, "month")
663663
info_maj[month_start] = True
664-
if dtype_code < FreqGroup.FR_HR:
664+
if dtype_code < FreqGroup.FR_HR.value:
665665
info["min"] = True
666666
else:
667667
day_start = period_break(dates_, "day")
@@ -872,14 +872,15 @@ def _annual_finder(vmin, vmax, freq):
872872
def get_finder(freq: BaseOffset):
873873
dtype_code = freq._period_dtype_code
874874
fgroup = (dtype_code // 1000) * 1000
875+
fgroup = FreqGroup(fgroup)
875876

876877
if fgroup == FreqGroup.FR_ANN:
877878
return _annual_finder
878879
elif fgroup == FreqGroup.FR_QTR:
879880
return _quarterly_finder
880-
elif dtype_code == FreqGroup.FR_MTH:
881+
elif dtype_code == FreqGroup.FR_MTH.value:
881882
return _monthly_finder
882-
elif (dtype_code >= FreqGroup.FR_BUS) or fgroup == FreqGroup.FR_WK:
883+
elif (dtype_code >= FreqGroup.FR_BUS.value) or fgroup == FreqGroup.FR_WK:
883884
return _daily_finder
884885
else: # pragma: no cover
885886
raise NotImplementedError(f"Unsupported frequency: {dtype_code}")

pandas/plotting/_matplotlib/timeseries.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def use_dynamic_x(ax: "Axes", data: FrameOrSeriesUnion) -> bool:
215215
if isinstance(data.index, ABCDatetimeIndex):
216216
base = to_offset(freq)._period_dtype_code
217217
x = data.index
218-
if base <= FreqGroup.FR_DAY:
218+
if base <= FreqGroup.FR_DAY.value:
219219
return x[:1].is_normalized
220220
return Period(x[0], freq).to_timestamp().tz_localize(x.tz) == x[0]
221221
return True

0 commit comments

Comments
 (0)