Skip to content

Commit a1e0752

Browse files
authored
CLN: MultiIndex.get_value is a hive of scum and villainy (#31662)
1 parent 1d5d5a3 commit a1e0752

File tree

2 files changed

+17
-50
lines changed

2 files changed

+17
-50
lines changed

pandas/core/indexes/multi.py

Lines changed: 15 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import datetime
21
from sys import getsizeof
32
from typing import Any, Hashable, Iterable, List, Optional, Sequence, Tuple, Union
43
import warnings
@@ -7,7 +6,7 @@
76

87
from pandas._config import get_option
98

10-
from pandas._libs import Timestamp, algos as libalgos, index as libindex, lib, tslibs
9+
from pandas._libs import algos as libalgos, index as libindex, lib
1110
from pandas._libs.hashtable import duplicated_int64
1211
from pandas._typing import AnyArrayLike, ArrayLike, Scalar
1312
from pandas.compat.numpy import function as nv
@@ -2321,65 +2320,33 @@ def reindex(self, target, method=None, level=None, limit=None, tolerance=None):
23212320

23222321
def get_value(self, series, key):
23232322
# Label-based
2324-
s = com.values_from_object(series)
2325-
k = com.values_from_object(key)
2323+
if not is_hashable(key) or is_iterator(key):
2324+
# We allow tuples if they are hashable, whereas other Index
2325+
# subclasses require scalar.
2326+
# We have to explicitly exclude generators, as these are hashable.
2327+
raise InvalidIndexError(key)
23262328

23272329
def _try_mi(k):
23282330
# TODO: what if a level contains tuples??
23292331
loc = self.get_loc(k)
2332+
23302333
new_values = series._values[loc]
2334+
if is_scalar(loc):
2335+
return new_values
2336+
23312337
new_index = self[loc]
23322338
new_index = maybe_droplevels(new_index, k)
23332339
return series._constructor(
23342340
new_values, index=new_index, name=series.name
23352341
).__finalize__(self)
23362342

23372343
try:
2338-
return self._engine.get_value(s, k)
2339-
except KeyError as e1:
2340-
try:
2341-
return _try_mi(key)
2342-
except KeyError:
2343-
pass
2344-
2345-
try:
2346-
return libindex.get_value_at(s, k)
2347-
except IndexError:
2344+
return _try_mi(key)
2345+
except KeyError:
2346+
if is_integer(key):
2347+
return series._values[key]
2348+
else:
23482349
raise
2349-
except TypeError:
2350-
# generator/iterator-like
2351-
if is_iterator(key):
2352-
raise InvalidIndexError(key)
2353-
else:
2354-
raise e1
2355-
except Exception: # pragma: no cover
2356-
raise e1
2357-
except TypeError:
2358-
2359-
# a Timestamp will raise a TypeError in a multi-index
2360-
# rather than a KeyError, try it here
2361-
# note that a string that 'looks' like a Timestamp will raise
2362-
# a KeyError! (GH5725)
2363-
if isinstance(key, (datetime.datetime, np.datetime64, str)):
2364-
try:
2365-
return _try_mi(key)
2366-
except KeyError:
2367-
raise
2368-
except (IndexError, ValueError, TypeError):
2369-
pass
2370-
2371-
try:
2372-
return _try_mi(Timestamp(key))
2373-
except (
2374-
KeyError,
2375-
TypeError,
2376-
IndexError,
2377-
ValueError,
2378-
tslibs.OutOfBoundsDatetime,
2379-
):
2380-
pass
2381-
2382-
raise InvalidIndexError(key)
23832350

23842351
def _convert_listlike_indexer(self, keyarr, kind=None):
23852352
"""

pandas/tests/indexing/multiindex/test_getitem.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ def test_series_getitem_returns_scalar(
8787
(lambda s: s[(2000, 3, 4)], KeyError, r"^\(2000, 3, 4\)$"),
8888
(lambda s: s.loc[(2000, 3, 4)], KeyError, r"^\(2000, 3, 4\)$"),
8989
(lambda s: s.loc[(2000, 3, 4, 5)], IndexingError, "Too many indexers"),
90-
(lambda s: s.__getitem__(len(s)), IndexError, "index out of bounds"),
91-
(lambda s: s[len(s)], IndexError, "index out of bounds"),
90+
(lambda s: s.__getitem__(len(s)), IndexError, "is out of bounds"),
91+
(lambda s: s[len(s)], IndexError, "is out of bounds"),
9292
(
9393
lambda s: s.iloc[len(s)],
9494
IndexError,

0 commit comments

Comments
 (0)