Skip to content

Commit 5c8cd4a

Browse files
authored
♻️ reduce reliance on "fake" *._typing modules (#731)
2 parents a4bfa01 + 48a79d5 commit 5c8cd4a

File tree

125 files changed

+1966
-1847
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+1966
-1847
lines changed

scipy-stubs/_lib/_elementwise_iterative_method.pyi

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import optype.numpy as onp
99
import optype.numpy.compat as npc
1010

1111
from ._util import _RichResult
12-
from scipy._typing import Falsy
1312

1413
###
1514

@@ -38,7 +37,7 @@ def _initialize(
3837
func: _FuncRealT,
3938
xs: Sequence[onp.ToFloat1D],
4039
args: tuple[onp.ToFloat1D, ...],
41-
complex_ok: Falsy = False,
40+
complex_ok: onp.ToFalse = False,
4241
preserve_shape: bool | None = None,
4342
xp: _ModuleT | None = None,
4443
) -> tuple[

scipy-stubs/_lib/_threadsafety.pyi

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
from collections.abc import Callable
22
from typing_extensions import TypeVar
33

4-
from scipy._typing import EnterNoneMixin
4+
from scipy._typing import ExitMixin
55

66
__all__ = ["ReentrancyError", "ReentrancyLock", "non_reentrant"]
77

88
_FT = TypeVar("_FT", bound=Callable[..., object])
99

1010
class ReentrancyError(RuntimeError): ...
1111

12-
class ReentrancyLock(EnterNoneMixin):
12+
class ReentrancyLock(ExitMixin):
1313
def __init__(self, /, err_msg: str) -> None: ...
14+
def __enter__(self, /) -> None: ...
1415
def decorate(self, /, func: _FT) -> _FT: ...
1516

1617
def non_reentrant(err_msg: str | None = None) -> Callable[[_FT], _FT]: ...

scipy-stubs/_lib/_uarray/_backend.pyi

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ from types import NotImplementedType
44
from typing import Any, ClassVar, Final, Generic, Literal, Protocol, TypeAlias, TypedDict, final, overload, type_check_only
55
from typing_extensions import ParamSpec, TypeVar, Unpack
66

7-
from scipy._typing import AnyBool, EnterNoneMixin
7+
import optype.numpy as onp
8+
9+
from scipy._typing import ExitMixin
810

911
__all__ = [
1012
"BackendNotImplementedError",
@@ -71,12 +73,14 @@ ArgumentReplacerType: TypeAlias = Callable[
7173
class _BackendState: ...
7274

7375
@final
74-
class _SetBackendContext(EnterNoneMixin):
76+
class _SetBackendContext(ExitMixin):
7577
def __init__(self, /, *args: object, **kwargs: object) -> None: ...
78+
def __enter__(self, /) -> None: ...
7679

7780
@final
78-
class _SkipBackendContext(EnterNoneMixin):
81+
class _SkipBackendContext(ExitMixin):
7982
def __init__(self, /, *args: object, **kwargs: object) -> None: ...
83+
def __enter__(self, /) -> None: ...
8084

8185
@final
8286
class _Function(Generic[_Tss, _T_co]):
@@ -96,7 +100,7 @@ class Dispatchable(Generic[_T_co]):
96100
type: _DispatchType[_T_co]
97101
coercible: Final[bool]
98102

99-
def __init__(self, /, value: _T_co, dispatch_type: _DispatchType[_T_co], coercible: AnyBool = True) -> None: ...
103+
def __init__(self, /, value: _T_co, dispatch_type: _DispatchType[_T_co], coercible: onp.ToBool = True) -> None: ...
100104
@overload
101105
def __getitem__(self, index: Literal[1, -1], /) -> _T_co: ...
102106
@overload
@@ -124,15 +128,15 @@ def generate_multimethod(
124128
) -> _Function[_Tss, _T]: ...
125129

126130
#
127-
def set_backend(backend: _Backend, coerce: AnyBool = False, only: AnyBool = False) -> _SetBackendContext: ...
131+
def set_backend(backend: _Backend, coerce: onp.ToBool = False, only: onp.ToBool = False) -> _SetBackendContext: ...
128132
def skip_backend(backend: _Backend) -> _SkipBackendContext: ...
129133

130134
#
131135
def set_global_backend(
132-
backend: _Backend, coerce: AnyBool = False, only: AnyBool = False, *, try_last: AnyBool = False
136+
backend: _Backend, coerce: onp.ToBool = False, only: onp.ToBool = False, *, try_last: onp.ToBool = False
133137
) -> None: ...
134138
def register_backend(backend: _Backend) -> None: ...
135-
def clear_backends(domain: str | None, registered: AnyBool = True, globals: AnyBool = False) -> None: ...
139+
def clear_backends(domain: str | None, registered: onp.ToBool = True, globals: onp.ToBool = False) -> None: ...
136140

137141
#
138142
def mark_as(dispatch_type: type[_T] | str) -> Callable[[_T], Dispatchable[_T]]: ...
@@ -144,37 +148,37 @@ def all_of_type(
144148
@overload
145149
def wrap_single_convertor(
146150
convert_single: Callable[[_V, _DispatchType[_V], bool], _C],
147-
) -> Callable[[Iterable[Dispatchable[_V]], AnyBool], list[_C]]: ...
151+
) -> Callable[[Iterable[Dispatchable[_V]], onp.ToBool], list[_C]]: ...
148152
@overload
149153
def wrap_single_convertor(
150154
convert_single: Callable[[_V, _DispatchType[_V], bool], NotImplementedType],
151-
) -> Callable[[Iterable[Dispatchable[_V]], AnyBool], NotImplementedType]: ...
155+
) -> Callable[[Iterable[Dispatchable[_V]], onp.ToBool], NotImplementedType]: ...
152156
@overload
153157
def wrap_single_convertor(
154158
convert_single: Callable[[_V, _DispatchType[_V], bool], _C | NotImplementedType],
155-
) -> Callable[[Iterable[Dispatchable[_V]], AnyBool], list[_C] | NotImplementedType]: ...
159+
) -> Callable[[Iterable[Dispatchable[_V]], onp.ToBool], list[_C] | NotImplementedType]: ...
156160
@overload
157161
def wrap_single_convertor_instance(
158162
convert_single: Callable[[_S, _V, _DispatchType[_V], bool], _C],
159-
) -> Callable[[_S, Iterable[Dispatchable[_V]], AnyBool], list[_C]]: ...
163+
) -> Callable[[_S, Iterable[Dispatchable[_V]], onp.ToBool], list[_C]]: ...
160164
@overload
161165
def wrap_single_convertor_instance(
162166
convert_single: Callable[[_S, _V, _DispatchType[_V], bool], NotImplementedType],
163-
) -> Callable[[_S, Iterable[Dispatchable[_V]], AnyBool], NotImplementedType]: ...
167+
) -> Callable[[_S, Iterable[Dispatchable[_V]], onp.ToBool], NotImplementedType]: ...
164168
@overload
165169
def wrap_single_convertor_instance(
166170
convert_single: Callable[[_S, _V, _DispatchType[_V], bool], _C | NotImplementedType],
167-
) -> Callable[[_S, Iterable[Dispatchable[_V]], AnyBool], list[_C] | NotImplementedType]: ...
171+
) -> Callable[[_S, Iterable[Dispatchable[_V]], onp.ToBool], list[_C] | NotImplementedType]: ...
168172

169173
#
170174
def determine_backend(
171-
value: _V, dispatch_type: _DispatchType[_V], *, domain: str, only: AnyBool = True, coerce: AnyBool = False
175+
value: _V, dispatch_type: _DispatchType[_V], *, domain: str, only: onp.ToBool = True, coerce: onp.ToBool = False
172176
) -> _SetBackendContext: ...
173177
def determine_backend_multi(
174178
dispatchables: Iterable[_V | Dispatchable[_V]],
175179
*,
176180
domain: str,
177-
only: AnyBool = True,
178-
coerce: AnyBool = False,
181+
only: onp.ToBool = True,
182+
coerce: onp.ToBool = False,
179183
**kwargs: Unpack[_DetermineBackendMultiKwargs[_T]],
180184
) -> _SetBackendContext: ...

scipy-stubs/_lib/_util.pyi

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import multiprocessing.pool as mpp
22
import sys
33
import types
44
from collections.abc import Callable, Iterable, Sequence
5-
from typing import Any, Concatenate, Final, Generic, Literal, NamedTuple, Never, TypeAlias, overload
5+
from typing import Any, Concatenate, Final, Generic, Literal, NamedTuple, Never, Self, TypeAlias, overload
66
from typing_extensions import TypeVar, override
77

88
import numpy as np
@@ -11,7 +11,7 @@ import optype.numpy as onp
1111
import optype.numpy.compat as npc
1212
from numpy.random import Generator as Generator # implicit re-export
1313

14-
from scipy._typing import RNG, EnterSelfMixin
14+
from scipy._typing import ExitMixin
1515

1616
_AnyRNGT = TypeVar("_AnyRNGT", np.random.RandomState, np.random.Generator)
1717

@@ -71,11 +71,12 @@ class _FunctionWrapper(Generic[_T_contra, _T_co]):
7171
def __init__(self, /, f: Callable[Concatenate[_T_contra, ...], _T_co], args: tuple[object, ...]) -> None: ...
7272
def __call__(self, /, x: _T_contra) -> _T_co: ...
7373

74-
class MapWrapper(EnterSelfMixin):
74+
class MapWrapper(ExitMixin):
7575
pool: int | mpp.Pool | None
7676

7777
def __init__(self, /, pool: Callable[[Callable[[_VT], _RT], Iterable[_VT]], Iterable[_RT]] | int = 1) -> None: ...
7878
def __call__(self, /, func: Callable[[_VT], _RT], iterable: Iterable[_VT]) -> Iterable[_RT]: ...
79+
def __enter__(self, /) -> Self: ...
7980
def terminate(self, /) -> None: ...
8081
def join(self, /) -> None: ...
8182
def close(self, /) -> None: ...
@@ -100,7 +101,7 @@ def check_random_state(seed: onp.ToJustInt | types.ModuleType | None) -> np.rand
100101
#
101102
@overload
102103
def rng_integers(
103-
gen: RNG | None,
104+
gen: onp.random.RNG | None,
104105
low: onp.ToInt,
105106
high: onp.ToInt | None = None,
106107
size: tuple[()] | None = None,
@@ -109,7 +110,7 @@ def rng_integers(
109110
) -> npc.integer: ...
110111
@overload
111112
def rng_integers(
112-
gen: RNG | None,
113+
gen: onp.random.RNG | None,
113114
low: onp.ToInt | onp.ToIntND,
114115
high: onp.ToInt | onp.ToIntND | None = None,
115116
size: op.CanIndex | Sequence[op.CanIndex] | None = None,

scipy-stubs/_typing.pyi

Lines changed: 7 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,16 @@
1-
# NOTE: This private(!) module only exists in `if typing.TYPE_CHECKING: ...` and in `.pyi` stubs
1+
# NOTE(scipy-stubs): This private module should not be used outside of scipy-stubs
22

3-
from _typeshed import Incomplete
4-
from collections.abc import Iterator, Sequence
5-
from os import PathLike
3+
from collections.abc import Sequence
64
from types import TracebackType
7-
from typing import IO, Literal, LiteralString, Protocol, Self, SupportsIndex, TypeAlias, overload, type_check_only
8-
from typing_extensions import TypeVar
5+
from typing import SupportsIndex, TypeAlias, final, type_check_only
96

10-
import numpy as np
11-
import optype as op
12-
import optype.numpy as onp
13-
import optype.numpy.compat as npc
14-
15-
__all__ = [
16-
"RNG",
17-
"Alternative",
18-
"AnyBool",
19-
"AnyShape",
20-
"ByteOrder",
21-
"Casting",
22-
"ConvMode",
23-
"EnterNoneMixin",
24-
"EnterSelfMixin",
25-
"Falsy",
26-
"FileLike",
27-
"FileModeRW",
28-
"FileModeRWA",
29-
"FileName",
30-
"NanPolicy",
31-
"OrderCF",
32-
"OrderKACF",
33-
"SequenceNotStr",
34-
"ToRNG",
35-
"Truthy",
36-
"_FortranFunction",
37-
]
7+
__all__ = "AnyShape", "ExitMixin"
388

399
# helper mixins
4010
@type_check_only
41-
class EnterSelfMixin:
42-
def __enter__(self, /) -> Self: ...
43-
def __exit__(self, /, type: type[BaseException] | None, value: BaseException | None, tb: TracebackType | None) -> None: ...
44-
45-
@type_check_only
46-
class EnterNoneMixin:
47-
def __enter__(self, /) -> None: ...
11+
class ExitMixin:
12+
@final
4813
def __exit__(self, /, type: type[BaseException] | None, value: BaseException | None, tb: TracebackType | None) -> None: ...
4914

50-
# used in `scipy.linalg.blas` and `scipy.linalg.lapack`
51-
@type_check_only
52-
class _FortranFunction(Protocol):
53-
@property
54-
def dtype(self, /) -> np.dtype[Incomplete]: ...
55-
@property
56-
def int_dtype(self, /) -> np.dtype[npc.integer]: ...
57-
@property
58-
def module_name(self, /) -> LiteralString: ...
59-
@property
60-
def prefix(self, /) -> LiteralString: ...
61-
@property
62-
def typecode(self, /) -> LiteralString: ...
63-
def __call__(self, /, *args: object, **kwargs: object) -> Incomplete: ...
64-
65-
_VT_co = TypeVar("_VT_co", covariant=True)
66-
67-
# A slightly modified variant from https://github.com/python/typing/issues/256#issuecomment-1442633430
68-
# This works because `str.__contains__` does not accept object (either in typeshed or at runtime)
69-
@type_check_only
70-
class SequenceNotStr(Protocol[_VT_co]):
71-
@overload
72-
def __getitem__(self, index: SupportsIndex, /) -> _VT_co: ...
73-
@overload
74-
def __getitem__(self, index: slice, /) -> Sequence[_VT_co]: ...
75-
def __iter__(self, /) -> Iterator[_VT_co]: ...
76-
def __reversed__(self, /) -> Iterator[_VT_co]: ...
77-
def __contains__(self, value: object, /) -> bool: ... # <-- the trick
78-
def __len__(self, /) -> int: ...
79-
def index(self, value: object, start: int = 0, stop: int = ..., /) -> int: ...
80-
def count(self, value: object, /) -> int: ...
81-
82-
# I/O
83-
_ByteSOrStr = TypeVar("_ByteSOrStr", bytes, str)
84-
FileName: TypeAlias = str | PathLike[str]
85-
FileLike: TypeAlias = FileName | IO[_ByteSOrStr]
86-
FileModeRW: TypeAlias = Literal["r", "w"]
87-
FileModeRWA: TypeAlias = Literal[FileModeRW, "a"]
88-
89-
# TODO(jorenham): Include `np.bool[L[False]]` once we have `numpy>=2.2`
90-
Falsy: TypeAlias = Literal[False, 0]
91-
Truthy: TypeAlias = Literal[True, 1]
92-
93-
# keep in sync with `numpy._typing._scalars`
94-
AnyBool: TypeAlias = bool | np.bool_ | Literal[0, 1]
95-
9615
# equivalent to `numpy._typing._shape._ShapeLike`
97-
AnyShape: TypeAlias = op.CanIndex | Sequence[op.CanIndex]
98-
99-
RNG: TypeAlias = np.random.Generator | np.random.RandomState
100-
# NOTE: This is less incorrect and more accurate than the current `np.random.default_rng` `seed` param annotation.
101-
ToRNG: TypeAlias = (
102-
int
103-
| npc.integer
104-
| np.timedelta64
105-
| onp.ArrayND[npc.integer | np.timedelta64 | np.flexible | np.object_]
106-
| np.random.SeedSequence
107-
| np.random.BitGenerator
108-
| RNG
109-
| None
110-
)
111-
112-
# numpy literals
113-
ByteOrder: TypeAlias = Literal["S", "<", "little", ">", "big", "=", "native", "|", "I"]
114-
OrderCF: TypeAlias = Literal["C", "F"]
115-
OrderKACF: TypeAlias = Literal["K", "A", OrderCF]
116-
Casting: TypeAlias = Literal["no", "equiv", "safe", "same_kind", "unsafe"]
117-
ConvMode: TypeAlias = Literal["valid", "same", "full"]
118-
119-
# scipy literals
120-
NanPolicy: TypeAlias = Literal["raise", "propagate", "omit"]
121-
Alternative: TypeAlias = Literal["two-sided", "less", "greater"]
122-
NormalizationMode: TypeAlias = Literal["backward", "ortho", "forward"]
123-
DCTType: TypeAlias = Literal[1, 2, 3, 4]
16+
AnyShape: TypeAlias = SupportsIndex | Sequence[SupportsIndex]

scipy-stubs/cluster/hierarchy.pyi

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import optype.numpy as onp
99
import optype.numpy.compat as npc
1010

1111
from scipy._lib._disjoint_set import DisjointSet
12-
from scipy._typing import Falsy, Truthy
1312
from scipy.spatial.distance import _Metric
1413

1514
__all__ = [
@@ -133,9 +132,9 @@ def cut_tree(
133132

134133
#
135134
@overload
136-
def to_tree(Z: onp.ToArray2D, rd: Falsy = False) -> ClusterNode: ...
135+
def to_tree(Z: onp.ToArray2D, rd: onp.ToFalse = False) -> ClusterNode: ...
137136
@overload
138-
def to_tree(Z: onp.ToArray2D, rd: Truthy) -> tuple[ClusterNode, list[ClusterNode]]: ...
137+
def to_tree(Z: onp.ToArray2D, rd: onp.ToTrue) -> tuple[ClusterNode, list[ClusterNode]]: ...
139138

140139
#
141140
def optimal_leaf_ordering(Z: onp.ToArray2D, y: onp.ToArrayND, metric: _Metric = "euclidean") -> _LinkageArray: ...

scipy-stubs/fft/_realtransforms.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import optype as op
55
import optype.numpy as onp
66
import optype.numpy.compat as npc
77

8-
from scipy._typing import AnyShape, DCTType, NormalizationMode
8+
from ._typing import DCTType, NormalizationMode
9+
from scipy._typing import AnyShape
910

1011
__all__ = ["dct", "dctn", "dst", "dstn", "idct", "idctn", "idst", "idstn"]
1112

@@ -16,7 +17,6 @@ _ToIntOrND: TypeAlias = onp.ToInt | onp.ToIntND
1617
_FloatND: TypeAlias = onp.ArrayND[np.float32 | np.float64 | np.longdouble] # doesn't include `numpy.float16`
1718

1819
###
19-
2020
# NOTE: These have (almost) identical signatures, so be sure to keep them in sync.
2121

2222
@overload

scipy-stubs/fft/_realtransforms_backend.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import optype.numpy as onp
66
import optype.numpy.compat as npc
77

88
from ._realtransforms import dct, dctn, dst, dstn, idct, idst
9-
from scipy._typing import AnyShape, DCTType, NormalizationMode
9+
from ._typing import DCTType, NormalizationMode
10+
from scipy._typing import AnyShape
1011

1112
__all__ = ["dct", "dctn", "dst", "dstn", "idct", "idctn", "idst", "idstn"]
1213

scipy-stubs/fft/_typing.pyi

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# NOTE(scipy-stubs): This private module should not be used outside of scipy-stubs
2+
3+
from typing import Literal, TypeAlias
4+
5+
__all__ = "DCTType", "NormalizationMode"
6+
7+
DCTType: TypeAlias = Literal[1, 2, 3, 4]
8+
NormalizationMode: TypeAlias = Literal["backward", "ortho", "forward"]

0 commit comments

Comments
 (0)