Skip to content

Commit 1ca35d1

Browse files
move list-like check inside
1 parent 3c5e4c6 commit 1ca35d1

File tree

9 files changed

+40
-27
lines changed

9 files changed

+40
-27
lines changed

pandas/core/arrays/categorical.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -2001,8 +2001,7 @@ def __getitem__(self, key):
20012001
else:
20022002
return self.categories[i]
20032003

2004-
if is_list_like(key) and not isinstance(key, tuple):
2005-
key = check_array_indexer(self, key)
2004+
key = check_array_indexer(self, key)
20062005

20072006
result = self._codes[key]
20082007
if result.ndim > 1:

pandas/core/arrays/datetimelike.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ def __getitem__(self, key):
530530
# see https://github.com/pandas-dev/pandas/issues/31299, need to allow
531531
# this for now (would otherwise raise in check_array_indexer)
532532
pass
533-
elif is_list_like(key) and not isinstance(key, tuple):
533+
else:
534534
key = check_array_indexer(self, key)
535535

536536
is_period = is_period_dtype(self)

pandas/core/arrays/interval.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -496,8 +496,7 @@ def __len__(self) -> int:
496496
return len(self.left)
497497

498498
def __getitem__(self, value):
499-
if is_list_like(value) and not isinstance(value, tuple):
500-
value = check_array_indexer(self, value)
499+
value = check_array_indexer(self, value)
501500
left = self.left[value]
502501
right = self.right[value]
503502

pandas/core/arrays/masked.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44

55
from pandas._libs import lib, missing as libmissing
66

7-
from pandas.core.dtypes.common import (
8-
is_integer,
9-
is_list_like,
10-
is_object_dtype,
11-
is_string_dtype,
12-
)
7+
from pandas.core.dtypes.common import is_integer, is_object_dtype, is_string_dtype
138
from pandas.core.dtypes.missing import isna, notna
149

1510
from pandas.core.algorithms import take
@@ -39,8 +34,7 @@ def __getitem__(self, item):
3934
return self.dtype.na_value
4035
return self._data[item]
4136

42-
elif is_list_like(item) and not isinstance(item, tuple):
43-
item = check_array_indexer(self, item)
37+
item = check_array_indexer(self, item)
4438

4539
return type(self)(self._data[item], self._mask[item])
4640

pandas/core/arrays/numpy_.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from pandas.util._decorators import Appender
1010
from pandas.util._validators import validate_fillna_kwargs
1111

12-
from pandas.core.dtypes.common import is_list_like
1312
from pandas.core.dtypes.dtypes import ExtensionDtype
1413
from pandas.core.dtypes.generic import ABCIndexClass, ABCSeries
1514
from pandas.core.dtypes.inference import is_array_like
@@ -234,8 +233,7 @@ def __getitem__(self, item):
234233
if isinstance(item, type(self)):
235234
item = item._ndarray
236235

237-
elif is_list_like(item) and not isinstance(item, tuple):
238-
item = check_array_indexer(self, item)
236+
item = check_array_indexer(self, item)
239237

240238
result = self._ndarray[item]
241239
if not lib.is_scalar(item):

pandas/core/arrays/sparse/array.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
is_datetime64_any_dtype,
3030
is_dtype_equal,
3131
is_integer,
32-
is_list_like,
3332
is_object_dtype,
3433
is_scalar,
3534
is_string_dtype,
@@ -770,8 +769,7 @@ def __getitem__(self, key):
770769
else:
771770
key = np.asarray(key)
772771

773-
if is_list_like(key) and not isinstance(key, tuple):
774-
key = check_array_indexer(self, key)
772+
key = check_array_indexer(self, key)
775773

776774
if com.is_bool_indexer(key):
777775
key = check_bool_indexer(self, key)

pandas/core/indexers.py

+22-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import numpy as np
77

8-
from pandas._typing import AnyArrayLike
8+
from pandas._typing import Any, AnyArrayLike
99

1010
from pandas.core.dtypes.common import (
1111
is_array_like,
@@ -274,14 +274,18 @@ def deprecate_ndim_indexing(result):
274274
# Public indexer validation
275275

276276

277-
def check_array_indexer(array: AnyArrayLike, indexer) -> np.ndarray:
277+
def check_array_indexer(array: AnyArrayLike, indexer: Any) -> Any:
278278
"""
279279
Check if `indexer` is a valid array indexer for `array`.
280280
281281
For a boolean mask, `array` and `indexer` are checked to have the same
282282
length. The dtype is validated, and if it is an integer or boolean
283283
ExtensionArray, it is checked if there are missing values present, and
284-
it is converted to the appropriate numpy array.
284+
it is converted to the appropriate numpy array. Other dtypes will raise
285+
an error.
286+
287+
Non-array indexers (integer, slice, Ellipsis, tuples, ..) are passed
288+
through as is.
285289
286290
.. versionadded:: 1.0.0
287291
@@ -290,9 +294,9 @@ def check_array_indexer(array: AnyArrayLike, indexer) -> np.ndarray:
290294
array : array-like
291295
The array that is being indexed (only used for the length).
292296
indexer : array-like or list-like
293-
The array-like that's used to index. The function assumes this is an
294-
array-like, and input that is not yet an numpy array or an ExtensionArray
295-
is converted to one.
297+
The array-like that's used to index. List-like input that is not yet
298+
a numpy array or an ExtensionArray is converted to one. Other input
299+
types are passed through as is
296300
297301
Returns
298302
-------
@@ -369,11 +373,23 @@ def check_array_indexer(array: AnyArrayLike, indexer) -> np.ndarray:
369373
"""
370374
from pandas.core.construction import array as pd_array
371375

376+
# whathever is not an array-like is returned as-is (possible valid array
377+
# indexers that are not array-like: integer, slice, Ellipsis, None)
378+
# In this context, tuples are not considered as array-like, as they have
379+
# a specific meaning in indexing (multi-dimensional indexing)
380+
if is_list_like(indexer):
381+
if isinstance(indexer, tuple):
382+
return indexer
383+
else:
384+
return indexer
385+
386+
# convert list-likes to array
372387
if not is_array_like(indexer):
373388
indexer = pd_array(indexer)
374389
if len(indexer) == 0:
375390
# empty list is converted to float array by pd.array
376391
indexer = np.array([], dtype=np.intp)
392+
377393
dtype = indexer.dtype
378394
if is_bool_dtype(dtype):
379395
try:

pandas/tests/extension/decimal/array.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ def __getitem__(self, item):
116116
return self._data[item]
117117
else:
118118
# array, slice.
119-
if pd.api.types.is_list_like(item):
120-
item = pd.api.indexers.check_array_indexer(self, item)
119+
item = pd.api.indexers.check_array_indexer(self, item)
121120
return type(self)(self._data[item])
122121

123122
def take(self, indexer, allow_fill=False, fill_value=None):

pandas/tests/indexing/test_check_indexer.py

+10
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,13 @@ def test_raise_invalid_array_dtypes(indexer):
8585
msg = "arrays used as indices must be of integer or boolean type"
8686
with pytest.raises(IndexError, match=msg):
8787
check_array_indexer(array, indexer)
88+
89+
90+
@pytest.mark.parametrize(
91+
"indexer", [None, Ellipsis, slice(0, 3), (None,)],
92+
)
93+
def test_pass_through_non_array_likes(indexer):
94+
array = np.array([1, 2, 3])
95+
96+
result = check_array_indexer(array, indexer)
97+
assert result == indexer

0 commit comments

Comments
 (0)