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):

`