Skip to content

Commit 0d28752

Browse files
dsaxtonjreback
authored andcommitted
Make MultiIndex.get_loc raise for unhashable type (pandas-dev#35914)
Co-authored-by: Jeff Reback <[email protected]>
1 parent 435a1d0 commit 0d28752

File tree

5 files changed

+23
-4
lines changed

5 files changed

+23
-4
lines changed

doc/source/whatsnew/v1.1.2.rst

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Fixed regressions
1717
- Regression in :meth:`DatetimeIndex.intersection` incorrectly raising ``AssertionError`` when intersecting against a list (:issue:`35876`)
1818
- Fix regression in updating a column inplace (e.g. using ``df['col'].fillna(.., inplace=True)``) (:issue:`35731`)
1919
- Performance regression for :meth:`RangeIndex.format` (:issue:`35712`)
20+
- Regression where :meth:`MultiIndex.get_loc` would return a slice spanning the full index when passed an empty list (:issue:`35878`)
2021
- Fix regression in invalid cache after an indexing operation; this can manifest when setting which does not update the data (:issue:`35521`)
2122
- Regression in :meth:`DataFrame.replace` where a ``TypeError`` would be raised when attempting to replace elements of type :class:`Interval` (:issue:`35931`)
2223
- Fix regression in pickle roundtrip of the ``closed`` attribute of :class:`IntervalIndex` (:issue:`35658`)

pandas/core/indexes/multi.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -2725,6 +2725,8 @@ def get_loc(self, key, method=None):
27252725
"currently supported for MultiIndex"
27262726
)
27272727

2728+
hash(key)
2729+
27282730
def _maybe_to_slice(loc):
27292731
"""convert integer indexer to boolean mask or slice if possible"""
27302732
if not isinstance(loc, np.ndarray) or loc.dtype != "int64":
@@ -2739,8 +2741,7 @@ def _maybe_to_slice(loc):
27392741
mask[loc] = True
27402742
return mask
27412743

2742-
if not isinstance(key, (tuple, list)):
2743-
# not including list here breaks some indexing, xref #30892
2744+
if not isinstance(key, tuple):
27442745
loc = self._get_level_indexer(key, level=0)
27452746
return _maybe_to_slice(loc)
27462747

pandas/tests/frame/indexing/test_indexing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2111,7 +2111,7 @@ def test_type_error_multiindex(self):
21112111
)
21122112
dg = df.pivot_table(index="i", columns="c", values=["x", "y"])
21132113

2114-
with pytest.raises(TypeError, match="is an invalid key"):
2114+
with pytest.raises(TypeError, match="unhashable type"):
21152115
dg[:, 0]
21162116

21172117
index = Index(range(2), name="i")

pandas/tests/indexing/multiindex/test_multiindex.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import numpy as np
2+
import pytest
23

34
import pandas._libs.index as _index
45
from pandas.errors import PerformanceWarning
@@ -83,3 +84,10 @@ def test_nested_tuples_duplicates(self):
8384
df3 = df.copy(deep=True)
8485
df3.loc[[(dti[0], "a")], "c2"] = 1.0
8586
tm.assert_frame_equal(df3, expected)
87+
88+
def test_multiindex_get_loc_list_raises(self):
89+
# https://github.com/pandas-dev/pandas/issues/35878
90+
idx = pd.MultiIndex.from_tuples([("a", 1), ("b", 2)])
91+
msg = "unhashable type"
92+
with pytest.raises(TypeError, match=msg):
93+
idx.get_loc([])

pandas/tests/series/indexing/test_setitem.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import numpy as np
22

3-
from pandas import NaT, Series, date_range
3+
from pandas import MultiIndex, NaT, Series, date_range
4+
import pandas.testing as tm
45

56

67
class TestSetitemDT64Values:
@@ -17,3 +18,11 @@ def test_setitem_none_nan(self):
1718

1819
series[5:7] = np.nan
1920
assert series[6] is NaT
21+
22+
def test_setitem_multiindex_empty_slice(self):
23+
# https://github.com/pandas-dev/pandas/issues/35878
24+
idx = MultiIndex.from_tuples([("a", 1), ("b", 2)])
25+
result = Series([1, 2], index=idx)
26+
expected = result.copy()
27+
result.loc[[]] = 0
28+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)