Skip to content

Commit ac1b6c1

Browse files
authored
Merge pull request #131 from jorenham/fix/numpy-compat
manual typing fixes on numpy 1.24 and python 3.10
2 parents 1d1fdb2 + 775bd62 commit ac1b6c1

File tree

13 files changed

+140
-86
lines changed

13 files changed

+140
-86
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ cmd = """
8585
stubtest
8686
--mypy-config-file=pyproject.toml
8787
--allowlist=tests/stubtest/allowlist.txt
88+
--ignore-unused-allowlist
8889
$modules
8990
"""
9091
args = [{name = "modules", positional = true, multiple = true, default = "scipy"}]

scipy-stubs/_lib/_util.pyi

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ import numpy as np
77
import numpy.typing as npt
88
import optype.numpy as onpt
99
from numpy._typing import _ArrayLikeInt
10-
from numpy.exceptions import (
11-
AxisError as AxisError,
12-
ComplexWarning as ComplexWarning,
13-
DTypePromotionError as DTypePromotionError,
14-
VisibleDeprecationWarning as VisibleDeprecationWarning,
15-
)
1610
from numpy.random import Generator as Generator # noqa: ICN003
1711
from scipy._typing import RNG, EnterSelfMixin, Seed
1812

@@ -23,13 +17,27 @@ _VT = TypeVar("_VT")
2317
_RT = TypeVar("_RT")
2418
_AxisT = TypeVar("_AxisT", bound=int | np.integer[Any])
2519

20+
###
21+
2622
np_long: Final[type[np.int32 | np.int64]] = ...
2723
np_ulong: Final[type[np.uint32 | np.uint64]] = ...
2824
copy_if_needed: Final[bool | None] = ...
2925

3026
IntNumber: TypeAlias = int | np.integer[Any]
3127
DecimalNumber: TypeAlias = float | np.floating[Any] | np.integer[Any]
3228

29+
class ComplexWarning(RuntimeWarning): ...
30+
class VisibleDeprecationWarning(UserWarning): ...
31+
class DTypePromotionError(TypeError): ...
32+
33+
class AxisError(ValueError, IndexError):
34+
axis: None | int
35+
ndim: None | int
36+
@overload
37+
def __init__(self, /, axis: str, ndim: None = None, msg_prefix: None = None) -> None: ...
38+
@overload
39+
def __init__(self, /, axis: int, ndim: int, msg_prefix: str | None = None) -> None: ...
40+
3341
class FullArgSpec(NamedTuple):
3442
args: Sequence[str]
3543
varargs: str | None

scipy-stubs/fftpack/helper.pyi

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
11
# This module is not meant for public use and will be removed in SciPy v2.0.0.
2+
import sys
23
from typing import Final
34
from typing_extensions import deprecated
45

56
__all__ = ["fftfreq", "fftshift", "ifftshift", "next_fast_len", "rfftfreq"]
67

78
__MESSAGE: Final = "will be removed in SciPy v2.0.0"
89

9-
@deprecated(__MESSAGE)
10-
def fftfreq(n: object, d: object = ..., device: object = ...) -> object: ...
10+
if sys.version_info >= (3, 13):
11+
# `device` was added in numpy 2
12+
@deprecated(__MESSAGE)
13+
def fftfreq(n: object, d: object = ..., device: object = ...) -> object: ...
14+
else:
15+
@deprecated(__MESSAGE)
16+
def fftfreq(n: object, d: object = ...) -> object: ...
17+
1118
@deprecated(__MESSAGE)
1219
def fftshift(x: object, axes: object = ...) -> object: ...
1320
@deprecated(__MESSAGE)

scipy-stubs/integrate/_quad_vec.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ _S = TypeVar("_S")
1313
_T = TypeVar("_T")
1414
_VT = TypeVar("_VT", default=object)
1515

16-
_FloatND: TypeAlias = np.ndarray[tuple[int, ...], np.dtype[np.floating[Any]]] | float | np.floating[Any]
16+
_FloatND: TypeAlias = np.ndarray[Any, np.dtype[np.floating[Any]]] | float | np.floating[Any]
1717
_NDT_f = TypeVar("_NDT_f", bound=_FloatND)
1818
_NDT_f_co = TypeVar("_NDT_f_co", bound=_FloatND, covariant=True, default=_FloatND)
1919
_SCT_f_co = TypeVar("_SCT_f_co", bound=np.floating[Any], covariant=True, default=np.float64)
@@ -147,7 +147,7 @@ def quad_vec(
147147
) -> tuple[np.floating[_NBT], float, _Bunch[np.floating[_NBT]]]: ...
148148
@overload
149149
def quad_vec(
150-
f: _QuadVecFunc[onpt.Array[_ShapeT, np.floating[_NBT]], Unpack[_Ts]],
150+
f: _QuadVecFunc[np.ndarray[_ShapeT, np.dtype[np.floating[_NBT]]], Unpack[_Ts]],
151151
a: float,
152152
b: float,
153153
epsabs: float = 1e-200,

scipy-stubs/io/matlab/_mio5_params.pyi

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ __all__ = [
5353
"mxUINT64_CLASS",
5454
]
5555

56-
_ShapeT_co = TypeVar("_ShapeT_co", covariant=True, bound=tuple[int, ...], default=tuple[int, ...])
56+
# NOTE: explicit covariance can't be used, because shape types are invariant in `numpy<2.1`
57+
_ShapeT = TypeVar("_ShapeT", bound=tuple[int, ...], default=tuple[int, ...])
5758

5859
@type_check_only
5960
class _CodecTemplateValue(TypedDict):
@@ -141,7 +142,7 @@ _MXName: TypeAlias = Literal[
141142
MDTYPES: Final[_MDTypes] = ...
142143
NP_TO_MTYPES: Final[_NP2M] = ...
143144
NP_TO_MXTYPES: Final[_NP2MX] = ...
144-
# TODO: use `np.dtypes.VoidDType[Literal[32]]` once we have `numpy >= 2.1.0`
145+
# TODO(jorenham): use `np.dtypes.VoidDType[Literal[32]]` once we have `numpy >= 2.1.0`
145146
OPAQUE_DTYPE: Final[np.dtype[np.void]] = ...
146147

147148
codecs_template: Final[_CodecsTemplate] = ...
@@ -187,18 +188,18 @@ mxOBJECT_CLASS_FROM_MATRIX_H: Final[_MXType] = 18
187188
@final
188189
class mat_struct: ...
189190

190-
class MatlabObject(np.ndarray[_ShapeT_co, np.dtype[np.void]], Generic[_ShapeT_co]):
191+
class MatlabObject(np.ndarray[_ShapeT, np.dtype[np.void]], Generic[_ShapeT]):
191192
classname: Final[str | None]
192193

193194
def __new__(cls, input_array: onpt.AnyVoidArray, classname: str | None = None) -> Self: ...
194195
@override
195196
def __array_finalize__(self, /, obj: None | npt.NDArray[np.void]) -> None: ...
196197

197-
class MatlabFunction(np.ndarray[_ShapeT_co, np.dtype[np.void]], Generic[_ShapeT_co]):
198+
class MatlabFunction(np.ndarray[_ShapeT, np.dtype[np.void]], Generic[_ShapeT]):
198199
@override
199200
def __new__(cls, input_array: onpt.AnyVoidArray) -> Self: ...
200201

201-
class MatlabOpaque(np.ndarray[_ShapeT_co, np.dtype[np.void]], Generic[_ShapeT_co]):
202+
class MatlabOpaque(np.ndarray[_ShapeT, np.dtype[np.void]], Generic[_ShapeT]):
202203
@override
203204
def __new__(cls, input_array: onpt.AnyVoidArray) -> Self: ...
204205

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from typing import Literal, TypeAlias, overload
2+
from typing_extensions import TypeVar
23

34
import numpy as np
45
import numpy.typing as npt
6+
import optype.numpy as onpt
57
import scipy._typing as spt
68

79
__all__ = [
@@ -24,42 +26,43 @@ __all__ = [
2426
"toeplitz",
2527
]
2628

27-
_Array_2d: TypeAlias = np.ndarray[tuple[int, int], np.dtype[np.generic]]
28-
_Array_O_2d: TypeAlias = np.ndarray[tuple[int, int], np.dtypes.ObjectDType]
29-
_Array_u8_2d: TypeAlias = np.ndarray[tuple[int, int], np.dtypes.UInt64DType]
30-
_Array_i8_2d: TypeAlias = np.ndarray[tuple[int, int], np.dtypes.Int64DType]
31-
_Array_f8_2d: TypeAlias = np.ndarray[tuple[int, int], np.dtypes.Float64DType]
32-
_Array_c16_2d: TypeAlias = np.ndarray[tuple[int, int], np.dtypes.Complex128DType]
29+
_SCT = TypeVar("_SCT", bound=np.generic, default=np.generic)
3330

34-
_SymmetryKind: TypeAlias = Literal["symmetric", "upper", "lower"]
31+
_Matrix: TypeAlias = onpt.Array[tuple[int, int], _SCT]
32+
_Kind: TypeAlias = Literal["symmetric", "upper", "lower"]
3533

36-
def toeplitz(c: npt.ArrayLike, r: npt.ArrayLike | None = None) -> _Array_2d: ...
37-
def circulant(c: npt.ArrayLike) -> _Array_2d: ...
38-
def hankel(c: npt.ArrayLike, r: npt.ArrayLike | None = None) -> _Array_2d: ...
39-
def hadamard(n: spt.AnyInt, dtype: npt.DTypeLike = ...) -> _Array_2d: ...
40-
def leslie(f: npt.ArrayLike, s: npt.ArrayLike) -> _Array_2d: ...
41-
def kron(a: npt.ArrayLike, b: npt.ArrayLike) -> _Array_2d: ...
42-
def block_diag(*arrs: npt.ArrayLike) -> _Array_2d: ...
43-
def companion(a: npt.ArrayLike) -> _Array_2d: ...
44-
def helmert(n: spt.AnyInt, full: bool = False) -> _Array_f8_2d: ...
45-
def hilbert(n: spt.AnyInt) -> _Array_f8_2d: ...
34+
###
35+
36+
# TODO(jorenham): transparent dtypes
37+
def toeplitz(c: npt.ArrayLike, r: npt.ArrayLike | None = None) -> _Matrix: ...
38+
def circulant(c: npt.ArrayLike) -> _Matrix: ...
39+
def hankel(c: npt.ArrayLike, r: npt.ArrayLike | None = None) -> _Matrix: ...
40+
def hadamard(n: spt.AnyInt, dtype: npt.DTypeLike = ...) -> _Matrix: ...
41+
def leslie(f: npt.ArrayLike, s: npt.ArrayLike) -> _Matrix: ...
42+
def kron(a: npt.ArrayLike, b: npt.ArrayLike) -> _Matrix: ...
43+
def block_diag(*arrs: npt.ArrayLike) -> _Matrix: ...
44+
def companion(a: npt.ArrayLike) -> _Matrix: ...
45+
def helmert(n: spt.AnyInt, full: bool = False) -> _Matrix[np.float64]: ...
46+
def hilbert(n: spt.AnyInt) -> _Matrix[np.float64]: ...
47+
def fiedler(a: npt.ArrayLike) -> _Matrix: ...
48+
def fiedler_companion(a: npt.ArrayLike) -> _Matrix: ...
49+
def convolution_matrix(a: npt.ArrayLike, n: spt.AnyInt, mode: spt.CorrelateMode = "full") -> _Matrix: ...
50+
51+
#
4652
@overload
47-
def invhilbert(n: spt.AnyInt, exact: Literal[False] = False) -> _Array_f8_2d: ...
53+
def invhilbert(n: spt.AnyInt, exact: Literal[False] = False) -> _Matrix[np.float64]: ...
4854
@overload
49-
def invhilbert(n: spt.AnyInt, exact: Literal[True]) -> _Array_i8_2d | _Array_O_2d: ...
55+
def invhilbert(n: spt.AnyInt, exact: Literal[True]) -> _Matrix[np.int64] | _Matrix[np.object_]: ...
5056
@overload
51-
def pascal(n: spt.AnyInt, kind: _SymmetryKind = "symmetric", exact: Literal[True] = True) -> _Array_u8_2d | _Array_O_2d: ...
57+
def pascal(n: spt.AnyInt, kind: _Kind = "symmetric", exact: Literal[True] = True) -> _Matrix[np.uint64 | np.object_]: ...
5258
@overload
53-
def pascal(n: spt.AnyInt, kind: _SymmetryKind = "symmetric", *, exact: Literal[False]) -> _Array_f8_2d: ...
59+
def pascal(n: spt.AnyInt, kind: _Kind = "symmetric", *, exact: Literal[False]) -> _Matrix[np.float64]: ...
5460
@overload
55-
def pascal(n: spt.AnyInt, kind: _SymmetryKind, exact: Literal[False]) -> _Array_f8_2d: ...
61+
def pascal(n: spt.AnyInt, kind: _Kind, exact: Literal[False]) -> _Matrix[np.float64]: ...
5662
@overload
57-
def invpascal(n: spt.AnyInt, kind: _SymmetryKind = "symmetric", exact: Literal[True] = True) -> _Array_i8_2d | _Array_O_2d: ...
63+
def invpascal(n: spt.AnyInt, kind: _Kind = "symmetric", exact: Literal[True] = True) -> _Matrix[np.int64 | np.object_]: ...
5864
@overload
59-
def invpascal(n: spt.AnyInt, kind: _SymmetryKind = "symmetric", *, exact: Literal[False]) -> _Array_f8_2d: ...
65+
def invpascal(n: spt.AnyInt, kind: _Kind = "symmetric", *, exact: Literal[False]) -> _Matrix[np.float64]: ...
6066
@overload
61-
def invpascal(n: spt.AnyInt, kind: _SymmetryKind, exact: Literal[False]) -> _Array_f8_2d: ...
62-
def dft(n: spt.AnyInt, scale: Literal["sqrtn", "n"] | None = None) -> _Array_c16_2d: ...
63-
def fiedler(a: npt.ArrayLike) -> _Array_2d: ...
64-
def fiedler_companion(a: npt.ArrayLike) -> _Array_2d: ...
65-
def convolution_matrix(a: npt.ArrayLike, n: spt.AnyInt, mode: spt.CorrelateMode = "full") -> _Array_2d: ...
67+
def invpascal(n: spt.AnyInt, kind: _Kind, exact: Literal[False]) -> _Matrix[np.float64]: ...
68+
def dft(n: spt.AnyInt, scale: Literal["sqrtn", "n"] | None = None) -> _Matrix[np.complex128]: ...

scipy-stubs/linalg/blas.pyi

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,19 @@ import scipy._typing as spt
77

88
__all__ = ["find_best_blas_type", "get_blas_funcs"]
99

10+
# see `scipy.linalg.blas._type_conv`
1011
def find_best_blas_type(
1112
arrays: Sequence[npt.NDArray[np.generic]] = (),
1213
dtype: npt.DTypeLike | None = None,
1314
) -> (
14-
# see `scipy.linalg.blas._type_conv`
15-
tuple[Literal["s"], np.dtypes.Float32DType, bool]
16-
| tuple[Literal["f"], np.dtypes.Float64DType, bool]
17-
| tuple[Literal["c"], np.dtypes.Complex64DType, bool]
18-
| tuple[Literal["z"], np.dtypes.Complex128DType, bool]
15+
tuple[Literal["s"], np.dtype[np.float32], bool]
16+
| tuple[Literal["f"], np.dtype[np.float64], bool]
17+
| tuple[Literal["c"], np.dtype[np.complex64], bool]
18+
| tuple[Literal["z"], np.dtype[np.complex128], bool]
1919
): ...
2020
def get_blas_funcs(
2121
names: Iterable[str] | str,
2222
arrays: Sequence[npt.NDArray[np.generic]] = (),
2323
dtype: npt.DTypeLike | None = None,
24-
ilp64: Literal[True, False, "preferred"] = False,
24+
ilp64: Literal[False, True, "preferred"] = False,
2525
) -> list[spt._FortranFunction] | spt._FortranFunction: ...

scipy-stubs/signal/_bsplines.pyi

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ from scipy._typing import AnyInt, AnyReal
88

99
__all__ = ["cspline1d", "cspline1d_eval", "gauss_spline", "qspline1d", "qspline1d_eval", "spline_filter"]
1010

11-
_SCT_fc = TypeVar("_SCT_fc", np.float64, np.float32, np.complex128, np.complex64)
11+
_SCT_fc = TypeVar("_SCT_fc", bound=np.inexact[Any])
1212

1313
@overload
1414
def gauss_spline(x: _ArrayLikeInt_co, n: AnyInt) -> npt.NDArray[np.float64]: ...
1515
@overload
16-
def gauss_spline(x: _ArrayLike[_SCT_fc], n: AnyInt) -> npt.NDArray[_SCT_fc]: ...
17-
@overload
1816
def gauss_spline(x: _ArrayLikeFloat_co, n: AnyInt) -> npt.NDArray[np.floating[Any]]: ...
1917
@overload
18+
def gauss_spline(x: _ArrayLike[_SCT_fc], n: AnyInt) -> npt.NDArray[_SCT_fc]: ...
19+
@overload
2020
def gauss_spline(x: _ArrayLikeComplex_co, n: AnyInt) -> npt.NDArray[np.inexact[Any]]: ...
2121
def spline_filter(Iin: _ArrayLike[_SCT_fc], lmbda: AnyReal = 5.0) -> npt.NDArray[_SCT_fc]: ...
2222
def cspline1d(signal: npt.NDArray[_SCT_fc], lamb: AnyReal = 0.0) -> npt.NDArray[_SCT_fc]: ...

scipy-stubs/sparse/bsr.pyi

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# This module is not meant for public use and will be removed in SciPy v2.0.0.
2+
import sys
23
from typing_extensions import deprecated
34

45
__all__ = [
@@ -57,15 +58,20 @@ def bsr_transpose(*args: object, **kwargs: object) -> object: ...
5758
def csr_matmat_maxnnz(*args: object, **kwargs: object) -> object: ...
5859
@deprecated("will be removed in SciPy v2.0.0")
5960
def isspmatrix_bsr(x: object) -> object: ...
60-
@deprecated("will be removed in SciPy v2.0.0")
61-
def warn(
62-
message: object,
63-
category: object = ...,
64-
stacklevel: object = ...,
65-
source: object = ...,
66-
*,
67-
skip_file_prefixes: object = ...,
68-
) -> None: ...
61+
62+
if sys.version_info >= (3, 12):
63+
@deprecated("will be removed in SciPy v2.0.0")
64+
def warn(
65+
message: object,
66+
category: object = ...,
67+
stacklevel: object = ...,
68+
source: object = ...,
69+
*,
70+
skip_file_prefixes: object = ...,
71+
) -> None: ...
72+
else:
73+
@deprecated("will be removed in SciPy v2.0.0")
74+
def warn(message: object, category: object = ..., stacklevel: object = ..., source: object = ...) -> None: ...
6975

7076
# sputils
7177
@deprecated("will be removed in SciPy v2.0.0")

scipy-stubs/sparse/compressed.pyi

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# This module is not meant for public use and will be removed in SciPy v2.0.0.
22
import operator
3+
import sys
34
from typing_extensions import deprecated
45

56
__all__ = [
@@ -37,15 +38,20 @@ class IndexMixin:
3738
def __getitem__(self, key: object, /) -> object: ...
3839
def __setitem__(self, key: object, x: object, /) -> None: ...
3940

40-
@deprecated("will be removed in SciPy v2.0.0")
41-
def warn(
42-
message: object,
43-
category: object = ...,
44-
stacklevel: object = ...,
45-
source: object = ...,
46-
*,
47-
skip_file_prefixes: object = ...,
48-
) -> None: ...
41+
if sys.version_info >= (3, 12):
42+
@deprecated("will be removed in SciPy v2.0.0")
43+
def warn(
44+
message: object,
45+
category: object = ...,
46+
stacklevel: object = ...,
47+
source: object = ...,
48+
*,
49+
skip_file_prefixes: object = ...,
50+
) -> None: ...
51+
else:
52+
@deprecated("will be removed in SciPy v2.0.0")
53+
def warn(message: object, category: object = ..., stacklevel: object = ..., source: object = ...) -> None: ...
54+
4955
@deprecated("will be removed in SciPy v2.0.0")
5056
def csr_column_index1(*args: object, **kwargs: object) -> object: ...
5157
@deprecated("will be removed in SciPy v2.0.0")

0 commit comments

Comments
 (0)