From 55df20cb89a378e73765f5acb514c717a1b9f21b Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 15 Apr 2026 14:43:58 +0200 Subject: [PATCH 1/5] Always return tuple from meshgrid() --- dpnp/dpnp_iface_arraycreation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dpnp/dpnp_iface_arraycreation.py b/dpnp/dpnp_iface_arraycreation.py index 5bcf5ea19b82..bb4fe8c2bb5e 100644 --- a/dpnp/dpnp_iface_arraycreation.py +++ b/dpnp/dpnp_iface_arraycreation.py @@ -3111,7 +3111,7 @@ def meshgrid(*xi, copy=True, sparse=False, indexing="xy"): ) if ndim < 1: - return [] + return () s0 = (1,) * ndim output = [ @@ -3132,7 +3132,7 @@ def meshgrid(*xi, copy=True, sparse=False, indexing="xy"): if copy: output = [dpt.copy(x) for x in output] - return [dpnp_array._create_from_usm_ndarray(x) for x in output] + return tuple(dpnp_array._create_from_usm_ndarray(x) for x in output) class MGridClass: From 15e568a68866dbb2c66d62a70145cff8781b807c Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 15 Apr 2026 14:45:01 +0200 Subject: [PATCH 2/5] Add testing of tuple to test_meshgrid --- dpnp/tests/test_arraycreation.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dpnp/tests/test_arraycreation.py b/dpnp/tests/test_arraycreation.py index d8a80ddbff78..bed50570e7e8 100644 --- a/dpnp/tests/test_arraycreation.py +++ b/dpnp/tests/test_arraycreation.py @@ -984,13 +984,19 @@ def test_dpctl_tensor_input(func, args): [[], [[1]], [[1, 2, 3], [4, 5, 6]], [[1, 2], [3, 4], [5, 6]]], ids=["[]", "[[1]]", "[[1, 2, 3], [4, 5, 6]]", "[[1, 2], [3, 4], [5, 6]]"], ) -@pytest.mark.parametrize("dtype", get_all_dtypes(no_float16=False)) +@pytest.mark.parametrize( + "dtype", get_all_dtypes(no_none=True, no_float16=False) +) @pytest.mark.parametrize("indexing", ["ij", "xy"]) def test_meshgrid(arrays, dtype, indexing): func = lambda xp, xi: xp.meshgrid(*xi, indexing=indexing) a = tuple(numpy.array(array, dtype=dtype) for array in arrays) ia = tuple(dpnp.array(array, dtype=dtype) for array in arrays) - assert_array_equal(func(numpy, a), func(dpnp, ia)) + + result = func(dpnp, ia) + expected = func(numpy, a) + assert_array_equal(result, expected, strict=True) + assert isinstance(result, tuple) @pytest.mark.parametrize("shape", [(24,), (4, 6), (2, 3, 4), (2, 3, 2, 2)]) From ef08ce9f0c92020efeed3343f8384085e3a2a8fb Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 15 Apr 2026 14:52:53 +0200 Subject: [PATCH 3/5] Populate the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8aaae542ec5..1c2f5adadecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,7 @@ Also, that release drops support for Python 3.9, making Python 3.10 the minimum * Updated QR tests to avoid element-wise comparisons for `raw` and `r` modes [#2785](https://github.com/IntelPython/dpnp/pull/2785) * Moved all SYCL kernel functors from `backend/extensions/` to a unified `backend/kernels/` directory hierarchy [#2816](https://github.com/IntelPython/dpnp/pull/2816) * `dpnp` uses pybind11 3.0.3 [#2834](https://github.com/IntelPython/dpnp/pull/2834) +* Changed `dpnp.meshgrid` to return a tuple instead of a list, aligning with NumPy 2.5+ behavior and 2025.12 version of the Python array API standard [#2854](https://github.com/IntelPython/dpnp/pull/2854) ### Deprecated From d5d8af1811b4d73bfe04829fca6f78014771a2dd Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Fri, 24 Apr 2026 10:55:55 +0200 Subject: [PATCH 4/5] Update third party tests --- dpnp/tests/third_party/cupy/creation_tests/test_ranges.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpnp/tests/third_party/cupy/creation_tests/test_ranges.py b/dpnp/tests/third_party/cupy/creation_tests/test_ranges.py index 69873473e0d7..ce716b10dd37 100644 --- a/dpnp/tests/third_party/cupy/creation_tests/test_ranges.py +++ b/dpnp/tests/third_party/cupy/creation_tests/test_ranges.py @@ -344,7 +344,7 @@ def test_meshgrid0(self, dtype): out = cupy.meshgrid( indexing=self.indexing, sparse=self.sparse, copy=self.copy ) - assert out == [] + assert out == () @testing.for_all_dtypes() @testing.numpy_cupy_array_equal() From 1fa85c30f623c5d96c2d38c61f3843b949122fbd Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 5 May 2026 09:43:34 -0700 Subject: [PATCH 5/5] Extend meshgrid tuple return to dpnp.tensor Co-Authored-By: Claude Sonnet 4.5 --- CHANGELOG.md | 2 +- dpnp/tensor/_ctors.py | 10 +++++----- dpnp/tests/tensor/test_usm_ndarray_ctor.py | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b35b5aff70d..489e79b27c32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed -* Changed `dpnp.meshgrid` to return a tuple instead of a list, aligning with NumPy 2.5+ behavior and 2025.12 version of the Python array API standard [#2854](https://github.com/IntelPython/dpnp/pull/2854) +* Changed `dpnp.meshgrid` and `dpnp.tensor.meshgrid` to return a tuple instead of a list, aligning with NumPy 2.5+ behavior and 2025.12 version of the Python array API standard [#2854](https://github.com/IntelPython/dpnp/pull/2854) ### Deprecated diff --git a/dpnp/tensor/_ctors.py b/dpnp/tensor/_ctors.py index b6e28afdc9e7..bff2a9537e24 100644 --- a/dpnp/tensor/_ctors.py +++ b/dpnp/tensor/_ctors.py @@ -1441,7 +1441,7 @@ def linspace( def meshgrid(*arrays, indexing="xy"): """ - Creates list of :class:`dpctl.tensor.usm_ndarray` coordinate matrices + Creates tuple of :class:`dpctl.tensor.usm_ndarray` coordinate matrices from vectors. Args: @@ -1456,8 +1456,8 @@ def meshgrid(*arrays, indexing="xy"): keyword has no effect and should be ignored. Default: ``"xy"`` Returns: - List[array]: - list of ``N`` arrays, where ``N`` is the number of + Tuple[array]: + tuple of ``N`` arrays, where ``N`` is the number of provided one-dimensional input arrays. Each returned array must have rank ``N``. For a set of ``n`` vectors with lengths ``N0``, ``N1``, ``N2``, ... @@ -1495,7 +1495,7 @@ def meshgrid(*arrays, indexing="xy"): ) n = len(arrays) if n == 0: - return [] + return () sh = (-1,) + (1,) * (n - 1) @@ -1511,7 +1511,7 @@ def meshgrid(*arrays, indexing="xy"): output = dpt.broadcast_arrays(*res) - return output + return tuple(output) def ones( diff --git a/dpnp/tests/tensor/test_usm_ndarray_ctor.py b/dpnp/tests/tensor/test_usm_ndarray_ctor.py index 70066860b19f..59f1d6c28b22 100644 --- a/dpnp/tests/tensor/test_usm_ndarray_ctor.py +++ b/dpnp/tests/tensor/test_usm_ndarray_ctor.py @@ -1924,7 +1924,8 @@ def test_meshgrid(): assert n == len(Znp) for i in range(n): assert np.array_equal(dpt.asnumpy(Z[i]), Znp[i]) - assert dpt.meshgrid() == [] + assert isinstance(Z, tuple) + assert dpt.meshgrid() == () # dimension > 1 must raise ValueError with pytest.raises(ValueError): dpt.meshgrid(dpt.usm_ndarray((4, 4)))