diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 27511c96faa5a..20ca67c0ad111 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -627,6 +627,7 @@ Indexing - Bug in :meth:`DataFrame.loc` raising ``TypeError`` when non-integer slice was given to select values from :class:`MultiIndex` (:issue:`25165`, :issue:`24263`) - Bug in :meth:`DataFrame.loc` returning and assigning elements in wrong order when indexer is differently ordered than the :class:`MultiIndex` to filter (:issue:`31330`, :issue:`34603`) - Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.__getitem__` raising ``KeyError`` when columns were :class:`MultiIndex` with only one level (:issue:`29749`) +- Bug in :meth:`Series.__getitem__` and :meth:`DataFrame.__getitem__` raising blank ``KeyError`` without missing keys for :class:`IntervalIndex` (:issue:`27365`) Missing ^^^^^^^ diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 98752a21e44a2..986c4d2c59723 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -806,7 +806,7 @@ def _convert_list_indexer(self, keyarr): # we have missing values if (locs == -1).any(): - raise KeyError + raise KeyError(keyarr[locs == -1].tolist()) return locs diff --git a/pandas/tests/indexing/interval/test_interval.py b/pandas/tests/indexing/interval/test_interval.py index 0fa6abb27cb61..f4e7296598d54 100644 --- a/pandas/tests/indexing/interval/test_interval.py +++ b/pandas/tests/indexing/interval/test_interval.py @@ -65,10 +65,10 @@ def test_non_matching(self): # this is a departure from our current # indexing scheme, but simpler - with pytest.raises(KeyError, match="^$"): + with pytest.raises(KeyError, match=r"^\[-1\]$"): s.loc[[-1, 3, 4, 5]] - with pytest.raises(KeyError, match="^$"): + with pytest.raises(KeyError, match=r"^\[-1\]$"): s.loc[[-1, 3]] @pytest.mark.arm_slow @@ -107,11 +107,11 @@ def test_loc_getitem_frame(self): expected = df.take([4, 5, 4, 5]) tm.assert_frame_equal(result, expected) - with pytest.raises(KeyError, match="^$"): + with pytest.raises(KeyError, match=r"^\[10\]$"): df.loc[[10]] # partial missing - with pytest.raises(KeyError, match="^$"): + with pytest.raises(KeyError, match=r"^\[10\]$"): df.loc[[10, 4]] diff --git a/pandas/tests/indexing/interval/test_interval_new.py b/pandas/tests/indexing/interval/test_interval_new.py index 03c3034772bc6..a9512bc97d9de 100644 --- a/pandas/tests/indexing/interval/test_interval_new.py +++ b/pandas/tests/indexing/interval/test_interval_new.py @@ -204,13 +204,13 @@ def test_loc_with_overlap(self): with pytest.raises(KeyError, match=re.escape("Interval(3, 5, closed='right')")): s.loc[Interval(3, 5)] - with pytest.raises(KeyError, match="^$"): + with pytest.raises(KeyError, match=r"^\[Interval\(3, 5, closed='right'\)\]$"): s.loc[[Interval(3, 5)]] with pytest.raises(KeyError, match=re.escape("Interval(3, 5, closed='right')")): s[Interval(3, 5)] - with pytest.raises(KeyError, match="^$"): + with pytest.raises(KeyError, match=r"^\[Interval\(3, 5, closed='right'\)\]$"): s[[Interval(3, 5)]] # slices with interval (only exact matches) @@ -266,3 +266,11 @@ def test_non_unique_moar(self): expected = s.iloc[[0, 1]] result = s[[Interval(1, 3)]] tm.assert_series_equal(expected, result) + + def test_missing_key_error_message(self, frame_or_series): + # GH#27365 + obj = frame_or_series( + np.arange(5), index=IntervalIndex.from_breaks(np.arange(6)) + ) + with pytest.raises(KeyError, match=r"\[6\]"): + obj.loc[[4, 5, 6]]