From 89b34c7aca77e3b3846f31a6a116d377b5882d41 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 17 Sep 2020 19:06:07 +0200 Subject: [PATCH 1/7] Use __new__ instead of __init__ for some builtin classes Closes #4514 #2630 #2686 --- stdlib/2/__builtin__.pyi | 24 ++++++++++++------------ stdlib/2and3/builtins.pyi | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/stdlib/2/__builtin__.pyi b/stdlib/2/__builtin__.pyi index 526cdbd88024..277451ca5cca 100644 --- a/stdlib/2/__builtin__.pyi +++ b/stdlib/2/__builtin__.pyi @@ -181,9 +181,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 @@ -262,7 +262,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: ... @@ -325,9 +325,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 @@ -446,9 +446,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: ... @@ -596,15 +596,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 526cdbd88024..277451ca5cca 100644 --- a/stdlib/2and3/builtins.pyi +++ b/stdlib/2and3/builtins.pyi @@ -181,9 +181,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 @@ -262,7 +262,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: ... @@ -325,9 +325,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 @@ -446,9 +446,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: ... @@ -596,15 +596,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: ... From 8e1ddd58fa6a0db7511079b874759b914e0cbbe9 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 17 Sep 2020 19:20:50 +0200 Subject: [PATCH 2/7] Override __new__ in IntEnum and IntFlag --- stdlib/3/enum.pyi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stdlib/3/enum.pyi b/stdlib/3/enum.pyi index ed209cc48216..e089fb569808 100644 --- a/stdlib/3/enum.pyi +++ b/stdlib/3/enum.pyi @@ -46,6 +46,7 @@ class Enum(metaclass=EnumMeta): def __reduce_ex__(self, proto: object) -> Any: ... class IntEnum(int, Enum): + def __new__(cls: Type[_T], value: object) -> _T: ... value: int def unique(enumeration: _S) -> _S: ... @@ -66,6 +67,7 @@ if sys.version_info >= (3, 6): def __xor__(self: _T, other: _T) -> _T: ... def __invert__(self: _T) -> _T: ... class IntFlag(int, Flag): + def __new__(cls: Type[_T], value: object) -> _T: ... def __or__(self: _T, other: Union[int, _T]) -> _T: ... def __and__(self: _T, other: Union[int, _T]) -> _T: ... def __xor__(self: _T, other: Union[int, _T]) -> _T: ... From 8527f18797733b867a3eaf44b9687b520194edff Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 17 Sep 2020 19:28:18 +0200 Subject: [PATCH 3/7] Revert "Override __new__ in IntEnum and IntFlag" This reverts commit 8e1ddd58fa6a0db7511079b874759b914e0cbbe9. --- stdlib/3/enum.pyi | 2 -- 1 file changed, 2 deletions(-) diff --git a/stdlib/3/enum.pyi b/stdlib/3/enum.pyi index e089fb569808..ed209cc48216 100644 --- a/stdlib/3/enum.pyi +++ b/stdlib/3/enum.pyi @@ -46,7 +46,6 @@ class Enum(metaclass=EnumMeta): def __reduce_ex__(self, proto: object) -> Any: ... class IntEnum(int, Enum): - def __new__(cls: Type[_T], value: object) -> _T: ... value: int def unique(enumeration: _S) -> _S: ... @@ -67,7 +66,6 @@ if sys.version_info >= (3, 6): def __xor__(self: _T, other: _T) -> _T: ... def __invert__(self: _T) -> _T: ... class IntFlag(int, Flag): - def __new__(cls: Type[_T], value: object) -> _T: ... def __or__(self: _T, other: Union[int, _T]) -> _T: ... def __and__(self: _T, other: Union[int, _T]) -> _T: ... def __xor__(self: _T, other: Union[int, _T]) -> _T: ... From cbe0de44a20354d8ecacd5b4f4e7de299d0bb176 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 17 Sep 2020 19:32:45 +0200 Subject: [PATCH 4/7] Add enums to stubtest whitelist --- tests/stubtest_whitelists/py3_common.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index 375f9002cf32..c7b5d8e5112c 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -412,6 +412,13 @@ 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__ +tkinter.EventType.__new__ + # ========== # Whitelist entries that cannot or should not be fixed # ========== From 667cdb7c1da16de795710df0fbd49ded23addfed Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 17 Sep 2020 19:37:34 +0200 Subject: [PATCH 5/7] Add enums __new__ to stubtest whitelist --- tests/stubtest_whitelists/py3_common.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index c7b5d8e5112c..e1117324bcd5 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -417,6 +417,13 @@ zlib.compressobj # str.__new__ as the mro would dictate, which is why stubtest balks. enum.IntEnum.__new__ enum.IntFlag.__new__ +http.HTTPStatus.__new__ +inspect._ParameterKind.__new__ +signal.Handlers.__new__ +signal.Sigmasks.__new__ +signal.Signals.__new__ +socket.AddressFamily.__new__ +socket.SocketKind.__new__ tkinter.EventType.__new__ # ========== From 20a205eb89e86eaf45bd265b02c0a0e99e02de1a Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 17 Sep 2020 19:40:33 +0200 Subject: [PATCH 6/7] Add more enums to whitelist --- tests/stubtest_whitelists/py3_common.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index e1117324bcd5..8f5e4eb1572e 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -419,11 +419,17 @@ enum.IntEnum.__new__ enum.IntFlag.__new__ http.HTTPStatus.__new__ inspect._ParameterKind.__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.VerifyFlags.__new__ +ssl.VerifyMode.__new__ tkinter.EventType.__new__ # ========== From d7417f369b347252c58d8595de11a06dd91bf7b4 Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Thu, 17 Sep 2020 19:42:58 +0200 Subject: [PATCH 7/7] Add even more enums --- tests/stubtest_whitelists/py3_common.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index 8f5e4eb1572e..362b6c056b87 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -419,6 +419,7 @@ enum.IntEnum.__new__ enum.IntFlag.__new__ http.HTTPStatus.__new__ inspect._ParameterKind.__new__ +pstats.SortKey.__new__ re.RegexFlag.__new__ signal.Handlers.__new__ signal.Sigmasks.__new__ @@ -428,6 +429,7 @@ socket.AddressInfo.__new__ socket.MsgFlag.__new__ socket.SocketKind.__new__ ssl.Options.__new__ +ssl.TLSVersion.__new__ ssl.VerifyFlags.__new__ ssl.VerifyMode.__new__ tkinter.EventType.__new__