diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index e8ad2bef099a1..c094996f69419 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3142,6 +3142,15 @@ def _convert_scalar_indexer(self, key, kind: str_t): return key + def _validate_positional_slice(self, key: slice): + """ + For positional indexing, a slice must have either int or None + for each of start, stop, and step. + """ + self._validate_indexer("positional", key.start, "iloc") + self._validate_indexer("positional", key.stop, "iloc") + self._validate_indexer("positional", key.step, "iloc") + def _convert_slice_indexer(self, key: slice, kind=None): """ Convert a slice indexer. @@ -3152,16 +3161,9 @@ def _convert_slice_indexer(self, key: slice, kind=None): Parameters ---------- key : label of the slice bound - kind : {'loc', 'getitem', 'iloc'} or None + kind : {'loc', 'getitem'} or None """ - assert kind in ["loc", "getitem", "iloc", None] - - # validate iloc - if kind == "iloc": - self._validate_indexer("positional", key.start, "iloc") - self._validate_indexer("positional", key.stop, "iloc") - self._validate_indexer("positional", key.step, "iloc") - return key + assert kind in ["loc", "getitem", None], kind # potentially cast the bounds to integers start, stop, step = key.start, key.stop, key.step diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index d67c40a78d807..f09713409c6cf 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -394,10 +394,9 @@ def _convert_scalar_indexer(self, key, kind: str): @Appender(Index._convert_slice_indexer.__doc__) def _convert_slice_indexer(self, key: slice, kind=None): + assert kind in ["loc", "getitem", None] - if kind == "iloc": - return super()._convert_slice_indexer(key, kind=kind) - + # We always treat __getitem__ slicing as label-based # translate to locations return self.slice_indexer(key.start, key.stop, key.step, kind=kind) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 5c0f893554957..70092c70a76ad 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1685,7 +1685,7 @@ def _get_slice_axis(self, slice_obj: slice, axis: int): labels = obj._get_axis(axis) indexer = labels.slice_indexer( - slice_obj.start, slice_obj.stop, slice_obj.step, kind=self.name + slice_obj.start, slice_obj.stop, slice_obj.step, kind="loc" ) if isinstance(indexer, slice): @@ -2035,8 +2035,8 @@ def _get_slice_axis(self, slice_obj: slice, axis: int): return obj.copy(deep=False) labels = obj._get_axis(axis) - indexer = labels._convert_slice_indexer(slice_obj, kind="iloc") - return self.obj._slice(indexer, axis=axis, kind="iloc") + labels._validate_positional_slice(slice_obj) + return self.obj._slice(slice_obj, axis=axis, kind="iloc") def _convert_to_indexer(self, key, axis: int, is_setter: bool = False): """ @@ -2046,7 +2046,8 @@ def _convert_to_indexer(self, key, axis: int, is_setter: bool = False): # make need to convert a float key if isinstance(key, slice): - return labels._convert_slice_indexer(key, kind="iloc") + labels._validate_positional_slice(key) + return key elif is_float(key): labels._validate_indexer("positional", key, "iloc") diff --git a/pandas/core/series.py b/pandas/core/series.py index c54331f867a9c..100500264be73 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -842,7 +842,10 @@ def _ixs(self, i: int, axis: int = 0): def _slice(self, slobj: slice, axis: int = 0, kind: str = "getitem") -> "Series": assert kind in ["getitem", "iloc"] - slobj = self.index._convert_slice_indexer(slobj, kind=kind) + if kind == "getitem": + # If called from getitem, we need to determine whether + # this slice is positional or label-based. + slobj = self.index._convert_slice_indexer(slobj, kind="getitem") return self._get_values(slobj) def __getitem__(self, key): @@ -884,7 +887,7 @@ def __getitem__(self, key): def _get_with(self, key): # other: fancy integer or otherwise if isinstance(key, slice): - return self._slice(key) + return self._slice(key, kind="getitem") elif isinstance(key, ABCDataFrame): raise TypeError( "Indexing a Series with DataFrame is not "