From d27024e35f8fef943dc031c626e074bd15cd2398 Mon Sep 17 00:00:00 2001 From: Evgeni Burovski Date: Sun, 11 Jan 2026 15:12:51 +0100 Subject: [PATCH 1/4] ENH: add a basic test of isin --- array_api_tests/_array_module.py | 2 ++ array_api_tests/test_set_functions.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/array_api_tests/_array_module.py b/array_api_tests/_array_module.py index 1c52a983..96d0d452 100644 --- a/array_api_tests/_array_module.py +++ b/array_api_tests/_array_module.py @@ -35,6 +35,8 @@ def __repr__(self): _funcs += ["take", "isdtype", "conj", "imag", "real"] # TODO: bump spec and update array-api-tests to new spec layout _top_level_attrs = _dtypes + _constants + _funcs + stubs.EXTENSIONS + ["fft"] +_top_level_attrs += ['isin'] # FIXME: until the spec is not updated + for attr in _top_level_attrs: try: globals()[attr] = getattr(xp, attr) diff --git a/array_api_tests/test_set_functions.py b/array_api_tests/test_set_functions.py index 8a6f7a9d..d72fb1e5 100644 --- a/array_api_tests/test_set_functions.py +++ b/array_api_tests/test_set_functions.py @@ -5,6 +5,7 @@ import pytest from hypothesis import assume, given +from hypothesis import strategies as st from . import _array_module as xp from . import dtype_helpers as dh @@ -256,3 +257,23 @@ def test_unique_values(x): except Exception as exc: ph.add_note(exc, repro_snippet) raise + + +@given( + *hh.two_mutual_arrays(two_shapes=st.tuples(hh.shapes(), hh.shapes())), + hh.kwargs(invert=st.booleans()) +) +def test_isin(x1, x2, kw): + print("\nx1 = ", type(x1)) + print(x1.shape, x2.shape, x1.dtype, x2.dtype, kw) + + repro_snippet = ph.format_snippet(f"xp.isin({x1!r}, {x2!r}, **kw) with {kw = }") + try: + out = xp.isin(x1, x2, **kw) + + assert out.dtype == xp.bool + assert out.shape == x1.shape + # TODO value tests + except Exception as exc: + ph.add_note(exc, repro_snippet) + raise From 9b063c723c68037996f88abd0287bca3a56f3f3b Mon Sep 17 00:00:00 2001 From: Evgeni Burovski Date: Sun, 11 Jan 2026 15:53:30 +0100 Subject: [PATCH 2/4] ENH: add test for isin with scalars --- array_api_tests/test_set_functions.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/array_api_tests/test_set_functions.py b/array_api_tests/test_set_functions.py index d72fb1e5..b349c500 100644 --- a/array_api_tests/test_set_functions.py +++ b/array_api_tests/test_set_functions.py @@ -277,3 +277,22 @@ def test_isin(x1, x2, kw): except Exception as exc: ph.add_note(exc, repro_snippet) raise + + +@given( + x1x2=hh.array_and_py_scalar(dh.all_dtypes), + kw=hh.kwargs(invert=st.booleans()) +) +def test_isin_scalars(x1x2, kw): + x1, x2 = x1x2 + + repro_snippet = ph.format_snippet(f"xp.isin({x1!r}, {x2!r}, **kw) with {kw = }") + try: + out = xp.isin(x1, x2, **kw) + + assert out.dtype == xp.bool + assert out.shape == () if isinstance(x1, bool | int | float | complex) else x1.shape + # TODO value tests + except Exception as exc: + ph.add_note(exc, repro_snippet) + raise From 976c032bd30cb19eceff03a57e997a66e6a4e028 Mon Sep 17 00:00:00 2001 From: Evgeni Burovski Date: Thu, 5 Feb 2026 13:09:51 +0100 Subject: [PATCH 3/4] MAINT: update isin tests 1. int dtypes only 2. no restriction on x1,x2 shapes --- array_api_tests/test_set_functions.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/array_api_tests/test_set_functions.py b/array_api_tests/test_set_functions.py index b349c500..b54591b5 100644 --- a/array_api_tests/test_set_functions.py +++ b/array_api_tests/test_set_functions.py @@ -260,11 +260,12 @@ def test_unique_values(x): @given( - *hh.two_mutual_arrays(two_shapes=st.tuples(hh.shapes(), hh.shapes())), + hh.arrays(dtype=hh.int_dtypes, shape=hh.shapes()), + hh.arrays(dtype=hh.int_dtypes, shape=hh.shapes()), hh.kwargs(invert=st.booleans()) ) def test_isin(x1, x2, kw): - print("\nx1 = ", type(x1)) + # print("\nx1 = ", type(x1)) print(x1.shape, x2.shape, x1.dtype, x2.dtype, kw) repro_snippet = ph.format_snippet(f"xp.isin({x1!r}, {x2!r}, **kw) with {kw = }") @@ -280,7 +281,7 @@ def test_isin(x1, x2, kw): @given( - x1x2=hh.array_and_py_scalar(dh.all_dtypes), + x1x2=hh.array_and_py_scalar(dh.int_dtypes), kw=hh.kwargs(invert=st.booleans()) ) def test_isin_scalars(x1x2, kw): From 985f670f829b2719f05b17b570e5cc21aa273ec1 Mon Sep 17 00:00:00 2001 From: Evgeni Burovski Date: Mon, 9 Feb 2026 09:57:02 +0100 Subject: [PATCH 4/4] skip uint64/signed int promotions --- array_api_tests/test_set_functions.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/array_api_tests/test_set_functions.py b/array_api_tests/test_set_functions.py index b54591b5..8b0f587a 100644 --- a/array_api_tests/test_set_functions.py +++ b/array_api_tests/test_set_functions.py @@ -260,14 +260,22 @@ def test_unique_values(x): @given( - hh.arrays(dtype=hh.int_dtypes, shape=hh.shapes()), - hh.arrays(dtype=hh.int_dtypes, shape=hh.shapes()), + hh.arrays(dtype=hh.all_int_dtypes, shape=hh.shapes()), + hh.arrays(dtype=hh.all_int_dtypes, shape=hh.shapes()), hh.kwargs(invert=st.booleans()) ) def test_isin(x1, x2, kw): # print("\nx1 = ", type(x1)) print(x1.shape, x2.shape, x1.dtype, x2.dtype, kw) + # uint64 promotion with signed integers is prohibited in the spec, but many + # array libraries allow it in an implementation-defined way + is_mixed_int_promotion = ( + (x1.dtype == xp.uint64 and x2.dtype in dh.int_dtypes) or + (x2.dtype == xp.uint64 and x1.dtype in dh.int_dtypes) + ) + assume(not is_mixed_int_promotion) + repro_snippet = ph.format_snippet(f"xp.isin({x1!r}, {x2!r}, **kw) with {kw = }") try: out = xp.isin(x1, x2, **kw)