From 7cb402a3b468dfddd13abddaf4d7e2dbdc294917 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 21 Jul 2025 15:42:15 +0200 Subject: [PATCH 1/4] Add __contains__() method --- dpnp/dpnp_array.py | 4 +++- dpnp/tests/test_ndarray.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index 791b2a8178c4..3e100952785e 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -242,7 +242,9 @@ def __bool__(self): def __complex__(self): return self._array_obj.__complex__() - # '__contains__', + def __contains__(self, key, /): + """Return :math:`key in self`.""" + return (self == key).any() def __copy__(self): """ diff --git a/dpnp/tests/test_ndarray.py b/dpnp/tests/test_ndarray.py index eaccf689a795..90b4045f62f9 100644 --- a/dpnp/tests/test_ndarray.py +++ b/dpnp/tests/test_ndarray.py @@ -74,6 +74,39 @@ def test_attributes(self): assert_equal(self.two.itemsize, self.two.dtype.itemsize) +@testing.parameterize(*testing.product({"xp": [dpnp, numpy]})) +class TestContains: + def test_basic(self): + a = self.xp.arange(10).reshape((2, 5)) + assert 4 in a + assert 20 not in a + + def test_broadcast(self): + xp = self.xp + a = xp.arange(6).reshape((2, 3)) + assert 4 in a + assert xp.array([0, 1, 2]) in a + assert xp.array([5, 3, 4]) not in a + + def test_broadcast_error(self): + a = self.xp.arange(10).reshape((2, 5)) + with pytest.raises( + ValueError, + match="operands could not be broadcast together with shapes", + ): + self.xp.array([1, 2]) in a + + def test_strides(self): + xp = self.xp + a = xp.arange(10).reshape((2, 5)) + a = a[:, ::2] + assert 4 in a + assert 8 not in a + assert xp.full(a.shape[-1], fill_value=2) in a + assert xp.full_like(a, fill_value=7) in a + assert xp.full_like(a, fill_value=6) not in a + + class TestView: def test_none_dtype(self): a = numpy.ones((1, 2, 4), dtype=numpy.int32) From 3ab8fdea32fae38054a093dc4388b55944cd3140 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 21 Jul 2025 15:44:06 +0200 Subject: [PATCH 2/4] Add PR to the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97c45c670ba8..38b2c20b7647 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Added a new backend routine `syrk` from oneMKL to perform symmetric rank-k update which is used for a specialized matrix multiplication where the result is a symmetric matrix [2509](https://github.com/IntelPython/dpnp/pull/2509) * Added `timeout-minutes` property to GitHub jobs [#2526](https://github.com/IntelPython/dpnp/pull/2526) * Added implementation of `dpnp.ndarray.data` and `dpnp.ndarray.data.ptr` attributes [#2521](https://github.com/IntelPython/dpnp/pull/2521) +* Added `dpnp.ndarray.__contains__` method [#2534](https://github.com/IntelPython/dpnp/pull/2534) ### Changed From c103a0face6d8f55d1a20520c003b70e0f059dfe Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 21 Jul 2025 15:47:43 +0200 Subject: [PATCH 3/4] Rename argument to `value` aligning with the latest NumPy changes --- dpnp/dpnp_array.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index 3e100952785e..ec536713eb76 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -242,9 +242,9 @@ def __bool__(self): def __complex__(self): return self._array_obj.__complex__() - def __contains__(self, key, /): - """Return :math:`key in self`.""" - return (self == key).any() + def __contains__(self, value, /): + """Return :math:`value in self`.""" + return (self == value).any() def __copy__(self): """ From 5c683f3e43ca18942583ae9d2d3e31b4c6ea39a4 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Mon, 21 Jul 2025 16:36:39 +0200 Subject: [PATCH 4/4] Use plain text inside a math expression --- dpnp/dpnp_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index ec536713eb76..a70a4e99e668 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -243,7 +243,7 @@ def __complex__(self): return self._array_obj.__complex__() def __contains__(self, value, /): - """Return :math:`value in self`.""" + r"""Return :math:`\text{value in self}`.""" return (self == value).any() def __copy__(self):