diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index b2b6fe393f069..a9a0d89ed01aa 100755 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -837,6 +837,7 @@ Datetimelike - Bug in :class:`DatetimeArray`, :class:`TimedeltaArray`, and :class:`PeriodArray` where inplace addition and subtraction did not actually operate inplace (:issue:`24115`) - Bug in :func:`pandas.to_datetime` when called with ``Series`` storing ``IntegerArray`` raising ``TypeError`` instead of returning ``Series`` (:issue:`30050`) - Bug in :func:`date_range` with custom business hours as ``freq`` and given number of ``periods`` (:issue:`30593`) +- Bug in :class:`PeriodIndex` comparisons with incorrectly casting integers to :class:`Period` objects, inconsistent with the :class:`Period` comparison behavior (:issue:`30722`) Timedelta ^^^^^^^^^ diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 7aa6f8e8aa090..97e5b87dafeac 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -73,7 +73,6 @@ def _period_array_cmp(cls, op): @unpack_zerodim_and_defer(opname) def wrapper(self, other): - ordinal_op = getattr(self.asi8, opname) if isinstance(other, str): try: @@ -81,11 +80,6 @@ def wrapper(self, other): except ValueError: # string that can't be parsed as Period return invalid_comparison(self, other, op) - elif isinstance(other, int): - # TODO: sure we want to allow this? we dont for DTA/TDA - # 2 tests rely on this - other = Period(other, freq=self.freq) - result = ordinal_op(other.ordinal) if isinstance(other, self._recognized_scalars) or other is NaT: other = self._scalar_type(other) diff --git a/pandas/tests/arithmetic/test_period.py b/pandas/tests/arithmetic/test_period.py index 03aa9acd6b917..abb667260f094 100644 --- a/pandas/tests/arithmetic/test_period.py +++ b/pandas/tests/arithmetic/test_period.py @@ -127,7 +127,7 @@ def test_compare_object_dtype(self, box_with_array, other_box): class TestPeriodIndexComparisons: # TODO: parameterize over boxes - @pytest.mark.parametrize("other", ["2017", 2017]) + @pytest.mark.parametrize("other", ["2017", pd.Period("2017", freq="D")]) def test_eq(self, other): idx = PeriodIndex(["2017", "2017", "2018"], freq="D") expected = np.array([True, True, False]) @@ -135,6 +135,34 @@ def test_eq(self, other): tm.assert_numpy_array_equal(result, expected) + @pytest.mark.parametrize( + "other", + [ + 2017, + [2017, 2017, 2017], + np.array([2017, 2017, 2017]), + np.array([2017, 2017, 2017], dtype=object), + pd.Index([2017, 2017, 2017]), + ], + ) + def test_eq_integer_disallowed(self, other): + # match Period semantics by not treating integers as Periods + + idx = PeriodIndex(["2017", "2017", "2018"], freq="D") + expected = np.array([False, False, False]) + result = idx == other + + tm.assert_numpy_array_equal(result, expected) + + with pytest.raises(TypeError): + idx < other + with pytest.raises(TypeError): + idx > other + with pytest.raises(TypeError): + idx <= other + with pytest.raises(TypeError): + idx >= other + def test_pi_cmp_period(self): idx = period_range("2007-01", periods=20, freq="M") diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index af5aa54c60476..3276fea4dd575 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -462,7 +462,7 @@ def test_index_duplicate_periods(self): ts = Series(np.random.randn(len(idx)), index=idx) result = ts[2007] - expected = ts[idx == 2007] + expected = ts[idx == "2007"] tm.assert_series_equal(result, expected) def test_index_unique(self):