diff --git a/array_api_strict/_manipulation_functions.py b/array_api_strict/_manipulation_functions.py index c2dcccf..02dcf16 100644 --- a/array_api_strict/_manipulation_functions.py +++ b/array_api_strict/_manipulation_functions.py @@ -122,8 +122,9 @@ def reshape(x: Array, /, shape: tuple[int, ...], *, copy: bool | None = None) -> reshaped = np.reshape(data, shape) - if copy is False and not np.shares_memory(data, reshaped): - raise AttributeError("Incompatible shape for in-place modification.") + # NB: `.size>0` works around that `x=np.asarray([]); np.shares_memory(x, x)` is False + if copy is False and data.size > 0 and not np.shares_memory(data, reshaped): + raise ValueError("Incompatible shape for a no-copy reshape.") return Array._new(reshaped, device=x.device) diff --git a/array_api_strict/tests/test_manipulation_functions.py b/array_api_strict/tests/test_manipulation_functions.py index bd247ee..53b8fcf 100644 --- a/array_api_strict/tests/test_manipulation_functions.py +++ b/array_api_strict/tests/test_manipulation_functions.py @@ -32,5 +32,15 @@ def test_reshape_copy(): a = asarray(np.ones((2, 3)).T) b = reshape(a, (3, 2), copy=True) - assert_raises(AttributeError, lambda: reshape(a, (2, 3), copy=False)) + assert_raises(ValueError, lambda: reshape(a, (2, 3), copy=False)) + + +def test_reshape_copy_false_keeps_an_empty_view(): + a = asarray(np.empty((0,))) + b = reshape(a, (0, 2), copy=False) + assert b.shape == (0, 2) + + a = asarray(np.empty((0, 2))) + b = reshape(a, (2, 0), copy=False) + assert b.shape == (2, 0)