Closed ordinary-jamie closed 11 months ago
Issue: https://github.com/MagicStack/uvloop/issues/584
For PY311 the task factory will be called with the context kwarg. This is not correctly reflected in the typing for Loop.set_task_factory and Loop.get_task_factory.
PY311
Loop.set_task_factory
Loop.get_task_factory
This commit addresses this with a protocol. Since uvloop requires a minimum Python 3.8 version, in which typing.Protocol is available. Note, neither typing.Unpack for kwargs, (introduced in Python 3.11) or typing.ParmSpec with ParamSpec.kwargs (introduced in Python 3.10) is available for 3.8
uvloop
typing.Protocol
typing.Unpack
typing.ParmSpec
ParamSpec.kwargs
Did not explicitly type the context parameter and used **kwargs since the Loop method allows for the legacy API without a context param for <PY311
context
**kwargs
<PY311
Also see discussion about name parameter for task factory in asyncio: https://github.com/python/cpython/pull/112623#issuecomment-1837405443
name
Quick demonstration of typing (see mypy Callback Protocols)
# test.py import asyncio from typing import Any, Generator, Protocol, TypeVar _T = TypeVar("_T") class TaskFactoryCallable(Protocol): def __call__( self, loop: asyncio.AbstractEventLoop, coro: Generator[Any, None, _T], **kwargs ) -> asyncio.Future[_T]: ... def set_task_factory(factory: TaskFactoryCallable) -> None: ... def task_factory_valid( loop: asyncio.AbstractEventLoop, coro: Generator[Any, None, _T], **kwargs ) -> asyncio.Future[_T]: return asyncio.Future() def task_factory_invalid( loop: asyncio.AbstractEventLoop, coro: Generator[Any, None, _T] ) -> asyncio.Future[_T]: return asyncio.Future() # Passes mypy set_task_factory(task_factory_valid) # Fails mypy set_task_factory(task_factory_invalid)
mypy test.py # test.py:35: error: Argument 1 to "set_task_factory" has incompatible type "Callable[[AbstractEventLoop, Generator[Any, None, _T]], Future[_T]]"; expected "TaskFactoryCallable" [arg-type] # Found 1 error in 1 file (checked 1 source file)
Issue: https://github.com/MagicStack/uvloop/issues/584
For
PY311
the task factory will be called with the context kwarg. This is not correctly reflected in the typing forLoop.set_task_factory
andLoop.get_task_factory
.This commit addresses this with a protocol. Since
uvloop
requires a minimum Python 3.8 version, in whichtyping.Protocol
is available. Note, neithertyping.Unpack
for kwargs, (introduced in Python 3.11) ortyping.ParmSpec
withParamSpec.kwargs
(introduced in Python 3.10) is available for 3.8Did not explicitly type the
context
parameter and used**kwargs
since the Loop method allows for the legacy API without a context param for<PY311
Also see discussion about
name
parameter for task factory in asyncio: https://github.com/python/cpython/pull/112623#issuecomment-1837405443Quick demonstration of typing (see mypy Callback Protocols)