diff --git a/.mypyignore b/.mypyignore index a1f49ff3..ae11d9de 100644 --- a/.mypyignore +++ b/.mypyignore @@ -2,7 +2,7 @@ scipy\.(\w+\.)?_typing # git submodules -scipy\._lib\.(array_api_compat|cobyqa).* +scipy\._lib\.(array_api_compat|array_api_extra|cobyqa).* # private bundled pypocketfft library scipy\.fft\._pocketfft\..* diff --git a/.mypyignore-todo b/.mypyignore-todo index 6d957a0a..f44dba14 100644 --- a/.mypyignore-todo +++ b/.mypyignore-todo @@ -1,29 +1,3 @@ -scipy\._lib\.array_api_extra -scipy\._lib\._array_api\.__all__ -scipy\._lib\._array_api\.SCIPY_(ARRAY_API|DEVICE) -scipy\._lib\._array_api\.assert_(array_)?almost_equal -scipy\._lib\._array_api\.get_xp_devices -scipy\._lib\._array_api\.is_complex -scipy\._lib\._array_api\.is_(array_api_strict|cupy|jax|numpy|torch) -scipy\._lib\._array_api\.scipy_namespace_for -scipy\._lib\._array_api\.xp_assert_(close|equal|less) -scipy\._lib\._array_api\.xp_copy(sign)? -scipy\._lib\._array_api\.(xp_)?device -scipy\._lib\._array_api\.xp_ravel -scipy\._lib\._array_api\.xp_real -scipy\._lib\._array_api\.xp_sign -scipy\._lib\._array_api\.(xp_)?size -scipy\._lib\._array_api\.xp_moveaxis_to_end -scipy\._lib\._array_api\.xp_take_along_axis -scipy\._lib\._array_api\.xp_unsupported_param_msg -scipy\._lib\._array_api\.xp_vector_norm -scipy\._lib\._docscrape\.(ClassDoc|FunctionDoc|NumpyDocString)\.__init__ -scipy\._lib\._docscrape\.ObjDoc -scipy\._lib\._docscrape\.get_doc_object -scipy\._lib\._docscrape\.header -scipy\._lib\._docscrape\.indent -scipy\._lib\._util\.(Generator|Seed)Type - scipy\.cluster\.hierarchy\.ClusterNode\.__init__ scipy\.cluster\.vq\.kmeans2? diff --git a/scipy-stubs/_lib/_array_api.pyi b/scipy-stubs/_lib/_array_api.pyi deleted file mode 100644 index dfa90fd6..00000000 --- a/scipy-stubs/_lib/_array_api.pyi +++ /dev/null @@ -1,76 +0,0 @@ -from types import ModuleType -from typing import Any, Literal, Protocol, TypeAlias, overload, type_check_only -from typing_extensions import TypeVar - -import numpy as np -import optype.numpy as onp -from scipy._typing import AnyBool, OrderKACF - -__all__ = ["_asarray", "array_namespace", "device", "size"] - -_0: TypeAlias = Literal[0] # noqa: PYI042 -_1: TypeAlias = Literal[1] # noqa: PYI042 - -# TODO(jorenham): Narrow this down (even though the array-api forgot to specify the type of the a dtype...) -_DType: TypeAlias = type | str | np.dtype[np.generic] -_Device: TypeAlias = Any - -_SizeT = TypeVar("_SizeT", bound=int) -_ShapeT_co = TypeVar("_ShapeT_co", covariant=True, bound=tuple[int, ...], default=tuple[int, ...]) - -_DTypeT_co = TypeVar("_DTypeT_co", bound=_DType, covariant=True, default=_DType) - -_DeviceT = TypeVar("_DeviceT") -_DeviceT_co = TypeVar("_DeviceT_co", covariant=True, default=_Device) - -@type_check_only -class _HasShape(Protocol[_ShapeT_co]): - @property - def shape(self, /) -> _ShapeT_co: ... - -@type_check_only -class _HasDevice(Protocol[_DeviceT_co]): - @property - def device(self, /) -> _DeviceT_co: ... - -# TODO(jorenham): Implement this properly in `optype`: -# https://github.com/jorenham/optype/issues/25 -@type_check_only -class _HasArrayAttrs(_HasShape[_ShapeT_co], _HasDevice[_DeviceT_co], Protocol[_ShapeT_co, _DTypeT_co, _DeviceT_co]): - @property - def dtype(self, /) -> _DTypeT_co: ... - @property - def ndim(self, /) -> int: ... - @property - def size(self, /) -> int: ... - - # TODO(jorenham): Use HKT for `T` and `mT` once implemented (the community has been asking for 6 years, but to no avail) - # https://github.com/python/typing/issues/548 - @property - def T(self, /) -> _HasArrayAttrs[tuple[int, ...], _DTypeT_co, _DeviceT_co]: ... - @property - def mT(self, /) -> _HasArrayAttrs[tuple[int, ...], _DTypeT_co, _DeviceT_co]: ... - -### - -Array: TypeAlias = _HasArrayAttrs[_ShapeT_co, _DTypeT_co, _DeviceT_co] -ArrayLike: TypeAlias = Array | onp.ToFloatND - -def _asarray( - array: ArrayLike, - dtype: _DType | None = None, - order: OrderKACF | None = None, - copy: AnyBool | None = None, - *, - xp: ModuleType | None = None, - check_finite: AnyBool = False, - subok: AnyBool = False, -) -> Array: ... -def array_namespace(*arrays: Array) -> ModuleType: ... -def device(x: _HasDevice[_DeviceT], /) -> _DeviceT: ... -@overload -def size(x: _HasShape[tuple[()] | tuple[_0, ...]]) -> _0: ... -@overload -def size(x: _HasShape[tuple[_SizeT] | onp.AtLeast1D[_SizeT, _1] | tuple[_1, _SizeT]]) -> _SizeT: ... -@overload -def size(x: _HasShape) -> int: ... diff --git a/scipy-stubs/_lib/_docscrape.pyi b/scipy-stubs/_lib/_docscrape.pyi index 7a07ce07..f7dcc2a4 100644 --- a/scipy-stubs/_lib/_docscrape.pyi +++ b/scipy-stubs/_lib/_docscrape.pyi @@ -5,7 +5,9 @@ from typing_extensions import TypeVar, override import optype as op _FT = TypeVar("_FT", bound=Callable[..., object], default=Callable[..., object]) -_SectionValue: TypeAlias = str | list[str] | dict[str, list[str]] +_SectionValue: TypeAlias = str | list[str] | Mapping[str, list[str]] + +### class ParseError(Exception): ... @@ -29,8 +31,9 @@ class Reader: class NumpyDocString(Mapping[str, _SectionValue]): empty_description: ClassVar[str] = ".." - sections: ClassVar[dict[str, _SectionValue]] - def __init__(self, /, docstring: str, config: dict[str, object] = {}) -> None: ... + sections: ClassVar[Mapping[str, _SectionValue]] + + def __init__(self, /, docstring: str, config: Mapping[str, object] | None = None) -> None: ... @override def __str__(self, /, func_role: str = "") -> str: ... @override @@ -48,7 +51,7 @@ class FunctionDoc(NumpyDocString, Generic[_FT]): func: _FT, role: Literal["func", "meth"] = "func", doc: str | None = None, - config: dict[str, object] = {}, + config: Mapping[str, object] | None = None, ) -> None: ... @override def __str__(self, /) -> str: ... # type: ignore[override] # noqa: PYI029 # pyright: ignore[reportIncompatibleMethodOverride] @@ -57,6 +60,7 @@ class FunctionDoc(NumpyDocString, Generic[_FT]): class ClassDoc(NumpyDocString): extra_public_methods: ClassVar[Sequence[str]] show_inherited_members: Final[bool] + @property def methods(self, /) -> list[str]: ... @property @@ -69,10 +73,21 @@ class ClassDoc(NumpyDocString): modulename: str = "", # NOTE: we can't set this to `type[FunctionDoc]` because of a mypy bug func_doc: type = ..., - config: dict[str, object] = {}, + config: Mapping[str, object] | None = None, ) -> None: ... +class ObjDoc(NumpyDocString): + def __init__(self, /, obj: object, doc: str | None = None, config: Mapping[str, object] | None = None) -> None: ... + def strip_blank_lines(l: list[str]) -> list[str]: ... -def indent(str: str | None, indent: int = 4) -> str: ... def dedent_lines(lines: op.CanIter[op.CanIterSelf[str]]) -> str: ... -def header(text: str, style: str = "-") -> str: ... +def get_doc_object( + obj: object, + what: str | None = None, + doc: str | None = None, + config: Mapping[str, object] | None = None, + # NOTE: due to a mypy bug, these can't be made any more specific + class_doc: type = ..., + func_doc: type = ..., + obj_doc: type = ..., +) -> NumpyDocString: ... diff --git a/scipy-stubs/_lib/_util.pyi b/scipy-stubs/_lib/_util.pyi index 0da7f935..0039457f 100644 --- a/scipy-stubs/_lib/_util.pyi +++ b/scipy-stubs/_lib/_util.pyi @@ -27,6 +27,11 @@ copy_if_needed: Final[bool | None] = ... IntNumber: TypeAlias = int | np.integer[Any] DecimalNumber: TypeAlias = float | np.floating[Any] | np.integer[Any] +_RNG: TypeAlias = np.random.Generator | np.random.RandomState +SeedType: TypeAlias = IntNumber | _RNG | None +# NOTE: This is actually a exported at runtime :( +GeneratorType = TypeVar("GeneratorType", bound=_RNG) # noqa: PYI001 + class ComplexWarning(RuntimeWarning): ... class VisibleDeprecationWarning(UserWarning): ... class DTypePromotionError(TypeError): ...