From 27dfbf68aaffab4f1ded7dc1b96f6f82f536a09d Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Wed, 30 Sep 2020 09:00:06 +0200 Subject: [PATCH] Use __new__ instead of __init__ for some builtin classes (#4555) Closes #4514 #2630 #2686 --- stdlib/2/__builtin__.pyi | 24 ++++++++++++------------ stdlib/2and3/builtins.pyi | 24 ++++++++++++------------ tests/stubtest_whitelists/py3_common.txt | 22 ++++++++++++++++++++++ 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/stdlib/2/__builtin__.pyi b/stdlib/2/__builtin__.pyi index 7a7245396..bd49c58d0 100644 --- a/stdlib/2/__builtin__.pyi +++ b/stdlib/2/__builtin__.pyi @@ -182,9 +182,9 @@ class super(object): class int: @overload - def __init__(self, x: Union[Text, bytes, SupportsInt, _SupportsIndex] = ...) -> None: ... + def __new__(cls: Type[_T], x: Union[Text, bytes, SupportsInt, _SupportsIndex] = ...) -> _T: ... @overload - def __init__(self, x: Union[Text, bytes, bytearray], base: int) -> None: ... + def __new__(cls: Type[_T], x: Union[Text, bytes, bytearray], base: int) -> _T: ... if sys.version_info >= (3, 8): def as_integer_ratio(self) -> Tuple[int, Literal[1]]: ... @property @@ -263,7 +263,7 @@ class int: def __index__(self) -> int: ... class float: - def __init__(self, x: Union[SupportsFloat, _SupportsIndex, Text, bytes, bytearray] = ...) -> None: ... + def __new__(cls: Type[_T], x: Union[SupportsFloat, _SupportsIndex, Text, bytes, bytearray] = ...) -> _T: ... def as_integer_ratio(self) -> Tuple[int, int]: ... def hex(self) -> str: ... def is_integer(self) -> bool: ... @@ -326,9 +326,9 @@ class float: class complex: @overload - def __init__(self, real: float = ..., imag: float = ...) -> None: ... + def __new__(cls: Type[_T], real: float = ..., imag: float = ...) -> _T: ... @overload - def __init__(self, real: Union[str, SupportsComplex, _SupportsIndex]) -> None: ... + def __new__(cls: Type[_T], real: Union[str, SupportsComplex, _SupportsIndex]) -> _T: ... @property def real(self) -> float: ... @property @@ -447,9 +447,9 @@ class _FormatMapMapping(Protocol): class str(Sequence[str], _str_base): if sys.version_info >= (3,): @overload - def __init__(self, o: object = ...) -> None: ... + def __new__(cls: Type[_T], o: object = ...) -> _T: ... @overload - def __init__(self, o: bytes, encoding: str = ..., errors: str = ...) -> None: ... + def __new__(cls: Type[_T], o: bytes, encoding: str = ..., errors: str = ...) -> _T: ... else: def __init__(self, o: object = ...) -> None: ... def capitalize(self) -> str: ... @@ -597,15 +597,15 @@ class str(Sequence[str], _str_base): if sys.version_info >= (3,): class bytes(ByteString): @overload - def __init__(self, ints: Iterable[int]) -> None: ... + def __new__(cls: Type[_T], ints: Iterable[int]) -> _T: ... @overload - def __init__(self, string: str, encoding: str, errors: str = ...) -> None: ... + def __new__(cls: Type[_T], string: str, encoding: str, errors: str = ...) -> _T: ... @overload - def __init__(self, length: int) -> None: ... + def __new__(cls: Type[_T], length: int) -> _T: ... @overload - def __init__(self) -> None: ... + def __new__(cls: Type[_T]) -> _T: ... @overload - def __init__(self, o: SupportsBytes) -> None: ... + def __new__(cls: Type[_T], o: SupportsBytes) -> _T: ... def capitalize(self) -> bytes: ... def center(self, __width: int, __fillchar: bytes = ...) -> bytes: ... def count(self, sub: Union[bytes, int], start: Optional[int] = ..., end: Optional[int] = ...) -> int: ... diff --git a/stdlib/2and3/builtins.pyi b/stdlib/2and3/builtins.pyi index 7a7245396..bd49c58d0 100644 --- a/stdlib/2and3/builtins.pyi +++ b/stdlib/2and3/builtins.pyi @@ -182,9 +182,9 @@ class super(object): class int: @overload - def __init__(self, x: Union[Text, bytes, SupportsInt, _SupportsIndex] = ...) -> None: ... + def __new__(cls: Type[_T], x: Union[Text, bytes, SupportsInt, _SupportsIndex] = ...) -> _T: ... @overload - def __init__(self, x: Union[Text, bytes, bytearray], base: int) -> None: ... + def __new__(cls: Type[_T], x: Union[Text, bytes, bytearray], base: int) -> _T: ... if sys.version_info >= (3, 8): def as_integer_ratio(self) -> Tuple[int, Literal[1]]: ... @property @@ -263,7 +263,7 @@ class int: def __index__(self) -> int: ... class float: - def __init__(self, x: Union[SupportsFloat, _SupportsIndex, Text, bytes, bytearray] = ...) -> None: ... + def __new__(cls: Type[_T], x: Union[SupportsFloat, _SupportsIndex, Text, bytes, bytearray] = ...) -> _T: ... def as_integer_ratio(self) -> Tuple[int, int]: ... def hex(self) -> str: ... def is_integer(self) -> bool: ... @@ -326,9 +326,9 @@ class float: class complex: @overload - def __init__(self, real: float = ..., imag: float = ...) -> None: ... + def __new__(cls: Type[_T], real: float = ..., imag: float = ...) -> _T: ... @overload - def __init__(self, real: Union[str, SupportsComplex, _SupportsIndex]) -> None: ... + def __new__(cls: Type[_T], real: Union[str, SupportsComplex, _SupportsIndex]) -> _T: ... @property def real(self) -> float: ... @property @@ -447,9 +447,9 @@ class _FormatMapMapping(Protocol): class str(Sequence[str], _str_base): if sys.version_info >= (3,): @overload - def __init__(self, o: object = ...) -> None: ... + def __new__(cls: Type[_T], o: object = ...) -> _T: ... @overload - def __init__(self, o: bytes, encoding: str = ..., errors: str = ...) -> None: ... + def __new__(cls: Type[_T], o: bytes, encoding: str = ..., errors: str = ...) -> _T: ... else: def __init__(self, o: object = ...) -> None: ... def capitalize(self) -> str: ... @@ -597,15 +597,15 @@ class str(Sequence[str], _str_base): if sys.version_info >= (3,): class bytes(ByteString): @overload - def __init__(self, ints: Iterable[int]) -> None: ... + def __new__(cls: Type[_T], ints: Iterable[int]) -> _T: ... @overload - def __init__(self, string: str, encoding: str, errors: str = ...) -> None: ... + def __new__(cls: Type[_T], string: str, encoding: str, errors: str = ...) -> _T: ... @overload - def __init__(self, length: int) -> None: ... + def __new__(cls: Type[_T], length: int) -> _T: ... @overload - def __init__(self) -> None: ... + def __new__(cls: Type[_T]) -> _T: ... @overload - def __init__(self, o: SupportsBytes) -> None: ... + def __new__(cls: Type[_T], o: SupportsBytes) -> _T: ... def capitalize(self) -> bytes: ... def center(self, __width: int, __fillchar: bytes = ...) -> bytes: ... def count(self, sub: Union[bytes, int], start: Optional[int] = ..., end: Optional[int] = ...) -> int: ... diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index 375f9002c..362b6c056 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -412,6 +412,28 @@ zipfile.ZipExtFile.read zipfile.ZipExtFile.readline zlib.compressobj +# These enums derive from (int, IntEnum) or (str, Enum). Strangely, +# at runtime, they inherit Enum.__new__, not int.__new__ or +# str.__new__ as the mro would dictate, which is why stubtest balks. +enum.IntEnum.__new__ +enum.IntFlag.__new__ +http.HTTPStatus.__new__ +inspect._ParameterKind.__new__ +pstats.SortKey.__new__ +re.RegexFlag.__new__ +signal.Handlers.__new__ +signal.Sigmasks.__new__ +signal.Signals.__new__ +socket.AddressFamily.__new__ +socket.AddressInfo.__new__ +socket.MsgFlag.__new__ +socket.SocketKind.__new__ +ssl.Options.__new__ +ssl.TLSVersion.__new__ +ssl.VerifyFlags.__new__ +ssl.VerifyMode.__new__ +tkinter.EventType.__new__ + # ========== # Whitelist entries that cannot or should not be fixed # ==========