From 4114e605a2f653f88f4296077efffa8a52aa1d89 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Wed, 29 Nov 2023 22:51:09 +0100 Subject: [PATCH 1/3] check freq has attr _period_dtype_code in dt64arr_to_periodarr --- pandas/core/arrays/period.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 57b244e8d02e9..02416cb4e6d8f 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -1174,7 +1174,14 @@ def dt64arr_to_periodarr( reso = get_unit_from_dtype(data.dtype) freq = Period._maybe_convert_freq(freq) - base = freq._period_dtype_code + try: + base = freq._period_dtype_code + except (AttributeError, TypeError): + # AttributeError: _period_dtype_code might not exist + # TypeError: _period_dtype_code might intentionally raise + raise TypeError( + f"{(type(freq).__name__)} is not supported as period frequency" + ) return c_dt64arr_to_periodarr(data.view("i8"), base, tz, reso=reso), freq From a4f7784d0cc4626bf2d15a2f1f303cb08375ab19 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Wed, 29 Nov 2023 23:09:08 +0100 Subject: [PATCH 2/3] fix pre-commit error --- pandas/core/arrays/period.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 02416cb4e6d8f..5cdb30eeb2fed 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -1179,9 +1179,7 @@ def dt64arr_to_periodarr( except (AttributeError, TypeError): # AttributeError: _period_dtype_code might not exist # TypeError: _period_dtype_code might intentionally raise - raise TypeError( - f"{(type(freq).__name__)} is not supported as period frequency" - ) + raise TypeError(f"{(type(freq).__name__)} is not supported as period frequency") return c_dt64arr_to_periodarr(data.view("i8"), base, tz, reso=reso), freq From 21b30732d3339022776cc49768bae118d32b190b Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Thu, 30 Nov 2023 00:52:59 +0100 Subject: [PATCH 3/3] add tests and a note to v2.2.0 --- doc/source/whatsnew/v2.2.0.rst | 1 + pandas/core/arrays/period.py | 2 +- pandas/tests/indexes/datetimes/methods/test_to_period.py | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst index 8cb4b3f24d435..85dfc3ebde873 100644 --- a/doc/source/whatsnew/v2.2.0.rst +++ b/doc/source/whatsnew/v2.2.0.rst @@ -195,6 +195,7 @@ Other enhancements - Allow passing ``read_only``, ``data_only`` and ``keep_links`` arguments to openpyxl using ``engine_kwargs`` of :func:`read_excel` (:issue:`55027`) - DataFrame.apply now allows the usage of numba (via ``engine="numba"``) to JIT compile the passed function, allowing for potential speedups (:issue:`54666`) - Implement masked algorithms for :meth:`Series.value_counts` (:issue:`54984`) +- Improved error message that appears in :meth:`DatetimeIndex.to_period` with frequencies which are not supported as period frequencies, such as "BMS" (:issue:`56243`) - Improved error message when constructing :class:`Period` with invalid offsets such as "QS" (:issue:`55785`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 5cdb30eeb2fed..a8c21cfbb6e2f 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -1179,7 +1179,7 @@ def dt64arr_to_periodarr( except (AttributeError, TypeError): # AttributeError: _period_dtype_code might not exist # TypeError: _period_dtype_code might intentionally raise - raise TypeError(f"{(type(freq).__name__)} is not supported as period frequency") + raise TypeError(f"{freq.name} is not supported as period frequency") return c_dt64arr_to_periodarr(data.view("i8"), base, tz, reso=reso), freq diff --git a/pandas/tests/indexes/datetimes/methods/test_to_period.py b/pandas/tests/indexes/datetimes/methods/test_to_period.py index aa217e895c30a..2c68ddd3d3d15 100644 --- a/pandas/tests/indexes/datetimes/methods/test_to_period.py +++ b/pandas/tests/indexes/datetimes/methods/test_to_period.py @@ -230,3 +230,11 @@ def test_to_period_nofreq(self): idx = DatetimeIndex(["2000-01-01", "2000-01-02", "2000-01-03"]) assert idx.freqstr is None tm.assert_index_equal(idx.to_period(), expected) + + @pytest.mark.parametrize("freq", ["2BMS", "1SME-15"]) + def test_to_period_offsets_not_supported(self, freq): + # GH#56243 + msg = f"{freq[1:]} is not supported as period frequency" + ts = date_range("1/1/2012", periods=4, freq=freq) + with pytest.raises(TypeError, match=msg): + ts.to_period()