diff --git a/pyproject.toml b/pyproject.toml index 328439a..593d921 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,6 +61,7 @@ test-min = [ ] typecheck = [ "array-api-compat!=1.15", # https://github.com/data-apis/array-api-compat/issues/436 + "cupy-stubs", "mypy", "scipy-stubs", "sphinx", diff --git a/src/fast_array_utils/stats/_power.py b/src/fast_array_utils/stats/_power.py index 429018e..d1176f8 100644 --- a/src/fast_array_utils/stats/_power.py +++ b/src/fast_array_utils/stats/_power.py @@ -47,7 +47,7 @@ def _power_array_api[A: AArray[object, object]](x: A, n: int, /, dtype: DTypeLik @_power.register(types.CSBase | types.CupyCSMatrix) def _power_cs[Mat: types.CSBase | types.CupyCSMatrix](x: Mat, n: int, /, dtype: DTypeLike | None = None) -> Mat: new_data = power(x.data, n, dtype=dtype) - return type(x)((new_data, x.indices, x.indptr), shape=x.shape, dtype=new_data.dtype) # type: ignore[call-overload] + return type(x)((new_data, x.indices, x.indptr), shape=x.shape, dtype=new_data.dtype) # type: ignore[arg-type] @_power.register(types.DaskArray) diff --git a/tests/test_stats.py b/tests/test_stats.py index d039fa3..bfd6a87 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -253,13 +253,13 @@ def test_mean_var( mean, var = stats.mean_var(arr, axis=axis, correction=1) if isinstance(mean, types.DaskArray) and isinstance(var, types.DaskArray): mean, var = mean.compute(), var.compute() # type: ignore[assignment] - if isinstance(mean, types.CupyArray) and isinstance(var, types.CupyArray): - mean, var = mean.get(), var.get() + # new names: `.get()` returns a less specific dtype than `mean` and `var` have + mean_np, var_np = (mean.get(), var.get()) if isinstance(mean, types.CupyArray) and isinstance(var, types.CupyArray) else (mean, var) mean_expected = np.mean(np_arr, axis=axis) var_expected = np.var(np_arr, axis=axis, ddof=1) - np.testing.assert_array_equal(mean, mean_expected) - np.testing.assert_array_almost_equal(var, var_expected) # type: ignore[arg-type] + np.testing.assert_array_equal(mean_np, mean_expected) + np.testing.assert_array_almost_equal(var_np, var_expected) # type: ignore[arg-type] @pytest.mark.skipif(not find_spec("sklearn"), reason="sklearn not installed") diff --git a/typings/cupy/__init__.pyi b/typings/cupy/__init__.pyi deleted file mode 100644 index 07276e9..0000000 --- a/typings/cupy/__init__.pyi +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from ._core import ndarray as ndarray -from ._creation.from_data import asarray as asarray diff --git a/typings/cupy/_core/__init__.pyi b/typings/cupy/_core/__init__.pyi deleted file mode 100644 index 7f0a46a..0000000 --- a/typings/cupy/_core/__init__.pyi +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 - -from .core import ndarray as ndarray diff --git a/typings/cupy/_core/core.pyi b/typings/cupy/_core/core.pyi deleted file mode 100644 index 2995181..0000000 --- a/typings/cupy/_core/core.pyi +++ /dev/null @@ -1,62 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from types import EllipsisType -from typing import Any, Literal, Self, overload - -import numpy as np -from cupy.cuda import MemoryPointer, Stream -from numpy._core.multiarray import flagsobj -from numpy.typing import DTypeLike, NDArray - -class ndarray: - dtype: np.dtype[Any] - shape: tuple[int, ...] - size: int - ndim: int - flags: flagsobj - - def __init__( - self, - shape: tuple[int, ...], - dtype: DTypeLike | None = ..., - memptr: MemoryPointer | None = None, - strides: tuple[int, ...] | None = None, - order: Literal["C", "F"] = "C", - ) -> None: ... - - # cupy-specific - def get( - self, stream: Stream | None = None, order: Literal["C", "F", "A"] = "C", out: NDArray[Any] | None = None, blocking: bool = True - ) -> NDArray[Any]: ... - - # operators - def __array__(self) -> NDArray[Any]: ... - def __len__(self) -> int: ... - def __getitem__( # never returns scalars - self, index: int | slice | EllipsisType | tuple[int | slice | EllipsisType | None, ...] - ) -> Self: ... - def __eq__(self, value: object) -> ndarray: ... # type: ignore[override] - def __power__(self, other: int) -> Self: ... - - # methods - def astype( - self, dtype: DTypeLike | None, order: Literal["C", "F", "A", "K"] = "K", casting: None = None, subok: None = None, copy: bool = True - ) -> Self: ... - @property - def T(self) -> Self: ... # noqa: N802 - @overload - def all(self, axis: None = None) -> np.bool: ... - @overload - def all(self, axis: int) -> ndarray: ... - def reshape(self, shape: tuple[int, ...] | int) -> ndarray: ... - def squeeze(self, axis: int | None = None) -> Self: ... - def ravel(self, order: Literal["C", "F", "A", "K"] = "C") -> Self: ... - def flatten(self, order: Literal["C", "F", "A", "K"] = "C") -> Self: ... - @property - def flat(self) -> _FlatIter: ... - def sum(self, axis: int | None = None, dtype: DTypeLike | None = None, out: ndarray | None = None, keepdims: bool = False) -> ndarray: ... - -class _FlatIter: - def __next__(self) -> np.float32 | np.float64: ... - def __iter__(self) -> _FlatIter: ... - def __len__(self) -> int: ... - def __getitem__(self, index: int) -> np.float32 | np.float64: ... diff --git a/typings/cupy/_creation/from_data.pyi b/typings/cupy/_creation/from_data.pyi deleted file mode 100644 index b1ba1ab..0000000 --- a/typings/cupy/_creation/from_data.pyi +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from typing import Any, Literal - -import h5py -import zarr -from numpy.typing import ArrayLike, DTypeLike - -from .._core import ndarray - -def asarray( - a: ArrayLike | h5py.Dataset | zarr.Array[Any], - dtype: DTypeLike | None = None, - order: Literal["C", "F", "A", "K"] | None = None, - *, - blocking: bool = False, -) -> ndarray: ... diff --git a/typings/cupy/cuda.pyi b/typings/cupy/cuda.pyi deleted file mode 100644 index 595d499..0000000 --- a/typings/cupy/cuda.pyi +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -class Stream: ... -class MemoryPointer: ... diff --git a/typings/cupyx/scipy/sparse/__init__.pyi b/typings/cupyx/scipy/sparse/__init__.pyi deleted file mode 100644 index 66d4646..0000000 --- a/typings/cupyx/scipy/sparse/__init__.pyi +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from ._base import spmatrix as spmatrix -from ._coo import coo_matrix as coo_matrix -from ._csc import csc_matrix as csc_matrix -from ._csr import csr_matrix as csr_matrix diff --git a/typings/cupyx/scipy/sparse/_base.pyi b/typings/cupyx/scipy/sparse/_base.pyi deleted file mode 100644 index 45a05b7..0000000 --- a/typings/cupyx/scipy/sparse/_base.pyi +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from typing import Any, Literal, Self - -import cupy.cuda -import numpy as np -import scipy.sparse as sps -from numpy.typing import NDArray - -class spmatrix: - dtype: np.dtype[Any] - shape: tuple[int, int] - ndim: int - def toarray(self, order: Literal["C", "F"] | None = None, out: None = None) -> cupy.ndarray: ... - def __power__(self, other: int) -> Self: ... - def __array__(self) -> NDArray[Any]: ... - def get(self, stream: cupy.cuda.Stream | None = None) -> sps.spmatrix: ... diff --git a/typings/cupyx/scipy/sparse/_compressed.pyi b/typings/cupyx/scipy/sparse/_compressed.pyi deleted file mode 100644 index 4f1035d..0000000 --- a/typings/cupyx/scipy/sparse/_compressed.pyi +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from typing import Literal, Self, overload - -from cupy import ndarray -from numpy.typing import DTypeLike - -from ._base import spmatrix - -class _compressed_sparse_matrix(spmatrix): - format: Literal["csr", "csc"] - data: ndarray - indices: ndarray - indptr: ndarray - - @overload - def __init__(self, arg1: ndarray | spmatrix) -> None: ... - @overload - def __init__(self, arg1: tuple[int, int], *, dtype: DTypeLike | None = None) -> None: ... - @overload - def __init__(self, arg1: tuple[ndarray, tuple[ndarray, ndarray]]) -> None: ... - @overload - def __init__(self, arg1: tuple[ndarray, ndarray, ndarray], shape: tuple[int, int] | None = None) -> None: ... - - # methods - def astype(self, dtype: DTypeLike | None) -> Self: ... - def power(self, n: int, dtype: DTypeLike | None = None) -> Self: ... - def sum(self, axis: Literal[0, 1] | None = None, dtype: DTypeLike | None = None, out: Self | None = None) -> ndarray: ... diff --git a/typings/cupyx/scipy/sparse/_coo.pyi b/typings/cupyx/scipy/sparse/_coo.pyi deleted file mode 100644 index e67e691..0000000 --- a/typings/cupyx/scipy/sparse/_coo.pyi +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from typing import Literal - -import cupy.cuda -import scipy.sparse as sps - -from ._base import spmatrix - -class coo_matrix(spmatrix): - format: Literal["coo"] = "coo" - def get(self, stream: cupy.cuda.Stream | None = None) -> sps.coo_matrix: ... diff --git a/typings/cupyx/scipy/sparse/_csc.pyi b/typings/cupyx/scipy/sparse/_csc.pyi deleted file mode 100644 index 9975096..0000000 --- a/typings/cupyx/scipy/sparse/_csc.pyi +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from typing import Literal - -import cupy.cuda -import scipy.sparse as sps - -from ._compressed import _compressed_sparse_matrix - -class csc_matrix(_compressed_sparse_matrix): - format: Literal["csc"] = "csc" - def get(self, stream: cupy.cuda.Stream | None = None) -> sps.csc_matrix: ... diff --git a/typings/cupyx/scipy/sparse/_csr.pyi b/typings/cupyx/scipy/sparse/_csr.pyi deleted file mode 100644 index e092517..0000000 --- a/typings/cupyx/scipy/sparse/_csr.pyi +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -from typing import Literal - -import cupy.cuda -import scipy.sparse as sps - -from ._compressed import _compressed_sparse_matrix - -class csr_matrix(_compressed_sparse_matrix): - format: Literal["csr"] = "csr" - def get(self, stream: cupy.cuda.Stream | None = None) -> sps.csr_matrix: ...