Skip to content

Commit

Permalink
DEPR: unused kind arg in Index methods (pandas-dev#42857)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel authored and feefladder committed Sep 7, 2021
1 parent e01ce2d commit 03adc0d
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 14 deletions.
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v1.4.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ Deprecations
- Deprecated treating ``numpy.datetime64`` objects as UTC times when passed to the :class:`Timestamp` constructor along with a timezone. In a future version, these will be treated as wall-times. To retain the old behavior, use ``Timestamp(dt64).tz_localize("UTC").tz_convert(tz)`` (:issue:`24559`)
- Deprecated ignoring missing labels when indexing with a sequence of labels on a level of a MultiIndex (:issue:`42351`)
- Creating an empty Series without a dtype will now raise a more visible ``FutureWarning`` instead of a ``DeprecationWarning`` (:issue:`30017`)
- Deprecated the 'kind' argument in :meth:`Index.get_slice_bound`, :meth:`Index.slice_indexer`, :meth:`Index.slice_locs`; in a future version passing 'kind' will raise (:issue:`42857`)
-

.. ---------------------------------------------------------------------------
Expand Down
20 changes: 16 additions & 4 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5839,7 +5839,7 @@ def slice_indexer(
start: Hashable | None = None,
end: Hashable | None = None,
step: int | None = None,
kind: str_t | None = None,
kind=no_default,
) -> slice:
"""
Compute the slice indexer for input labels and step.
Expand All @@ -5855,6 +5855,8 @@ def slice_indexer(
step : int, default None
kind : str, default None
.. deprecated:: 1.4.0
Returns
-------
indexer : slice
Expand All @@ -5880,6 +5882,8 @@ def slice_indexer(
>>> idx.slice_indexer(start='b', end=('c', 'g'))
slice(1, 3, None)
"""
self._deprecated_arg(kind, "kind", "slice_indexer")

start_slice, end_slice = self.slice_locs(start, end, step=step)

# return a slice
Expand Down Expand Up @@ -5928,6 +5932,8 @@ def _maybe_cast_slice_bound(self, label, side: str_t, kind=no_default):
side : {'left', 'right'}
kind : {'loc', 'getitem'} or None
.. deprecated:: 1.3.0
Returns
-------
label : object
Expand Down Expand Up @@ -5962,7 +5968,7 @@ def _searchsorted_monotonic(self, label, side: str_t = "left"):

raise ValueError("index must be monotonic increasing or decreasing")

def get_slice_bound(self, label, side: str_t, kind=None) -> int:
def get_slice_bound(self, label, side: str_t, kind=no_default) -> int:
"""
Calculate slice bound that corresponds to given label.
Expand All @@ -5975,12 +5981,15 @@ def get_slice_bound(self, label, side: str_t, kind=None) -> int:
side : {'left', 'right'}
kind : {'loc', 'getitem'} or None
.. deprecated:: 1.4.0
Returns
-------
int
Index of label.
"""
assert kind in ["loc", "getitem", None]
assert kind in ["loc", "getitem", None, no_default]
self._deprecated_arg(kind, "kind", "get_slice_bound")

if side not in ("left", "right"):
raise ValueError(
Expand Down Expand Up @@ -6030,7 +6039,7 @@ def get_slice_bound(self, label, side: str_t, kind=None) -> int:
else:
return slc

def slice_locs(self, start=None, end=None, step=None, kind=None):
def slice_locs(self, start=None, end=None, step=None, kind=no_default):
"""
Compute slice locations for input labels.
Expand All @@ -6044,6 +6053,8 @@ def slice_locs(self, start=None, end=None, step=None, kind=None):
If None, defaults to 1.
kind : {'loc', 'getitem'} or None
.. deprecated:: 1.4.0
Returns
-------
start, end : int
Expand All @@ -6062,6 +6073,7 @@ def slice_locs(self, start=None, end=None, step=None, kind=None):
>>> idx.slice_locs(start='b', end='c')
(1, 3)
"""
self._deprecated_arg(kind, "kind", "slice_locs")
inc = step is None or step >= 0

if not inc:
Expand Down
4 changes: 3 additions & 1 deletion pandas/core/indexes/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ def _maybe_cast_slice_bound(self, label, side: str, kind=lib.no_default):

return self._maybe_cast_for_get_loc(label)

def slice_indexer(self, start=None, end=None, step=None, kind=None):
def slice_indexer(self, start=None, end=None, step=None, kind=lib.no_default):
"""
Return indexer for specified label slice.
Index.slice_indexer, customized to handle time slicing.
Expand All @@ -743,6 +743,8 @@ def slice_indexer(self, start=None, end=None, step=None, kind=None):
value-based selection in non-monotonic cases.
"""
self._deprecated_arg(kind, "kind", "slice_indexer")

# For historical reasons DatetimeIndex supports slices between two
# instances of datetime.time as if it were applying a slice mask to
# an array of (self.hour, self.minute, self.seconds, self.microsecond).
Expand Down
11 changes: 9 additions & 2 deletions pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2586,7 +2586,7 @@ def _get_indexer_level_0(self, target) -> np.ndarray:
return ci.get_indexer_for(target)

def get_slice_bound(
self, label: Hashable | Sequence[Hashable], side: str, kind: str | None = None
self, label: Hashable | Sequence[Hashable], side: str, kind=lib.no_default
) -> int:
"""
For an ordered MultiIndex, compute slice bound
Expand All @@ -2601,6 +2601,8 @@ def get_slice_bound(
side : {'left', 'right'}
kind : {'loc', 'getitem', None}
.. deprecated:: 1.4.0
Returns
-------
int
Expand Down Expand Up @@ -2632,11 +2634,13 @@ def get_slice_bound(
MultiIndex.get_locs : Get location for a label/slice/list/mask or a
sequence of such.
"""
self._deprecated_arg(kind, "kind", "get_slice_bound")

if not isinstance(label, tuple):
label = (label,)
return self._partial_tup_index(label, side=side)

def slice_locs(self, start=None, end=None, step=None, kind=None):
def slice_locs(self, start=None, end=None, step=None, kind=lib.no_default):
"""
For an ordered MultiIndex, compute the slice locations for input
labels.
Expand All @@ -2655,6 +2659,8 @@ def slice_locs(self, start=None, end=None, step=None, kind=None):
Slice step
kind : string, optional, defaults None
.. deprecated:: 1.4.0
Returns
-------
(start, end) : (int, int)
Expand Down Expand Up @@ -2688,6 +2694,7 @@ def slice_locs(self, start=None, end=None, step=None, kind=None):
MultiIndex.get_locs : Get location for a label/slice/list/mask or a
sequence of such.
"""
self._deprecated_arg(kind, "kind", "slice_locs")
# This function adds nothing to its parent implementation (the magic
# happens in get_slice_bound method), but it adds meaningful doc.
return super().slice_locs(start, end, step)
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ def _convert_slice_indexer(self, key: slice, kind: str):

# We always treat __getitem__ slicing as label-based
# translate to locations
return self.slice_indexer(key.start, key.stop, key.step, kind=kind)
return self.slice_indexer(key.start, key.stop, key.step)

return super()._convert_slice_indexer(key, kind=kind)

Expand Down
8 changes: 5 additions & 3 deletions pandas/tests/indexes/base_class/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class TestGetSliceBounds:
@pytest.mark.parametrize("side, expected", [("left", 4), ("right", 5)])
def test_get_slice_bounds_within(self, kind, side, expected):
index = Index(list("abcdef"))
result = index.get_slice_bound("e", kind=kind, side=side)
with tm.assert_produces_warning(FutureWarning, match="'kind' argument"):
result = index.get_slice_bound("e", kind=kind, side=side)
assert result == expected

@pytest.mark.parametrize("kind", ["getitem", "loc", None])
Expand All @@ -20,12 +21,13 @@ def test_get_slice_bounds_within(self, kind, side, expected):
)
def test_get_slice_bounds_outside(self, kind, side, expected, data, bound):
index = Index(data)
result = index.get_slice_bound(bound, kind=kind, side=side)
with tm.assert_produces_warning(FutureWarning, match="'kind' argument"):
result = index.get_slice_bound(bound, kind=kind, side=side)
assert result == expected

def test_get_slice_bounds_invalid_side(self):
with pytest.raises(ValueError, match="Invalid value for side kwarg"):
Index([]).get_slice_bound("a", kind=None, side="middle")
Index([]).get_slice_bound("a", side="middle")


class TestGetIndexerNonUnique:
Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/indexes/multi/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,8 @@ def test_timestamp_multiindex_indexer():
def test_get_slice_bound_with_missing_value(index_arr, expected, target, algo):
# issue 19132
idx = MultiIndex.from_arrays(index_arr)
result = idx.get_slice_bound(target, side=algo, kind="loc")
with tm.assert_produces_warning(FutureWarning, match="'kind' argument"):
result = idx.get_slice_bound(target, side=algo, kind="loc")
assert result == expected


Expand Down
7 changes: 5 additions & 2 deletions pandas/tests/indexes/numeric/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,13 +545,16 @@ class TestGetSliceBounds:
@pytest.mark.parametrize("side, expected", [("left", 4), ("right", 5)])
def test_get_slice_bounds_within(self, kind, side, expected):
index = Index(range(6))
result = index.get_slice_bound(4, kind=kind, side=side)
with tm.assert_produces_warning(FutureWarning, match="'kind' argument"):

result = index.get_slice_bound(4, kind=kind, side=side)
assert result == expected

@pytest.mark.parametrize("kind", ["getitem", "loc", None])
@pytest.mark.parametrize("side", ["left", "right"])
@pytest.mark.parametrize("bound, expected", [(-1, 0), (10, 6)])
def test_get_slice_bounds_outside(self, kind, side, expected, bound):
index = Index(range(6))
result = index.get_slice_bound(bound, kind=kind, side=side)
with tm.assert_produces_warning(FutureWarning, match="'kind' argument"):
result = index.get_slice_bound(bound, kind=kind, side=side)
assert result == expected

0 comments on commit 03adc0d

Please sign in to comment.