如何在Python 3.7中注释异步函数的装饰器类型?

问题描述 投票:0回答:1

我想为异步函数编写一个装饰器。 如何注释装饰器定义的类型?

这是我想做的一个例子:

from typing import TypeVar # will Awaitable help?
AsyncFn = TypeVar('AsyncFn') # how to narrow this type definition down to async functions?

def my_decorator(to_decorate: AsyncFn) -> AsyncFn:
    async def decorated(*args, **kwargs): # mypy keeps saying "Function is missing a type"
       return await to_decorate(*args, **kwargs)

@my_decorator
async def foo(bar: int) -> str:
    return f"async: {bar}"

@my_decorator
async def quux(spam: str, **eggs: str) -> None:
    return

foo(1) # should check
foo("baz") # mypy should yell
quux("spam") # should check
quux(1) # mypy should complain
quux(spam="lovely", eggs="plentiful") # ok
quux(spam=1, eggs=0) # mypy should throw a fit
python python-asyncio python-typing mypy
1个回答
10
投票

async
函数是返回
Awaitable
的函数。

随着 Python 3.10 中引入

ParamSpec
async
函数的装饰器的完整类型注释是:

from typing import Awaitable, Callable, ParamSpec, TypeVar

T = TypeVar("T")
P = ParamSpec("P")


def decorator(fn: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]:
    async def decorated(*args: P.args, **kwargs: P.kwargs) -> T:
        return await fn(*args, **kwargs)

    return decorated

在 Python 3.7 中

ParamSpec
可以从 typing_extensions 导入。

© www.soinside.com 2019 - 2024. All rights reserved.