DEPR: deprecate returning a tuple from a callable in iloc indexing (#… · pandas-dev/pandas@0e2277b (original) (raw)
`@@ -4,6 +4,8 @@
`
4
4
`import sys
`
5
5
`from typing import (
`
6
6
`TYPE_CHECKING,
`
``
7
`+
Any,
`
``
8
`+
TypeVar,
`
7
9
`cast,
`
8
10
`final,
`
9
11
`)
`
`@@ -25,6 +27,7 @@
`
25
27
`_chained_assignment_msg,
`
26
28
`)
`
27
29
`from pandas.util._decorators import doc
`
``
30
`+
from pandas.util._exceptions import find_stack_level
`
28
31
``
29
32
`from pandas.core.dtypes.cast import (
`
30
33
`can_hold_element,
`
90
93
`Series,
`
91
94
` )
`
92
95
``
``
96
`+
T = TypeVar("T")
`
93
97
`# "null slice"
`
94
98
`_NS = slice(None, None)
`
95
99
`_one_ellipsis_message = "indexer may only contain one '...' entry"
`
`@@ -153,6 +157,10 @@ def iloc(self) -> _iLocIndexer:
`
153
157
`"""
`
154
158
` Purely integer-location based indexing for selection by position.
`
155
159
``
``
160
`+
.. deprecated:: 2.2.0
`
``
161
+
``
162
`+
Returning a tuple from a callable is deprecated.
`
``
163
+
156
164
``` .iloc[]
is primarily integer position based (from 0
to
`157`
`165`
``` ``length-1`` of the axis), but may also be used with a boolean
158
166
` array.
`
`@@ -166,7 +174,8 @@ def iloc(self) -> _iLocIndexer:
`
166
174
``` - A callable
function with one argument (the calling Series or
`167`
`175`
` DataFrame) and that returns valid output for indexing (one of the above).
`
`168`
`176`
` This is useful in method chains, when you don't have a reference to the
`
`169`
``
`-
calling object, but would like to base your selection on some value.
`
``
`177`
`+
calling object, but would like to base your selection on
`
``
`178`
`+
some value.
`
`170`
`179`
` - A tuple of row and column indexes. The tuple elements consist of one of the
`
`171`
`180`
``` above inputs, e.g. ``(0, 1)``.
172
181
``
`@@ -878,7 +887,8 @@ def setitem(self, key, value) -> None:
`
878
887
`key = tuple(list(x) if is_iterator(x) else x for x in key)
`
879
888
`key = tuple(com.apply_if_callable(x, self.obj) for x in key)
`
880
889
`else:
`
881
``
`-
key = com.apply_if_callable(key, self.obj)
`
``
890
`+
maybe_callable = com.apply_if_callable(key, self.obj)
`
``
891
`+
key = self._check_deprecated_callable_usage(key, maybe_callable)
`
882
892
`indexer = self._get_setitem_indexer(key)
`
883
893
`self._has_valid_setitem_indexer(key)
`
884
894
``
`@@ -1137,6 +1147,17 @@ def _contains_slice(x: object) -> bool:
`
1137
1147
`def _convert_to_indexer(self, key, axis: AxisInt):
`
1138
1148
`raise AbstractMethodError(self)
`
1139
1149
``
``
1150
`+
def _check_deprecated_callable_usage(self, key: Any, maybe_callable: T) -> T:
`
``
1151
`+
GH53533
`
``
1152
`+
if self.name == "iloc" and callable(key) and isinstance(maybe_callable, tuple):
`
``
1153
`+
warnings.warn(
`
``
1154
`+
"Returning a tuple from a callable with iloc "
`
``
1155
`+
"is deprecated and will be removed in a future version",
`
``
1156
`+
FutureWarning,
`
``
1157
`+
stacklevel=find_stack_level(),
`
``
1158
`+
)
`
``
1159
`+
return maybe_callable
`
``
1160
+
1140
1161
`@final
`
1141
1162
`def getitem(self, key):
`
1142
1163
`check_dict_or_set_indexers(key)
`
`@@ -1151,6 +1172,7 @@ def getitem(self, key):
`
1151
1172
`axis = self.axis or 0
`
1152
1173
``
1153
1174
`maybe_callable = com.apply_if_callable(key, self.obj)
`
``
1175
`+
maybe_callable = self._check_deprecated_callable_usage(key, maybe_callable)
`
1154
1176
`return self._getitem_axis(maybe_callable, axis=axis)
`
1155
1177
``
1156
1178
`def _is_scalar_access(self, key: tuple):
`