From b60f19d2b0fefbc56ef821934c756eb3fd803d6c Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Sat, 23 Nov 2024 16:13:44 -0800 Subject: [PATCH 1/4] adjusting socketserver.BaseServer This one might be a bad idea. fileno, get_request, and server_bind are documented to exist on BaseServer, but they don't. Of these, only get_request is actually called from the existing implementation of BaseServer (as part of handle_request and serve_forever). In the ideal case, they'd probably all be abstract methods in CPython. --- stdlib/@tests/stubtest_allowlists/common.txt | 6 +++--- stdlib/socketserver.pyi | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index e87ba193ce40..9f247b0533a7 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -61,9 +61,6 @@ pickle.Pickler.reducer_override # implemented in C pickler 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 -socketserver.BaseServer.get_request # implemented in derived classes -socketserver.BaseServer.server_bind # implemented in derived classes ssl.Purpose.__new__ # the multiple inheritance confuses mypy tarfile.TarFile.errors # errors is initialized for some reason as None even though it really only accepts str tkinter.simpledialog.[A-Z_]+ @@ -435,6 +432,9 @@ multiprocessing.pool.Pool.__del__ # C signature is broader than what is actually accepted _?queue.SimpleQueue.__init__ +# Not implemented, but expected to exist on subclasses. +socketserver.BaseServer.get_request + # Items that depend on the existence and flags of SSL imaplib.IMAP4_SSL.ssl ssl.PROTOCOL_SSLv2 diff --git a/stdlib/socketserver.pyi b/stdlib/socketserver.pyi index ae6575d85082..9c4d308f44db 100644 --- a/stdlib/socketserver.pyi +++ b/stdlib/socketserver.pyi @@ -49,18 +49,16 @@ class BaseServer: def __init__( self, server_address: _Address, RequestHandlerClass: Callable[[Any, _RetAddress, Self], BaseRequestHandler] ) -> None: ... - def fileno(self) -> int: ... def handle_request(self) -> None: ... def serve_forever(self, poll_interval: float = 0.5) -> None: ... def shutdown(self) -> None: ... def server_close(self) -> None: ... def finish_request(self, request: _RequestType, client_address: _RetAddress) -> None: ... - def get_request(self) -> tuple[Any, Any]: ... + def get_request(self) -> tuple[Any, Any]: ... # Not implemented here, but expected to exist on subclasses def handle_error(self, request: _RequestType, client_address: _RetAddress) -> None: ... def handle_timeout(self) -> None: ... def process_request(self, request: _RequestType, client_address: _RetAddress) -> None: ... def server_activate(self) -> None: ... - def server_bind(self) -> None: ... def verify_request(self, request: _RequestType, client_address: _RetAddress) -> bool: ... def __enter__(self) -> Self: ... def __exit__( @@ -80,7 +78,9 @@ class TCPServer(BaseServer): RequestHandlerClass: Callable[[Any, _RetAddress, Self], BaseRequestHandler], bind_and_activate: bool = True, ) -> None: ... + def fileno(self) -> int: ... def get_request(self) -> tuple[_socket, _RetAddress]: ... + def server_bind(self) -> None: ... class UDPServer(TCPServer): max_packet_size: ClassVar[int] From d68350692769c12dde706509c312cc2400ec9958 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Sun, 15 Dec 2024 14:35:17 -0800 Subject: [PATCH 2/4] various attributes that are added by TCPServer --- stdlib/socketserver.pyi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stdlib/socketserver.pyi b/stdlib/socketserver.pyi index 9c4d308f44db..061932f0fac7 100644 --- a/stdlib/socketserver.pyi +++ b/stdlib/socketserver.pyi @@ -38,12 +38,7 @@ _AfInetAddress: TypeAlias = tuple[str | bytes | bytearray, int] # address accep # This can possibly be generic at some point: class BaseServer: - address_family: int server_address: _Address - socket: _socket - allow_reuse_address: bool - request_queue_size: int - socket_type: int timeout: float | None RequestHandlerClass: Callable[[Any, _RetAddress, Self], BaseRequestHandler] def __init__( @@ -69,6 +64,11 @@ class BaseServer: def close_request(self, request: _RequestType) -> None: ... # undocumented class TCPServer(BaseServer): + address_family: int + socket: _socket + allow_reuse_address: bool + request_queue_size: int + socket_type: int if sys.version_info >= (3, 11): allow_reuse_port: bool server_address: _AfInetAddress From 624f4e87ade68e97cf1b098f7415f1b62fca7813 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Sun, 15 Dec 2024 14:44:02 -0800 Subject: [PATCH 3/4] we don't need to lie about BaseSever.get_request --- stdlib/@tests/stubtest_allowlists/common.txt | 1 - stdlib/socketserver.pyi | 1 - 2 files changed, 2 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index 269fc034a2e7..ff54f0d48287 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -441,7 +441,6 @@ pickle._Pickler\..* # Best effort typing for undocumented internals pickle._Unpickler\..* # Best effort typing for undocumented internals _?queue.SimpleQueue.__init__ # C signature is broader than what is actually accepted shutil.rmtree # function with attributes, which we approximate with a callable protocol -socketserver.BaseServer.get_request # Not implemented, but expected to exist on subclasses. ssl.PROTOCOL_SSLv2 # Depends on the existence and flags of SSL ssl.PROTOCOL_SSLv3 # Depends on the existence and flags of SSL sys.implementation # Actually SimpleNamespace but then you wouldn't have convenient attributes diff --git a/stdlib/socketserver.pyi b/stdlib/socketserver.pyi index 061932f0fac7..fbd1e7c44aff 100644 --- a/stdlib/socketserver.pyi +++ b/stdlib/socketserver.pyi @@ -49,7 +49,6 @@ class BaseServer: def shutdown(self) -> None: ... def server_close(self) -> None: ... def finish_request(self, request: _RequestType, client_address: _RetAddress) -> None: ... - def get_request(self) -> tuple[Any, Any]: ... # Not implemented here, but expected to exist on subclasses def handle_error(self, request: _RequestType, client_address: _RetAddress) -> None: ... def handle_timeout(self) -> None: ... def process_request(self, request: _RequestType, client_address: _RetAddress) -> None: ... From dbedcb8e7ac9df80f86c547f901d11c5c19dfc74 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Sun, 15 Dec 2024 14:46:45 -0800 Subject: [PATCH 4/4] Revert "we don't need to lie about BaseSever.get_request" This reverts commit 624f4e87ade68e97cf1b098f7415f1b62fca7813. --- stdlib/@tests/stubtest_allowlists/common.txt | 1 + stdlib/socketserver.pyi | 1 + 2 files changed, 2 insertions(+) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index ff54f0d48287..269fc034a2e7 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -441,6 +441,7 @@ pickle._Pickler\..* # Best effort typing for undocumented internals pickle._Unpickler\..* # Best effort typing for undocumented internals _?queue.SimpleQueue.__init__ # C signature is broader than what is actually accepted shutil.rmtree # function with attributes, which we approximate with a callable protocol +socketserver.BaseServer.get_request # Not implemented, but expected to exist on subclasses. ssl.PROTOCOL_SSLv2 # Depends on the existence and flags of SSL ssl.PROTOCOL_SSLv3 # Depends on the existence and flags of SSL sys.implementation # Actually SimpleNamespace but then you wouldn't have convenient attributes diff --git a/stdlib/socketserver.pyi b/stdlib/socketserver.pyi index fbd1e7c44aff..061932f0fac7 100644 --- a/stdlib/socketserver.pyi +++ b/stdlib/socketserver.pyi @@ -49,6 +49,7 @@ class BaseServer: def shutdown(self) -> None: ... def server_close(self) -> None: ... def finish_request(self, request: _RequestType, client_address: _RetAddress) -> None: ... + def get_request(self) -> tuple[Any, Any]: ... # Not implemented here, but expected to exist on subclasses def handle_error(self, request: _RequestType, client_address: _RetAddress) -> None: ... def handle_timeout(self) -> None: ... def process_request(self, request: _RequestType, client_address: _RetAddress) -> None: ...