From 6e9227a8cedf268799d2f0442ec855db46414778 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 30 Nov 2022 19:43:29 -0800 Subject: [PATCH] Sync typeshed (#14228) Sync typeshed Source commit: https://github.com/python/typeshed/commit/87d2683ef974ef6d6d8b38313f73e9ef0acad06c --- mypy/typeshed/stdlib/_typeshed/__init__.pyi | 26 ++++++++- mypy/typeshed/stdlib/abc.pyi | 4 +- mypy/typeshed/stdlib/asyncio/base_events.pyi | 28 +++++----- mypy/typeshed/stdlib/asyncio/events.pyi | 32 +++++------ mypy/typeshed/stdlib/builtins.pyi | 53 ++++++++++++------- mypy/typeshed/stdlib/marshal.pyi | 30 +++++++++-- .../stdlib/multiprocessing/reduction.pyi | 37 ++++++++----- mypy/typeshed/stdlib/ssl.pyi | 4 ++ mypy/typeshed/stdlib/string.pyi | 11 +++- mypy/typeshed/stdlib/unicodedata.pyi | 9 ++-- mypy/typeshed/stdlib/unittest/mock.pyi | 2 +- mypy/typeshed/stdlib/urllib/parse.pyi | 19 +++++-- mypy/typeshed/stdlib/urllib/request.pyi | 48 +++++++++-------- mypy/typeshed/stdlib/xmlrpc/client.pyi | 45 +++++++++++----- mypy/typeshed/stdlib/xmlrpc/server.pyi | 6 +-- 15 files changed, 234 insertions(+), 120 deletions(-) diff --git a/mypy/typeshed/stdlib/_typeshed/__init__.pyi b/mypy/typeshed/stdlib/_typeshed/__init__.pyi index 3ae2fca1d19d..f01db74caf40 100644 --- a/mypy/typeshed/stdlib/_typeshed/__init__.pyi +++ b/mypy/typeshed/stdlib/_typeshed/__init__.pyi @@ -236,6 +236,29 @@ else: ReadableBuffer: TypeAlias = ReadOnlyBuffer | WriteableBuffer # stable _BufferWithLen: TypeAlias = ReadableBuffer # not stable # noqa: Y047 +# Anything that implements the read-write buffer interface, and can be sliced/indexed. +SliceableBuffer: TypeAlias = bytes | bytearray | memoryview | array.array[Any] | mmap.mmap +IndexableBuffer: TypeAlias = bytes | bytearray | memoryview | array.array[Any] | mmap.mmap +# https://github.com/python/typeshed/pull/9115#issuecomment-1304905864 +# Post PEP 688, they should be rewritten as such: +# from collections.abc import Sequence +# from typing import Sized, overload +# class SliceableBuffer(Protocol): +# def __buffer__(self, __flags: int) -> memoryview: ... +# def __getitem__(self, __slice: slice) -> Sequence[int]: ... +# class IndexableBuffer(Protocol): +# def __buffer__(self, __flags: int) -> memoryview: ... +# def __getitem__(self, __i: int) -> int: ... +# class SupportsGetItemBuffer(SliceableBuffer, IndexableBuffer, Protocol): +# def __buffer__(self, __flags: int) -> memoryview: ... +# def __contains__(self, __x: Any) -> bool: ... +# @overload +# def __getitem__(self, __slice: slice) -> Sequence[int]: ... +# @overload +# def __getitem__(self, __i: int) -> int: ... +# class SizedBuffer(Sized, Protocol): # instead of _BufferWithLen +# def __buffer__(self, __flags: int) -> memoryview: ... + ExcInfo: TypeAlias = tuple[type[BaseException], BaseException, TracebackType] OptExcInfo: TypeAlias = Union[ExcInfo, tuple[None, None, None]] @@ -276,5 +299,4 @@ StrOrLiteralStr = TypeVar("StrOrLiteralStr", LiteralString, str) # noqa: Y001 ProfileFunction: TypeAlias = Callable[[FrameType, str, Any], object] # Objects suitable to be passed to sys.settrace, threading.settrace, and similar -# TODO: Ideally this would be a recursive type alias -TraceFunction: TypeAlias = Callable[[FrameType, str, Any], Callable[[FrameType, str, Any], Any] | None] +TraceFunction: TypeAlias = Callable[[FrameType, str, Any], TraceFunction | None] diff --git a/mypy/typeshed/stdlib/abc.pyi b/mypy/typeshed/stdlib/abc.pyi index 110eba24a9ca..7b39c88ed394 100644 --- a/mypy/typeshed/stdlib/abc.pyi +++ b/mypy/typeshed/stdlib/abc.pyi @@ -18,8 +18,8 @@ class ABCMeta(type): else: def __new__(mcls: type[Self], name: str, bases: tuple[type, ...], namespace: dict[str, Any], **kwargs: Any) -> Self: ... - def __instancecheck__(cls: ABCMeta, instance: Any) -> Any: ... - def __subclasscheck__(cls: ABCMeta, subclass: Any) -> Any: ... + def __instancecheck__(cls: ABCMeta, instance: Any) -> bool: ... + def __subclasscheck__(cls: ABCMeta, subclass: type) -> bool: ... def _dump_registry(cls: ABCMeta, file: SupportsWrite[str] | None = ...) -> None: ... def register(cls: ABCMeta, subclass: type[_T]) -> type[_T]: ... diff --git a/mypy/typeshed/stdlib/asyncio/base_events.pyi b/mypy/typeshed/stdlib/asyncio/base_events.pyi index c1ab114b6036..83576ab6455e 100644 --- a/mypy/typeshed/stdlib/asyncio/base_events.pyi +++ b/mypy/typeshed/stdlib/asyncio/base_events.pyi @@ -5,7 +5,7 @@ from asyncio.events import AbstractEventLoop, AbstractServer, Handle, TimerHandl from asyncio.futures import Future from asyncio.protocols import BaseProtocol from asyncio.tasks import Task -from asyncio.transports import BaseTransport, ReadTransport, SubprocessTransport, WriteTransport +from asyncio.transports import BaseTransport, DatagramTransport, ReadTransport, SubprocessTransport, Transport, WriteTransport from collections.abc import Awaitable, Callable, Coroutine, Generator, Iterable, Sequence from contextvars import Context from socket import AddressFamily, SocketKind, _Address, _RetAddress, socket @@ -129,7 +129,7 @@ class BaseEventLoop(AbstractEventLoop): ssl_shutdown_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... @overload async def create_connection( self, @@ -148,7 +148,7 @@ class BaseEventLoop(AbstractEventLoop): ssl_shutdown_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... elif sys.version_info >= (3, 8): @overload async def create_connection( @@ -167,7 +167,7 @@ class BaseEventLoop(AbstractEventLoop): ssl_handshake_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... @overload async def create_connection( self, @@ -185,7 +185,7 @@ class BaseEventLoop(AbstractEventLoop): ssl_handshake_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... else: @overload async def create_connection( @@ -202,7 +202,7 @@ class BaseEventLoop(AbstractEventLoop): local_addr: tuple[str, int] | None = ..., server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... @overload async def create_connection( self, @@ -218,7 +218,7 @@ class BaseEventLoop(AbstractEventLoop): local_addr: None = ..., server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... if sys.version_info >= (3, 11): @overload async def create_server( @@ -266,7 +266,7 @@ class BaseEventLoop(AbstractEventLoop): server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., ssl_shutdown_timeout: float | None = ..., - ) -> BaseTransport: ... + ) -> Transport: ... async def connect_accepted_socket( self, protocol_factory: Callable[[], _ProtocolT], @@ -275,7 +275,7 @@ class BaseEventLoop(AbstractEventLoop): ssl: _SSLContext = ..., ssl_handshake_timeout: float | None = ..., ssl_shutdown_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... else: @overload async def create_server( @@ -320,7 +320,7 @@ class BaseEventLoop(AbstractEventLoop): server_side: bool = ..., server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., - ) -> BaseTransport: ... + ) -> Transport: ... async def connect_accepted_socket( self, protocol_factory: Callable[[], _ProtocolT], @@ -328,13 +328,13 @@ class BaseEventLoop(AbstractEventLoop): *, ssl: _SSLContext = ..., ssl_handshake_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... async def sock_sendfile( self, sock: socket, file: IO[bytes], offset: int = ..., count: int | None = ..., *, fallback: bool | None = ... ) -> int: ... async def sendfile( - self, transport: BaseTransport, file: IO[bytes], offset: int = ..., count: int | None = ..., *, fallback: bool = ... + self, transport: WriteTransport, file: IO[bytes], offset: int = ..., count: int | None = ..., *, fallback: bool = ... ) -> int: ... if sys.version_info >= (3, 11): async def create_datagram_endpoint( # type: ignore[override] @@ -349,7 +349,7 @@ class BaseEventLoop(AbstractEventLoop): reuse_port: bool | None = ..., allow_broadcast: bool | None = ..., sock: socket | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[DatagramTransport, _ProtocolT]: ... else: async def create_datagram_endpoint( self, @@ -364,7 +364,7 @@ class BaseEventLoop(AbstractEventLoop): reuse_port: bool | None = ..., allow_broadcast: bool | None = ..., sock: socket | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[DatagramTransport, _ProtocolT]: ... # Pipes and subprocesses. async def connect_read_pipe( self, protocol_factory: Callable[[], _ProtocolT], pipe: Any diff --git a/mypy/typeshed/stdlib/asyncio/events.pyi b/mypy/typeshed/stdlib/asyncio/events.pyi index 280be4ab5ba9..7241d5a29f8d 100644 --- a/mypy/typeshed/stdlib/asyncio/events.pyi +++ b/mypy/typeshed/stdlib/asyncio/events.pyi @@ -12,7 +12,7 @@ from .base_events import Server from .futures import Future from .protocols import BaseProtocol from .tasks import Task -from .transports import BaseTransport, ReadTransport, SubprocessTransport, WriteTransport +from .transports import BaseTransport, DatagramTransport, ReadTransport, SubprocessTransport, Transport, WriteTransport from .unix_events import AbstractChildWatcher if sys.version_info >= (3, 8): @@ -223,7 +223,7 @@ class AbstractEventLoop: ssl_shutdown_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... @overload @abstractmethod async def create_connection( @@ -243,7 +243,7 @@ class AbstractEventLoop: ssl_shutdown_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... elif sys.version_info >= (3, 8): @overload @abstractmethod @@ -263,7 +263,7 @@ class AbstractEventLoop: ssl_handshake_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... @overload @abstractmethod async def create_connection( @@ -282,7 +282,7 @@ class AbstractEventLoop: ssl_handshake_timeout: float | None = ..., happy_eyeballs_delay: float | None = ..., interleave: int | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... else: @overload @abstractmethod @@ -300,7 +300,7 @@ class AbstractEventLoop: local_addr: tuple[str, int] | None = ..., server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... @overload @abstractmethod async def create_connection( @@ -317,7 +317,7 @@ class AbstractEventLoop: local_addr: None = ..., server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... if sys.version_info >= (3, 11): @overload @abstractmethod @@ -360,7 +360,7 @@ class AbstractEventLoop: @abstractmethod async def start_tls( self, - transport: BaseTransport, + transport: WriteTransport, protocol: BaseProtocol, sslcontext: ssl.SSLContext, *, @@ -368,7 +368,7 @@ class AbstractEventLoop: server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., ssl_shutdown_timeout: float | None = ..., - ) -> BaseTransport: ... + ) -> Transport: ... async def create_unix_server( self, protocol_factory: _ProtocolFactory, @@ -428,7 +428,7 @@ class AbstractEventLoop: server_side: bool = ..., server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., - ) -> BaseTransport: ... + ) -> Transport: ... async def create_unix_server( self, protocol_factory: _ProtocolFactory, @@ -449,7 +449,7 @@ class AbstractEventLoop: ssl: _SSLContext = ..., ssl_handshake_timeout: float | None = ..., ssl_shutdown_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... elif sys.version_info >= (3, 10): async def connect_accepted_socket( self, @@ -458,7 +458,7 @@ class AbstractEventLoop: *, ssl: _SSLContext = ..., ssl_handshake_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... if sys.version_info >= (3, 11): async def create_unix_connection( self, @@ -470,7 +470,7 @@ class AbstractEventLoop: server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., ssl_shutdown_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... else: async def create_unix_connection( self, @@ -481,7 +481,7 @@ class AbstractEventLoop: sock: socket | None = ..., server_hostname: str | None = ..., ssl_handshake_timeout: float | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[Transport, _ProtocolT]: ... @abstractmethod async def sock_sendfile( @@ -489,7 +489,7 @@ class AbstractEventLoop: ) -> int: ... @abstractmethod async def sendfile( - self, transport: BaseTransport, file: IO[bytes], offset: int = ..., count: int | None = ..., *, fallback: bool = ... + self, transport: WriteTransport, file: IO[bytes], offset: int = ..., count: int | None = ..., *, fallback: bool = ... ) -> int: ... @abstractmethod async def create_datagram_endpoint( @@ -505,7 +505,7 @@ class AbstractEventLoop: reuse_port: bool | None = ..., allow_broadcast: bool | None = ..., sock: socket | None = ..., - ) -> tuple[BaseTransport, _ProtocolT]: ... + ) -> tuple[DatagramTransport, _ProtocolT]: ... # Pipes and subprocesses. @abstractmethod async def connect_read_pipe( diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi index 5482955eb0ab..a47d774467dd 100644 --- a/mypy/typeshed/stdlib/builtins.pyi +++ b/mypy/typeshed/stdlib/builtins.pyi @@ -1232,19 +1232,13 @@ def iter(__function: Callable[[], _T | None], __sentinel: None) -> Iterator[_T]: @overload def iter(__function: Callable[[], _T], __sentinel: object) -> Iterator[_T]: ... -# We need recursive types to express the type of the second argument to `isinstance` properly, hence the use of `Any` if sys.version_info >= (3, 10): - def isinstance( - __obj: object, __class_or_tuple: type | types.UnionType | tuple[type | types.UnionType | tuple[Any, ...], ...] - ) -> bool: ... - def issubclass( - __cls: type, __class_or_tuple: type | types.UnionType | tuple[type | types.UnionType | tuple[Any, ...], ...] - ) -> bool: ... - + _ClassInfo: TypeAlias = type | types.UnionType | tuple[_ClassInfo, ...] else: - def isinstance(__obj: object, __class_or_tuple: type | tuple[type | tuple[Any, ...], ...]) -> bool: ... - def issubclass(__cls: type, __class_or_tuple: type | tuple[type | tuple[Any, ...], ...]) -> bool: ... + _ClassInfo: TypeAlias = type | tuple[_ClassInfo, ...] +def isinstance(__obj: object, __class_or_tuple: _ClassInfo) -> bool: ... +def issubclass(__cls: type, __class_or_tuple: _ClassInfo) -> bool: ... def len(__obj: Sized) -> int: ... def license() -> None: ... def locals() -> dict[str, Any]: ... @@ -1852,6 +1846,7 @@ if sys.version_info >= (3, 11): _ExceptionT_co = TypeVar("_ExceptionT_co", bound=Exception, covariant=True) _ExceptionT = TypeVar("_ExceptionT", bound=Exception) + # See `check_exception_group.py` for use-cases and comments. class BaseExceptionGroup(BaseException, Generic[_BaseExceptionT_co]): def __new__(cls: type[Self], __message: str, __exceptions: Sequence[_BaseExceptionT_co]) -> Self: ... @property @@ -1859,18 +1854,34 @@ if sys.version_info >= (3, 11): @property def exceptions(self) -> tuple[_BaseExceptionT_co | BaseExceptionGroup[_BaseExceptionT_co], ...]: ... @overload + def subgroup( + self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + ) -> ExceptionGroup[_ExceptionT] | None: ... + @overload def subgroup( self, __condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...] ) -> BaseExceptionGroup[_BaseExceptionT] | None: ... @overload - def subgroup(self: Self, __condition: Callable[[_BaseExceptionT_co], bool]) -> Self | None: ... + def subgroup( + self: Self, __condition: Callable[[_BaseExceptionT_co | Self], bool] + ) -> BaseExceptionGroup[_BaseExceptionT_co] | None: ... + @overload + def split( + self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + ) -> tuple[ExceptionGroup[_ExceptionT] | None, BaseExceptionGroup[_BaseExceptionT_co] | None]: ... + @overload + def split( + self, __condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...] + ) -> tuple[BaseExceptionGroup[_BaseExceptionT] | None, BaseExceptionGroup[_BaseExceptionT_co] | None]: ... @overload def split( - self: Self, __condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...] - ) -> tuple[BaseExceptionGroup[_BaseExceptionT] | None, Self | None]: ... + self: Self, __condition: Callable[[_BaseExceptionT_co | Self], bool] + ) -> tuple[BaseExceptionGroup[_BaseExceptionT_co] | None, BaseExceptionGroup[_BaseExceptionT_co] | None]: ... + # In reality it is `NonEmptySequence`: @overload - def split(self: Self, __condition: Callable[[_BaseExceptionT_co], bool]) -> tuple[Self | None, Self | None]: ... - def derive(self: Self, __excs: Sequence[_BaseExceptionT_co]) -> Self: ... + def derive(self, __excs: Sequence[_ExceptionT]) -> ExceptionGroup[_ExceptionT]: ... + @overload + def derive(self, __excs: Sequence[_BaseExceptionT]) -> BaseExceptionGroup[_BaseExceptionT]: ... def __class_getitem__(cls, __item: Any) -> GenericAlias: ... class ExceptionGroup(BaseExceptionGroup[_ExceptionT_co], Exception): @@ -1883,10 +1894,14 @@ if sys.version_info >= (3, 11): self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] ) -> ExceptionGroup[_ExceptionT] | None: ... @overload - def subgroup(self: Self, __condition: Callable[[_ExceptionT_co], bool]) -> Self | None: ... + def subgroup( + self: Self, __condition: Callable[[_ExceptionT_co | Self], bool] + ) -> ExceptionGroup[_ExceptionT_co] | None: ... @overload # type: ignore[override] def split( - self: Self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] - ) -> tuple[ExceptionGroup[_ExceptionT] | None, Self | None]: ... + self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + ) -> tuple[ExceptionGroup[_ExceptionT] | None, ExceptionGroup[_ExceptionT_co] | None]: ... @overload - def split(self: Self, __condition: Callable[[_ExceptionT_co], bool]) -> tuple[Self | None, Self | None]: ... + def split( + self: Self, __condition: Callable[[_ExceptionT_co | Self], bool] + ) -> tuple[ExceptionGroup[_ExceptionT_co] | None, ExceptionGroup[_ExceptionT_co] | None]: ... diff --git a/mypy/typeshed/stdlib/marshal.pyi b/mypy/typeshed/stdlib/marshal.pyi index d68cdd143109..d46d9c10483d 100644 --- a/mypy/typeshed/stdlib/marshal.pyi +++ b/mypy/typeshed/stdlib/marshal.pyi @@ -1,9 +1,33 @@ +import builtins +import types from _typeshed import ReadableBuffer, SupportsRead, SupportsWrite -from typing import Any +from typing import Any, Union +from typing_extensions import TypeAlias version: int -def dump(__value: Any, __file: SupportsWrite[bytes], __version: int = ...) -> None: ... +_Marshallable: TypeAlias = Union[ + # handled in w_object() in marshal.c + None, + type[StopIteration], + builtins.ellipsis, + bool, + # handled in w_complex_object() in marshal.c + int, + float, + complex, + bytes, + str, + tuple[_Marshallable, ...], + list[Any], + dict[Any, Any], + set[Any], + frozenset[_Marshallable], + types.CodeType, + ReadableBuffer, +] + +def dump(__value: _Marshallable, __file: SupportsWrite[bytes], __version: int = ...) -> None: ... def load(__file: SupportsRead[bytes]) -> Any: ... -def dumps(__value: Any, __version: int = ...) -> bytes: ... +def dumps(__value: _Marshallable, __version: int = ...) -> bytes: ... def loads(__bytes: ReadableBuffer) -> Any: ... diff --git a/mypy/typeshed/stdlib/multiprocessing/reduction.pyi b/mypy/typeshed/stdlib/multiprocessing/reduction.pyi index cab86d866bab..d6b70aefa48d 100644 --- a/mypy/typeshed/stdlib/multiprocessing/reduction.pyi +++ b/mypy/typeshed/stdlib/multiprocessing/reduction.pyi @@ -1,9 +1,14 @@ import pickle import sys -from _typeshed import HasFileno, Incomplete +from _typeshed import HasFileno, SupportsWrite from abc import ABCMeta +from builtins import type as Type # alias to avoid name clash +from collections.abc import Callable from copyreg import _DispatchTableType +from multiprocessing import connection +from pickle import _ReducedType from socket import socket +from typing import Any from typing_extensions import Literal if sys.platform == "win32": @@ -11,18 +16,20 @@ if sys.platform == "win32": else: __all__ = ["send_handle", "recv_handle", "ForkingPickler", "register", "dump", "DupFd", "sendfds", "recvfds"] +HAVE_SEND_HANDLE: bool + class ForkingPickler(pickle.Pickler): dispatch_table: _DispatchTableType - def __init__(self, *args) -> None: ... + def __init__(self, file: SupportsWrite[bytes], protocol: int | None = ...) -> None: ... @classmethod - def register(cls, type, reduce) -> None: ... + def register(cls, type: Type, reduce: Callable[[Any], _ReducedType]) -> None: ... @classmethod - def dumps(cls, obj, protocol: Incomplete | None = ...): ... + def dumps(cls, obj: Any, protocol: int | None = ...) -> memoryview: ... loads = pickle.loads register = ForkingPickler.register -def dump(obj, file, protocol: Incomplete | None = ...) -> None: ... +def dump(obj: Any, file: SupportsWrite[bytes], protocol: int | None = ...) -> None: ... if sys.platform == "win32": if sys.version_info >= (3, 8): @@ -32,13 +39,13 @@ if sys.platform == "win32": else: def duplicate(handle: int, target_process: int | None = ..., inheritable: bool = ...) -> int: ... - def steal_handle(source_pid, handle): ... - def send_handle(conn, handle, destination_pid) -> None: ... - def recv_handle(conn): ... + def steal_handle(source_pid: int, handle: int) -> int: ... + def send_handle(conn: connection.PipeConnection, handle: int, destination_pid: int) -> None: ... + def recv_handle(conn: connection.PipeConnection) -> int: ... class DupHandle: - def __init__(self, handle, access, pid: Incomplete | None = ...) -> None: ... - def detach(self): ... + def __init__(self, handle: int, access: int, pid: int | None = ...) -> None: ... + def detach(self) -> int: ... else: if sys.platform == "darwin": @@ -47,10 +54,11 @@ else: ACKNOWLEDGE: Literal[False] def recvfds(sock: socket, size: int) -> list[int]: ... - def send_handle(conn, handle, destination_pid) -> None: ... + # destination_pid is unused + def send_handle(conn: HasFileno, handle: int, destination_pid: object) -> None: ... def recv_handle(conn: HasFileno) -> int: ... - def sendfds(sock, fds) -> None: ... - def DupFd(fd): ... + def sendfds(sock: socket, fds: list[int]) -> None: ... + def DupFd(fd: int) -> Any: ... # Return type is really hard to get right # These aliases are to work around pyright complaints. # Pyright doesn't like it when a class object is defined as an alias @@ -84,4 +92,5 @@ class AbstractReducer(metaclass=ABCMeta): sendfds = _sendfds recvfds = _recvfds DupFd = _DupFd - def __init__(self, *args) -> None: ... + # *args are unused + def __init__(self, *args: object) -> None: ... diff --git a/mypy/typeshed/stdlib/ssl.pyi b/mypy/typeshed/stdlib/ssl.pyi index 543433f2fbd0..91844e8369df 100644 --- a/mypy/typeshed/stdlib/ssl.pyi +++ b/mypy/typeshed/stdlib/ssl.pyi @@ -180,6 +180,8 @@ class Options(enum.IntFlag): OP_NO_RENEGOTIATION: int if sys.version_info >= (3, 8): OP_ENABLE_MIDDLEBOX_COMPAT: int + if sys.platform == "linux": + OP_IGNORE_UNEXPECTED_EOF: int OP_ALL: Options OP_NO_SSLv2: Options @@ -196,6 +198,8 @@ OP_NO_TICKET: Options OP_NO_RENEGOTIATION: Options if sys.version_info >= (3, 8): OP_ENABLE_MIDDLEBOX_COMPAT: Options + if sys.platform == "linux": + OP_IGNORE_UNEXPECTED_EOF: Options HAS_NEVER_CHECK_COMMON_NAME: bool HAS_SSLv2: bool diff --git a/mypy/typeshed/stdlib/string.pyi b/mypy/typeshed/stdlib/string.pyi index 6fb803fe53be..49802ce81019 100644 --- a/mypy/typeshed/stdlib/string.pyi +++ b/mypy/typeshed/stdlib/string.pyi @@ -64,11 +64,20 @@ class Formatter: ) -> LiteralString: ... @overload def vformat(self, format_string: str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> str: ... + def _vformat( # undocumented + self, + format_string: str, + args: Sequence[Any], + kwargs: Mapping[str, Any], + used_args: set[int | str], + recursion_depth: int, + auto_arg_index: int = ..., + ) -> tuple[str, int]: ... def parse( self, format_string: StrOrLiteralStr ) -> Iterable[tuple[StrOrLiteralStr, StrOrLiteralStr | None, StrOrLiteralStr | None, StrOrLiteralStr | None]]: ... def get_field(self, field_name: str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> Any: ... def get_value(self, key: int | str, args: Sequence[Any], kwargs: Mapping[str, Any]) -> Any: ... - def check_unused_args(self, used_args: Sequence[int | str], args: Sequence[Any], kwargs: Mapping[str, Any]) -> None: ... + def check_unused_args(self, used_args: set[int | str], args: Sequence[Any], kwargs: Mapping[str, Any]) -> None: ... def format_field(self, value: Any, format_spec: str) -> Any: ... def convert_field(self, value: Any, conversion: str) -> Any: ... diff --git a/mypy/typeshed/stdlib/unicodedata.pyi b/mypy/typeshed/stdlib/unicodedata.pyi index 5a9aa0a3395f..4569d6584fd6 100644 --- a/mypy/typeshed/stdlib/unicodedata.pyi +++ b/mypy/typeshed/stdlib/unicodedata.pyi @@ -1,7 +1,7 @@ import sys from _typeshed import ReadOnlyBuffer from typing import Any, TypeVar -from typing_extensions import final +from typing_extensions import Literal, TypeAlias, final ucd_3_2_0: UCD unidata_version: str @@ -17,7 +17,10 @@ def combining(__chr: str) -> int: ... def decimal(__chr: str, __default: _T = ...) -> int | _T: ... def decomposition(__chr: str) -> str: ... def digit(__chr: str, __default: _T = ...) -> int | _T: ... -def east_asian_width(__chr: str) -> str: ... + +_EastAsianWidth: TypeAlias = Literal["F", "H", "W", "Na", "A", "N"] + +def east_asian_width(__chr: str) -> _EastAsianWidth: ... if sys.version_info >= (3, 8): def is_normalized(__form: str, __unistr: str) -> bool: ... @@ -38,7 +41,7 @@ class UCD: def decimal(self, __chr: str, __default: _T = ...) -> int | _T: ... def decomposition(self, __chr: str) -> str: ... def digit(self, __chr: str, __default: _T = ...) -> int | _T: ... - def east_asian_width(self, __chr: str) -> str: ... + def east_asian_width(self, __chr: str) -> _EastAsianWidth: ... if sys.version_info >= (3, 8): def is_normalized(self, __form: str, __unistr: str) -> bool: ... diff --git a/mypy/typeshed/stdlib/unittest/mock.pyi b/mypy/typeshed/stdlib/unittest/mock.pyi index 6c58f38a0d82..e4cedef1b425 100644 --- a/mypy/typeshed/stdlib/unittest/mock.pyi +++ b/mypy/typeshed/stdlib/unittest/mock.pyi @@ -82,7 +82,7 @@ class _Call(tuple[Any, ...]): def __eq__(self, other: object) -> bool: ... def __ne__(self, __other: object) -> bool: ... def __call__(self, *args: Any, **kwargs: Any) -> _Call: ... - def __getattr__(self, attr: Any) -> Any: ... + def __getattr__(self, attr: str) -> Any: ... def __getattribute__(self, attr: str) -> Any: ... if sys.version_info >= (3, 8): @property diff --git a/mypy/typeshed/stdlib/urllib/parse.pyi b/mypy/typeshed/stdlib/urllib/parse.pyi index 02e2774b3b8e..efb91a4b34ff 100644 --- a/mypy/typeshed/stdlib/urllib/parse.pyi +++ b/mypy/typeshed/stdlib/urllib/parse.pyi @@ -147,7 +147,7 @@ if sys.version_info >= (3, 9): else: def unquote(string: str, encoding: str = ..., errors: str = ...) -> str: ... -def unquote_to_bytes(string: str | bytes) -> bytes: ... +def unquote_to_bytes(string: str | bytes | bytearray) -> bytes: ... def unquote_plus(string: str, encoding: str = ..., errors: str = ...) -> str: ... @overload def urldefrag(url: str) -> DefragResult: ... @@ -168,11 +168,22 @@ def urljoin(base: AnyStr, url: AnyStr | None, allow_fragments: bool = ...) -> An @overload def urlparse(url: str, scheme: str | None = ..., allow_fragments: bool = ...) -> ParseResult: ... @overload -def urlparse(url: bytes | bytearray | None, scheme: bytes | None = ..., allow_fragments: bool = ...) -> ParseResultBytes: ... +def urlparse( + url: bytes | bytearray | None, scheme: bytes | bytearray | None = ..., allow_fragments: bool = ... +) -> ParseResultBytes: ... @overload def urlsplit(url: str, scheme: str | None = ..., allow_fragments: bool = ...) -> SplitResult: ... -@overload -def urlsplit(url: bytes | bytearray | None, scheme: bytes | None = ..., allow_fragments: bool = ...) -> SplitResultBytes: ... + +if sys.version_info >= (3, 11): + @overload + def urlsplit(url: bytes | None, scheme: bytes | None = ..., allow_fragments: bool = ...) -> SplitResultBytes: ... + +else: + @overload + def urlsplit( + url: bytes | bytearray | None, scheme: bytes | bytearray | None = ..., allow_fragments: bool = ... + ) -> SplitResultBytes: ... + @overload def urlunparse( components: tuple[AnyStr | None, AnyStr | None, AnyStr | None, AnyStr | None, AnyStr | None, AnyStr | None] diff --git a/mypy/typeshed/stdlib/urllib/request.pyi b/mypy/typeshed/stdlib/urllib/request.pyi index 3cd5fc740fca..00c160293762 100644 --- a/mypy/typeshed/stdlib/urllib/request.pyi +++ b/mypy/typeshed/stdlib/urllib/request.pyi @@ -1,6 +1,6 @@ import ssl import sys -from _typeshed import StrOrBytesPath, SupportsRead +from _typeshed import ReadableBuffer, StrOrBytesPath, SupportsRead from collections.abc import Callable, Iterable, Mapping, MutableMapping, Sequence from email.message import Message from http.client import HTTPConnection, HTTPMessage, HTTPResponse @@ -50,7 +50,7 @@ __all__ = [ _T = TypeVar("_T") _UrlopenRet: TypeAlias = Any -_DataType: TypeAlias = bytes | SupportsRead[bytes] | Iterable[bytes] | None +_DataType: TypeAlias = ReadableBuffer | SupportsRead[bytes] | Iterable[bytes] | None def urlopen( url: str | Request, @@ -214,7 +214,7 @@ class AbstractDigestAuthHandler: def get_cnonce(self, nonce: str) -> str: ... def get_authorization(self, req: Request, chal: Mapping[str, str]) -> str: ... def get_algorithm_impls(self, algorithm: str) -> tuple[Callable[[str], str], Callable[[str, str], str]]: ... - def get_entity_digest(self, data: bytes | None, chal: Mapping[str, str]) -> str | None: ... + def get_entity_digest(self, data: ReadableBuffer | None, chal: Mapping[str, str]) -> str | None: ... class HTTPDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): auth_header: ClassVar[str] # undocumented @@ -301,14 +301,14 @@ def urlcleanup() -> None: ... class URLopener: version: ClassVar[str] def __init__(self, proxies: dict[str, str] | None = ..., **x509: str) -> None: ... - def open(self, fullurl: str, data: bytes | None = ...) -> _UrlopenRet: ... - def open_unknown(self, fullurl: str, data: bytes | None = ...) -> _UrlopenRet: ... + def open(self, fullurl: str, data: ReadableBuffer | None = ...) -> _UrlopenRet: ... + def open_unknown(self, fullurl: str, data: ReadableBuffer | None = ...) -> _UrlopenRet: ... def retrieve( self, url: str, filename: str | None = ..., reporthook: Callable[[int, int, int], object] | None = ..., - data: bytes | None = ..., + data: ReadableBuffer | None = ..., ) -> tuple[str, Message | None]: ... def addheader(self, *args: tuple[str, str]) -> None: ... # undocumented def cleanup(self) -> None: ... # undocumented @@ -319,32 +319,32 @@ class URLopener: def http_error_default( self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage ) -> _UrlopenRet: ... # undocumented - def open_data(self, url: str, data: bytes | None = ...) -> addinfourl: ... # undocumented + def open_data(self, url: str, data: ReadableBuffer | None = ...) -> addinfourl: ... # undocumented def open_file(self, url: str) -> addinfourl: ... # undocumented def open_ftp(self, url: str) -> addinfourl: ... # undocumented - def open_http(self, url: str, data: bytes | None = ...) -> _UrlopenRet: ... # undocumented - def open_https(self, url: str, data: bytes | None = ...) -> _UrlopenRet: ... # undocumented + def open_http(self, url: str, data: ReadableBuffer | None = ...) -> _UrlopenRet: ... # undocumented + def open_https(self, url: str, data: ReadableBuffer | None = ...) -> _UrlopenRet: ... # undocumented def open_local_file(self, url: str) -> addinfourl: ... # undocumented - def open_unknown_proxy(self, proxy: str, fullurl: str, data: bytes | None = ...) -> None: ... # undocumented + def open_unknown_proxy(self, proxy: str, fullurl: str, data: ReadableBuffer | None = ...) -> None: ... # undocumented class FancyURLopener(URLopener): def prompt_user_passwd(self, host: str, realm: str) -> tuple[str, str]: ... def get_user_passwd(self, host: str, realm: str, clear_cache: int = ...) -> tuple[str, str]: ... # undocumented def http_error_301( - self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: bytes | None = ... + self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: ReadableBuffer | None = ... ) -> _UrlopenRet | addinfourl | None: ... # undocumented def http_error_302( - self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: bytes | None = ... + self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: ReadableBuffer | None = ... ) -> _UrlopenRet | addinfourl | None: ... # undocumented def http_error_303( - self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: bytes | None = ... + self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: ReadableBuffer | None = ... ) -> _UrlopenRet | addinfourl | None: ... # undocumented def http_error_307( - self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: bytes | None = ... + self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: ReadableBuffer | None = ... ) -> _UrlopenRet | addinfourl | None: ... # undocumented if sys.version_info >= (3, 11): def http_error_308( - self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: bytes | None = ... + self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: ReadableBuffer | None = ... ) -> _UrlopenRet | addinfourl | None: ... # undocumented def http_error_401( @@ -354,7 +354,7 @@ class FancyURLopener(URLopener): errcode: int, errmsg: str, headers: HTTPMessage, - data: bytes | None = ..., + data: ReadableBuffer | None = ..., retry: bool = ..., ) -> _UrlopenRet | None: ... # undocumented def http_error_407( @@ -364,20 +364,24 @@ class FancyURLopener(URLopener): errcode: int, errmsg: str, headers: HTTPMessage, - data: bytes | None = ..., + data: ReadableBuffer | None = ..., retry: bool = ..., ) -> _UrlopenRet | None: ... # undocumented def http_error_default( self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage ) -> addinfourl: ... # undocumented def redirect_internal( - self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: bytes | None + self, url: str, fp: IO[bytes], errcode: int, errmsg: str, headers: HTTPMessage, data: ReadableBuffer | None + ) -> _UrlopenRet | None: ... # undocumented + def retry_http_basic_auth( + self, url: str, realm: str, data: ReadableBuffer | None = ... + ) -> _UrlopenRet | None: ... # undocumented + def retry_https_basic_auth( + self, url: str, realm: str, data: ReadableBuffer | None = ... ) -> _UrlopenRet | None: ... # undocumented - def retry_http_basic_auth(self, url: str, realm: str, data: bytes | None = ...) -> _UrlopenRet | None: ... # undocumented - def retry_https_basic_auth(self, url: str, realm: str, data: bytes | None = ...) -> _UrlopenRet | None: ... # undocumented def retry_proxy_http_basic_auth( - self, url: str, realm: str, data: bytes | None = ... + self, url: str, realm: str, data: ReadableBuffer | None = ... ) -> _UrlopenRet | None: ... # undocumented def retry_proxy_https_basic_auth( - self, url: str, realm: str, data: bytes | None = ... + self, url: str, realm: str, data: ReadableBuffer | None = ... ) -> _UrlopenRet | None: ... # undocumented diff --git a/mypy/typeshed/stdlib/xmlrpc/client.pyi b/mypy/typeshed/stdlib/xmlrpc/client.pyi index 150291009f54..0e048f57844d 100644 --- a/mypy/typeshed/stdlib/xmlrpc/client.pyi +++ b/mypy/typeshed/stdlib/xmlrpc/client.pyi @@ -2,7 +2,7 @@ import gzip import http.client import sys import time -from _typeshed import Self, SupportsRead, SupportsWrite +from _typeshed import ReadableBuffer, Self, SupportsRead, SupportsWrite, _BufferWithLen from collections.abc import Callable, Iterable, Mapping from datetime import datetime from io import BytesIO @@ -15,7 +15,20 @@ class _SupportsTimeTuple(Protocol): _DateTimeComparable: TypeAlias = DateTime | datetime | str | _SupportsTimeTuple _Marshallable: TypeAlias = ( - bool | int | float | str | bytes | None | tuple[Any, ...] | list[Any] | dict[Any, Any] | datetime | DateTime | Binary + bool + | int + | float + | str + | bytes + | bytearray + | None + | tuple[_Marshallable, ...] + # Ideally we'd use _Marshallable for list and dict, but invariance makes that impractical + | list[Any] + | dict[str, Any] + | datetime + | DateTime + | Binary ) _XMLDate: TypeAlias = int | datetime | tuple[int, ...] | time.struct_time _HostType: TypeAlias = Union[tuple[str, dict[str, str]], str] @@ -83,18 +96,18 @@ def _datetime_type(data: str) -> datetime: ... # undocumented class Binary: data: bytes - def __init__(self, data: bytes | None = ...) -> None: ... - def decode(self, data: bytes) -> None: ... + def __init__(self, data: bytes | bytearray | None = ...) -> None: ... + def decode(self, data: ReadableBuffer) -> None: ... def encode(self, out: SupportsWrite[str]) -> None: ... def __eq__(self, other: object) -> bool: ... -def _binary(data: bytes) -> Binary: ... # undocumented +def _binary(data: ReadableBuffer) -> Binary: ... # undocumented WRAPPERS: tuple[type[DateTime], type[Binary]] # undocumented class ExpatParser: # undocumented def __init__(self, target: Unmarshaller) -> None: ... - def feed(self, data: str | bytes) -> None: ... + def feed(self, data: str | ReadableBuffer) -> None: ... def close(self) -> None: ... _WriteCallback: TypeAlias = Callable[[str], object] @@ -115,7 +128,7 @@ class Marshaller: def dump_int(self, value: int, write: _WriteCallback) -> None: ... def dump_double(self, value: float, write: _WriteCallback) -> None: ... def dump_unicode(self, value: str, write: _WriteCallback, escape: Callable[[str], str] = ...) -> None: ... - def dump_bytes(self, value: bytes, write: _WriteCallback) -> None: ... + def dump_bytes(self, value: ReadableBuffer, write: _WriteCallback) -> None: ... def dump_array(self, value: Iterable[_Marshallable], write: _WriteCallback) -> None: ... def dump_struct( self, value: Mapping[str, _Marshallable], write: _WriteCallback, escape: Callable[[str], str] = ... @@ -196,13 +209,13 @@ def dumps( allow_none: bool = ..., ) -> str: ... def loads(data: str, use_datetime: bool = ..., use_builtin_types: bool = ...) -> tuple[tuple[_Marshallable, ...], str | None]: ... -def gzip_encode(data: bytes) -> bytes: ... # undocumented -def gzip_decode(data: bytes, max_decode: int = ...) -> bytes: ... # undocumented +def gzip_encode(data: ReadableBuffer) -> bytes: ... # undocumented +def gzip_decode(data: ReadableBuffer, max_decode: int = ...) -> bytes: ... # undocumented class GzipDecodedResponse(gzip.GzipFile): # undocumented io: BytesIO - def __init__(self, response: SupportsRead[bytes]) -> None: ... + def __init__(self, response: SupportsRead[ReadableBuffer]) -> None: ... class _Method: # undocumented @@ -231,17 +244,21 @@ class Transport: else: def __init__(self, use_datetime: bool = ..., use_builtin_types: bool = ...) -> None: ... - def request(self, host: _HostType, handler: str, request_body: bytes, verbose: bool = ...) -> tuple[_Marshallable, ...]: ... + def request( + self, host: _HostType, handler: str, request_body: _BufferWithLen, verbose: bool = ... + ) -> tuple[_Marshallable, ...]: ... def single_request( - self, host: _HostType, handler: str, request_body: bytes, verbose: bool = ... + self, host: _HostType, handler: str, request_body: _BufferWithLen, verbose: bool = ... ) -> tuple[_Marshallable, ...]: ... def getparser(self) -> tuple[ExpatParser, Unmarshaller]: ... def get_host_info(self, host: _HostType) -> tuple[str, list[tuple[str, str]], dict[str, str]]: ... def make_connection(self, host: _HostType) -> http.client.HTTPConnection: ... def close(self) -> None: ... - def send_request(self, host: _HostType, handler: str, request_body: bytes, debug: bool) -> http.client.HTTPConnection: ... + def send_request( + self, host: _HostType, handler: str, request_body: _BufferWithLen, debug: bool + ) -> http.client.HTTPConnection: ... def send_headers(self, connection: http.client.HTTPConnection, headers: list[tuple[str, str]]) -> None: ... - def send_content(self, connection: http.client.HTTPConnection, request_body: bytes) -> None: ... + def send_content(self, connection: http.client.HTTPConnection, request_body: _BufferWithLen) -> None: ... def parse_response(self, response: http.client.HTTPResponse) -> tuple[_Marshallable, ...]: ... class SafeTransport(Transport): diff --git a/mypy/typeshed/stdlib/xmlrpc/server.pyi b/mypy/typeshed/stdlib/xmlrpc/server.pyi index c11d8d8e7a14..4d28974cbbed 100644 --- a/mypy/typeshed/stdlib/xmlrpc/server.pyi +++ b/mypy/typeshed/stdlib/xmlrpc/server.pyi @@ -2,14 +2,10 @@ import http.server import pydoc import socketserver from collections.abc import Callable, Iterable, Mapping -from datetime import datetime from re import Pattern from typing import Any, ClassVar, Protocol from typing_extensions import TypeAlias -from xmlrpc.client import Fault - -# TODO: Recursive type on tuple, list, dict -_Marshallable: TypeAlias = None | bool | int | float | str | bytes | tuple[Any, ...] | list[Any] | dict[Any, Any] | datetime +from xmlrpc.client import Fault, _Marshallable # The dispatch accepts anywhere from 0 to N arguments, no easy way to allow this in mypy class _DispatchArity0(Protocol):