From b37bcdafed6c520907b4f80a51452e9356bf53b1 Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Tue, 31 Oct 2023 10:21:03 +0100
Subject: [PATCH 01/10] rename Y to YE for offsets

---
 pandas/_libs/tslibs/dtypes.pyx  | 26 ++++++++++++++++++++++++++
 pandas/_libs/tslibs/offsets.pyx |  8 ++++----
 pandas/core/resample.py         |  4 ++--
 pandas/tseries/frequencies.py   |  2 +-
 4 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/pandas/_libs/tslibs/dtypes.pyx b/pandas/_libs/tslibs/dtypes.pyx
index ac0b15dc73a8d..115954b4ed6fe 100644
--- a/pandas/_libs/tslibs/dtypes.pyx
+++ b/pandas/_libs/tslibs/dtypes.pyx
@@ -214,6 +214,19 @@ OFFSET_TO_PERIOD_FREQSTR: dict = {
     "QE-SEP": "Q-SEP",
     "QE-OCT": "Q-OCT",
     "QE-NOV": "Q-NOV",
+    "YE": "Y",
+    "YE-DEC": "Y-DEC",
+    "YE-JAN": "Y-JAN",
+    "YE-FEB": "Y-FEB",
+    "YE-MAR": "Y-MAR",
+    "YE-APR": "Y-APR",
+    "YE-MAY": "Y-MAY",
+    "YE-JUN": "Y-JUN",
+    "YE-JUL": "Y-JUL",
+    "YE-AUG": "Y-AUG",
+    "YE-SEP": "Y-SEP",
+    "YE-OCT": "Y-OCT",
+    "YE-NOV": "Y-NOV",
     "W": "W",
     "ME": "M",
     "Y": "Y",
@@ -236,6 +249,19 @@ OFFSET_DEPR_FREQSTR: dict[str, str]= {
     "Q-SEP": "QE-SEP",
     "Q-OCT": "QE-OCT",
     "Q-NOV": "QE-NOV",
+    "Y": "YE",
+    "Y-DEC": "YE-DEC",
+    "Y-JAN": "YE-JAN",
+    "Y-FEB": "YE-FEB",
+    "Y-MAR": "YE-MAR",
+    "Y-APR": "YE-APR",
+    "Y-MAY": "YE-MAY",
+    "Y-JUN": "YE-JUN",
+    "Y-JUL": "YE-JUL",
+    "Y-AUG": "YE-AUG",
+    "Y-SEP": "YE-SEP",
+    "Y-OCT": "YE-OCT",
+    "Y-NOV": "YE-NOV",
 }
 cdef dict c_OFFSET_TO_PERIOD_FREQSTR = OFFSET_TO_PERIOD_FREQSTR
 cdef dict c_OFFSET_DEPR_FREQSTR = OFFSET_DEPR_FREQSTR
diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx
index c23bccdea3a8a..fb12976ceccaa 100644
--- a/pandas/_libs/tslibs/offsets.pyx
+++ b/pandas/_libs/tslibs/offsets.pyx
@@ -2518,7 +2518,7 @@ cdef class YearEnd(YearOffset):
     """
 
     _default_month = 12
-    _prefix = "Y"
+    _prefix = "YE"
     _day_opt = "end"
 
     cdef readonly:
@@ -4562,7 +4562,7 @@ prefix_mapping = {
     offset._prefix: offset
     for offset in [
         YearBegin,  # 'YS'
-        YearEnd,  # 'Y'
+        YearEnd,  # 'YE'
         BYearBegin,  # 'BYS'
         BYearEnd,  # 'BY'
         BusinessDay,  # 'B'
@@ -4604,7 +4604,7 @@ _lite_rule_alias = {
     "W": "W-SUN",
     "QE": "QE-DEC",
 
-    "Y": "Y-DEC",      # YearEnd(month=12),
+    "YE": "YE-DEC",      # YearEnd(month=12),
     "YS": "YS-JAN",    # YearBegin(month=1),
     "BY": "BY-DEC",    # BYearEnd(month=12),
     "BYS": "BYS-JAN",  # BYearBegin(month=1),
@@ -4616,7 +4616,7 @@ _lite_rule_alias = {
     "ns": "ns",
 }
 
-_dont_uppercase = {"h", "bh", "cbh", "MS", "ms", "s", "me", "qe"}
+_dont_uppercase = {"h", "bh", "cbh", "MS", "ms", "s", "me", "qe", "ye"}
 
 
 INVALID_FREQ_ERR_MSG = "Invalid frequency: {0}"
diff --git a/pandas/core/resample.py b/pandas/core/resample.py
index d648a0afb8ce4..0827f9c8da4cc 100644
--- a/pandas/core/resample.py
+++ b/pandas/core/resample.py
@@ -2130,7 +2130,7 @@ def __init__(
         else:
             freq = to_offset(freq)
 
-        end_types = {"ME", "Y", "QE", "BME", "BY", "BQ", "W"}
+        end_types = {"ME", "YE", "QE", "BME", "BY", "BQ", "W"}
         rule = freq.rule_code
         if rule in end_types or ("-" in rule and rule[: rule.find("-")] in end_types):
             if closed is None:
@@ -2330,7 +2330,7 @@ def _adjust_bin_edges(
             "BQ",
             "BY",
             "QE",
-            "Y",
+            "YE",
             "W",
         ):
             # If the right end-point is on the last day of the month, roll forwards
diff --git a/pandas/tseries/frequencies.py b/pandas/tseries/frequencies.py
index 7a6083f2246b1..8460ef5826e34 100644
--- a/pandas/tseries/frequencies.py
+++ b/pandas/tseries/frequencies.py
@@ -345,7 +345,7 @@ def _get_annual_rule(self) -> str | None:
         if pos_check is None:
             return None
         else:
-            return {"cs": "YS", "bs": "BYS", "ce": "Y", "be": "BY"}.get(pos_check)
+            return {"cs": "YS", "bs": "BYS", "ce": "YE", "be": "BY"}.get(pos_check)
 
     def _get_quarterly_rule(self) -> str | None:
         if len(self.mdiffs) > 1:

From d8f49d771083e395c209ed3badec15149cfbe1c5 Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Wed, 1 Nov 2023 09:15:45 +0100
Subject: [PATCH 02/10] fix tests

---
 pandas/_libs/tslibs/dtypes.pyx                | 13 ++++++
 pandas/_libs/tslibs/offsets.pyx               |  7 ++++
 .../datetimes/methods/test_resolution.py      |  2 +-
 .../indexes/datetimes/methods/test_round.py   |  2 +-
 .../datetimes/methods/test_to_period.py       |  2 +-
 .../indexes/datetimes/test_constructors.py    | 10 ++---
 .../indexes/datetimes/test_date_range.py      | 42 ++++++++++++++-----
 .../tests/indexes/period/test_constructors.py |  2 +-
 pandas/tests/indexes/period/test_period.py    | 17 +++++---
 .../tests/indexes/period/test_period_range.py |  2 +-
 .../indexes/timedeltas/test_scalar_compat.py  |  2 +-
 pandas/tests/plotting/test_datetimelike.py    | 18 ++++----
 pandas/tests/resample/test_base.py            |  2 +-
 pandas/tests/resample/test_datetime_index.py  | 14 +++----
 pandas/tests/resample/test_period_index.py    | 26 ++++++------
 pandas/tests/resample/test_resample_api.py    |  8 ++--
 .../tests/resample/test_resampler_grouper.py  |  2 +-
 pandas/tests/resample/test_time_grouper.py    |  8 ++--
 pandas/tests/reshape/concat/test_concat.py    |  4 +-
 pandas/tests/reshape/test_pivot.py            | 10 ++---
 pandas/tests/scalar/period/test_period.py     |  6 +--
 .../scalar/timedelta/methods/test_round.py    |  2 +-
 .../tseries/frequencies/test_inference.py     | 32 +++++++-------
 23 files changed, 139 insertions(+), 94 deletions(-)

diff --git a/pandas/_libs/tslibs/dtypes.pyx b/pandas/_libs/tslibs/dtypes.pyx
index 115954b4ed6fe..a8dc6b12a54b5 100644
--- a/pandas/_libs/tslibs/dtypes.pyx
+++ b/pandas/_libs/tslibs/dtypes.pyx
@@ -262,6 +262,19 @@ OFFSET_DEPR_FREQSTR: dict[str, str]= {
     "Y-SEP": "YE-SEP",
     "Y-OCT": "YE-OCT",
     "Y-NOV": "YE-NOV",
+    "A": "YE",
+    "A-DEC": "YE-DEC",
+    "A-JAN": "YE-JAN",
+    "A-FEB": "YE-FEB",
+    "A-MAR": "YE-MAR",
+    "A-APR": "YE-APR",
+    "A-MAY": "YE-MAY",
+    "A-JUN": "YE-JUN",
+    "A-JUL": "YE-JUL",
+    "A-AUG": "YE-AUG",
+    "A-SEP": "YE-SEP",
+    "A-OCT": "YE-OCT",
+    "A-NOV": "YE-NOV",
 }
 cdef dict c_OFFSET_TO_PERIOD_FREQSTR = OFFSET_TO_PERIOD_FREQSTR
 cdef dict c_OFFSET_DEPR_FREQSTR = OFFSET_DEPR_FREQSTR
diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx
index fb12976ceccaa..77958778aef73 100644
--- a/pandas/_libs/tslibs/offsets.pyx
+++ b/pandas/_libs/tslibs/offsets.pyx
@@ -4741,6 +4741,13 @@ cpdef to_offset(freq, bint is_period=False):
                         f"instead of \'{name}\'"
                     )
                 elif is_period is True and name in c_OFFSET_DEPR_FREQSTR:
+                    if name.startswith("A"):
+                        warnings.warn(
+                            f"\'{name}\' will be deprecated, please use "
+                            f"\'{c_DEPR_ABBREVS.get(name)}\' instead.",
+                            FutureWarning,
+                            stacklevel=find_stack_level(),
+                        )
                     name = c_OFFSET_DEPR_FREQSTR.get(name)
 
                 if sep != "" and not sep.isspace():
diff --git a/pandas/tests/indexes/datetimes/methods/test_resolution.py b/pandas/tests/indexes/datetimes/methods/test_resolution.py
index 5dcf2ad2a5a80..ea59cc3d45971 100644
--- a/pandas/tests/indexes/datetimes/methods/test_resolution.py
+++ b/pandas/tests/indexes/datetimes/methods/test_resolution.py
@@ -9,7 +9,7 @@
 @pytest.mark.parametrize(
     "freq,expected",
     [
-        ("Y", "day"),
+        ("YE", "day"),
         ("QE", "day"),
         ("ME", "day"),
         ("D", "day"),
diff --git a/pandas/tests/indexes/datetimes/methods/test_round.py b/pandas/tests/indexes/datetimes/methods/test_round.py
index 6c9fb8ded0650..dbfe54bad37ce 100644
--- a/pandas/tests/indexes/datetimes/methods/test_round.py
+++ b/pandas/tests/indexes/datetimes/methods/test_round.py
@@ -29,7 +29,7 @@ def test_round_daily(self):
     @pytest.mark.parametrize(
         "freq, error_msg",
         [
-            ("Y", "<YearEnd: month=12> is a non-fixed frequency"),
+            ("YE", "<YearEnd: month=12> is a non-fixed frequency"),
             ("ME", "<MonthEnd> is a non-fixed frequency"),
             ("foobar", "Invalid frequency: foobar"),
         ],
diff --git a/pandas/tests/indexes/datetimes/methods/test_to_period.py b/pandas/tests/indexes/datetimes/methods/test_to_period.py
index c6fbf0f8d4489..b83b5aaa75836 100644
--- a/pandas/tests/indexes/datetimes/methods/test_to_period.py
+++ b/pandas/tests/indexes/datetimes/methods/test_to_period.py
@@ -60,7 +60,7 @@ def test_to_period_quarterlyish(self, off):
     def test_to_period_annualish(self, off):
         rng = date_range("01-Jan-2012", periods=8, freq=off)
         prng = rng.to_period()
-        assert prng.freq == "Y-DEC"
+        assert prng.freq == "YE-DEC"
 
     def test_to_period_monthish(self):
         offsets = ["MS", "BME"]
diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py
index ef86e7800dbb7..4e93d1289da36 100644
--- a/pandas/tests/indexes/datetimes/test_constructors.py
+++ b/pandas/tests/indexes/datetimes/test_constructors.py
@@ -764,7 +764,7 @@ def test_constructor_invalid_dtype_raises(self, dtype):
             DatetimeIndex([1, 2], dtype=dtype)
 
     def test_constructor_name(self):
-        idx = date_range(start="2000-01-01", periods=1, freq="Y", name="TEST")
+        idx = date_range(start="2000-01-01", periods=1, freq="YE", name="TEST")
         assert idx.name == "TEST"
 
     def test_000constructor_resolution(self):
@@ -851,7 +851,7 @@ def test_construction_from_replaced_timestamps_with_dst(self):
             tz="Australia/Melbourne",
         )
         test = pd.DataFrame({"data": range(len(index))}, index=index)
-        test = test.resample("Y").mean()
+        test = test.resample("YE").mean()
         result = DatetimeIndex([x.replace(month=6, day=1) for x in test.index])
         expected = DatetimeIndex(
             [
@@ -1077,8 +1077,8 @@ def test_dti_constructor_years_only(self, tz_naive_fixture):
         rng2 = date_range("2014", "2015", freq="MS", tz=tz)
         expected2 = date_range("2014-01-01", "2015-01-01", freq="MS", tz=tz)
 
-        rng3 = date_range("2014", "2020", freq="Y", tz=tz)
-        expected3 = date_range("2014-12-31", "2019-12-31", freq="Y", tz=tz)
+        rng3 = date_range("2014", "2020", freq="YE", tz=tz)
+        expected3 = date_range("2014-12-31", "2019-12-31", freq="YE", tz=tz)
 
         rng4 = date_range("2014", "2020", freq="YS", tz=tz)
         expected4 = date_range("2014-01-01", "2020-01-01", freq="YS", tz=tz)
@@ -1136,7 +1136,7 @@ def test_constructor_int64_nocopy(self):
 
     @pytest.mark.parametrize(
         "freq",
-        ["ME", "QE", "Y", "D", "B", "bh", "min", "s", "ms", "us", "h", "ns", "C"],
+        ["ME", "QE", "YE", "D", "B", "bh", "min", "s", "ms", "us", "h", "ns", "C"],
     )
     def test_from_freq_recreate_from_data(self, freq):
         org = date_range(start="2001/02/01 09:00", freq=freq, periods=1)
diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py
index e902c8236894e..1eeadab0237d7 100644
--- a/pandas/tests/indexes/datetimes/test_date_range.py
+++ b/pandas/tests/indexes/datetimes/test_date_range.py
@@ -268,9 +268,9 @@ def test_begin_year_alias(self):
 
     def test_end_year_alias(self):
         # see gh-9313
-        rng = date_range("1/1/2013", "7/1/2017", freq="Y")
+        rng = date_range("1/1/2013", "7/1/2017", freq="YE")
         exp = DatetimeIndex(
-            ["2013-12-31", "2014-12-31", "2015-12-31", "2016-12-31"], freq="Y"
+            ["2013-12-31", "2014-12-31", "2015-12-31", "2016-12-31"], freq="YE"
         )
         tm.assert_index_equal(rng, exp)
 
@@ -284,10 +284,10 @@ def test_business_end_year_alias(self):
 
     def test_date_range_negative_freq(self):
         # GH 11018
-        rng = date_range("2011-12-31", freq="-2Y", periods=3)
-        exp = DatetimeIndex(["2011-12-31", "2009-12-31", "2007-12-31"], freq="-2Y")
+        rng = date_range("2011-12-31", freq="-2YE", periods=3)
+        exp = DatetimeIndex(["2011-12-31", "2009-12-31", "2007-12-31"], freq="-2YE")
         tm.assert_index_equal(rng, exp)
-        assert rng.freq == "-2Y"
+        assert rng.freq == "-2YE"
 
         rng = date_range("2011-01-31", freq="-2ME", periods=3)
         exp = DatetimeIndex(["2011-01-31", "2010-11-30", "2010-09-30"], freq="-2ME")
@@ -650,7 +650,7 @@ def test_range_tz_dateutil(self):
         assert dr[0] == start
         assert dr[2] == end
 
-    @pytest.mark.parametrize("freq", ["1D", "3D", "2ME", "7W", "3h", "Y"])
+    @pytest.mark.parametrize("freq", ["1D", "3D", "2ME", "7W", "3h", "YE"])
     def test_range_closed(self, freq, inclusive_endpoints_fixture):
         begin = datetime(2011, 1, 1)
         end = datetime(2014, 1, 1)
@@ -665,7 +665,7 @@ def test_range_closed(self, freq, inclusive_endpoints_fixture):
 
         tm.assert_index_equal(expected_range, result_range)
 
-    @pytest.mark.parametrize("freq", ["1D", "3D", "2ME", "7W", "3h", "Y"])
+    @pytest.mark.parametrize("freq", ["1D", "3D", "2ME", "7W", "3h", "YE"])
     def test_range_closed_with_tz_aware_start_end(
         self, freq, inclusive_endpoints_fixture
     ):
@@ -686,7 +686,7 @@ def test_range_closed_with_tz_aware_start_end(
 
         tm.assert_index_equal(expected_range, result_range)
 
-    @pytest.mark.parametrize("freq", ["1D", "3D", "2ME", "7W", "3h", "Y"])
+    @pytest.mark.parametrize("freq", ["1D", "3D", "2ME", "7W", "3h", "YE"])
     def test_range_with_tz_closed_with_tz_aware_start_end(
         self, freq, inclusive_endpoints_fixture
     ):
@@ -851,8 +851,6 @@ def test_freq_dateoffset_with_relateivedelta_nanos(self):
     @pytest.mark.parametrize(
         "freq,freq_depr",
         [
-            ("2Y", "2A"),
-            ("200Y-MAY", "200A-MAY"),
             ("h", "H"),
             ("2min", "2T"),
             ("1s", "1S"),
@@ -861,7 +859,7 @@ def test_freq_dateoffset_with_relateivedelta_nanos(self):
             ("2ns", "2N"),
         ],
     )
-    def test_frequencies_A_T_S_L_U_N_deprecated(self, freq, freq_depr):
+    def test_frequencies_H_T_S_L_U_N_deprecated(self, freq, freq_depr):
         # GH#52536
         freq_msg = re.split("[0-9]*", freq_depr, maxsplit=1)[1]
         msg = f"'{freq_msg}' is deprecated and will be removed in a future version."
@@ -871,6 +869,28 @@ def test_frequencies_A_T_S_L_U_N_deprecated(self, freq, freq_depr):
             result = date_range("1/1/2000", periods=2, freq=freq_depr)
         tm.assert_index_equal(result, expected)
 
+    @pytest.mark.parametrize(
+        "freq,freq_depr",
+        [
+            ("200YE", "200A"),
+            ("YE", "Y"),
+            ("2YE-MAY", "2A-MAY"),
+            ("YE-MAY", "Y-MAY"),
+        ],
+    )
+    def test_frequencies_A_deprecated_Y_renamed(self, freq, freq_depr): 
+        # GH#9586, GH#52536
+        freq_msg = re.split("[0-9]*", freq, maxsplit=1)[1]
+        freq_depr_msg = re.split("[0-9]*", freq_depr, maxsplit=1)[1]
+        msg = (
+            f"'{freq_depr_msg}' will be deprecated, please use '{freq_msg}' instead."
+        )
+
+        expected = date_range("1/1/2000", periods=2, freq=freq)
+        with tm.assert_produces_warning(FutureWarning, match=msg):
+            result = date_range("1/1/2000", periods=2, freq=freq_depr)
+        tm.assert_index_equal(result, expected)
+
 
 class TestDateRangeTZ:
     """Tests for date_range with timezones"""
diff --git a/pandas/tests/indexes/period/test_constructors.py b/pandas/tests/indexes/period/test_constructors.py
index f1db5ab28be30..054d1ad0b5d23 100644
--- a/pandas/tests/indexes/period/test_constructors.py
+++ b/pandas/tests/indexes/period/test_constructors.py
@@ -418,7 +418,7 @@ def test_constructor_freq_mult(self):
     @pytest.mark.parametrize(
         "freq_offset, freq_period",
         [
-            ("Y", "Y"),
+            ("YE", "Y"),
             ("ME", "M"),
             ("D", "D"),
             ("min", "min"),
diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py
index 9ac105ac5fc1b..50da8f0d8e8b4 100644
--- a/pandas/tests/indexes/period/test_period.py
+++ b/pandas/tests/indexes/period/test_period.py
@@ -287,14 +287,21 @@ def test_H_deprecated_from_time_series(self):
         series = Series(1, index=index)
         assert isinstance(series, Series)
 
-    @pytest.mark.parametrize("freq", ["2A", "A-DEC", "200A-AUG"])
-    def test_a_deprecated_from_time_series(self, freq):
+    @pytest.mark.parametrize(
+        "freq_depr,freq",
+        [
+            ("2A", "2Y"),
+            ("A-DEC", "Y-DEC"),
+            ("200A-AUG", "200Y-AUG"),
+        ],
+    )
+    def test_a_deprecated_from_time_series(self, freq_depr, freq):
         # GH#52536
-        freq_msg = freq[freq.index("A") :]
-        msg = f"'{freq_msg}' is deprecated and will be removed in a future version."
+        freq_msg = freq_depr[freq_depr.index("A"):]
+        msg = f"'{freq_msg}' will be deprecated, please use 'Y{freq_msg[1:]}' instead."
 
         with tm.assert_produces_warning(FutureWarning, match=msg):
-            index = period_range(freq=freq, start="1/1/2001", end="12/1/2009")
+            index = period_range(freq=freq_depr, start="1/1/2001", end="12/1/2009")
         series = Series(1, index=index)
         assert isinstance(series, Series)
 
diff --git a/pandas/tests/indexes/period/test_period_range.py b/pandas/tests/indexes/period/test_period_range.py
index e908cda449ee6..fd6db389fbbf4 100644
--- a/pandas/tests/indexes/period/test_period_range.py
+++ b/pandas/tests/indexes/period/test_period_range.py
@@ -26,7 +26,7 @@ def test_required_arguments(self):
             ("D", "D"),
             ("W", "W"),
             ("QE", "Q"),
-            ("Y", "Y"),
+            ("YE", "Y"),
         ],
     )
     def test_construction_from_string(self, freq_offset, freq_period):
diff --git a/pandas/tests/indexes/timedeltas/test_scalar_compat.py b/pandas/tests/indexes/timedeltas/test_scalar_compat.py
index 63db5c1b9c91d..96ca3af59cb48 100644
--- a/pandas/tests/indexes/timedeltas/test_scalar_compat.py
+++ b/pandas/tests/indexes/timedeltas/test_scalar_compat.py
@@ -81,7 +81,7 @@ def test_tdi_round(self):
     @pytest.mark.parametrize(
         "freq,msg",
         [
-            ("Y", "<YearEnd: month=12> is a non-fixed frequency"),
+            ("YE", "<YearEnd: month=12> is a non-fixed frequency"),
             ("ME", "<MonthEnd> is a non-fixed frequency"),
             ("foobar", "Invalid frequency: foobar"),
         ],
diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py
index 42f1a30983414..282fbdae33c11 100644
--- a/pandas/tests/plotting/test_datetimelike.py
+++ b/pandas/tests/plotting/test_datetimelike.py
@@ -102,7 +102,7 @@ def test_is_error_nozeroindex(self):
         _check_plot_works(a.plot, yerr=a)
 
     def test_nonnumeric_exclude(self):
-        idx = date_range("1/1/1987", freq="Y", periods=3)
+        idx = date_range("1/1/1987", freq="YE", periods=3)
         df = DataFrame({"A": ["x", "y", "z"], "B": [1, 2, 3]}, idx)
 
         fig, ax = mpl.pyplot.subplots()
@@ -111,7 +111,7 @@ def test_nonnumeric_exclude(self):
         mpl.pyplot.close(fig)
 
     def test_nonnumeric_exclude_error(self):
-        idx = date_range("1/1/1987", freq="Y", periods=3)
+        idx = date_range("1/1/1987", freq="YE", periods=3)
         df = DataFrame({"A": ["x", "y", "z"], "B": [1, 2, 3]}, idx)
         msg = "no numeric data to plot"
         with pytest.raises(TypeError, match=msg):
@@ -125,7 +125,7 @@ def test_tsplot_period(self, freq):
         _check_plot_works(ser.plot, ax=ax)
 
     @pytest.mark.parametrize(
-        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "Y", "1B30Min"]
+        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "YE", "1B30Min"]
     )
     def test_tsplot_datetime(self, freq):
         idx = date_range("12/31/1999", freq=freq, periods=100)
@@ -176,7 +176,7 @@ def check_format_of_first_point(ax, expected_string):
             first_y = first_line.get_ydata()[0]
             assert expected_string == ax.format_coord(first_x, first_y)
 
-        annual = Series(1, index=date_range("2014-01-01", periods=3, freq="Y-DEC"))
+        annual = Series(1, index=date_range("2014-01-01", periods=3, freq="YE-DEC"))
         _, ax = mpl.pyplot.subplots()
         annual.plot(ax=ax)
         check_format_of_first_point(ax, "t = 2014  y = 1.000000")
@@ -204,14 +204,14 @@ def test_line_plot_period_mlt_series(self, frqncy):
         _check_plot_works(s.plot, s.index.freq.rule_code)
 
     @pytest.mark.parametrize(
-        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "Y", "1B30Min"]
+        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "YE", "1B30Min"]
     )
     def test_line_plot_datetime_series(self, freq):
         idx = date_range("12/31/1999", freq=freq, periods=100)
         ser = Series(np.random.default_rng(2).standard_normal(len(idx)), idx)
         _check_plot_works(ser.plot, ser.index.freq.rule_code)
 
-    @pytest.mark.parametrize("freq", ["s", "min", "h", "D", "W", "ME", "QE", "Y"])
+    @pytest.mark.parametrize("freq", ["s", "min", "h", "D", "W", "ME", "QE", "YE"])
     def test_line_plot_period_frame(self, freq):
         idx = date_range("12/31/1999", freq=freq, periods=100)
         df = DataFrame(
@@ -240,7 +240,7 @@ def test_line_plot_period_mlt_frame(self, frqncy):
 
     @pytest.mark.filterwarnings(r"ignore:PeriodDtype\[B\] is deprecated:FutureWarning")
     @pytest.mark.parametrize(
-        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "Y", "1B30Min"]
+        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "YE", "1B30Min"]
     )
     def test_line_plot_datetime_frame(self, freq):
         idx = date_range("12/31/1999", freq=freq, periods=100)
@@ -254,7 +254,7 @@ def test_line_plot_datetime_frame(self, freq):
         _check_plot_works(df.plot, freq)
 
     @pytest.mark.parametrize(
-        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "Y", "1B30Min"]
+        "freq", ["s", "min", "h", "D", "W", "ME", "QE-DEC", "YE", "1B30Min"]
     )
     def test_line_plot_inferred_freq(self, freq):
         idx = date_range("12/31/1999", freq=freq, periods=100)
@@ -440,7 +440,7 @@ def test_get_finder(self):
         assert conv.get_finder(to_offset("D")) == conv._daily_finder
         assert conv.get_finder(to_offset("ME")) == conv._monthly_finder
         assert conv.get_finder(to_offset("QE")) == conv._quarterly_finder
-        assert conv.get_finder(to_offset("Y")) == conv._annual_finder
+        assert conv.get_finder(to_offset("YE")) == conv._annual_finder
         assert conv.get_finder(to_offset("W")) == conv._daily_finder
 
     def test_finder_daily(self):
diff --git a/pandas/tests/resample/test_base.py b/pandas/tests/resample/test_base.py
index 42e741119b0a1..fee52780585b8 100644
--- a/pandas/tests/resample/test_base.py
+++ b/pandas/tests/resample/test_base.py
@@ -96,7 +96,7 @@ def test_raises_on_non_datetimelike_index():
         "but got an instance of 'RangeIndex'"
     )
     with pytest.raises(TypeError, match=msg):
-        xp.resample("Y")
+        xp.resample("YE")
 
 
 @all_ts
diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py
index 302cab8e90db7..eb53f21c4f05f 100644
--- a/pandas/tests/resample/test_datetime_index.py
+++ b/pandas/tests/resample/test_datetime_index.py
@@ -430,7 +430,7 @@ def test_resample_frame_basic_cy_funcs(f, unit):
     g._cython_agg_general(f, alt=None, numeric_only=True)
 
 
-@pytest.mark.parametrize("freq", ["Y", "ME"])
+@pytest.mark.parametrize("freq", ["YE", "ME"])
 def test_resample_frame_basic_M_A(freq, unit):
     df = tm.makeTimeDataFrame()
     df.index = df.index.as_unit(unit)
@@ -512,7 +512,7 @@ def test_upsample_with_limit(unit):
 
 
 @pytest.mark.parametrize("freq", ["1D", "10h", "5Min", "10s"])
-@pytest.mark.parametrize("rule", ["Y", "3ME", "15D", "30h", "15Min", "30s"])
+@pytest.mark.parametrize("rule", ["YE", "3ME", "15D", "30h", "15Min", "30s"])
 def test_nearest_upsample_with_limit(tz_aware_fixture, freq, rule, unit):
     # GH 33939
     rng = date_range("1/1/2000", periods=3, freq=freq, tz=tz_aware_fixture).as_unit(
@@ -663,8 +663,8 @@ def test_resample_reresample(unit):
 @pytest.mark.parametrize(
     "freq, expected_kwargs",
     [
-        ["Y-DEC", {"start": "1990", "end": "2000", "freq": "y-dec"}],
-        ["Y-JUN", {"start": "1990", "end": "2000", "freq": "y-jun"}],
+        ["YE-DEC", {"start": "1990", "end": "2000", "freq": "Y-DEC"}],
+        ["YE-JUN", {"start": "1990", "end": "2000", "freq": "Y-JUN"}],
         ["ME", {"start": "1990-01", "end": "2000-01", "freq": "M"}],
     ],
 )
@@ -1966,9 +1966,9 @@ def test_resample_unsigned_int(any_unsigned_int_numpy_dtype, unit):
 
 def test_long_rule_non_nano():
     # https://github.com/pandas-dev/pandas/issues/51024
-    idx = date_range("0300-01-01", "2000-01-01", unit="s", freq="100Y")
+    idx = date_range("0300-01-01", "2000-01-01", unit="s", freq="100YE")
     ser = Series([1, 4, 2, 8, 5, 7, 1, 4, 2, 8, 5, 7, 1, 4, 2, 8, 5], index=idx)
-    result = ser.resample("200Y").mean()
+    result = ser.resample("200YE").mean()
     expected_idx = DatetimeIndex(
         np.array(
             [
@@ -1983,7 +1983,7 @@ def test_long_rule_non_nano():
                 "1900-12-31",
             ]
         ).astype("datetime64[s]"),
-        freq="200Y-DEC",
+        freq="200YE-DEC",
     )
     expected = Series([1.0, 3.0, 6.5, 4.0, 3.0, 6.5, 4.0, 3.0, 6.5], index=expected_idx)
     tm.assert_series_equal(result, expected)
diff --git a/pandas/tests/resample/test_period_index.py b/pandas/tests/resample/test_period_index.py
index e768d9266ab89..9b4ec8dd79ea8 100644
--- a/pandas/tests/resample/test_period_index.py
+++ b/pandas/tests/resample/test_period_index.py
@@ -120,20 +120,20 @@ def test_annual_upsample_cases(
 
     def test_basic_downsample(self, simple_period_range_series):
         ts = simple_period_range_series("1/1/1990", "6/30/1995", freq="M")
-        result = ts.resample("y-dec").mean()
+        result = ts.resample("Y-DEC").mean()
 
         expected = ts.groupby(ts.index.year).mean()
-        expected.index = period_range("1/1/1990", "6/30/1995", freq="y-dec")
+        expected.index = period_range("1/1/1990", "6/30/1995", freq="Y-DEC")
         tm.assert_series_equal(result, expected)
 
         # this is ok
-        tm.assert_series_equal(ts.resample("y-dec").mean(), result)
-        tm.assert_series_equal(ts.resample("y").mean(), result)
+        tm.assert_series_equal(ts.resample("Y-DEC").mean(), result)
+        tm.assert_series_equal(ts.resample("Y").mean(), result)
 
     @pytest.mark.parametrize(
         "rule,expected_error_msg",
         [
-            ("y-dec", "<YearEnd: month=12>"),
+            ("Y-DEC", "<YearEnd: month=12>"),
             ("qe-mar", "<QuarterEnd: startingMonth=3>"),
             ("M", "<MonthEnd>"),
             ("w-thu", "<Week: weekday=3>"),
@@ -152,7 +152,7 @@ def test_not_subperiod(self, simple_period_range_series, rule, expected_error_ms
     @pytest.mark.parametrize("freq", ["D", "2D"])
     def test_basic_upsample(self, freq, simple_period_range_series):
         ts = simple_period_range_series("1/1/1990", "6/30/1995", freq="M")
-        result = ts.resample("y-dec").mean()
+        result = ts.resample("Y-DEC").mean()
 
         resampled = result.resample(freq, convention="end").ffill()
         expected = result.to_timestamp(freq, how="end")
@@ -392,7 +392,7 @@ def test_resample_to_timestamps(self, simple_period_range_series):
         ts = simple_period_range_series("1/1/1990", "12/31/1995", freq="M")
 
         result = ts.resample("Y-DEC", kind="timestamp").mean()
-        expected = ts.to_timestamp(how="start").resample("Y-DEC").mean()
+        expected = ts.to_timestamp(how="start").resample("YE-DEC").mean()
         tm.assert_series_equal(result, expected)
 
     @pytest.mark.parametrize("month", MONTHS)
@@ -432,7 +432,7 @@ def test_resample_fill_missing(self):
 
         stamps = s.to_timestamp()
         filled = s.resample("Y").ffill()
-        expected = stamps.resample("Y").ffill().to_period("Y")
+        expected = stamps.resample("YE").ffill().to_period("Y")
         tm.assert_series_equal(filled, expected)
 
     def test_cant_fill_missing_dups(self):
@@ -537,13 +537,13 @@ def test_resample_tz_localized(self):
         ts["second"] = np.cumsum(np.random.default_rng(2).standard_normal(len(rng)))
         expected = DataFrame(
             {
-                "first": ts.resample("Y").sum()["first"],
-                "second": ts.resample("Y").mean()["second"],
+                "first": ts.resample("YE").sum()["first"],
+                "second": ts.resample("YE").mean()["second"],
             },
             columns=["first", "second"],
         )
         result = (
-            ts.resample("Y")
+            ts.resample("YE")
             .agg({"first": "sum", "second": "mean"})
             .reindex(columns=["first", "second"])
         )
@@ -574,7 +574,7 @@ def test_quarterly_resampling(self):
         ts = Series(np.arange(10), index=rng)
 
         result = ts.resample("Y").mean()
-        exp = ts.to_timestamp().resample("Y").mean().to_period()
+        exp = ts.to_timestamp().resample("YE").mean().to_period()
         tm.assert_series_equal(result, exp)
 
     def test_resample_weekly_bug_1726(self):
@@ -647,7 +647,7 @@ def test_monthly_convention_span(self):
         tm.assert_series_equal(result, expected)
 
     @pytest.mark.parametrize(
-        "from_freq, to_freq", [("D", "ME"), ("QE", "Y"), ("ME", "QE"), ("D", "W")]
+        "from_freq, to_freq", [("D", "ME"), ("QE", "YE"), ("ME", "QE"), ("D", "W")]
     )
     def test_default_right_closed_label(self, from_freq, to_freq):
         idx = date_range(start="8/15/2012", periods=100, freq=from_freq)
diff --git a/pandas/tests/resample/test_resample_api.py b/pandas/tests/resample/test_resample_api.py
index ff7b129c52f71..12618f42c7f07 100644
--- a/pandas/tests/resample/test_resample_api.py
+++ b/pandas/tests/resample/test_resample_api.py
@@ -902,9 +902,9 @@ def test_frame_downsample_method(method, numeric_only, expected_data):
     # GH#46442 test if `numeric_only` behave as expected for DataFrameGroupBy
 
     index = date_range("2018-01-01", periods=2, freq="D")
-    expected_index = date_range("2018-12-31", periods=1, freq="Y")
+    expected_index = date_range("2018-12-31", periods=1, freq="YE")
     df = DataFrame({"cat": ["cat_1", "cat_2"], "num": [5, 20]}, index=index)
-    resampled = df.resample("Y")
+    resampled = df.resample("YE")
     if numeric_only is lib.no_default:
         kwargs = {}
     else:
@@ -953,9 +953,9 @@ def test_series_downsample_method(method, numeric_only, expected_data):
     # GH#46442 test if `numeric_only` behave as expected for SeriesGroupBy
 
     index = date_range("2018-01-01", periods=2, freq="D")
-    expected_index = date_range("2018-12-31", periods=1, freq="Y")
+    expected_index = date_range("2018-12-31", periods=1, freq="YE")
     df = Series(["cat_1", "cat_2"], index=index)
-    resampled = df.resample("Y")
+    resampled = df.resample("YE")
     kwargs = {} if numeric_only is lib.no_default else {"numeric_only": numeric_only}
 
     func = getattr(resampled, method)
diff --git a/pandas/tests/resample/test_resampler_grouper.py b/pandas/tests/resample/test_resampler_grouper.py
index b85ccdc70068f..f0c970284ab1b 100644
--- a/pandas/tests/resample/test_resampler_grouper.py
+++ b/pandas/tests/resample/test_resampler_grouper.py
@@ -452,7 +452,7 @@ def test_resample_groupby_agg():
     )
     df["date"] = pd.to_datetime(df["date"])
 
-    resampled = df.groupby("cat").resample("Y", on="date")
+    resampled = df.groupby("cat").resample("YE", on="date")
     expected = resampled[["num"]].sum()
     result = resampled.agg({"num": "sum"})
 
diff --git a/pandas/tests/resample/test_time_grouper.py b/pandas/tests/resample/test_time_grouper.py
index e5593302625ec..41d34be79bc9c 100644
--- a/pandas/tests/resample/test_time_grouper.py
+++ b/pandas/tests/resample/test_time_grouper.py
@@ -24,7 +24,7 @@ def test_series():
 
 
 def test_apply(test_series):
-    grouper = Grouper(freq="Y", label="right", closed="right")
+    grouper = Grouper(freq="YE", label="right", closed="right")
 
     grouped = test_series.groupby(grouper)
 
@@ -44,18 +44,18 @@ def test_count(test_series):
 
     expected = test_series.groupby(lambda x: x.year).count()
 
-    grouper = Grouper(freq="Y", label="right", closed="right")
+    grouper = Grouper(freq="YE", label="right", closed="right")
     result = test_series.groupby(grouper).count()
     expected.index = result.index
     tm.assert_series_equal(result, expected)
 
-    result = test_series.resample("Y").count()
+    result = test_series.resample("YE").count()
     expected.index = result.index
     tm.assert_series_equal(result, expected)
 
 
 def test_numpy_reduction(test_series):
-    result = test_series.resample("Y", closed="right").prod()
+    result = test_series.resample("YE", closed="right").prod()
 
     msg = "using SeriesGroupBy.prod"
     with tm.assert_produces_warning(FutureWarning, match=msg):
diff --git a/pandas/tests/reshape/concat/test_concat.py b/pandas/tests/reshape/concat/test_concat.py
index 216422bc12dc2..ed111ff4e0ee1 100644
--- a/pandas/tests/reshape/concat/test_concat.py
+++ b/pandas/tests/reshape/concat/test_concat.py
@@ -30,8 +30,8 @@
 class TestConcatenate:
     def test_append_concat(self):
         # GH#1815
-        d1 = date_range("12/31/1990", "12/31/1999", freq="Y-DEC")
-        d2 = date_range("12/31/2000", "12/31/2009", freq="Y-DEC")
+        d1 = date_range("12/31/1990", "12/31/1999", freq="YE-DEC")
+        d2 = date_range("12/31/2000", "12/31/2009", freq="YE-DEC")
 
         s1 = Series(np.random.default_rng(2).standard_normal(10), d1)
         s2 = Series(np.random.default_rng(2).standard_normal(10), d2)
diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py
index 2d41b6d355ead..f6c6d2c0f67ee 100644
--- a/pandas/tests/reshape/test_pivot.py
+++ b/pandas/tests/reshape/test_pivot.py
@@ -445,10 +445,10 @@ def test_pivot_no_values(self):
         tm.assert_frame_equal(res, exp)
 
         res = df.pivot_table(
-            index=Grouper(freq="Y"), columns=Grouper(key="dt", freq="ME")
+            index=Grouper(freq="YE"), columns=Grouper(key="dt", freq="ME")
         )
         exp = DataFrame(
-            [3.0], index=pd.DatetimeIndex(["2011-12-31"], freq="Y"), columns=exp_columns
+            [3.0], index=pd.DatetimeIndex(["2011-12-31"], freq="YE"), columns=exp_columns
         )
         tm.assert_frame_equal(res, exp)
 
@@ -1273,7 +1273,7 @@ def test_pivot_timegrouper(self, using_array_manager):
 
         expected = DataFrame(
             np.array([10, 18, 3], dtype="int64").reshape(1, 3),
-            index=pd.DatetimeIndex([datetime(2013, 12, 31)], freq="Y"),
+            index=pd.DatetimeIndex([datetime(2013, 12, 31)], freq="YE"),
             columns="Carl Joe Mark".split(),
         )
         expected.index.name = "Date"
@@ -1281,7 +1281,7 @@ def test_pivot_timegrouper(self, using_array_manager):
 
         result = pivot_table(
             df,
-            index=Grouper(freq="Y"),
+            index=Grouper(freq="YE"),
             columns="Buyer",
             values="Quantity",
             aggfunc="sum",
@@ -1291,7 +1291,7 @@ def test_pivot_timegrouper(self, using_array_manager):
         result = pivot_table(
             df,
             index="Buyer",
-            columns=Grouper(freq="Y"),
+            columns=Grouper(freq="YE"),
             values="Quantity",
             aggfunc="sum",
         )
diff --git a/pandas/tests/scalar/period/test_period.py b/pandas/tests/scalar/period/test_period.py
index 8cc3ace52a4d4..efccc9aa70a31 100644
--- a/pandas/tests/scalar/period/test_period.py
+++ b/pandas/tests/scalar/period/test_period.py
@@ -61,15 +61,13 @@ def test_construction(self):
 
         assert i1 == i2
 
+        # GH#54105 - Period can be confusingly instantiated with lowercase freq
+        # TODO: raise in the future an error when passing lowercase freq
         i1 = Period("2005", freq="Y")
         i2 = Period("2005")
-        i3 = Period("2005", freq="y")
 
         assert i1 == i2
-        assert i1 == i3
 
-        # GH#54105 - Period can be confusingly instantiated with lowercase freq
-        # TODO: raise in the future an error when passing lowercase freq
         i4 = Period("2005", freq="M")
         assert i1 != i4
 
diff --git a/pandas/tests/scalar/timedelta/methods/test_round.py b/pandas/tests/scalar/timedelta/methods/test_round.py
index c68dfc7a16719..4beb39510413c 100644
--- a/pandas/tests/scalar/timedelta/methods/test_round.py
+++ b/pandas/tests/scalar/timedelta/methods/test_round.py
@@ -54,7 +54,7 @@ def test_round_invalid(self):
         t1 = Timedelta("1 days 02:34:56.789123456")
 
         for freq, msg in [
-            ("Y", "<YearEnd: month=12> is a non-fixed frequency"),
+            ("YE", "<YearEnd: month=12> is a non-fixed frequency"),
             ("ME", "<MonthEnd> is a non-fixed frequency"),
             ("foobar", "Invalid frequency: foobar"),
         ]:
diff --git a/pandas/tests/tseries/frequencies/test_inference.py b/pandas/tests/tseries/frequencies/test_inference.py
index 313e6ba592fe0..19c6425c12ce1 100644
--- a/pandas/tests/tseries/frequencies/test_inference.py
+++ b/pandas/tests/tseries/frequencies/test_inference.py
@@ -52,7 +52,7 @@ def base_delta_code_pair(request):
 
 freqs = (
     [f"QE-{month}" for month in MONTHS]
-    + [f"{annual}-{month}" for annual in ["Y", "BY"] for month in MONTHS]
+    + [f"{annual}-{month}" for annual in ["YE", "BY"] for month in MONTHS]
     + ["ME", "BME", "BMS"]
     + [f"WOM-{count}{day}" for count in range(1, 5) for day in DAYS]
     + [f"W-{day}" for day in DAYS]
@@ -167,7 +167,7 @@ def test_monthly_ambiguous():
 
 def test_annual_ambiguous():
     rng = DatetimeIndex(["1/31/2000", "1/31/2001", "1/31/2002"])
-    assert rng.inferred_freq == "Y-JAN"
+    assert rng.inferred_freq == "YE-JAN"
 
 
 @pytest.mark.parametrize("count", range(1, 5))
@@ -360,7 +360,7 @@ def test_not_monotonic():
     rng = DatetimeIndex(["1/31/2000", "1/31/2001", "1/31/2002"])
     rng = rng[::-1]
 
-    assert rng.inferred_freq == "-1Y-JAN"
+    assert rng.inferred_freq == "-1YE-JAN"
 
 
 def test_non_datetime_index2():
@@ -480,19 +480,19 @@ def test_series_datetime_index(freq):
         "QE@JAN",
         "QE@FEB",
         "QE@MAR",
-        "Y@JAN",
-        "Y@FEB",
-        "Y@MAR",
-        "Y@APR",
-        "Y@MAY",
-        "Y@JUN",
-        "Y@JUL",
-        "Y@AUG",
-        "Y@SEP",
-        "Y@OCT",
-        "Y@NOV",
-        "Y@DEC",
-        "Y@JAN",
+        "YE@JAN",
+        "YE@FEB",
+        "YE@MAR",
+        "YE@APR",
+        "YE@MAY",
+        "YE@JUN",
+        "YE@JUL",
+        "YE@AUG",
+        "YE@SEP",
+        "YE@OCT",
+        "YE@NOV",
+        "YE@DEC",
+        "YE@JAN",
         "WOM@1MON",
         "WOM@2MON",
         "WOM@3MON",

From 2ee6b5bba288126c937bd720a1b8aa245f04297e Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Wed, 1 Nov 2023 16:10:21 +0100
Subject: [PATCH 03/10] fix tests

---
 pandas/tests/arithmetic/test_datetime64.py         | 2 +-
 pandas/tests/arrays/period/test_arrow_compat.py    | 2 +-
 pandas/tests/arrays/test_datetimelike.py           | 2 +-
 pandas/tests/frame/methods/test_reindex.py         | 2 +-
 pandas/tests/frame/methods/test_to_timestamp.py    | 6 +++---
 pandas/tests/frame/test_repr.py                    | 2 +-
 pandas/tests/groupby/test_timegrouper.py           | 6 +++---
 pandas/tests/indexes/datetimes/test_date_range.py  | 6 ++----
 pandas/tests/indexes/period/test_period.py         | 2 +-
 pandas/tests/io/json/test_json_table_schema.py     | 2 +-
 pandas/tests/reshape/test_pivot.py                 | 4 +++-
 pandas/tests/series/test_repr.py                   | 2 +-
 pandas/tests/tseries/frequencies/test_freq_code.py | 2 +-
 pandas/tests/tseries/offsets/test_offsets.py       | 4 ++--
 pandas/tests/tslibs/test_conversion.py             | 2 +-
 15 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/pandas/tests/arithmetic/test_datetime64.py b/pandas/tests/arithmetic/test_datetime64.py
index 190ce0caceb20..2818b60bfc916 100644
--- a/pandas/tests/arithmetic/test_datetime64.py
+++ b/pandas/tests/arithmetic/test_datetime64.py
@@ -1667,7 +1667,7 @@ def test_dt64_series_arith_overflow(self):
         # GH#12534, fixed by GH#19024
         dt = Timestamp("1700-01-31")
         td = Timedelta("20000 Days")
-        dti = date_range("1949-09-30", freq="100Y", periods=4)
+        dti = date_range("1949-09-30", freq="100YE", periods=4)
         ser = Series(dti)
         msg = "Overflow in int64 addition"
         with pytest.raises(OverflowError, match=msg):
diff --git a/pandas/tests/arrays/period/test_arrow_compat.py b/pandas/tests/arrays/period/test_arrow_compat.py
index bb41b564f6db0..41a632b3211ff 100644
--- a/pandas/tests/arrays/period/test_arrow_compat.py
+++ b/pandas/tests/arrays/period/test_arrow_compat.py
@@ -33,7 +33,7 @@ def test_arrow_extension_type():
     "data, freq",
     [
         (pd.date_range("2017", periods=3), "D"),
-        (pd.date_range("2017", periods=3, freq="Y"), "Y-DEC"),
+        (pd.date_range("2017", periods=3, freq="YE"), "Y-DEC"),
     ],
 )
 def test_arrow_array(data, freq):
diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py
index 9718381e58fcb..5a5abcc4aa85d 100644
--- a/pandas/tests/arrays/test_datetimelike.py
+++ b/pandas/tests/arrays/test_datetimelike.py
@@ -30,7 +30,7 @@
 
 
 # TODO: more freq variants
-@pytest.fixture(params=["D", "B", "W", "ME", "QE", "Y"])
+@pytest.fixture(params=["D", "B", "W", "ME", "QE", "YE"])
 def freqstr(request):
     """Fixture returning parametrized frequency in string format."""
     return request.param
diff --git a/pandas/tests/frame/methods/test_reindex.py b/pandas/tests/frame/methods/test_reindex.py
index fb6e08cd52d97..3df14c0778be9 100644
--- a/pandas/tests/frame/methods/test_reindex.py
+++ b/pandas/tests/frame/methods/test_reindex.py
@@ -36,7 +36,7 @@ def test_dti_set_index_reindex_datetimeindex(self):
         # GH#6631
         df = DataFrame(np.random.default_rng(2).random(6))
         idx1 = date_range("2011/01/01", periods=6, freq="ME", tz="US/Eastern")
-        idx2 = date_range("2013", periods=6, freq="Y", tz="Asia/Tokyo")
+        idx2 = date_range("2013", periods=6, freq="YE", tz="Asia/Tokyo")
 
         df = df.set_index(idx1)
         tm.assert_index_equal(df.index, idx1)
diff --git a/pandas/tests/frame/methods/test_to_timestamp.py b/pandas/tests/frame/methods/test_to_timestamp.py
index 859dc56de4a25..0e7e1d595d6be 100644
--- a/pandas/tests/frame/methods/test_to_timestamp.py
+++ b/pandas/tests/frame/methods/test_to_timestamp.py
@@ -16,7 +16,7 @@
 import pandas._testing as tm
 
 
-def _get_with_delta(delta, freq="Y-DEC"):
+def _get_with_delta(delta, freq="YE-DEC"):
     return date_range(
         to_datetime("1/1/2001") + delta,
         to_datetime("12/31/2009") + delta,
@@ -36,7 +36,7 @@ def test_to_timestamp(self, frame_or_series):
         obj["mix"] = "a"
         obj = tm.get_obj(obj, frame_or_series)
 
-        exp_index = date_range("1/1/2001", end="12/31/2009", freq="Y-DEC")
+        exp_index = date_range("1/1/2001", end="12/31/2009", freq="YE-DEC")
         exp_index = exp_index + Timedelta(1, "D") - Timedelta(1, "ns")
         result = obj.to_timestamp("D", "end")
         tm.assert_index_equal(result.index, exp_index)
@@ -82,7 +82,7 @@ def test_to_timestamp_columns(self):
         # columns
         df = df.T
 
-        exp_index = date_range("1/1/2001", end="12/31/2009", freq="Y-DEC")
+        exp_index = date_range("1/1/2001", end="12/31/2009", freq="YE-DEC")
         exp_index = exp_index + Timedelta(1, "D") - Timedelta(1, "ns")
         result = df.to_timestamp("D", "end", axis=1)
         tm.assert_index_equal(result.columns, exp_index)
diff --git a/pandas/tests/frame/test_repr.py b/pandas/tests/frame/test_repr.py
index 7c0e374c50bab..5a4b219e901a1 100644
--- a/pandas/tests/frame/test_repr.py
+++ b/pandas/tests/frame/test_repr.py
@@ -319,7 +319,7 @@ def test_repr_np_nat_with_object(self, arg, box, expected):
         assert result == expected
 
     def test_frame_datetime64_pre1900_repr(self):
-        df = DataFrame({"year": date_range("1/1/1700", periods=50, freq="Y-DEC")})
+        df = DataFrame({"year": date_range("1/1/1700", periods=50, freq="YE-DEC")})
         # it works!
         repr(df)
 
diff --git a/pandas/tests/groupby/test_timegrouper.py b/pandas/tests/groupby/test_timegrouper.py
index 48c51cdfab4e4..40b6dba6025d1 100644
--- a/pandas/tests/groupby/test_timegrouper.py
+++ b/pandas/tests/groupby/test_timegrouper.py
@@ -192,7 +192,7 @@ def test_timegrouper_with_reg_groups(self):
             ).set_index(["Date", "Buyer"])
 
             msg = "The default value of numeric_only"
-            result = df.groupby([Grouper(freq="Y"), "Buyer"]).sum(numeric_only=True)
+            result = df.groupby([Grouper(freq="YE"), "Buyer"]).sum(numeric_only=True)
             tm.assert_frame_equal(result, expected)
 
             expected = DataFrame(
@@ -335,7 +335,7 @@ def test_timegrouper_with_reg_groups(self):
             )
             tm.assert_frame_equal(result, expected)
 
-    @pytest.mark.parametrize("freq", ["D", "ME", "Y", "QE-APR"])
+    @pytest.mark.parametrize("freq", ["D", "ME", "YE", "QE-APR"])
     def test_timegrouper_with_reg_groups_freq(self, freq):
         # GH 6764 multiple grouping with/without sort
         df = DataFrame(
@@ -906,7 +906,7 @@ def test_groupby_apply_timegrouper_with_nat_apply_squeeze(
 
         # We need to create a GroupBy object with only one non-NaT group,
         #  so use a huge freq so that all non-NaT dates will be grouped together
-        tdg = Grouper(key="Date", freq="100Y")
+        tdg = Grouper(key="Date", freq="100YE")
         gb = df.groupby(tdg)
 
         # check that we will go through the singular_series path
diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py
index 1eeadab0237d7..7db71ecc8ec6a 100644
--- a/pandas/tests/indexes/datetimes/test_date_range.py
+++ b/pandas/tests/indexes/datetimes/test_date_range.py
@@ -878,13 +878,11 @@ def test_frequencies_H_T_S_L_U_N_deprecated(self, freq, freq_depr):
             ("YE-MAY", "Y-MAY"),
         ],
     )
-    def test_frequencies_A_deprecated_Y_renamed(self, freq, freq_depr): 
+    def test_frequencies_A_deprecated_Y_renamed(self, freq, freq_depr):
         # GH#9586, GH#52536
         freq_msg = re.split("[0-9]*", freq, maxsplit=1)[1]
         freq_depr_msg = re.split("[0-9]*", freq_depr, maxsplit=1)[1]
-        msg = (
-            f"'{freq_depr_msg}' will be deprecated, please use '{freq_msg}' instead."
-        )
+        msg = f"'{freq_depr_msg}' will be deprecated, please use '{freq_msg}' instead."
 
         expected = date_range("1/1/2000", periods=2, freq=freq)
         with tm.assert_produces_warning(FutureWarning, match=msg):
diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py
index 50da8f0d8e8b4..bcde5f10bf46f 100644
--- a/pandas/tests/indexes/period/test_period.py
+++ b/pandas/tests/indexes/period/test_period.py
@@ -297,7 +297,7 @@ def test_H_deprecated_from_time_series(self):
     )
     def test_a_deprecated_from_time_series(self, freq_depr, freq):
         # GH#52536
-        freq_msg = freq_depr[freq_depr.index("A"):]
+        freq_msg = freq_depr[freq_depr.index("A") :]
         msg = f"'{freq_msg}' will be deprecated, please use 'Y{freq_msg[1:]}' instead."
 
         with tm.assert_produces_warning(FutureWarning, match=msg):
diff --git a/pandas/tests/io/json/test_json_table_schema.py b/pandas/tests/io/json/test_json_table_schema.py
index 507e99a4d6490..6e6923ba9a534 100644
--- a/pandas/tests/io/json/test_json_table_schema.py
+++ b/pandas/tests/io/json/test_json_table_schema.py
@@ -482,7 +482,7 @@ def test_convert_pandas_type_to_json_field_datetime(
     def test_convert_pandas_type_to_json_period_range(self):
         arr = pd.period_range("2016", freq="Y-DEC", periods=4)
         result = convert_pandas_type_to_json_field(arr)
-        expected = {"name": "values", "type": "datetime", "freq": "Y-DEC"}
+        expected = {"name": "values", "type": "datetime", "freq": "YE-DEC"}
         assert result == expected
 
     @pytest.mark.parametrize("kind", [pd.Categorical, pd.CategoricalIndex])
diff --git a/pandas/tests/reshape/test_pivot.py b/pandas/tests/reshape/test_pivot.py
index f6c6d2c0f67ee..c9f85e955e07c 100644
--- a/pandas/tests/reshape/test_pivot.py
+++ b/pandas/tests/reshape/test_pivot.py
@@ -448,7 +448,9 @@ def test_pivot_no_values(self):
             index=Grouper(freq="YE"), columns=Grouper(key="dt", freq="ME")
         )
         exp = DataFrame(
-            [3.0], index=pd.DatetimeIndex(["2011-12-31"], freq="YE"), columns=exp_columns
+            [3.0],
+            index=pd.DatetimeIndex(["2011-12-31"], freq="YE"),
+            columns=exp_columns,
         )
         tm.assert_frame_equal(res, exp)
 
diff --git a/pandas/tests/series/test_repr.py b/pandas/tests/series/test_repr.py
index 86addb9dadfad..229315d5ac641 100644
--- a/pandas/tests/series/test_repr.py
+++ b/pandas/tests/series/test_repr.py
@@ -257,7 +257,7 @@ def test_index_repr_in_frame_with_nan(self):
         assert repr(s) == exp
 
     def test_format_pre_1900_dates(self):
-        rng = date_range("1/1/1850", "1/1/1950", freq="Y-DEC")
+        rng = date_range("1/1/1850", "1/1/1950", freq="YE-DEC")
         msg = "DatetimeIndex.format is deprecated"
         with tm.assert_produces_warning(FutureWarning, match=msg):
             rng.format()
diff --git a/pandas/tests/tseries/frequencies/test_freq_code.py b/pandas/tests/tseries/frequencies/test_freq_code.py
index fa92590fb5ec1..96b71ef4fe662 100644
--- a/pandas/tests/tseries/frequencies/test_freq_code.py
+++ b/pandas/tests/tseries/frequencies/test_freq_code.py
@@ -90,7 +90,7 @@ def test_cat(args):
         ("1D", "2021-01-02T08:00:00"),
         ("1W", "2021-01-03T08:00:00"),
         ("1ME", "2021-01-31T08:00:00"),
-        ("1Y", "2021-12-31T08:00:00"),
+        ("1YE", "2021-12-31T08:00:00"),
     ],
 )
 def test_compatibility(freqstr, expected):
diff --git a/pandas/tests/tseries/offsets/test_offsets.py b/pandas/tests/tseries/offsets/test_offsets.py
index c46c0ddfdc201..6d5b762b4f15a 100644
--- a/pandas/tests/tseries/offsets/test_offsets.py
+++ b/pandas/tests/tseries/offsets/test_offsets.py
@@ -838,7 +838,7 @@ def test_rule_code(self):
             "NOV",
             "DEC",
         ]
-        base_lst = ["Y", "YS", "BY", "BYS", "QE", "QS", "BQ", "BQS"]
+        base_lst = ["YE", "YS", "BY", "BYS", "QE", "QS", "BQ", "BQS"]
         for base in base_lst:
             for v in suffix_lst:
                 alias = "-".join([base, v])
@@ -857,7 +857,7 @@ def test_freq_offsets():
 class TestReprNames:
     def test_str_for_named_is_name(self):
         # look at all the amazing combinations!
-        month_prefixes = ["Y", "YS", "BY", "BYS", "QE", "BQ", "BQS", "QS"]
+        month_prefixes = ["YE", "YS", "BY", "BYS", "QE", "BQ", "BQS", "QS"]
         names = [
             prefix + "-" + month
             for prefix in month_prefixes
diff --git a/pandas/tests/tslibs/test_conversion.py b/pandas/tests/tslibs/test_conversion.py
index cefe449f3484d..9d7a5e906c3c3 100644
--- a/pandas/tests/tslibs/test_conversion.py
+++ b/pandas/tests/tslibs/test_conversion.py
@@ -73,7 +73,7 @@ def test_tz_convert_single_matches_tz_convert_hourly(tz_aware_fixture):
     _compare_local_to_utc(tz_didx, naive_didx)
 
 
-@pytest.mark.parametrize("freq", ["D", "Y"])
+@pytest.mark.parametrize("freq", ["D", "YE"])
 def test_tz_convert_single_matches_tz_convert(tz_aware_fixture, freq):
     tz = tz_aware_fixture
     tz_didx = date_range("2018-01-01", "2020-01-01", freq=freq, tz=tz)

From d0f31f19bc3117a06dcf65315170af082c386d58 Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Wed, 1 Nov 2023 22:14:19 +0100
Subject: [PATCH 04/10] correct docstrings, user_guide/timeseries.rst, fix test

---
 doc/source/user_guide/timeseries.rst          | 30 +++++++++----------
 pandas/core/arrays/datetimes.py               | 10 +++----
 pandas/core/generic.py                        |  4 +--
 pandas/core/series.py                         |  2 +-
 .../datetimes/methods/test_resolution.py      |  2 +-
 5 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/doc/source/user_guide/timeseries.rst b/doc/source/user_guide/timeseries.rst
index c78921655eb05..d5ed5f952b919 100644
--- a/doc/source/user_guide/timeseries.rst
+++ b/doc/source/user_guide/timeseries.rst
@@ -895,7 +895,7 @@ into ``freq`` keyword arguments. The available date offsets and associated frequ
     :class:`~pandas.tseries.offsets.BQuarterEnd`, ``'BQ``, "business quarter end"
     :class:`~pandas.tseries.offsets.BQuarterBegin`, ``'BQS'``, "business quarter begin"
     :class:`~pandas.tseries.offsets.FY5253Quarter`, ``'REQ'``, "retail (aka 52-53 week) quarter"
-    :class:`~pandas.tseries.offsets.YearEnd`, ``'Y'``, "calendar year end"
+    :class:`~pandas.tseries.offsets.YearEnd`, ``'YE'``, "calendar year end"
     :class:`~pandas.tseries.offsets.YearBegin`, ``'YS'`` or ``'BYS'``,"calendar year begin"
     :class:`~pandas.tseries.offsets.BYearEnd`, ``'BY'``, "business year end"
     :class:`~pandas.tseries.offsets.BYearBegin`, ``'BYS'``, "business year begin"
@@ -1258,7 +1258,7 @@ frequencies. We will refer to these aliases as *offset aliases*.
     "BQ", "business quarter end frequency"
     "QS", "quarter start frequency"
     "BQS", "business quarter start frequency"
-    "Y", "year end frequency"
+    "YE", "year end frequency"
     "BY", "business year end frequency"
     "YS", "year start frequency"
     "BYS", "business year start frequency"
@@ -1385,18 +1385,18 @@ For some frequencies you can specify an anchoring suffix:
     "(B)Q(E)(S)\-SEP", "quarterly frequency, year ends in September"
     "(B)Q(E)(S)\-OCT", "quarterly frequency, year ends in October"
     "(B)Q(E)(S)\-NOV", "quarterly frequency, year ends in November"
-    "(B)Y(S)\-DEC", "annual frequency, anchored end of December. Same as 'Y'"
-    "(B)Y(S)\-JAN", "annual frequency, anchored end of January"
-    "(B)Y(S)\-FEB", "annual frequency, anchored end of February"
-    "(B)Y(S)\-MAR", "annual frequency, anchored end of March"
-    "(B)Y(S)\-APR", "annual frequency, anchored end of April"
-    "(B)Y(S)\-MAY", "annual frequency, anchored end of May"
-    "(B)Y(S)\-JUN", "annual frequency, anchored end of June"
-    "(B)Y(S)\-JUL", "annual frequency, anchored end of July"
-    "(B)Y(S)\-AUG", "annual frequency, anchored end of August"
-    "(B)Y(S)\-SEP", "annual frequency, anchored end of September"
-    "(B)Y(S)\-OCT", "annual frequency, anchored end of October"
-    "(B)Y(S)\-NOV", "annual frequency, anchored end of November"
+    "(B)Y(E)(S)\-DEC", "annual frequency, anchored end of December. Same as 'YE'"
+    "(B)Y(E)(S)\-JAN", "annual frequency, anchored end of January"
+    "(B)Y(E)(S)\-FEB", "annual frequency, anchored end of February"
+    "(B)Y(E)(S)\-MAR", "annual frequency, anchored end of March"
+    "(B)Y(E)(S)\-APR", "annual frequency, anchored end of April"
+    "(B)Y(E)(S)\-MAY", "annual frequency, anchored end of May"
+    "(B)Y(E)(S)\-JUN", "annual frequency, anchored end of June"
+    "(B)Y(E)(S)\-JUL", "annual frequency, anchored end of July"
+    "(B)Y(E)(S)\-AUG", "annual frequency, anchored end of August"
+    "(B)Y(E)(S)\-SEP", "annual frequency, anchored end of September"
+    "(B)Y(E)(S)\-OCT", "annual frequency, anchored end of October"
+    "(B)Y(E)(S)\-NOV", "annual frequency, anchored end of November"
 
 These can be used as arguments to ``date_range``, ``bdate_range``, constructors
 for ``DatetimeIndex``, as well as various other timeseries-related functions
@@ -1692,7 +1692,7 @@ the end of the interval.
 .. warning::
 
     The default values for ``label`` and ``closed`` is '**left**' for all
-    frequency offsets except for 'ME', 'Y', 'QE', 'BME', 'BY', 'BQ', and 'W'
+    frequency offsets except for 'ME', 'YE', 'QE', 'BME', 'BY', 'BQ', and 'W'
     which all have a default of 'right'.
 
     This might unintendedly lead to looking ahead, where the value for a later
diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py
index 968b64e2c3de3..be4b1b7fb6501 100644
--- a/pandas/core/arrays/datetimes.py
+++ b/pandas/core/arrays/datetimes.py
@@ -1513,14 +1513,14 @@ def isocalendar(self) -> DataFrame:
 
     year = _field_accessor(
         "year",
-        "Y",
+        "YE",
         """
         The year of the datetime.
 
         Examples
         --------
         >>> datetime_series = pd.Series(
-        ...     pd.date_range("2000-01-01", periods=3, freq="Y")
+        ...     pd.date_range("2000-01-01", periods=3, freq="YE")
         ... )
         >>> datetime_series
         0   2000-12-31
@@ -1536,7 +1536,7 @@ def isocalendar(self) -> DataFrame:
     )
     month = _field_accessor(
         "month",
-        "M",
+        "ME",
         """
         The month as January=1, December=12.
 
@@ -2058,10 +2058,10 @@ def isocalendar(self) -> DataFrame:
         This method is available on Series with datetime values under
         the ``.dt`` accessor, and directly on DatetimeIndex.
 
-        >>> idx = pd.date_range("2012-01-01", "2015-01-01", freq="Y")
+        >>> idx = pd.date_range("2012-01-01", "2015-01-01", freq="YE")
         >>> idx
         DatetimeIndex(['2012-12-31', '2013-12-31', '2014-12-31'],
-                      dtype='datetime64[ns]', freq='Y-DEC')
+                      dtype='datetime64[ns]', freq='YE-DEC')
         >>> idx.is_leap_year
         array([ True, False, False])
 
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
index 45139d84614b3..f16eac428cde0 100644
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -9199,11 +9199,11 @@ def resample(
                 Use frame.T.resample(...) instead.
         closed : {{'right', 'left'}}, default None
             Which side of bin interval is closed. The default is 'left'
-            for all frequency offsets except for 'ME', 'Y', 'Q', 'BME',
+            for all frequency offsets except for 'ME', 'YE', 'QE', 'BME',
             'BA', 'BQ', and 'W' which all have a default of 'right'.
         label : {{'right', 'left'}}, default None
             Which bin edge label to label bucket with. The default is 'left'
-            for all frequency offsets except for 'ME', 'Y', 'Q', 'BME',
+            for all frequency offsets except for 'ME', 'YE', 'QE', 'BME',
             'BA', 'BQ', and 'W' which all have a default of 'right'.
         convention : {{'start', 'end', 's', 'e'}}, default 'start'
             For `PeriodIndex` only, controls whether to use the start or
diff --git a/pandas/core/series.py b/pandas/core/series.py
index c5f622a113258..1551428a0483b 100644
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -5782,7 +5782,7 @@ def to_timestamp(
         2023-01-31    1
         2024-01-31    2
         2025-01-31    3
-        Freq: Y-JAN, dtype: int64
+        Freq: YE-JAN, dtype: int64
         """
         if not isinstance(self.index, PeriodIndex):
             raise TypeError(f"unsupported Type {type(self.index).__name__}")
diff --git a/pandas/tests/indexes/datetimes/methods/test_resolution.py b/pandas/tests/indexes/datetimes/methods/test_resolution.py
index ea59cc3d45971..8399fafbbaff2 100644
--- a/pandas/tests/indexes/datetimes/methods/test_resolution.py
+++ b/pandas/tests/indexes/datetimes/methods/test_resolution.py
@@ -22,7 +22,7 @@
 )
 def test_dti_resolution(request, tz_naive_fixture, freq, expected):
     tz = tz_naive_fixture
-    if freq == "Y" and not IS64 and isinstance(tz, tzlocal):
+    if freq == "YE" and not IS64 and isinstance(tz, tzlocal):
         request.applymarker(
             pytest.mark.xfail(reason="OverflowError inside tzlocal past 2038")
         )

From 34790e7c018dd4d6836ff971a679aee61e18d1f0 Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Wed, 1 Nov 2023 23:22:50 +0100
Subject: [PATCH 05/10] add note to v2.2.0.rst

---
 doc/source/whatsnew/v2.2.0.rst  | 23 +++++++++++++++++++++--
 pandas/core/arrays/datetimes.py |  4 ++--
 2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst
index 16d279bb0d52c..e29abad449498 100644
--- a/doc/source/whatsnew/v2.2.0.rst
+++ b/doc/source/whatsnew/v2.2.0.rst
@@ -211,8 +211,8 @@ Other API changes
 Deprecations
 ~~~~~~~~~~~~
 
-Deprecate aliases ``M`` and ``Q`` in favour of ``ME`` and ``QE`` for offsets
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Deprecate aliases ``M``, ``Q``, and ``Y`` in favour of ``ME``, ``QE``, and ``YE`` for offsets
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 The alias ``M`` is deprecated in favour of ``ME`` for offsets, please use ``ME`` for "month end" instead of ``M`` (:issue:`9586`)
 
@@ -252,6 +252,25 @@ For example:
 
     pd.date_range('2020-01-01', periods=3, freq='QE-NOV')
 
+The alias ``Y`` is deprecated in favour of ``YE`` for offsets, please use ``YE`` for "year end" instead of ``Y`` (:issue:`9586`)
+
+For example:
+
+*Previous behavior*:
+
+.. code-block:: ipython
+
+    In [9]: pd.date_range('2020-01-01', periods=3, freq='Y-MAR')
+    Out[9]:
+    DatetimeIndex(['2020-03-31', '2021-03-31', '2022-03-31'],
+                  dtype='datetime64[ns]', freq='YE-MAR')
+
+*Future behavior*:
+
+.. ipython:: python
+
+    pd.date_range('2020-01-01', periods=3, freq='YE-MAR')
+
 Other Deprecations
 ^^^^^^^^^^^^^^^^^^
 - Changed :meth:`Timedelta.resolution_string` to return ``h``, ``min``, ``s``, ``ms``, ``us``, and ``ns`` instead of ``H``, ``T``, ``S``, ``L``, ``U``, and ``N``, for compatibility with respective deprecations in frequency aliases (:issue:`52536`)
diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py
index be4b1b7fb6501..540e041604075 100644
--- a/pandas/core/arrays/datetimes.py
+++ b/pandas/core/arrays/datetimes.py
@@ -1513,7 +1513,7 @@ def isocalendar(self) -> DataFrame:
 
     year = _field_accessor(
         "year",
-        "YE",
+        "Y",
         """
         The year of the datetime.
 
@@ -1536,7 +1536,7 @@ def isocalendar(self) -> DataFrame:
     )
     month = _field_accessor(
         "month",
-        "ME",
+        "M",
         """
         The month as January=1, December=12.
 

From 7a19b51e7d2630d77683515f16762cb06747f385 Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Thu, 2 Nov 2023 00:20:37 +0100
Subject: [PATCH 06/10] add tests

---
 pandas/tests/arrays/test_datetimes.py               |  4 +++-
 pandas/tests/frame/methods/test_asfreq.py           |  4 +++-
 .../indexes/datetimes/methods/test_to_period.py     |  2 ++
 pandas/tests/indexes/period/test_period.py          | 13 +++----------
 pandas/tests/resample/test_datetime_index.py        |  4 +++-
 5 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/pandas/tests/arrays/test_datetimes.py b/pandas/tests/arrays/test_datetimes.py
index 9b1562b24d11b..e2297fc1b81cd 100644
--- a/pandas/tests/arrays/test_datetimes.py
+++ b/pandas/tests/arrays/test_datetimes.py
@@ -752,9 +752,11 @@ def test_iter_zoneinfo_fold(self, tz):
             ("2ME", "2M"),
             ("2QE", "2Q"),
             ("2QE-SEP", "2Q-SEP"),
+            ("1YE", "1Y"),
+            ("2YE-MAR", "2Y-MAR"),
         ],
     )
-    def test_date_range_frequency_M_Q_deprecated(self, freq, freq_depr):
+    def test_date_range_frequency_M_Q_Y_deprecated(self, freq, freq_depr):
         # GH#9586
         depr_msg = (
             f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
diff --git a/pandas/tests/frame/methods/test_asfreq.py b/pandas/tests/frame/methods/test_asfreq.py
index 4fd2e8235f76e..b9a38b76c7a0a 100644
--- a/pandas/tests/frame/methods/test_asfreq.py
+++ b/pandas/tests/frame/methods/test_asfreq.py
@@ -240,9 +240,11 @@ def test_asfreq_2ME(self, freq, freq_half):
             ("2ME", "2M"),
             ("2QE", "2Q"),
             ("2QE-SEP", "2Q-SEP"),
+            ("1YE", "1Y"),
+            ("2YE-MAR", "2Y-MAR"),
         ],
     )
-    def test_asfreq_frequency_M_Q_deprecated(self, freq, freq_depr):
+    def test_asfreq_frequency_M_Q_Y_deprecated(self, freq, freq_depr):
         # GH#9586
         depr_msg = (
             f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
diff --git a/pandas/tests/indexes/datetimes/methods/test_to_period.py b/pandas/tests/indexes/datetimes/methods/test_to_period.py
index b83b5aaa75836..4010efb2a943e 100644
--- a/pandas/tests/indexes/datetimes/methods/test_to_period.py
+++ b/pandas/tests/indexes/datetimes/methods/test_to_period.py
@@ -95,6 +95,8 @@ def test_dti_to_period_2monthish(self, freq_offset, freq_period):
             ("2ME", "2M"),
             ("2QE", "2Q"),
             ("2QE-SEP", "2Q-SEP"),
+            ("1YE", "1Y"),
+            ("2YE-MAR", "2Y-MAR"),
         ],
     )
     def test_to_period_freq_deprecated(self, freq, freq_depr):
diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py
index bcde5f10bf46f..f710ac88ede1d 100644
--- a/pandas/tests/indexes/period/test_period.py
+++ b/pandas/tests/indexes/period/test_period.py
@@ -287,15 +287,8 @@ def test_H_deprecated_from_time_series(self):
         series = Series(1, index=index)
         assert isinstance(series, Series)
 
-    @pytest.mark.parametrize(
-        "freq_depr,freq",
-        [
-            ("2A", "2Y"),
-            ("A-DEC", "Y-DEC"),
-            ("200A-AUG", "200Y-AUG"),
-        ],
-    )
-    def test_a_deprecated_from_time_series(self, freq_depr, freq):
+    @pytest.mark.parametrize("freq_depr", ["2A", "A-DEC", "200A-AUG"])
+    def test_a_deprecated_from_time_series(self, freq_depr):
         # GH#52536
         freq_msg = freq_depr[freq_depr.index("A") :]
         msg = f"'{freq_msg}' will be deprecated, please use 'Y{freq_msg[1:]}' instead."
@@ -305,7 +298,7 @@ def test_a_deprecated_from_time_series(self, freq_depr, freq):
         series = Series(1, index=index)
         assert isinstance(series, Series)
 
-    @pytest.mark.parametrize("freq_depr", ["2ME", "2QE"])
+    @pytest.mark.parametrize("freq_depr", ["2ME", "2QE", "2YE"])
     def test_period_index_frequency_error_message(self, freq_depr):
         # GH#9586
         msg = f"Invalid frequency: {freq_depr}"
diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py
index eb53f21c4f05f..a3345c91451ef 100644
--- a/pandas/tests/resample/test_datetime_index.py
+++ b/pandas/tests/resample/test_datetime_index.py
@@ -2011,9 +2011,11 @@ def test_resample_empty_series_with_tz():
         ("2ME", "2M"),
         ("2QE", "2Q"),
         ("2QE-SEP", "2Q-SEP"),
+        ("1YE", "1Y"),
+        ("2YE-MAR", "2Y-MAR"),
     ],
 )
-def test_resample_M_Q_deprecated(freq, freq_depr):
+def test_resample_M_Q_Y_deprecated(freq, freq_depr):
     # GH#9586
     depr_msg = f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
 

From 9a070946788dd5096165c2a8e09a438205947864 Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Thu, 2 Nov 2023 01:26:47 +0100
Subject: [PATCH 07/10] correct an example in v2.2.0.rst

---
 doc/source/whatsnew/v2.2.0.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst
index e29abad449498..94916849e6f64 100644
--- a/doc/source/whatsnew/v2.2.0.rst
+++ b/doc/source/whatsnew/v2.2.0.rst
@@ -263,7 +263,7 @@ For example:
     In [9]: pd.date_range('2020-01-01', periods=3, freq='Y-MAR')
     Out[9]:
     DatetimeIndex(['2020-03-31', '2021-03-31', '2022-03-31'],
-                  dtype='datetime64[ns]', freq='YE-MAR')
+                  dtype='datetime64[ns]', freq='Y-MAR')
 
 *Future behavior*:
 

From 644a502de04ec06edf520dbc010ddeb40cec3eae Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Thu, 2 Nov 2023 12:58:09 +0100
Subject: [PATCH 08/10] add tests

---
 doc/source/whatsnew/v2.2.0.rst                           | 2 +-
 pandas/tests/arrays/test_datetimes.py                    | 6 ++++--
 pandas/tests/frame/methods/test_asfreq.py                | 4 +++-
 pandas/tests/indexes/datetimes/methods/test_to_period.py | 4 +++-
 pandas/tests/indexes/datetimes/test_date_range.py        | 2 +-
 pandas/tests/io/json/test_json_table_schema.py           | 4 ++--
 pandas/tests/resample/test_datetime_index.py             | 4 +++-
 pandas/tests/resample/test_period_index.py               | 2 +-
 8 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst
index 94916849e6f64..396e8685f14e3 100644
--- a/doc/source/whatsnew/v2.2.0.rst
+++ b/doc/source/whatsnew/v2.2.0.rst
@@ -252,7 +252,7 @@ For example:
 
     pd.date_range('2020-01-01', periods=3, freq='QE-NOV')
 
-The alias ``Y`` is deprecated in favour of ``YE`` for offsets, please use ``YE`` for "year end" instead of ``Y`` (:issue:`9586`)
+The alias ``Y`` is deprecated in favour of ``YE`` for offsets, please use ``YE`` for "year end" instead of ``Y`` (:issue:`54275`)
 
 For example:
 
diff --git a/pandas/tests/arrays/test_datetimes.py b/pandas/tests/arrays/test_datetimes.py
index e2297fc1b81cd..c614bc1a26424 100644
--- a/pandas/tests/arrays/test_datetimes.py
+++ b/pandas/tests/arrays/test_datetimes.py
@@ -754,10 +754,12 @@ def test_iter_zoneinfo_fold(self, tz):
             ("2QE-SEP", "2Q-SEP"),
             ("1YE", "1Y"),
             ("2YE-MAR", "2Y-MAR"),
+            ("1YE", "1A"),
+            ("2YE-MAR", "2A-MAR"),
         ],
     )
-    def test_date_range_frequency_M_Q_Y_deprecated(self, freq, freq_depr):
-        # GH#9586
+    def test_date_range_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
+        # GH#9586, GH#54275
         depr_msg = (
             f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
         )
diff --git a/pandas/tests/frame/methods/test_asfreq.py b/pandas/tests/frame/methods/test_asfreq.py
index b9a38b76c7a0a..616ad5133e778 100644
--- a/pandas/tests/frame/methods/test_asfreq.py
+++ b/pandas/tests/frame/methods/test_asfreq.py
@@ -242,9 +242,11 @@ def test_asfreq_2ME(self, freq, freq_half):
             ("2QE-SEP", "2Q-SEP"),
             ("1YE", "1Y"),
             ("2YE-MAR", "2Y-MAR"),
+            ("1YE", "1A"),
+            ("2YE-MAR", "2A-MAR"),
         ],
     )
-    def test_asfreq_frequency_M_Q_Y_deprecated(self, freq, freq_depr):
+    def test_asfreq_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
         # GH#9586
         depr_msg = (
             f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
diff --git a/pandas/tests/indexes/datetimes/methods/test_to_period.py b/pandas/tests/indexes/datetimes/methods/test_to_period.py
index 4010efb2a943e..af04f827d4593 100644
--- a/pandas/tests/indexes/datetimes/methods/test_to_period.py
+++ b/pandas/tests/indexes/datetimes/methods/test_to_period.py
@@ -97,9 +97,11 @@ def test_dti_to_period_2monthish(self, freq_offset, freq_period):
             ("2QE-SEP", "2Q-SEP"),
             ("1YE", "1Y"),
             ("2YE-MAR", "2Y-MAR"),
+            ("1YE", "1A"),
+            ("2YE-MAR", "2A-MAR"),
         ],
     )
-    def test_to_period_freq_deprecated(self, freq, freq_depr):
+    def test_to_period_frequency_M_Q_Y_A_deprecated(self, freq, freq_depr):
         # GH#9586
         msg = f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
 
diff --git a/pandas/tests/indexes/datetimes/test_date_range.py b/pandas/tests/indexes/datetimes/test_date_range.py
index 7db71ecc8ec6a..07437052d3650 100644
--- a/pandas/tests/indexes/datetimes/test_date_range.py
+++ b/pandas/tests/indexes/datetimes/test_date_range.py
@@ -879,7 +879,7 @@ def test_frequencies_H_T_S_L_U_N_deprecated(self, freq, freq_depr):
         ],
     )
     def test_frequencies_A_deprecated_Y_renamed(self, freq, freq_depr):
-        # GH#9586, GH#52536
+        # GH#9586, GH#54275
         freq_msg = re.split("[0-9]*", freq, maxsplit=1)[1]
         freq_depr_msg = re.split("[0-9]*", freq_depr, maxsplit=1)[1]
         msg = f"'{freq_depr_msg}' will be deprecated, please use '{freq_msg}' instead."
diff --git a/pandas/tests/io/json/test_json_table_schema.py b/pandas/tests/io/json/test_json_table_schema.py
index 6e6923ba9a534..79dbe448e9cbe 100644
--- a/pandas/tests/io/json/test_json_table_schema.py
+++ b/pandas/tests/io/json/test_json_table_schema.py
@@ -846,12 +846,12 @@ def test_read_json_orient_table_old_schema_version(self):
         result = pd.read_json(StringIO(df_json), orient="table")
         tm.assert_frame_equal(expected, result)
 
-    @pytest.mark.parametrize("freq", ["M", "2M", "Q", "2Q"])
+    @pytest.mark.parametrize("freq", ["M", "2M", "Q", "2Q", "Y", "2Y"])
     def test_read_json_table_orient_period_depr_freq(self, freq, recwarn):
         # GH#9586
         df = DataFrame(
             {"ints": [1, 2]},
-            index=pd.PeriodIndex(["2020-01", "2020-06"], freq=freq),
+            index=pd.PeriodIndex(["2020-01", "2021-06"], freq=freq),
         )
         out = df.to_json(orient="table")
         result = pd.read_json(out, orient="table")
diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py
index a3345c91451ef..21937a35629a0 100644
--- a/pandas/tests/resample/test_datetime_index.py
+++ b/pandas/tests/resample/test_datetime_index.py
@@ -2013,9 +2013,11 @@ def test_resample_empty_series_with_tz():
         ("2QE-SEP", "2Q-SEP"),
         ("1YE", "1Y"),
         ("2YE-MAR", "2Y-MAR"),
+        ("1YE", "1A"),
+        ("2YE-MAR", "2A-MAR"),
     ],
 )
-def test_resample_M_Q_Y_deprecated(freq, freq_depr):
+def test_resample_M_Q_Y_A_deprecated(freq, freq_depr):
     # GH#9586
     depr_msg = f"'{freq_depr[1:]}' will be deprecated, please use '{freq[1:]}' instead."
 
diff --git a/pandas/tests/resample/test_period_index.py b/pandas/tests/resample/test_period_index.py
index 50f07750355a1..b8b2325f03889 100644
--- a/pandas/tests/resample/test_period_index.py
+++ b/pandas/tests/resample/test_period_index.py
@@ -931,7 +931,7 @@ def test_resample_t_l_deprecated(self):
         tm.assert_series_equal(result, expected)
 
 
-@pytest.mark.parametrize("freq_depr", ["2ME", "2QE", "2QE-FEB"])
+@pytest.mark.parametrize("freq_depr", ["2ME", "2QE", "2QE-FEB", "2YE"])
 def test_resample_frequency_ME_QE_error_message(series_and_frame, freq_depr):
     # GH#9586
     msg = f"Invalid frequency: {freq_depr}"

From 47cd34c39df769847a6452f11b04960c41187497 Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Wed, 8 Nov 2023 16:10:42 +0100
Subject: [PATCH 09/10] correct typo in v2.2.0 note

---
 doc/source/whatsnew/v2.2.0.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst
index 96862ba87cfff..2920c2011964b 100644
--- a/doc/source/whatsnew/v2.2.0.rst
+++ b/doc/source/whatsnew/v2.2.0.rst
@@ -238,7 +238,7 @@ Deprecate aliases ``M``, ``Q``, and ``Y`` in favour of ``ME``, ``QE``, and ``YE`
 Deprecated the following frequency aliases (:issue:`9586`):
 
 - ``M`` (month end) has been renamed ``ME`` for offsets
-- ``Q`` (year end) has been renamed ``QE`` for offsets
+- ``Q`` (quarter end) has been renamed ``QE`` for offsets
 - ``Y`` (year end) has been renamed ``YE`` for offsets
 
 For example:

From 2d6c14162ac399b16e0d026d13bff0527664deeb Mon Sep 17 00:00:00 2001
From: Natalia Mokeeva <natalia.mokeeva.de@gmail.com>
Date: Thu, 9 Nov 2023 13:13:47 +0100
Subject: [PATCH 10/10] change warning message, fix test

---
 pandas/_libs/tslibs/offsets.pyx            | 5 +++--
 pandas/tests/indexes/period/test_period.py | 3 ++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx
index 6798f276deebb..c5d4010d4ba47 100644
--- a/pandas/_libs/tslibs/offsets.pyx
+++ b/pandas/_libs/tslibs/offsets.pyx
@@ -4765,8 +4765,9 @@ cpdef to_offset(freq, bint is_period=False):
                 elif is_period is True and name in c_OFFSET_DEPR_FREQSTR:
                     if name.startswith("A"):
                         warnings.warn(
-                            f"\'{name}\' will be deprecated, please use "
-                            f"\'{c_DEPR_ABBREVS.get(name)}\' instead.",
+                            f"\'{name}\' is deprecated and will be removed in a future "
+                            f"version, please use \'{c_DEPR_ABBREVS.get(name)}\' "
+                            f"instead.",
                             FutureWarning,
                             stacklevel=find_stack_level(),
                         )
diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py
index f710ac88ede1d..4f946edf148fd 100644
--- a/pandas/tests/indexes/period/test_period.py
+++ b/pandas/tests/indexes/period/test_period.py
@@ -291,7 +291,8 @@ def test_H_deprecated_from_time_series(self):
     def test_a_deprecated_from_time_series(self, freq_depr):
         # GH#52536
         freq_msg = freq_depr[freq_depr.index("A") :]
-        msg = f"'{freq_msg}' will be deprecated, please use 'Y{freq_msg[1:]}' instead."
+        msg = f"'{freq_msg}' is deprecated and will be removed in a future version, "
+        f"please use 'Y{freq_msg[1:]}' instead."
 
         with tm.assert_produces_warning(FutureWarning, match=msg):
             index = period_range(freq=freq_depr, start="1/1/2001", end="12/1/2009")