Skip to content

Commit 1a357f0

Browse files
authored
Merge pull request numpy#26930 from seberg/issue-26922
BUG: Fix out-of-bound minimum offset for in1d table method
2 parents c1d1ff4 + c899a67 commit 1a357f0

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

numpy/lib/_arraysetops_impl.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,8 +922,25 @@ def _in1d(ar1, ar2, assume_unique=False, invert=False, *, kind=None):
922922

923923
# Mask out elements we know won't work
924924
basic_mask = (ar1 <= ar2_max) & (ar1 >= ar2_min)
925+
in_range_ar1 = ar1[basic_mask]
926+
if in_range_ar1.size == 0:
927+
# Nothing more to do, since all values are out of range.
928+
return outgoing_array
929+
930+
# Unfortunately, ar2_min can be out of range for `intp` even
931+
# if the calculation result must fit in range (and be positive).
932+
# In that case, use ar2.dtype which must work for all unmasked
933+
# values.
934+
try:
935+
ar2_min = np.array(ar2_min, dtype=np.intp)
936+
dtype = np.intp
937+
except OverflowError:
938+
dtype = ar2.dtype
939+
940+
out = np.empty_like(in_range_ar1, dtype=np.intp)
925941
outgoing_array[basic_mask] = isin_helper_ar[
926-
np.subtract(ar1[basic_mask], ar2_min, dtype=np.intp)]
942+
np.subtract(in_range_ar1, ar2_min, dtype=dtype,
943+
out=out, casting="unsafe")]
927944

928945
return outgoing_array
929946
elif kind == 'table': # not range_safe_from_overflow

numpy/lib/tests/test_arraysetops.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,22 @@ def test_isin_mixed_dtype(self, dtype1, dtype2, kind):
440440
else:
441441
assert_array_equal(isin(ar1, ar2, kind=kind), expected)
442442

443+
@pytest.mark.parametrize("data", [
444+
np.array([2**63, 2**63+1], dtype=np.uint64),
445+
np.array([-2**62, -2**62-1], dtype=np.int64),
446+
])
447+
@pytest.mark.parametrize("kind", [None, "sort", "table"])
448+
def test_isin_mixed_huge_vals(self, kind, data):
449+
"""Test values outside intp range (negative ones if 32bit system)"""
450+
query = data[1]
451+
res = np.isin(data, query, kind=kind)
452+
assert_array_equal(res, [False, True])
453+
# Also check that nothing weird happens for values can't possibly
454+
# in range.
455+
data = data.astype(np.int32) # clearly different values
456+
res = np.isin(data, query, kind=kind)
457+
assert_array_equal(res, [False, False])
458+
443459
@pytest.mark.parametrize("kind", [None, "sort", "table"])
444460
def test_isin_mixed_boolean(self, kind):
445461
"""Test that isin works as expected for bool/int input."""

0 commit comments

Comments
 (0)