From 3a63a18216a00cbff1d5dc9fd39875f8533d5d50 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Thu, 1 Feb 2024 15:01:59 +0000 Subject: [PATCH 1/5] Add more return types to the `numbers` module --- stdlib/numbers.pyi | 108 +++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 47 deletions(-) diff --git a/stdlib/numbers.pyi b/stdlib/numbers.pyi index c2a0301d5636..5a8b3f5d50c6 100644 --- a/stdlib/numbers.pyi +++ b/stdlib/numbers.pyi @@ -1,9 +1,15 @@ # Note: these stubs are incomplete. The more complex type # signatures are currently omitted. +# +# Use SupportsComplex, SupportsFloat and SupportsIndex for return types in this module +# rather than `numbers.Complex`, `numbers.Real` and `numbers.Integral`, +# to avoid an excessive number of `type: ignore`s in subclasses of these ABCs +# (since type checkers don't see `complex` as a subtype of `numbers.Complex`, +# nor `float` as a subtype of `numbers.Real`, etc.) from _typeshed import Incomplete from abc import ABCMeta, abstractmethod -from typing import SupportsFloat, overload +from typing import Literal, SupportsComplex, SupportsFloat, SupportsIndex, overload __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -11,120 +17,128 @@ class Number(metaclass=ABCMeta): @abstractmethod def __hash__(self) -> int: ... +# See comment at the top of the file +# for why some of these return types are purposefully vague class Complex(Number): @abstractmethod def __complex__(self) -> complex: ... def __bool__(self) -> bool: ... @property @abstractmethod - def real(self): ... + def real(self) -> SupportsFloat: ... @property @abstractmethod - def imag(self): ... + def imag(self) -> SupportsFloat: ... @abstractmethod - def __add__(self, other): ... + def __add__(self, other) -> SupportsComplex: ... @abstractmethod - def __radd__(self, other): ... + def __radd__(self, other) -> SupportsComplex: ... @abstractmethod - def __neg__(self): ... + def __neg__(self) -> SupportsComplex: ... @abstractmethod - def __pos__(self): ... - def __sub__(self, other): ... - def __rsub__(self, other): ... + def __pos__(self) -> SupportsComplex: ... + def __sub__(self, other) -> SupportsComplex: ... + def __rsub__(self, other) -> SupportsComplex: ... @abstractmethod - def __mul__(self, other): ... + def __mul__(self, other) -> SupportsComplex: ... @abstractmethod - def __rmul__(self, other): ... + def __rmul__(self, other) -> SupportsComplex: ... @abstractmethod - def __truediv__(self, other): ... + def __truediv__(self, other) -> SupportsComplex: ... @abstractmethod - def __rtruediv__(self, other): ... + def __rtruediv__(self, other) -> SupportsComplex: ... @abstractmethod - def __pow__(self, exponent): ... + def __pow__(self, exponent) -> SupportsComplex: ... @abstractmethod - def __rpow__(self, base): ... + def __rpow__(self, base) -> SupportsComplex: ... @abstractmethod - def __abs__(self) -> Real: ... + def __abs__(self) -> SupportsFloat: ... @abstractmethod - def conjugate(self): ... + def conjugate(self) -> SupportsComplex: ... @abstractmethod def __eq__(self, other: object) -> bool: ... +# See comment at the top of the file +# for why some of these return types are purposefully vague class Real(Complex, SupportsFloat): @abstractmethod def __float__(self) -> float: ... @abstractmethod - def __trunc__(self) -> int: ... + def __trunc__(self) -> SupportsIndex: ... @abstractmethod - def __floor__(self) -> int: ... + def __floor__(self) -> SupportsIndex: ... @abstractmethod - def __ceil__(self) -> int: ... + def __ceil__(self) -> SupportsIndex: ... @abstractmethod @overload - def __round__(self, ndigits: None = None) -> int: ... + def __round__(self, ndigits: None = None) -> SupportsIndex: ... @abstractmethod @overload - def __round__(self, ndigits: int): ... - def __divmod__(self, other): ... - def __rdivmod__(self, other): ... + def __round__(self, ndigits: int) -> SupportsFloat: ... + def __divmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... + def __rdivmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... @abstractmethod - def __floordiv__(self, other) -> int: ... + def __floordiv__(self, other) -> SupportsFloat: ... @abstractmethod - def __rfloordiv__(self, other) -> int: ... + def __rfloordiv__(self, other) -> SupportsFloat: ... @abstractmethod - def __mod__(self, other): ... + def __mod__(self, other) -> SupportsFloat: ... @abstractmethod - def __rmod__(self, other): ... + def __rmod__(self, other) -> SupportsFloat: ... @abstractmethod def __lt__(self, other) -> bool: ... @abstractmethod def __le__(self, other) -> bool: ... def __complex__(self) -> complex: ... @property - def real(self): ... + def real(self) -> SupportsFloat: ... @property - def imag(self): ... - def conjugate(self): ... + def imag(self) -> Literal[0]: ... + def conjugate(self) -> SupportsFloat: ... # type: ignore[override] +# See comment at the top of the file +# for why some of these return types are purposefully vague class Rational(Real): @property @abstractmethod - def numerator(self) -> int: ... + def numerator(self) -> SupportsIndex: ... @property @abstractmethod - def denominator(self) -> int: ... + def denominator(self) -> SupportsIndex: ... def __float__(self) -> float: ... +# See comment at the top of the file +# for why some of these return types are purposefully vague class Integral(Rational): @abstractmethod def __int__(self) -> int: ... def __index__(self) -> int: ... @abstractmethod - def __pow__(self, exponent, modulus: Incomplete | None = None): ... + def __pow__(self, exponent, modulus: Incomplete | None = None) -> SupportsIndex: ... # type: ignore[override] @abstractmethod - def __lshift__(self, other): ... + def __lshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rlshift__(self, other): ... + def __rlshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rshift__(self, other): ... + def __rshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rrshift__(self, other): ... + def __rrshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __and__(self, other): ... + def __and__(self, other) -> SupportsIndex: ... @abstractmethod - def __rand__(self, other): ... + def __rand__(self, other) -> SupportsIndex: ... @abstractmethod - def __xor__(self, other): ... + def __xor__(self, other) -> SupportsIndex: ... @abstractmethod - def __rxor__(self, other): ... + def __rxor__(self, other) -> SupportsIndex: ... @abstractmethod - def __or__(self, other): ... + def __or__(self, other) -> SupportsIndex: ... @abstractmethod - def __ror__(self, other): ... + def __ror__(self, other) -> SupportsIndex: ... @abstractmethod - def __invert__(self): ... + def __invert__(self) -> SupportsIndex: ... def __float__(self) -> float: ... @property - def numerator(self) -> int: ... + def numerator(self) -> SupportsIndex: ... @property - def denominator(self) -> int: ... + def denominator(self) -> Literal[1]: ... From e64f895d9d569ab0abbb7e44df7f8f0c09f2160e Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Thu, 1 Feb 2024 15:20:36 +0000 Subject: [PATCH 2/5] py310 compat --- stdlib/numbers.pyi | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/stdlib/numbers.pyi b/stdlib/numbers.pyi index 5a8b3f5d50c6..b1d5316f472b 100644 --- a/stdlib/numbers.pyi +++ b/stdlib/numbers.pyi @@ -7,9 +7,19 @@ # (since type checkers don't see `complex` as a subtype of `numbers.Complex`, # nor `float` as a subtype of `numbers.Real`, etc.) +import sys from _typeshed import Incomplete from abc import ABCMeta, abstractmethod -from typing import Literal, SupportsComplex, SupportsFloat, SupportsIndex, overload +from typing import Literal, SupportsFloat, SupportsIndex, overload +from typing_extensions import TypeAlias + +if sys.version_info >= (3, 11): + from typing import SupportsComplex +else: + # builtins.complex didn't have a __complex__ method on older Pythons + import typing + + SupportsComplex: TypeAlias = typing.SupportsComplex | complex __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] From feb33657377359bc7a15718d10f6f557008b220c Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Thu, 1 Feb 2024 15:23:40 +0000 Subject: [PATCH 3/5] stubtest --- stdlib/numbers.pyi | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/stdlib/numbers.pyi b/stdlib/numbers.pyi index b1d5316f472b..9f507d8335cf 100644 --- a/stdlib/numbers.pyi +++ b/stdlib/numbers.pyi @@ -14,12 +14,12 @@ from typing import Literal, SupportsFloat, SupportsIndex, overload from typing_extensions import TypeAlias if sys.version_info >= (3, 11): - from typing import SupportsComplex + from typing import SupportsComplex as _SupportsComplex else: # builtins.complex didn't have a __complex__ method on older Pythons import typing - SupportsComplex: TypeAlias = typing.SupportsComplex | complex + _SupportsComplex: TypeAlias = typing.SupportsComplex | complex __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -40,31 +40,31 @@ class Complex(Number): @abstractmethod def imag(self) -> SupportsFloat: ... @abstractmethod - def __add__(self, other) -> SupportsComplex: ... + def __add__(self, other) -> _SupportsComplex: ... @abstractmethod - def __radd__(self, other) -> SupportsComplex: ... + def __radd__(self, other) -> _SupportsComplex: ... @abstractmethod - def __neg__(self) -> SupportsComplex: ... + def __neg__(self) -> _SupportsComplex: ... @abstractmethod - def __pos__(self) -> SupportsComplex: ... - def __sub__(self, other) -> SupportsComplex: ... - def __rsub__(self, other) -> SupportsComplex: ... + def __pos__(self) -> _SupportsComplex: ... + def __sub__(self, other) -> _SupportsComplex: ... + def __rsub__(self, other) -> _SupportsComplex: ... @abstractmethod - def __mul__(self, other) -> SupportsComplex: ... + def __mul__(self, other) -> _SupportsComplex: ... @abstractmethod - def __rmul__(self, other) -> SupportsComplex: ... + def __rmul__(self, other) -> _SupportsComplex: ... @abstractmethod - def __truediv__(self, other) -> SupportsComplex: ... + def __truediv__(self, other) -> _SupportsComplex: ... @abstractmethod - def __rtruediv__(self, other) -> SupportsComplex: ... + def __rtruediv__(self, other) -> _SupportsComplex: ... @abstractmethod - def __pow__(self, exponent) -> SupportsComplex: ... + def __pow__(self, exponent) -> _SupportsComplex: ... @abstractmethod - def __rpow__(self, base) -> SupportsComplex: ... + def __rpow__(self, base) -> _SupportsComplex: ... @abstractmethod def __abs__(self) -> SupportsFloat: ... @abstractmethod - def conjugate(self) -> SupportsComplex: ... + def conjugate(self) -> _SupportsComplex: ... @abstractmethod def __eq__(self, other: object) -> bool: ... From 687709c395a594ca9ffb6746c486276eb0dc7b36 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Thu, 1 Feb 2024 16:32:39 +0000 Subject: [PATCH 4/5] Address review --- stdlib/numbers.pyi | 137 +++++++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 53 deletions(-) diff --git a/stdlib/numbers.pyi b/stdlib/numbers.pyi index 9f507d8335cf..0d24c58876b1 100644 --- a/stdlib/numbers.pyi +++ b/stdlib/numbers.pyi @@ -1,7 +1,7 @@ # Note: these stubs are incomplete. The more complex type # signatures are currently omitted. # -# Use SupportsComplex, SupportsFloat and SupportsIndex for return types in this module +# Use _ComplexLikeOrComplex, _RealLike and _IntegralLike for return types in this module # rather than `numbers.Complex`, `numbers.Real` and `numbers.Integral`, # to avoid an excessive number of `type: ignore`s in subclasses of these ABCs # (since type checkers don't see `complex` as a subtype of `numbers.Complex`, @@ -10,18 +10,49 @@ import sys from _typeshed import Incomplete from abc import ABCMeta, abstractmethod -from typing import Literal, SupportsFloat, SupportsIndex, overload +from typing import Literal, Protocol, SupportsAbs, SupportsComplex, overload from typing_extensions import TypeAlias +__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] + +############################ +# Protocols for return types +############################ + +# Structural-typing approximation +# of the `Complex` ABC, which is not (and cannot be) a protocol +_ComplexLike: TypeAlias = SupportsAbs[_RealLike] + if sys.version_info >= (3, 11): - from typing import SupportsComplex as _SupportsComplex + _ComplexLikeOrComplex: TypeAlias = _ComplexLike | SupportsComplex else: # builtins.complex didn't have a __complex__ method on older Pythons - import typing + _ComplexLikeOrComplex: TypeAlias = _ComplexLike | SupportsComplex | complex - _SupportsComplex: TypeAlias = typing.SupportsComplex | complex +# Structural-typing approximation +# of the `Real` ABC, which is not (and cannot be) a protocol +class _RealLike(Protocol): + @abstractmethod + def __float__(self) -> float: ... + @abstractmethod + def __trunc__(self) -> _IntegralLike: ... + @abstractmethod + def __floor__(self) -> _IntegralLike: ... + @abstractmethod + def __ceil__(self) -> _IntegralLike: ... -__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] +# Structural-typing approximation +# of the `Integral` ABC, which is not (and cannot be) a protocol +class _IntegralLike(_RealLike, Protocol): + @abstractmethod + def __invert__(self) -> _IntegralLike: ... + @abstractmethod + def __int__(self) -> int: ... + def __index__(self) -> int: ... + +################# +# Module "proper" +################# class Number(metaclass=ABCMeta): @abstractmethod @@ -29,126 +60,126 @@ class Number(metaclass=ABCMeta): # See comment at the top of the file # for why some of these return types are purposefully vague -class Complex(Number): +class Complex(Number, _ComplexLike): @abstractmethod def __complex__(self) -> complex: ... def __bool__(self) -> bool: ... @property @abstractmethod - def real(self) -> SupportsFloat: ... + def real(self) -> _RealLike: ... @property @abstractmethod - def imag(self) -> SupportsFloat: ... + def imag(self) -> _RealLike: ... @abstractmethod - def __add__(self, other) -> _SupportsComplex: ... + def __add__(self, other) -> _ComplexLikeOrComplex: ... @abstractmethod - def __radd__(self, other) -> _SupportsComplex: ... + def __radd__(self, other) -> _ComplexLikeOrComplex: ... @abstractmethod - def __neg__(self) -> _SupportsComplex: ... + def __neg__(self) -> _ComplexLikeOrComplex: ... @abstractmethod - def __pos__(self) -> _SupportsComplex: ... - def __sub__(self, other) -> _SupportsComplex: ... - def __rsub__(self, other) -> _SupportsComplex: ... + def __pos__(self) -> _ComplexLikeOrComplex: ... + def __sub__(self, other) -> _ComplexLikeOrComplex: ... + def __rsub__(self, other) -> _ComplexLikeOrComplex: ... @abstractmethod - def __mul__(self, other) -> _SupportsComplex: ... + def __mul__(self, other) -> _ComplexLikeOrComplex: ... @abstractmethod - def __rmul__(self, other) -> _SupportsComplex: ... + def __rmul__(self, other) -> _ComplexLikeOrComplex: ... @abstractmethod - def __truediv__(self, other) -> _SupportsComplex: ... + def __truediv__(self, other) -> _ComplexLikeOrComplex: ... @abstractmethod - def __rtruediv__(self, other) -> _SupportsComplex: ... + def __rtruediv__(self, other) -> _ComplexLikeOrComplex: ... @abstractmethod - def __pow__(self, exponent) -> _SupportsComplex: ... + def __pow__(self, exponent) -> _ComplexLikeOrComplex: ... @abstractmethod - def __rpow__(self, base) -> _SupportsComplex: ... + def __rpow__(self, base) -> _ComplexLikeOrComplex: ... @abstractmethod - def __abs__(self) -> SupportsFloat: ... + def __abs__(self) -> _RealLike: ... @abstractmethod - def conjugate(self) -> _SupportsComplex: ... + def conjugate(self) -> _ComplexLikeOrComplex: ... @abstractmethod def __eq__(self, other: object) -> bool: ... # See comment at the top of the file # for why some of these return types are purposefully vague -class Real(Complex, SupportsFloat): +class Real(Complex, _RealLike): @abstractmethod def __float__(self) -> float: ... @abstractmethod - def __trunc__(self) -> SupportsIndex: ... + def __trunc__(self) -> _IntegralLike: ... @abstractmethod - def __floor__(self) -> SupportsIndex: ... + def __floor__(self) -> _IntegralLike: ... @abstractmethod - def __ceil__(self) -> SupportsIndex: ... + def __ceil__(self) -> _IntegralLike: ... @abstractmethod @overload - def __round__(self, ndigits: None = None) -> SupportsIndex: ... + def __round__(self, ndigits: None = None) -> _IntegralLike: ... @abstractmethod @overload - def __round__(self, ndigits: int) -> SupportsFloat: ... - def __divmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... - def __rdivmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... + def __round__(self, ndigits: int) -> _RealLike: ... + def __divmod__(self, other) -> tuple[_RealLike, _RealLike]: ... + def __rdivmod__(self, other) -> tuple[_RealLike, _RealLike]: ... @abstractmethod - def __floordiv__(self, other) -> SupportsFloat: ... + def __floordiv__(self, other) -> _RealLike: ... @abstractmethod - def __rfloordiv__(self, other) -> SupportsFloat: ... + def __rfloordiv__(self, other) -> _RealLike: ... @abstractmethod - def __mod__(self, other) -> SupportsFloat: ... + def __mod__(self, other) -> _RealLike: ... @abstractmethod - def __rmod__(self, other) -> SupportsFloat: ... + def __rmod__(self, other) -> _RealLike: ... @abstractmethod def __lt__(self, other) -> bool: ... @abstractmethod def __le__(self, other) -> bool: ... def __complex__(self) -> complex: ... @property - def real(self) -> SupportsFloat: ... + def real(self) -> _RealLike: ... @property def imag(self) -> Literal[0]: ... - def conjugate(self) -> SupportsFloat: ... # type: ignore[override] + def conjugate(self) -> _RealLike: ... # type: ignore[override] # See comment at the top of the file # for why some of these return types are purposefully vague class Rational(Real): @property @abstractmethod - def numerator(self) -> SupportsIndex: ... + def numerator(self) -> _IntegralLike: ... @property @abstractmethod - def denominator(self) -> SupportsIndex: ... + def denominator(self) -> _IntegralLike: ... def __float__(self) -> float: ... # See comment at the top of the file # for why some of these return types are purposefully vague -class Integral(Rational): +class Integral(Rational, _IntegralLike): @abstractmethod def __int__(self) -> int: ... def __index__(self) -> int: ... @abstractmethod - def __pow__(self, exponent, modulus: Incomplete | None = None) -> SupportsIndex: ... # type: ignore[override] + def __pow__(self, exponent, modulus: Incomplete | None = None) -> _IntegralLike: ... # type: ignore[override] @abstractmethod - def __lshift__(self, other) -> SupportsIndex: ... + def __lshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __rlshift__(self, other) -> SupportsIndex: ... + def __rlshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __rshift__(self, other) -> SupportsIndex: ... + def __rshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __rrshift__(self, other) -> SupportsIndex: ... + def __rrshift__(self, other) -> _IntegralLike: ... @abstractmethod - def __and__(self, other) -> SupportsIndex: ... + def __and__(self, other) -> _IntegralLike: ... @abstractmethod - def __rand__(self, other) -> SupportsIndex: ... + def __rand__(self, other) -> _IntegralLike: ... @abstractmethod - def __xor__(self, other) -> SupportsIndex: ... + def __xor__(self, other) -> _IntegralLike: ... @abstractmethod - def __rxor__(self, other) -> SupportsIndex: ... + def __rxor__(self, other) -> _IntegralLike: ... @abstractmethod - def __or__(self, other) -> SupportsIndex: ... + def __or__(self, other) -> _IntegralLike: ... @abstractmethod - def __ror__(self, other) -> SupportsIndex: ... + def __ror__(self, other) -> _IntegralLike: ... @abstractmethod - def __invert__(self) -> SupportsIndex: ... + def __invert__(self) -> _IntegralLike: ... def __float__(self) -> float: ... @property - def numerator(self) -> SupportsIndex: ... + def numerator(self) -> _IntegralLike: ... @property def denominator(self) -> Literal[1]: ... From cce9ac1fdba6339ea39a3ef57513b23d37cadf78 Mon Sep 17 00:00:00 2001 From: AlexWaygood Date: Thu, 1 Feb 2024 17:53:12 +0000 Subject: [PATCH 5/5] Revert "Address review" This reverts commit 687709c395a594ca9ffb6746c486276eb0dc7b36. --- stdlib/numbers.pyi | 137 ++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 84 deletions(-) diff --git a/stdlib/numbers.pyi b/stdlib/numbers.pyi index 0d24c58876b1..9f507d8335cf 100644 --- a/stdlib/numbers.pyi +++ b/stdlib/numbers.pyi @@ -1,7 +1,7 @@ # Note: these stubs are incomplete. The more complex type # signatures are currently omitted. # -# Use _ComplexLikeOrComplex, _RealLike and _IntegralLike for return types in this module +# Use SupportsComplex, SupportsFloat and SupportsIndex for return types in this module # rather than `numbers.Complex`, `numbers.Real` and `numbers.Integral`, # to avoid an excessive number of `type: ignore`s in subclasses of these ABCs # (since type checkers don't see `complex` as a subtype of `numbers.Complex`, @@ -10,49 +10,18 @@ import sys from _typeshed import Incomplete from abc import ABCMeta, abstractmethod -from typing import Literal, Protocol, SupportsAbs, SupportsComplex, overload +from typing import Literal, SupportsFloat, SupportsIndex, overload from typing_extensions import TypeAlias -__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] - -############################ -# Protocols for return types -############################ - -# Structural-typing approximation -# of the `Complex` ABC, which is not (and cannot be) a protocol -_ComplexLike: TypeAlias = SupportsAbs[_RealLike] - if sys.version_info >= (3, 11): - _ComplexLikeOrComplex: TypeAlias = _ComplexLike | SupportsComplex + from typing import SupportsComplex as _SupportsComplex else: # builtins.complex didn't have a __complex__ method on older Pythons - _ComplexLikeOrComplex: TypeAlias = _ComplexLike | SupportsComplex | complex + import typing -# Structural-typing approximation -# of the `Real` ABC, which is not (and cannot be) a protocol -class _RealLike(Protocol): - @abstractmethod - def __float__(self) -> float: ... - @abstractmethod - def __trunc__(self) -> _IntegralLike: ... - @abstractmethod - def __floor__(self) -> _IntegralLike: ... - @abstractmethod - def __ceil__(self) -> _IntegralLike: ... + _SupportsComplex: TypeAlias = typing.SupportsComplex | complex -# Structural-typing approximation -# of the `Integral` ABC, which is not (and cannot be) a protocol -class _IntegralLike(_RealLike, Protocol): - @abstractmethod - def __invert__(self) -> _IntegralLike: ... - @abstractmethod - def __int__(self) -> int: ... - def __index__(self) -> int: ... - -################# -# Module "proper" -################# +__all__ = ["Number", "Complex", "Real", "Rational", "Integral"] class Number(metaclass=ABCMeta): @abstractmethod @@ -60,126 +29,126 @@ class Number(metaclass=ABCMeta): # See comment at the top of the file # for why some of these return types are purposefully vague -class Complex(Number, _ComplexLike): +class Complex(Number): @abstractmethod def __complex__(self) -> complex: ... def __bool__(self) -> bool: ... @property @abstractmethod - def real(self) -> _RealLike: ... + def real(self) -> SupportsFloat: ... @property @abstractmethod - def imag(self) -> _RealLike: ... + def imag(self) -> SupportsFloat: ... @abstractmethod - def __add__(self, other) -> _ComplexLikeOrComplex: ... + def __add__(self, other) -> _SupportsComplex: ... @abstractmethod - def __radd__(self, other) -> _ComplexLikeOrComplex: ... + def __radd__(self, other) -> _SupportsComplex: ... @abstractmethod - def __neg__(self) -> _ComplexLikeOrComplex: ... + def __neg__(self) -> _SupportsComplex: ... @abstractmethod - def __pos__(self) -> _ComplexLikeOrComplex: ... - def __sub__(self, other) -> _ComplexLikeOrComplex: ... - def __rsub__(self, other) -> _ComplexLikeOrComplex: ... + def __pos__(self) -> _SupportsComplex: ... + def __sub__(self, other) -> _SupportsComplex: ... + def __rsub__(self, other) -> _SupportsComplex: ... @abstractmethod - def __mul__(self, other) -> _ComplexLikeOrComplex: ... + def __mul__(self, other) -> _SupportsComplex: ... @abstractmethod - def __rmul__(self, other) -> _ComplexLikeOrComplex: ... + def __rmul__(self, other) -> _SupportsComplex: ... @abstractmethod - def __truediv__(self, other) -> _ComplexLikeOrComplex: ... + def __truediv__(self, other) -> _SupportsComplex: ... @abstractmethod - def __rtruediv__(self, other) -> _ComplexLikeOrComplex: ... + def __rtruediv__(self, other) -> _SupportsComplex: ... @abstractmethod - def __pow__(self, exponent) -> _ComplexLikeOrComplex: ... + def __pow__(self, exponent) -> _SupportsComplex: ... @abstractmethod - def __rpow__(self, base) -> _ComplexLikeOrComplex: ... + def __rpow__(self, base) -> _SupportsComplex: ... @abstractmethod - def __abs__(self) -> _RealLike: ... + def __abs__(self) -> SupportsFloat: ... @abstractmethod - def conjugate(self) -> _ComplexLikeOrComplex: ... + def conjugate(self) -> _SupportsComplex: ... @abstractmethod def __eq__(self, other: object) -> bool: ... # See comment at the top of the file # for why some of these return types are purposefully vague -class Real(Complex, _RealLike): +class Real(Complex, SupportsFloat): @abstractmethod def __float__(self) -> float: ... @abstractmethod - def __trunc__(self) -> _IntegralLike: ... + def __trunc__(self) -> SupportsIndex: ... @abstractmethod - def __floor__(self) -> _IntegralLike: ... + def __floor__(self) -> SupportsIndex: ... @abstractmethod - def __ceil__(self) -> _IntegralLike: ... + def __ceil__(self) -> SupportsIndex: ... @abstractmethod @overload - def __round__(self, ndigits: None = None) -> _IntegralLike: ... + def __round__(self, ndigits: None = None) -> SupportsIndex: ... @abstractmethod @overload - def __round__(self, ndigits: int) -> _RealLike: ... - def __divmod__(self, other) -> tuple[_RealLike, _RealLike]: ... - def __rdivmod__(self, other) -> tuple[_RealLike, _RealLike]: ... + def __round__(self, ndigits: int) -> SupportsFloat: ... + def __divmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... + def __rdivmod__(self, other) -> tuple[SupportsFloat, SupportsFloat]: ... @abstractmethod - def __floordiv__(self, other) -> _RealLike: ... + def __floordiv__(self, other) -> SupportsFloat: ... @abstractmethod - def __rfloordiv__(self, other) -> _RealLike: ... + def __rfloordiv__(self, other) -> SupportsFloat: ... @abstractmethod - def __mod__(self, other) -> _RealLike: ... + def __mod__(self, other) -> SupportsFloat: ... @abstractmethod - def __rmod__(self, other) -> _RealLike: ... + def __rmod__(self, other) -> SupportsFloat: ... @abstractmethod def __lt__(self, other) -> bool: ... @abstractmethod def __le__(self, other) -> bool: ... def __complex__(self) -> complex: ... @property - def real(self) -> _RealLike: ... + def real(self) -> SupportsFloat: ... @property def imag(self) -> Literal[0]: ... - def conjugate(self) -> _RealLike: ... # type: ignore[override] + def conjugate(self) -> SupportsFloat: ... # type: ignore[override] # See comment at the top of the file # for why some of these return types are purposefully vague class Rational(Real): @property @abstractmethod - def numerator(self) -> _IntegralLike: ... + def numerator(self) -> SupportsIndex: ... @property @abstractmethod - def denominator(self) -> _IntegralLike: ... + def denominator(self) -> SupportsIndex: ... def __float__(self) -> float: ... # See comment at the top of the file # for why some of these return types are purposefully vague -class Integral(Rational, _IntegralLike): +class Integral(Rational): @abstractmethod def __int__(self) -> int: ... def __index__(self) -> int: ... @abstractmethod - def __pow__(self, exponent, modulus: Incomplete | None = None) -> _IntegralLike: ... # type: ignore[override] + def __pow__(self, exponent, modulus: Incomplete | None = None) -> SupportsIndex: ... # type: ignore[override] @abstractmethod - def __lshift__(self, other) -> _IntegralLike: ... + def __lshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rlshift__(self, other) -> _IntegralLike: ... + def __rlshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rshift__(self, other) -> _IntegralLike: ... + def __rshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __rrshift__(self, other) -> _IntegralLike: ... + def __rrshift__(self, other) -> SupportsIndex: ... @abstractmethod - def __and__(self, other) -> _IntegralLike: ... + def __and__(self, other) -> SupportsIndex: ... @abstractmethod - def __rand__(self, other) -> _IntegralLike: ... + def __rand__(self, other) -> SupportsIndex: ... @abstractmethod - def __xor__(self, other) -> _IntegralLike: ... + def __xor__(self, other) -> SupportsIndex: ... @abstractmethod - def __rxor__(self, other) -> _IntegralLike: ... + def __rxor__(self, other) -> SupportsIndex: ... @abstractmethod - def __or__(self, other) -> _IntegralLike: ... + def __or__(self, other) -> SupportsIndex: ... @abstractmethod - def __ror__(self, other) -> _IntegralLike: ... + def __ror__(self, other) -> SupportsIndex: ... @abstractmethod - def __invert__(self) -> _IntegralLike: ... + def __invert__(self) -> SupportsIndex: ... def __float__(self) -> float: ... @property - def numerator(self) -> _IntegralLike: ... + def numerator(self) -> SupportsIndex: ... @property def denominator(self) -> Literal[1]: ...