Repository: pandas-dev/pandas

Issue:
DEPR: freq ''2BQ-SEP" for to_period should raise an error
on the latest main this
```
>>> rng = pd.date_range('01-Jan-2012', periods=8, freq='2BQ-SEP')
<stdin>:1: FutureWarning: 'BQ-SEP' is deprecated and will be removed in a future version, please use 'BQE-SEP' instead.
>>> rng.to_period()
```
works as
```
PeriodIndex(['2012Q1', '2012Q3', '2013Q1', '2013Q3', '2014Q1', '2014Q3',
             '2015Q1', '2015Q3'],
            dtype='period[2Q-DEC]')
```
While before it raised an error
```
AttributeError: 'pandas._libs.tslibs.offsets.BQuarterEnd' object has no attribute '_period_dtype_code'
```



Discussion:

Patch:
diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py
index cd6689e9f1ce2..d5714d5b676fb 100644
--- a/pandas/core/arrays/datetimes.py
+++ b/pandas/core/arrays/datetimes.py
@@ -40,10 +40,7 @@
     tz_convert_from_utc,
     tzconversion,
 )
-from pandas._libs.tslibs.dtypes import (
-    abbrev_to_npy_unit,
-    freq_to_period_freqstr,
-)
+from pandas._libs.tslibs.dtypes import abbrev_to_npy_unit
 from pandas.errors import PerformanceWarning
 from pandas.util._exceptions import find_stack_level
 from pandas.util._validators import validate_inclusive
@@ -1242,8 +1239,10 @@ def to_period(self, freq=None) -> PeriodArray:
 
         if freq is None:
             freq = self.freqstr or self.inferred_freq
-            if isinstance(self.freq, BaseOffset):
-                freq = freq_to_period_freqstr(self.freq.n, self.freq.name)
+            if isinstance(self.freq, BaseOffset) and hasattr(
+                self.freq, "_period_dtype_code"
+            ):
+                freq = PeriodDtype(self.freq)._freqstr
 
             if freq is None:
                 raise ValueError(


Test patch:
diff --git a/pandas/tests/indexes/datetimes/methods/test_to_period.py b/pandas/tests/indexes/datetimes/methods/test_to_period.py
index 42a3f3b0f7b42..00c0216a9b3b5 100644
--- a/pandas/tests/indexes/datetimes/methods/test_to_period.py
+++ b/pandas/tests/indexes/datetimes/methods/test_to_period.py
@@ -111,23 +111,6 @@ def test_to_period_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
         with tm.assert_produces_warning(FutureWarning, match=msg):
             assert prng.freq == freq_depr
 
-    @pytest.mark.parametrize(
-        "freq, freq_depr",
-        [
-            ("2BQE-SEP", "2BQ-SEP"),
-            ("2BYE-MAR", "2BY-MAR"),
-        ],
-    )
-    def test_to_period_frequency_BQ_BY_deprecated(self, freq, freq_depr):
-        # GH#9586
-        msg = f"'{freq_depr[1:]}' is deprecated and will be removed "
-        f"in a future version, please use '{freq[1:]}' instead."
-
-        rng = date_range("01-Jan-2012", periods=8, freq=freq)
-        prng = rng.to_period()
-        with tm.assert_produces_warning(FutureWarning, match=msg):
-            prng.freq == freq_depr
-
     def test_to_period_infer(self):
         # https://github.com/pandas-dev/pandas/issues/33358
         rng = date_range(
diff --git a/pandas/tests/indexes/period/test_constructors.py b/pandas/tests/indexes/period/test_constructors.py
index 387dc47c48d20..0cd4ddef5a3c9 100644
--- a/pandas/tests/indexes/period/test_constructors.py
+++ b/pandas/tests/indexes/period/test_constructors.py
@@ -48,6 +48,15 @@ def test_period_index_frequency_invalid_freq(self, freq_depr):
         with pytest.raises(ValueError, match=msg):
             PeriodIndex(["2020-01", "2020-05"], freq=freq_depr)
 
+    @pytest.mark.parametrize("freq", ["2BQE-SEP", "2BYE-MAR", "2BME"])
+    def test_period_index_from_datetime_index_invalid_freq(self, freq):
+        # GH#56899
+        msg = f"Invalid frequency: {freq[1:]}"
+
+        rng = date_range("01-Jan-2012", periods=8, freq=freq)
+        with pytest.raises(ValueError, match=msg):
+            rng.to_period()
+
 
 class TestPeriodIndex:
     def test_from_ordinals(self):