diff --git a/pandas/core/groupby/grouper.py b/pandas/core/groupby/grouper.py index 0b89e702c9867..f0c6eedf5cee4 100644 --- a/pandas/core/groupby/grouper.py +++ b/pandas/core/groupby/grouper.py @@ -27,6 +27,7 @@ from pandas.core.groupby import ops from pandas.core.groupby.categorical import recode_for_groupby, recode_from_groupby from pandas.core.indexes.api import CategoricalIndex, Index, MultiIndex +from pandas.core.indexes.base import InvalidIndexError from pandas.core.series import Series from pandas.io.formats.printing import pprint_thing @@ -565,7 +566,7 @@ def is_in_axis(key) -> bool: items = obj._data.items try: items.get_loc(key) - except (KeyError, TypeError): + except (KeyError, TypeError, InvalidIndexError): # TypeError shows up here if we pass e.g. Int64Index return False diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index b1463f52333a1..fbcca270b2be3 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -27,7 +27,7 @@ validate_tz_from_dtype, ) import pandas.core.common as com -from pandas.core.indexes.base import Index, maybe_extract_name +from pandas.core.indexes.base import Index, InvalidIndexError, maybe_extract_name from pandas.core.indexes.datetimelike import ( DatetimelikeDelegateMixin, DatetimeTimedeltaMixin, @@ -641,6 +641,8 @@ def get_value(self, series, key): Fast lookup of value from 1-dimensional ndarray. Only use this if you know what you're doing """ + if not is_scalar(key): + raise InvalidIndexError(key) if isinstance(key, (datetime, np.datetime64)): return self.get_value_maybe_box(series, key) @@ -677,6 +679,9 @@ def get_loc(self, key, method=None, tolerance=None): ------- loc : int """ + if not is_scalar(key): + raise InvalidIndexError(key) + if is_valid_nat_for_dtype(key, self.dtype): key = NaT diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index a26a01ab7be21..704430fbb4c9d 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -2778,7 +2778,7 @@ def maybe_mi_droplevels(indexer, levels, drop_level: bool): indexer = self._get_level_indexer(key, level=level) new_index = maybe_mi_droplevels(indexer, [0], drop_level) return indexer, new_index - except TypeError: + except (TypeError, InvalidIndexError): pass if not any(isinstance(k, slice) for k in key): diff --git a/pandas/core/series.py b/pandas/core/series.py index 2af41393078cb..7dadf5186f228 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -947,6 +947,9 @@ def __setitem__(self, key, value): self[:] = value else: self.loc[key] = value + except InvalidIndexError: + # e.g. slice + self._set_with(key, value) except TypeError as e: if isinstance(key, tuple) and not isinstance(self.index, MultiIndex): diff --git a/pandas/tests/indexes/datetimes/test_indexing.py b/pandas/tests/indexes/datetimes/test_indexing.py index 26d99da42cd2b..2f954117f48d7 100644 --- a/pandas/tests/indexes/datetimes/test_indexing.py +++ b/pandas/tests/indexes/datetimes/test_indexing.py @@ -7,6 +7,7 @@ import pandas as pd from pandas import DatetimeIndex, Index, Timestamp, date_range, notna import pandas._testing as tm +from pandas.core.indexes.base import InvalidIndexError from pandas.tseries.offsets import BDay, CDay @@ -697,7 +698,7 @@ def test_get_loc(self): with pytest.raises(KeyError, match="'foobar'"): idx.get_loc("foobar") - with pytest.raises(TypeError): + with pytest.raises(InvalidIndexError, match=r"slice\(None, 2, None\)"): idx.get_loc(slice(2)) idx = pd.to_datetime(["2000-01-01", "2000-01-04"])