Skip to content

Commit 4019490

Browse files
authored
BUG: MultiIndex.get_loc re-raise TypeError as KeyError (#42440)
1 parent 2846bf6 commit 4019490

File tree

4 files changed

+23
-5
lines changed

4 files changed

+23
-5
lines changed

doc/source/whatsnew/v1.4.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ MultiIndex
235235
^^^^^^^^^^
236236
- Bug in :meth:`MultiIndex.get_loc` where the first level is a :class:`DatetimeIndex` and a string key is passed (:issue:`42465`)
237237
- Bug in :meth:`MultiIndex.reindex` when passing a ``level`` that corresponds to an ``ExtensionDtype`` level (:issue:`42043`)
238+
- Bug in :meth:`MultiIndex.get_loc` raising ``TypeError`` instead of ``KeyError`` on nested tuple (:issue:`42440`)
238239
-
239240

240241
I/O

pandas/core/indexes/multi.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -2846,9 +2846,17 @@ def _maybe_to_slice(loc):
28462846
# needs linear search within the slice
28472847
i = self._lexsort_depth
28482848
lead_key, follow_key = key[:i], key[i:]
2849-
start, stop = (
2850-
self.slice_locs(lead_key, lead_key) if lead_key else (0, len(self))
2851-
)
2849+
2850+
if not lead_key:
2851+
start = 0
2852+
stop = len(self)
2853+
else:
2854+
try:
2855+
start, stop = self.slice_locs(lead_key, lead_key)
2856+
except TypeError as err:
2857+
# e.g. test_groupby_example key = ((0, 0, 1, 2), "new_col")
2858+
# when self has 5 integer levels
2859+
raise KeyError(key) from err
28522860

28532861
if start == stop:
28542862
raise KeyError(key)

pandas/core/indexing.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,8 @@ def _get_setitem_indexer(self, key):
646646

647647
ax = self.obj._get_axis(0)
648648

649-
if isinstance(ax, MultiIndex) and self.name != "iloc":
650-
with suppress(TypeError, KeyError, InvalidIndexError):
649+
if isinstance(ax, MultiIndex) and self.name != "iloc" and is_hashable(key):
650+
with suppress(KeyError, InvalidIndexError):
651651
# TypeError e.g. passed a bool
652652
return ax.get_loc(key)
653653

pandas/tests/indexes/multi/test_indexing.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import timedelta
2+
import re
23

34
import numpy as np
45
import pytest
@@ -698,6 +699,14 @@ def test_multiindex_get_loc_list_raises(self):
698699
with pytest.raises(TypeError, match=msg):
699700
idx.get_loc([])
700701

702+
def test_get_loc_nested_tuple_raises_keyerror(self):
703+
# raise KeyError, not TypeError
704+
mi = MultiIndex.from_product([range(3), range(4), range(5), range(6)])
705+
key = ((2, 3, 4), "foo")
706+
707+
with pytest.raises(KeyError, match=re.escape(str(key))):
708+
mi.get_loc(key)
709+
701710

702711
class TestWhere:
703712
def test_where(self):

0 commit comments

Comments
 (0)