From ed6437840a64027de0d2d31bb350324985cd3dda Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Fri, 13 Dec 2024 12:39:54 -0800 Subject: [PATCH 1/3] select.poll is a function that returns a type, not the type --- stdlib/@tests/stubtest_allowlists/common.txt | 1 - stdlib/select.pyi | 16 ++++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index 9000131fde9c..788fc4195841 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -27,7 +27,6 @@ importlib.abc.MetaPathFinder.find_spec # Not defined on the actual class, but e importlib.abc.PathEntryFinder.find_spec # Not defined on the actual class, but expected to exist. numbers.Number.__hash__ # typeshed marks this as abstract but code just sets this as None optparse.Values.__getattr__ # Some attributes are set in __init__ using setattr -select.poll # Depends on configuration selectors.DevpollSelector # Depends on configuration shutil.rmtree # stubtest doesn't like that we have this as an instance of a callback protocol instead of a function socketserver.BaseServer.fileno # implemented in derived classes diff --git a/stdlib/select.pyi b/stdlib/select.pyi index 67203905ab66..99ffd0755179 100644 --- a/stdlib/select.pyi +++ b/stdlib/select.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import FileDescriptorLike from collections.abc import Iterable from types import TracebackType -from typing import Any, final +from typing import Any, final, type_check_only from typing_extensions import Self if sys.platform != "win32": @@ -22,12 +22,16 @@ if sys.platform != "win32": POLLWRBAND: int POLLWRNORM: int -class poll: - def register(self, fd: FileDescriptorLike, eventmask: int = ...) -> None: ... - def modify(self, fd: FileDescriptorLike, eventmask: int) -> None: ... - def unregister(self, fd: FileDescriptorLike) -> None: ... - def poll(self, timeout: float | None = ...) -> list[tuple[int, int]]: ... +# This type is not exposed. It calls itself select.poll. +@type_check_only +class _poll: + # default value is select.POLLIN | select.POLLPRI | select.POLLOUT + def register(self, fd: FileDescriptorLike, eventmask: int = 7, /) -> None: ... + def modify(self, fd: FileDescriptorLike, eventmask: int, /) -> None: ... + def unregister(self, fd: FileDescriptorLike, /) -> None: ... + def poll(self, timeout: float | None = None, /) -> list[tuple[int, int]]: ... +def poll() -> _poll: ... def select( rlist: Iterable[Any], wlist: Iterable[Any], xlist: Iterable[Any], timeout: float | None = None, / ) -> tuple[list[Any], list[Any], list[Any]]: ... From 5a5840dc296402be40f13dbe041fb7d37dd19570 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Fri, 13 Dec 2024 12:44:02 -0800 Subject: [PATCH 2/3] not available on windows --- stdlib/select.pyi | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/stdlib/select.pyi b/stdlib/select.pyi index 99ffd0755179..9c07c647c6a2 100644 --- a/stdlib/select.pyi +++ b/stdlib/select.pyi @@ -22,16 +22,17 @@ if sys.platform != "win32": POLLWRBAND: int POLLWRNORM: int -# This type is not exposed. It calls itself select.poll. -@type_check_only -class _poll: - # default value is select.POLLIN | select.POLLPRI | select.POLLOUT - def register(self, fd: FileDescriptorLike, eventmask: int = 7, /) -> None: ... - def modify(self, fd: FileDescriptorLike, eventmask: int, /) -> None: ... - def unregister(self, fd: FileDescriptorLike, /) -> None: ... - def poll(self, timeout: float | None = None, /) -> list[tuple[int, int]]: ... + # This type is not exposed. It calls itself select.poll. + @type_check_only + class _poll: + # default value is select.POLLIN | select.POLLPRI | select.POLLOUT + def register(self, fd: FileDescriptorLike, eventmask: int = 7, /) -> None: ... + def modify(self, fd: FileDescriptorLike, eventmask: int, /) -> None: ... + def unregister(self, fd: FileDescriptorLike, /) -> None: ... + def poll(self, timeout: float | None = None, /) -> list[tuple[int, int]]: ... + + def poll() -> _poll: ... -def poll() -> _poll: ... def select( rlist: Iterable[Any], wlist: Iterable[Any], xlist: Iterable[Any], timeout: float | None = None, / ) -> tuple[list[Any], list[Any], list[Any]]: ... From 73f16abc395938f0d6f60feafba7fb833f4a9fe0 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Fri, 13 Dec 2024 13:40:16 -0800 Subject: [PATCH 3/3] keep select.poll as a class --- stdlib/@tests/stubtest_allowlists/darwin.txt | 1 + stdlib/@tests/stubtest_allowlists/linux.txt | 1 + stdlib/select.pyi | 10 ++++------ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/darwin.txt b/stdlib/@tests/stubtest_allowlists/darwin.txt index 4654ecb79a64..e02468b6b6c9 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin.txt @@ -44,6 +44,7 @@ curses.has_key # stubtest gets confused because this is both a module and a fun multiprocessing.popen_spawn_win32 # exists on Darwin but fails to import readline.append_history_file # Only available if compiled with GNU readline, not editline select.kqueue.__init__ # default C signature is wrong +select.poll # Actually a function; we have a class so it can be used as a type # Some of these exist on non-windows, but they are useless and this is not intended stat.FILE_ATTRIBUTE_[A-Z_]+ diff --git a/stdlib/@tests/stubtest_allowlists/linux.txt b/stdlib/@tests/stubtest_allowlists/linux.txt index d82c0a7dc83c..8d7176ce37a4 100644 --- a/stdlib/@tests/stubtest_allowlists/linux.txt +++ b/stdlib/@tests/stubtest_allowlists/linux.txt @@ -25,6 +25,7 @@ curses.LINES # Initialized only after initscr call curses.has_key # stubtest gets confused because this is both a module and a function in curses fcntl.I_[A-Z0-9_]+ # Platform differences that cannot be captured by the type system multiprocessing.popen_spawn_win32 # exists on Linux but fails to import +select.poll # Actually a function; we have a class so it can be used as a type # These seem like they should be available on Linux, but they're not # on GitHub Actions runners for some reason. diff --git a/stdlib/select.pyi b/stdlib/select.pyi index 9c07c647c6a2..ddcebd5ab608 100644 --- a/stdlib/select.pyi +++ b/stdlib/select.pyi @@ -2,7 +2,7 @@ import sys from _typeshed import FileDescriptorLike from collections.abc import Iterable from types import TracebackType -from typing import Any, final, type_check_only +from typing import Any, final from typing_extensions import Self if sys.platform != "win32": @@ -22,17 +22,15 @@ if sys.platform != "win32": POLLWRBAND: int POLLWRNORM: int - # This type is not exposed. It calls itself select.poll. - @type_check_only - class _poll: + # This is actually a function that returns an instance of a class. + # The class is not accessible directly, and also calls itself select.poll. + class poll: # default value is select.POLLIN | select.POLLPRI | select.POLLOUT def register(self, fd: FileDescriptorLike, eventmask: int = 7, /) -> None: ... def modify(self, fd: FileDescriptorLike, eventmask: int, /) -> None: ... def unregister(self, fd: FileDescriptorLike, /) -> None: ... def poll(self, timeout: float | None = None, /) -> list[tuple[int, int]]: ... - def poll() -> _poll: ... - def select( rlist: Iterable[Any], wlist: Iterable[Any], xlist: Iterable[Any], timeout: float | None = None, / ) -> tuple[list[Any], list[Any], list[Any]]: ...