Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gevent: Use a TypeVarTuple in gevent.baseserver.BaseServer #11138

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions stubs/gevent/@tests/stubtest_allowlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ gevent._config._PositiveValueMixin.validate
# internal API implementation detail we don't care about
gevent._ffi.watcher.AbstractWatcherType.__new__

# these are inconsistent due to the ParamSpec hack for positional only callables
gevent.baseserver.BaseServer.do_close
gevent.baseserver.BaseServer.do_handle

# we don't care about write/writeall allowing a named parameter
gevent._fileobjectcommon.FlushingBufferedWriter.write
gevent._fileobjectcommon.WriteIsWriteallMixin.write
Expand Down
23 changes: 10 additions & 13 deletions stubs/gevent/gevent/baseserver.pyi
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
from collections.abc import Callable, Container
from types import TracebackType
from typing import Any, Generic, Literal, Protocol
from typing_extensions import ParamSpec, Self, TypeAlias
from typing import Generic, Literal, Protocol
from typing_extensions import ParamSpec, Self, TypeAlias, TypeVarTuple, Unpack

from gevent._types import _Loop
from gevent.pool import Pool
from gevent.socket import socket as _GeventSocket
from greenlet import greenlet

_Ts = TypeVarTuple("_Ts")
_P = ParamSpec("_P")

class _SpawnFunc(Protocol):
def __call__(self, func: Callable[_P, object], /, *args: _P.args, **kwargs: _P.kwargs) -> greenlet: ...

_Spawner: TypeAlias = Pool | _SpawnFunc | int | Literal["default"] | None

class BaseServer(Generic[_P]):
class BaseServer(Generic[Unpack[_Ts]]):
min_delay: float
max_delay: float
max_accept: int
Expand All @@ -27,27 +28,23 @@ class BaseServer(Generic[_P]):
family: int
address: str | tuple[str, int]
socket: _GeventSocket
handle: Callable[..., object]
handle: Callable[[Unpack[_Ts]], object]
def __init__(
self,
listener: _GeventSocket | tuple[str, int] | str,
handle: Callable[_P, object] | None = None,
handle: Callable[[Unpack[_Ts]], object] | None = None,
spawn: _Spawner = "default",
) -> None: ...
def __enter__(self) -> Self: ...
def __exit__(self, typ: type[BaseException] | None, value: BaseException | None, tb: TracebackType | None, /) -> None: ...
def set_listener(self, listener: _GeventSocket | tuple[str, int] | str) -> None: ...
def set_spawn(self, spawn: _Spawner) -> None: ...
def set_handle(self, handle: Callable[_P, object]) -> None: ...
def set_handle(self, handle: Callable[[Unpack[_Ts]], object]) -> None: ...
def start_accepting(self) -> None: ...
def stop_accepting(self) -> None: ...
# neither of these accept keyword arguments, but if we omit them, then ParamSpec
# won't match the arguments correctly
def do_handle(self, *args: _P.args, **_: _P.kwargs) -> None: ...
def do_close(self, *args: _P.args, **_: _P.kwargs) -> None: ...
# we would like to return _P.args here, however pyright will complain
# mypy doesn't seem to mind
def do_read(self) -> tuple[Any, ...] | None: ...
def do_handle(self, *args: Unpack[_Ts]) -> None: ...
def do_close(self, *args: Unpack[_Ts]) -> None: ...
def do_read(self) -> tuple[Unpack[_Ts]] | None: ...
def full(self) -> bool: ...
@property
def server_host(self) -> str | None: ...
Expand Down
4 changes: 2 additions & 2 deletions stubs/gevent/gevent/server.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class _SSLArguments(TypedDict, total=False):
do_handshake_on_connect: bool
ciphers: str

class StreamServer(BaseServer[[_GeventSocket, _Address]]):
class StreamServer(BaseServer[_GeventSocket, _Address]):
backlog: int
reuse_addr: ClassVar[int | None]
wrap_socket = ssl_wrap_socket
Expand Down Expand Up @@ -67,7 +67,7 @@ class StreamServer(BaseServer[[_GeventSocket, _Address]]):
def do_close(self, sock: _GeventSocket, address: _Address) -> None: ...
def wrap_socket_and_handle(self, client_socket: _GeventSocket, address: _StrictAddress) -> Any: ...

class DatagramServer(BaseServer[[_GeventSocket, _Address]]):
class DatagramServer(BaseServer[_GeventSocket, _Address]):
reuse_addr: ClassVar[int | None]
def __init__(
self,
Expand Down
Loading