diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 1eca83f394987..f540dc99e91f3 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -157,19 +157,18 @@ cdef class IndexEngine: try: return self.mapping.get_item(val) - except (TypeError, ValueError, OverflowError): + except OverflowError as err: # GH#41775 OverflowError e.g. if we are uint64 and val is -1 - raise KeyError(val) + # or if we are int64 and value is np.iinfo(np.int64).max+1 + # (the uint64 with -1 case should actually be excluded by _check_type) + raise KeyError(val) from err cdef Py_ssize_t _searchsorted_left(self, val) except? -1: """ See ObjectEngine._searchsorted_left.__doc__. """ - try: - loc = self.values.searchsorted(val, side="left") - except TypeError as err: - # GH#35788 e.g. val=None with float64 values - raise KeyError(val) + # Caller is responsible for ensuring _check_type has already been called + loc = self.values.searchsorted(val, side="left") return loc cdef inline _get_loc_duplicates(self, object val): @@ -184,6 +183,7 @@ cdef class IndexEngine: right = values.searchsorted(val, side='right') except TypeError: # e.g. GH#29189 get_loc(None) with a Float64Index + # 2021-09-29 Now only reached for object-dtype raise KeyError(val) diff = right - left diff --git a/pandas/_libs/index_class_helper.pxi.in b/pandas/_libs/index_class_helper.pxi.in index 1b8e43ac24fa4..7a2bbec96e413 100644 --- a/pandas/_libs/index_class_helper.pxi.in +++ b/pandas/_libs/index_class_helper.pxi.in @@ -36,6 +36,11 @@ cdef class {{name}}Engine(IndexEngine): {{if name not in {'Float64', 'Float32'} }} if not util.is_integer_object(val): raise KeyError(val) + {{if name.startswith("U")}} + if val < 0: + # cannot have negative values with unsigned int dtype + raise KeyError(val) + {{endif}} {{else}} if not util.is_integer_object(val) and not util.is_float_object(val): # in particular catch bool and avoid casting True -> 1.0 diff --git a/pandas/tests/indexes/numeric/test_indexing.py b/pandas/tests/indexes/numeric/test_indexing.py index dae8a3340bcd2..4621cbcb9d462 100644 --- a/pandas/tests/indexes/numeric/test_indexing.py +++ b/pandas/tests/indexes/numeric/test_indexing.py @@ -160,6 +160,17 @@ def test_get_loc_numericindex_none_raises(self, dtype): with pytest.raises(KeyError, match="None"): idx.get_loc(None) + def test_get_loc_overflows(self): + # unique but non-monotonic goes through IndexEngine.mapping.get_item + idx = Index([0, 2, 1]) + + val = np.iinfo(np.int64).max + 1 + + with pytest.raises(KeyError, match=str(val)): + idx.get_loc(val) + with pytest.raises(KeyError, match=str(val)): + idx._engine.get_loc(val) + class TestGetIndexer: def test_get_indexer(self):