diff --git a/changes/3780.bugfix.md b/changes/3780.bugfix.md new file mode 100644 index 0000000000..daaea51ce6 --- /dev/null +++ b/changes/3780.bugfix.md @@ -0,0 +1 @@ +Update `NDArrayLike` typing for NumPy 2.0 compatibility. Methods that transform arrays (reshape, view, astype, copy, transpose, ravel) now correctly return `NDArrayLike` instead of `Self` to accurately represent shape and dtype changes in NumPy 2.0+ typing. diff --git a/src/zarr/core/buffer/core.py b/src/zarr/core/buffer/core.py index 9602a55258..32cffca4fb 100644 --- a/src/zarr/core/buffer/core.py +++ b/src/zarr/core/buffer/core.py @@ -48,7 +48,14 @@ def __setitem__(self, key: slice, value: Any) -> None: ... @runtime_checkable class NDArrayLike(Protocol): - """Protocol for the nd-array-like type that underlie NDBuffer""" + """Protocol for the nd-array-like type that underlie NDBuffer + + Notes + ----- + Methods that transform the array (reshape, view, astype, ravel, transpose) + return NDArrayLike rather than Self to correctly represent NumPy 2.0+ typing, + which is stricter about shape and dtype transformations. + """ @property def dtype(self) -> np.dtype[Any]: ... @@ -72,9 +79,9 @@ def __array__(self) -> npt.NDArray[Any]: ... def reshape( self, shape: tuple[int, ...] | Literal[-1], *, order: Literal["A", "C", "F"] = ... - ) -> Self: ... + ) -> NDArrayLike: ... - def view(self, dtype: npt.DTypeLike) -> Self: ... + def view(self, dtype: npt.DTypeLike) -> NDArrayLike: ... def astype( self, @@ -82,15 +89,15 @@ def astype( order: Literal["K", "A", "C", "F"] = ..., *, copy: bool = ..., - ) -> Self: ... + ) -> NDArrayLike: ... def fill(self, value: Any) -> None: ... - def copy(self) -> Self: ... + def copy(self) -> NDArrayLike: ... - def transpose(self, axes: SupportsIndex | Sequence[SupportsIndex] | None) -> Self: ... + def transpose(self, axes: SupportsIndex | Sequence[SupportsIndex] | None) -> NDArrayLike: ... - def ravel(self, order: Literal["K", "A", "C", "F"] = ...) -> Self: ... + def ravel(self, order: Literal["K", "A", "C", "F"] = ...) -> NDArrayLike: ... def all(self) -> bool: ...