From f79e0e28e832e8f2cb343430fb027d1e80dbd22a Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 12 Aug 2026 13:04:55 +0200 Subject: [PATCH] Add reshape copy keyword tests to third-party shape suite Cover the copy keyword on reshape/ndarray.reshape: copy None/False/True across orders and dtypes, plus the ValueError paths for a string copy value and for copy=False when a copy is unavoidable. Error-message matches accept both backends' wording. --- .../cupy/manipulation_tests/test_shape.py | 57 +++++++++++++++++-- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/dpnp/tests/third_party/cupy/manipulation_tests/test_shape.py b/dpnp/tests/third_party/cupy/manipulation_tests/test_shape.py index 0520fbbc0ff9..16c0ddd11acb 100644 --- a/dpnp/tests/third_party/cupy/manipulation_tests/test_shape.py +++ b/dpnp/tests/third_party/cupy/manipulation_tests/test_shape.py @@ -7,6 +7,15 @@ from dpnp.tests.helper import has_support_aspect64 from dpnp.tests.third_party.cupy import testing +for_all_copy_args = pytest.mark.parametrize( + "copy", + [ + pytest.param(None, id="copy-None"), + pytest.param(False, id="copy-False"), + pytest.param(True, id="copy-True"), + ], +) + @pytest.mark.parametrize("shape", [(2, 3), (), (4,)]) class TestShape: @@ -56,6 +65,37 @@ def test_nocopy_reshape_with_order(self, xp, dtype, order): b[1] = 1 return a + @testing.with_requires("numpy>=2.1") + @testing.for_orders("CFA") + @testing.for_all_dtypes() + @for_all_copy_args + @testing.numpy_cupy_array_equal(accept_error=ValueError) + def test_copy_arg_reshape(self, xp, dtype, order, copy): + a = xp.zeros((2, 3, 4), dtype=dtype) + b = a.reshape(4, 3, 2, order=order, copy=copy) + a[1] = 1 + return b + + @testing.with_requires("numpy>=2.1") + def test_copy_arg_str_reshape_raises(self): + for xp in (numpy, cupy): + with pytest.raises( + ValueError, + match="strings are not allowed for|Keyword 'copy' not recognized", + ): + a = xp.zeros((2, 3, 4), dtype=numpy.int32) + a.reshape(4, 3, 2, copy="False") + + @testing.with_requires("numpy>=2.1") + def test_copy_arg_false_reshape_raises(self): + for xp in (numpy, cupy): + a = xp.zeros((2, 3, 4)) + with pytest.raises( + ValueError, + match="Unable to avoid creating a copy|requires a copy", + ): + a.transpose(2, 0, 1).reshape(4, 3, 2, order="F", copy=False) + @testing.for_orders("CFA") @testing.numpy_cupy_array_equal() def test_transposed_reshape2(self, xp, order): @@ -77,7 +117,7 @@ def test_reshape_with_multiple_unknown_dimensions(self): def test_reshape_with_changed_arraysize(self): for xp in (numpy, cupy): a = testing.shaped_arange((2, 3, 4), xp) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="not reshape"): a.reshape(2, 4, 4) def test_reshape_invalid_order(self): @@ -89,13 +129,13 @@ def test_reshape_invalid_order(self): def test_reshape_zerosize_invalid(self): for xp in (numpy, cupy): a = xp.zeros((0,)) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="not reshape"): a.reshape(()) def test_reshape_zerosize_invalid_unknown(self): for xp in (numpy, cupy): a = xp.zeros((0,)) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="not reshape array of size"): a.reshape((-1, 0)) @testing.numpy_cupy_array_equal(type_check=has_support_aspect64()) @@ -119,11 +159,13 @@ def test_reshape_zerosize2(self, xp, order): assert b.base is a return b + @testing.with_requires("numpy>=2.1") @testing.for_orders("CFA") + @for_all_copy_args @testing.numpy_cupy_array_equal() - def test_external_reshape(self, xp, order): + def test_external_reshape(self, xp, order, copy): a = xp.zeros((8,), dtype=xp.float32) - return xp.reshape(a, (1, 1, 1, 4, 1, 2), order=order) + return xp.reshape(a, (1, 1, 1, 4, 1, 2), order=order, copy=copy) def _test_ndim_limit(self, xp, ndim, dtype, order): idx = [1] * ndim @@ -146,7 +188,10 @@ def test_ndim_limit1(self, xp, dtype, order): @testing.for_all_dtypes() def test_ndim_limit2(self, dtype, order): for xp in (numpy, cupy): - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match="maximum supported dimension for an ndarray is", + ): self._test_ndim_limit(xp, 65, dtype, order)