diff --git a/stdlib/@tests/stubtest_allowlists/py310.txt b/stdlib/@tests/stubtest_allowlists/py310.txt index 8d0631cdd291..0fd777dcc7a4 100644 --- a/stdlib/@tests/stubtest_allowlists/py310.txt +++ b/stdlib/@tests/stubtest_allowlists/py310.txt @@ -259,3 +259,6 @@ tkinter.EventType.__new__ ctypes._endian.DEFAULT_MODE ctypes._endian.RTLD_GLOBAL ctypes._endian.RTLD_LOCAL + +# This doesn't exist at runtime +builtins.complex.__complex__ diff --git a/stdlib/@tests/stubtest_allowlists/py38.txt b/stdlib/@tests/stubtest_allowlists/py38.txt index 8a8cebab1364..2f80a247f1f4 100644 --- a/stdlib/@tests/stubtest_allowlists/py38.txt +++ b/stdlib/@tests/stubtest_allowlists/py38.txt @@ -262,3 +262,8 @@ email._header_value_parser.SPECIALSNL email.errors.HeaderWriteError email.utils.getaddresses email.utils.parseaddr + +# These don't exist at runtime +builtins.complex.__complex__ +builtins.float.__ceil__ +builtins.float.__floor__ diff --git a/stdlib/@tests/stubtest_allowlists/py39.txt b/stdlib/@tests/stubtest_allowlists/py39.txt index 9c646178b383..1420d8b6b142 100644 --- a/stdlib/@tests/stubtest_allowlists/py39.txt +++ b/stdlib/@tests/stubtest_allowlists/py39.txt @@ -237,3 +237,6 @@ _ssl.RAND_egd ctypes._endian.DEFAULT_MODE ctypes._endian.RTLD_GLOBAL ctypes._endian.RTLD_LOCAL + +# This doesn't exist at runtime +builtins.complex.__complex__ diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 40847ca1a4a5..d4e4d9941467 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1,6 +1,7 @@ # ruff: noqa: PYI036 # This is the module declaring BaseException import _ast import _typeshed +import numbers import sys import types from _collections_abc import dict_items, dict_keys, dict_values @@ -329,7 +330,7 @@ class int: def __bool__(self) -> bool: ... def __index__(self) -> int: ... -class float: +class float(numbers.Real): def __new__(cls, x: ConvertibleToFloat = ..., /) -> Self: ... def as_integer_ratio(self) -> tuple[int, int]: ... def hex(self) -> str: ... @@ -339,7 +340,7 @@ class float: @property def real(self) -> float: ... @property - def imag(self) -> float: ... + def imag(self) -> float: ... # type: ignore[override] def conjugate(self) -> float: ... def __add__(self, value: float, /) -> float: ... def __sub__(self, value: float, /) -> float: ... @@ -370,10 +371,8 @@ class float: def __rpow__(self, value: float, mod: None = None, /) -> Any: ... def __getnewargs__(self) -> tuple[float]: ... def __trunc__(self) -> int: ... - if sys.version_info >= (3, 9): - def __ceil__(self) -> int: ... - def __floor__(self) -> int: ... - + def __ceil__(self) -> int: ... + def __floor__(self) -> int: ... @overload def __round__(self, ndigits: None = None, /) -> int: ... @overload @@ -392,7 +391,7 @@ class float: def __hash__(self) -> int: ... def __bool__(self) -> bool: ... -class complex: +class complex(numbers.Complex): # Python doesn't currently accept SupportsComplex for the second argument @overload def __new__( @@ -424,8 +423,7 @@ class complex: def __abs__(self) -> float: ... def __hash__(self) -> int: ... def __bool__(self) -> bool: ... - if sys.version_info >= (3, 11): - def __complex__(self) -> complex: ... + def __complex__(self) -> complex: ... class _FormatMapMapping(Protocol): def __getitem__(self, key: str, /) -> Any: ... diff --git a/stdlib/decimal.pyi b/stdlib/decimal.pyi index 3da75ec192ac..be158aa07f7f 100644 --- a/stdlib/decimal.pyi +++ b/stdlib/decimal.pyi @@ -24,6 +24,7 @@ from _decimal import ( setcontext as setcontext, ) from collections.abc import Container, Sequence +from numbers import Number from typing import Any, ClassVar, Literal, NamedTuple, overload from typing_extensions import Self, TypeAlias @@ -55,7 +56,7 @@ class Overflow(Inexact, Rounded): ... class Underflow(Inexact, Rounded, Subnormal): ... class FloatOperation(DecimalException, TypeError): ... -class Decimal: +class Decimal(Number): def __new__(cls, value: _DecimalNew = ..., context: Context | None = ...) -> Self: ... @classmethod def from_float(cls, f: float, /) -> Self: ... diff --git a/stdlib/numbers.pyi b/stdlib/numbers.pyi index e129de2cdc67..86340df5e3b0 100644 --- a/stdlib/numbers.pyi +++ b/stdlib/numbers.pyi @@ -10,6 +10,7 @@ from _typeshed import Incomplete from abc import ABCMeta, abstractmethod from typing import Literal, Protocol, overload +from typing_extensions import Self __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -24,8 +25,8 @@ __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] # as we want `int` to be seen as a subtype of `_ComplexLike`, # and `int.__complex__` does not exist :( class _ComplexLike(Protocol): - def __neg__(self) -> _ComplexLike: ... - def __pos__(self) -> _ComplexLike: ... + def __neg__(self) -> Self: ... + def __pos__(self) -> Self: ... def __abs__(self) -> _RealLike: ... # _RealLike is a structural-typing approximation @@ -35,10 +36,6 @@ class _RealLike(_ComplexLike, Protocol): def __floor__(self) -> _IntegralLike: ... def __ceil__(self) -> _IntegralLike: ... def __float__(self) -> float: ... - # Overridden from `_ComplexLike` - # for a more precise return type: - def __neg__(self) -> _RealLike: ... - def __pos__(self) -> _RealLike: ... # _IntegralLike is a structural-typing approximation # of the `Integral` ABC, which is not (and cannot be) a protocol @@ -49,10 +46,6 @@ class _IntegralLike(_RealLike, Protocol): # Overridden from `_ComplexLike` # for a more precise return type: def __abs__(self) -> _IntegralLike: ... - # Overridden from `RealLike` - # for a more precise return type: - def __neg__(self) -> _IntegralLike: ... - def __pos__(self) -> _IntegralLike: ... ################# # Module "proper" @@ -79,9 +72,9 @@ class Complex(Number, _ComplexLike): @abstractmethod def __radd__(self, other) -> _ComplexLike: ... @abstractmethod - def __neg__(self) -> _ComplexLike: ... + def __neg__(self) -> Self: ... @abstractmethod - def __pos__(self) -> _ComplexLike: ... + def __pos__(self) -> Self: ... def __sub__(self, other) -> _ComplexLike: ... def __rsub__(self, other) -> _ComplexLike: ... @abstractmethod @@ -140,12 +133,6 @@ class Real(Complex, _RealLike): @property def imag(self) -> Literal[0]: ... def conjugate(self) -> _RealLike: ... - # Not actually overridden at runtime, - # but we override these in the stub to give them more precise return types: - @abstractmethod - def __pos__(self) -> _RealLike: ... - @abstractmethod - def __neg__(self) -> _RealLike: ... # See comment at the top of the file # for why some of these return types are purposefully vague @@ -196,10 +183,6 @@ class Integral(Rational, _IntegralLike): # Not actually overridden at runtime, # but we override these in the stub to give them more precise return types: @abstractmethod - def __pos__(self) -> _IntegralLike: ... - @abstractmethod - def __neg__(self) -> _IntegralLike: ... - @abstractmethod def __abs__(self) -> _IntegralLike: ... @abstractmethod @overload