Skip to content

Commit 3a38728

Browse files
jbrockmendelgasparitiago
authored andcommitted
REF: handle uint-negatve cases in _check_type (pandas-dev#43811)
1 parent cd5eaf5 commit 3a38728

File tree

3 files changed

+23
-7
lines changed

3 files changed

+23
-7
lines changed

pandas/_libs/index.pyx

+7-7
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,18 @@ cdef class IndexEngine:
157157

158158
try:
159159
return self.mapping.get_item(val)
160-
except (TypeError, ValueError, OverflowError):
160+
except OverflowError as err:
161161
# GH#41775 OverflowError e.g. if we are uint64 and val is -1
162-
raise KeyError(val)
162+
# or if we are int64 and value is np.iinfo(np.int64).max+1
163+
# (the uint64 with -1 case should actually be excluded by _check_type)
164+
raise KeyError(val) from err
163165

164166
cdef Py_ssize_t _searchsorted_left(self, val) except? -1:
165167
"""
166168
See ObjectEngine._searchsorted_left.__doc__.
167169
"""
168-
try:
169-
loc = self.values.searchsorted(val, side="left")
170-
except TypeError as err:
171-
# GH#35788 e.g. val=None with float64 values
172-
raise KeyError(val)
170+
# Caller is responsible for ensuring _check_type has already been called
171+
loc = self.values.searchsorted(val, side="left")
173172
return loc
174173

175174
cdef inline _get_loc_duplicates(self, object val):
@@ -184,6 +183,7 @@ cdef class IndexEngine:
184183
right = values.searchsorted(val, side='right')
185184
except TypeError:
186185
# e.g. GH#29189 get_loc(None) with a Float64Index
186+
# 2021-09-29 Now only reached for object-dtype
187187
raise KeyError(val)
188188

189189
diff = right - left

pandas/_libs/index_class_helper.pxi.in

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ cdef class {{name}}Engine(IndexEngine):
3636
{{if name not in {'Float64', 'Float32'} }}
3737
if not util.is_integer_object(val):
3838
raise KeyError(val)
39+
{{if name.startswith("U")}}
40+
if val < 0:
41+
# cannot have negative values with unsigned int dtype
42+
raise KeyError(val)
43+
{{endif}}
3944
{{else}}
4045
if not util.is_integer_object(val) and not util.is_float_object(val):
4146
# in particular catch bool and avoid casting True -> 1.0

pandas/tests/indexes/numeric/test_indexing.py

+11
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,17 @@ def test_get_loc_numericindex_none_raises(self, dtype):
160160
with pytest.raises(KeyError, match="None"):
161161
idx.get_loc(None)
162162

163+
def test_get_loc_overflows(self):
164+
# unique but non-monotonic goes through IndexEngine.mapping.get_item
165+
idx = Index([0, 2, 1])
166+
167+
val = np.iinfo(np.int64).max + 1
168+
169+
with pytest.raises(KeyError, match=str(val)):
170+
idx.get_loc(val)
171+
with pytest.raises(KeyError, match=str(val)):
172+
idx._engine.get_loc(val)
173+
163174

164175
class TestGetIndexer:
165176
def test_get_indexer(self):

0 commit comments

Comments
 (0)