From a07115bc455b6e5c9b329021be509ba89af0548f Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 10 Apr 2023 10:34:32 -0700 Subject: [PATCH] BUG: disallow constructing Period with freq=C --- doc/source/whatsnew/v2.1.0.rst | 1 + pandas/_libs/tslibs/offsets.pyx | 7 +++++++ pandas/tests/dtypes/test_dtypes.py | 8 ++++++++ pandas/tests/scalar/period/test_period.py | 8 ++++++++ pandas/tseries/frequencies.py | 1 - 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index 9f5d6011a7780..023ef04292e86 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -284,6 +284,7 @@ Period - :meth:`PeriodIndex.map` with ``na_action="ignore"`` now works as expected (:issue:`51644`) - Bug in :class:`PeriodDtype` constructor raising ``ValueError`` instead of ``TypeError`` when an invalid type is passed (:issue:`51790`) - Bug in :meth:`arrays.PeriodArray.map` and :meth:`PeriodIndex.map`, where the supplied callable operated array-wise instead of element-wise (:issue:`51977`) +- Bug in incorrectly allowing construction of :class:`Period` or :class:`PeriodDtype` with :class:`CustomBusinessDay` freq; use :class:`BusinessDay` instead (:issue:`52534`) - Plotting diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 034b5456ce4d8..8bbaafa536457 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -3778,6 +3778,13 @@ cdef class CustomBusinessDay(BusinessDay): ["n", "normalize", "weekmask", "holidays", "calendar", "offset"] ) + @property + def _period_dtype_code(self): + # GH#52534 + raise TypeError( + "CustomBusinessDay cannot be used with Period or PeriodDtype" + ) + _apply_array = BaseOffset._apply_array def __init__( diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py index 2d353bab3ebe8..32ab5abed6f50 100644 --- a/pandas/tests/dtypes/test_dtypes.py +++ b/pandas/tests/dtypes/test_dtypes.py @@ -438,6 +438,14 @@ def test_construction(self): assert dt.freq == pd.tseries.offsets.Hour(26) assert is_period_dtype(dt) + def test_cannot_use_custom_businessday(self): + # GH#52534 + msg = "CustomBusinessDay cannot be used with Period or PeriodDtype" + with pytest.raises(TypeError, match=msg): + PeriodDtype("C") + with pytest.raises(TypeError, match=msg): + PeriodDtype(pd.offsets.CustomBusinessDay()) + def test_subclass(self): a = PeriodDtype("period[D]") b = PeriodDtype("period[3D]") diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py index b8a0a8068ba31..a17079d0e76cb 100644 --- a/pandas/tests/scalar/period/test_period.py +++ b/pandas/tests/scalar/period/test_period.py @@ -34,6 +34,14 @@ class TestPeriodConstruction: + def test_custom_business_day_freq_raises(self): + # GH#52534 + msg = "CustomBusinessDay cannot be used with Period or PeriodDtype" + with pytest.raises(TypeError, match=msg): + Period("2023-04-10", freq="C") + with pytest.raises(TypeError, match=msg): + Period("2023-04-10", freq=offsets.CustomBusinessDay()) + def test_from_td64nat_raises(self): # GH#44507 td = NaT.to_numpy("m8[ns]") diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py index 4ac7f4c8d0a77..f269aaa5db719 100644 --- a/pandas/tseries/frequencies.py +++ b/pandas/tseries/frequencies.py @@ -67,7 +67,6 @@ "BAS": "A", "MS": "M", "D": "D", - "C": "C", "B": "B", "T": "T", "S": "S",