|
1 | 1 | # Note: these stubs are incomplete. The more complex type
|
2 | 2 | # signatures are currently omitted.
|
3 | 3 | #
|
4 |
| -# Use SupportsComplex, SupportsFloat and SupportsIndex for return types in this module |
| 4 | +# Use _ComplexLike, _RealLike and _IntegralLike for return types in this module |
5 | 5 | # rather than `numbers.Complex`, `numbers.Real` and `numbers.Integral`,
|
6 | 6 | # to avoid an excessive number of `type: ignore`s in subclasses of these ABCs
|
7 | 7 | # (since type checkers don't see `complex` as a subtype of `numbers.Complex`,
|
8 | 8 | # nor `float` as a subtype of `numbers.Real`, etc.)
|
9 | 9 |
|
10 |
| -import sys |
11 | 10 | from _typeshed import Incomplete
|
12 | 11 | from abc import ABCMeta, abstractmethod
|
13 |
| -from typing import Literal, SupportsFloat, SupportsIndex, overload |
14 |
| -from typing_extensions import TypeAlias |
| 12 | +from typing import Literal, Protocol, overload |
15 | 13 |
|
16 |
| -if sys.version_info >= (3, 11): |
17 |
| - from typing import SupportsComplex as _SupportsComplex |
18 |
| -else: |
19 |
| - # builtins.complex didn't have a __complex__ method on older Pythons |
20 |
| - import typing |
| 14 | +__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] |
21 | 15 |
|
22 |
| - _SupportsComplex: TypeAlias = typing.SupportsComplex | complex |
| 16 | +############################ |
| 17 | +# Protocols for return types |
| 18 | +############################ |
23 | 19 |
|
24 |
| -__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] |
| 20 | +# `_ComplexLike` is a structural-typing approximation |
| 21 | +# of the `Complex` ABC, which is not (and cannot be) a protocol |
| 22 | +# |
| 23 | +# NOTE: We can't include `__complex__` here, |
| 24 | +# as we want `int` to be seen as a subtype of `_ComplexLike`, |
| 25 | +# and `int.__complex__` does not exist :( |
| 26 | +class _ComplexLike(Protocol): |
| 27 | + def __neg__(self) -> _ComplexLike: ... |
| 28 | + def __pos__(self) -> _ComplexLike: ... |
| 29 | + def __abs__(self) -> _RealLike: ... |
| 30 | + |
| 31 | +# _RealLike is a structural-typing approximation |
| 32 | +# of the `Real` ABC, which is not (and cannot be) a protocol |
| 33 | +class _RealLike(_ComplexLike, Protocol): |
| 34 | + def __trunc__(self) -> _IntegralLike: ... |
| 35 | + def __floor__(self) -> _IntegralLike: ... |
| 36 | + def __ceil__(self) -> _IntegralLike: ... |
| 37 | + def __float__(self) -> float: ... |
| 38 | + # Overridden from `_ComplexLike` |
| 39 | + # for a more precise return type: |
| 40 | + def __neg__(self) -> _RealLike: ... |
| 41 | + def __pos__(self) -> _RealLike: ... |
| 42 | + |
| 43 | +# _IntegralLike is a structural-typing approximation |
| 44 | +# of the `Integral` ABC, which is not (and cannot be) a protocol |
| 45 | +class _IntegralLike(_RealLike, Protocol): |
| 46 | + def __invert__(self) -> _IntegralLike: ... |
| 47 | + def __int__(self) -> int: ... |
| 48 | + def __index__(self) -> int: ... |
| 49 | + # Overridden from `_ComplexLike` |
| 50 | + # for a more precise return type: |
| 51 | + def __abs__(self) -> _IntegralLike: ... |
| 52 | + # Overridden from `RealLike` |
| 53 | + # for a more precise return type: |
| 54 | + def __neg__(self) -> _IntegralLike: ... |
| 55 | + def __pos__(self) -> _IntegralLike: ... |
| 56 | + |
| 57 | +################# |
| 58 | +# Module "proper" |
| 59 | +################# |
25 | 60 |
|
26 | 61 | class Number(metaclass=ABCMeta):
|
27 | 62 | @abstractmethod
|
28 | 63 | def __hash__(self) -> int: ...
|
29 | 64 |
|
30 | 65 | # See comment at the top of the file
|
31 | 66 | # for why some of these return types are purposefully vague
|
32 |
| -class Complex(Number): |
| 67 | +class Complex(Number, _ComplexLike): |
33 | 68 | @abstractmethod
|
34 | 69 | def __complex__(self) -> complex: ...
|
35 | 70 | def __bool__(self) -> bool: ...
|
36 | 71 | @property
|
37 | 72 | @abstractmethod
|
38 |
| - def real(self) -> SupportsFloat: ... |
| 73 | + def real(self) -> _RealLike: ... |
39 | 74 | @property
|
40 | 75 | @abstractmethod
|
41 |
| - def imag(self) -> SupportsFloat: ... |
| 76 | + def imag(self) -> _RealLike: ... |
42 | 77 | @abstractmethod
|
43 |
| - def __add__(self, other) -> _SupportsComplex: ... |
| 78 | + def __add__(self, other) -> _ComplexLike: ... |
44 | 79 | @abstractmethod
|
45 |
| - def __radd__(self, other) -> _SupportsComplex: ... |
| 80 | + def __radd__(self, other) -> _ComplexLike: ... |
46 | 81 | @abstractmethod
|
47 |
| - def __neg__(self) -> _SupportsComplex: ... |
| 82 | + def __neg__(self) -> _ComplexLike: ... |
48 | 83 | @abstractmethod
|
49 |
| - def __pos__(self) -> _SupportsComplex: ... |
50 |
| - def __sub__(self, other) -> _SupportsComplex: ... |
51 |
| - def __rsub__(self, other) -> _SupportsComplex: ... |
| 84 | + def __pos__(self) -> _ComplexLike: ... |
| 85 | + def __sub__(self, other) -> _ComplexLike: ... |
| 86 | + def __rsub__(self, other) -> _ComplexLike: ... |
52 | 87 | @abstractmethod
|
53 |
| - def __mul__(self, other) -> _SupportsComplex: ... |
| 88 | + def __mul__(self, other) -> _ComplexLike: ... |
54 | 89 | @abstractmethod
|
55 |
| - def __rmul__(self, other) -> _SupportsComplex: ... |
| 90 | + def __rmul__(self, other) -> _ComplexLike: ... |
56 | 91 | @abstractmethod
|
57 |
| - def __truediv__(self, other) -> _SupportsComplex: ... |
| 92 | + def __truediv__(self, other) -> _ComplexLike: ... |
58 | 93 | @abstractmethod
|
59 |
| - def __rtruediv__(self, other) -> _SupportsComplex: ... |
| 94 | + def __rtruediv__(self, other) -> _ComplexLike: ... |
60 | 95 | @abstractmethod
|
61 |
| - def __pow__(self, exponent) -> _SupportsComplex: ... |
| 96 | + def __pow__(self, exponent) -> _ComplexLike: ... |
62 | 97 | @abstractmethod
|
63 |
| - def __rpow__(self, base) -> _SupportsComplex: ... |
| 98 | + def __rpow__(self, base) -> _ComplexLike: ... |
64 | 99 | @abstractmethod
|
65 |
| - def __abs__(self) -> SupportsFloat: ... |
| 100 | + def __abs__(self) -> _RealLike: ... |
66 | 101 | @abstractmethod
|
67 |
| - def conjugate(self) -> _SupportsComplex: ... |
| 102 | + def conjugate(self) -> _ComplexLike: ... |
68 | 103 | @abstractmethod
|
69 | 104 | def __eq__(self, other: object) -> bool: ...
|
70 | 105 |
|
71 | 106 | # See comment at the top of the file
|
72 | 107 | # for why some of these return types are purposefully vague
|
73 |
| -class Real(Complex, SupportsFloat): |
| 108 | +class Real(Complex, _RealLike): |
74 | 109 | @abstractmethod
|
75 | 110 | def __float__(self) -> float: ...
|
76 | 111 | @abstractmethod
|
77 |
| - def __trunc__(self) -> SupportsIndex: ... |
| 112 | + def __trunc__(self) -> _IntegralLike: ... |
78 | 113 | @abstractmethod
|
79 |
| - def __floor__(self) -> SupportsIndex: ... |
| 114 | + def __floor__(self) -> _IntegralLike: ... |
80 | 115 | @abstractmethod
|
81 |
| - def __ceil__(self) -> SupportsIndex: ... |
| 116 | + def __ceil__(self) -> _IntegralLike: ... |
82 | 117 | @abstractmethod
|
83 | 118 | @overload
|
84 |
| - def __round__(self, ndigits: None = None) -> SupportsIndex: ... |
| 119 | + def __round__(self, ndigits: None = None) -> _IntegralLike: ... |
85 | 120 | @abstractmethod
|
86 | 121 | @overload
|
87 |
| - def __round__(self, ndigits: int) -> SupportsFloat: ... |
88 |
| - def __divmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... |
89 |
| - def __rdivmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... |
| 122 | + def __round__(self, ndigits: int) -> _RealLike: ... |
| 123 | + def __divmod__(self, other) -> tuple[_RealLike, _RealLike]: ... |
| 124 | + def __rdivmod__(self, other) -> tuple[_RealLike, _RealLike]: ... |
90 | 125 | @abstractmethod
|
91 |
| - def __floordiv__(self, other) -> SupportsFloat: ... |
| 126 | + def __floordiv__(self, other) -> _RealLike: ... |
92 | 127 | @abstractmethod
|
93 |
| - def __rfloordiv__(self, other) -> SupportsFloat: ... |
| 128 | + def __rfloordiv__(self, other) -> _RealLike: ... |
94 | 129 | @abstractmethod
|
95 |
| - def __mod__(self, other) -> SupportsFloat: ... |
| 130 | + def __mod__(self, other) -> _RealLike: ... |
96 | 131 | @abstractmethod
|
97 |
| - def __rmod__(self, other) -> SupportsFloat: ... |
| 132 | + def __rmod__(self, other) -> _RealLike: ... |
98 | 133 | @abstractmethod
|
99 | 134 | def __lt__(self, other) -> bool: ...
|
100 | 135 | @abstractmethod
|
101 | 136 | def __le__(self, other) -> bool: ...
|
102 | 137 | def __complex__(self) -> complex: ...
|
103 | 138 | @property
|
104 |
| - def real(self) -> SupportsFloat: ... |
| 139 | + def real(self) -> _RealLike: ... |
105 | 140 | @property
|
106 | 141 | def imag(self) -> Literal[0]: ...
|
107 |
| - def conjugate(self) -> SupportsFloat: ... # type: ignore[override] |
| 142 | + def conjugate(self) -> _RealLike: ... |
| 143 | + # Not actually overridden at runtime, |
| 144 | + # but we override these in the stub to give them more precise return types: |
| 145 | + @abstractmethod |
| 146 | + def __pos__(self) -> _RealLike: ... |
| 147 | + @abstractmethod |
| 148 | + def __neg__(self) -> _RealLike: ... |
108 | 149 |
|
109 | 150 | # See comment at the top of the file
|
110 | 151 | # for why some of these return types are purposefully vague
|
111 | 152 | class Rational(Real):
|
112 | 153 | @property
|
113 | 154 | @abstractmethod
|
114 |
| - def numerator(self) -> SupportsIndex: ... |
| 155 | + def numerator(self) -> _IntegralLike: ... |
115 | 156 | @property
|
116 | 157 | @abstractmethod
|
117 |
| - def denominator(self) -> SupportsIndex: ... |
| 158 | + def denominator(self) -> _IntegralLike: ... |
118 | 159 | def __float__(self) -> float: ...
|
119 | 160 |
|
120 | 161 | # See comment at the top of the file
|
121 | 162 | # for why some of these return types are purposefully vague
|
122 |
| -class Integral(Rational): |
| 163 | +class Integral(Rational, _IntegralLike): |
123 | 164 | @abstractmethod
|
124 | 165 | def __int__(self) -> int: ...
|
125 | 166 | def __index__(self) -> int: ...
|
126 | 167 | @abstractmethod
|
127 |
| - def __pow__(self, exponent, modulus: Incomplete | None = None) -> SupportsIndex: ... # type: ignore[override] |
| 168 | + def __pow__(self, exponent, modulus: Incomplete | None = None) -> _IntegralLike: ... |
128 | 169 | @abstractmethod
|
129 |
| - def __lshift__(self, other) -> SupportsIndex: ... |
| 170 | + def __lshift__(self, other) -> _IntegralLike: ... |
130 | 171 | @abstractmethod
|
131 |
| - def __rlshift__(self, other) -> SupportsIndex: ... |
| 172 | + def __rlshift__(self, other) -> _IntegralLike: ... |
132 | 173 | @abstractmethod
|
133 |
| - def __rshift__(self, other) -> SupportsIndex: ... |
| 174 | + def __rshift__(self, other) -> _IntegralLike: ... |
134 | 175 | @abstractmethod
|
135 |
| - def __rrshift__(self, other) -> SupportsIndex: ... |
| 176 | + def __rrshift__(self, other) -> _IntegralLike: ... |
136 | 177 | @abstractmethod
|
137 |
| - def __and__(self, other) -> SupportsIndex: ... |
| 178 | + def __and__(self, other) -> _IntegralLike: ... |
138 | 179 | @abstractmethod
|
139 |
| - def __rand__(self, other) -> SupportsIndex: ... |
| 180 | + def __rand__(self, other) -> _IntegralLike: ... |
140 | 181 | @abstractmethod
|
141 |
| - def __xor__(self, other) -> SupportsIndex: ... |
| 182 | + def __xor__(self, other) -> _IntegralLike: ... |
142 | 183 | @abstractmethod
|
143 |
| - def __rxor__(self, other) -> SupportsIndex: ... |
| 184 | + def __rxor__(self, other) -> _IntegralLike: ... |
144 | 185 | @abstractmethod
|
145 |
| - def __or__(self, other) -> SupportsIndex: ... |
| 186 | + def __or__(self, other) -> _IntegralLike: ... |
146 | 187 | @abstractmethod
|
147 |
| - def __ror__(self, other) -> SupportsIndex: ... |
| 188 | + def __ror__(self, other) -> _IntegralLike: ... |
148 | 189 | @abstractmethod
|
149 |
| - def __invert__(self) -> SupportsIndex: ... |
| 190 | + def __invert__(self) -> _IntegralLike: ... |
150 | 191 | def __float__(self) -> float: ...
|
151 | 192 | @property
|
152 |
| - def numerator(self) -> SupportsIndex: ... |
| 193 | + def numerator(self) -> _IntegralLike: ... |
153 | 194 | @property
|
154 | 195 | def denominator(self) -> Literal[1]: ...
|
| 196 | + # Not actually overridden at runtime, |
| 197 | + # but we override these in the stub to give them more precise return types: |
| 198 | + @abstractmethod |
| 199 | + def __pos__(self) -> _IntegralLike: ... |
| 200 | + @abstractmethod |
| 201 | + def __neg__(self) -> _IntegralLike: ... |
| 202 | + @abstractmethod |
| 203 | + def __abs__(self) -> _IntegralLike: ... |
| 204 | + @abstractmethod |
| 205 | + @overload |
| 206 | + def __round__(self, ndigits: None = None) -> _IntegralLike: ... |
| 207 | + @abstractmethod |
| 208 | + @overload |
| 209 | + def __round__(self, ndigits: int) -> _IntegralLike: ... |
0 commit comments