异步函数的Python类型提示为函数参数

时间:2018-03-19 10:18:07

标签: python pycharm python-asyncio type-hinting

我正在尝试确保函数参数是异步函数。 所以我正在玩下面的代码:

async def test(*args, **kwargs):
    pass

def consumer(function_: Optional[Coroutine[Any, Any, Any]]=None):
    func = function_

consumer(test)

但它没有用。

在pyCharm中的类型检查期间,我遇到以下错误:

Expected type 'Optional[Coroutine]', got '(args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Coroutine[Any, Any, None]' instead

任何人都可以给我一些提示如何解决这个问题吗?

2 个答案:

答案 0 :(得分:0)

我不能为您提供太多帮助,尤其是因为现在(PyCharm 2018.2),Pycharm中不再出现此错误。

目前,类型提示介于可靠的元数据之间,以进行反射/自省和赞美的注释,这些注释可以接受用户输入的任何内容。对于普通数据结构来说,这很棒(我的同事甚至建立了基于类型的验证框架),但是当回调和异步函数起作用时,会变得更加复杂。

看看这些问题:

https://github.com/python/typing/issues/424(今天开始营业)-异步输入 https://github.com/python/mypy/issues/3028(今天开始开放)-可变参数可调用类型

我会选择:

from typing import Optional, Coroutine, Any, Callable


async def test(*args, **kwargs):
    return args, kwargs


def consumer(function_: Optional[Callable[..., Coroutine[Any, Any, Any]]] = None):
    func = function_
    return func


consumer(test)

我不保证它们的意思完全一样,但是我的提示是这样构建的:

Optional-在这种情况下,可以是None之类的东西

Callable-可以用()调用的东西,...代表任何参数,它产生:

Coroutine[Any, Any, Any]-这是从OP复制的,非常笼统。您建议此function_版本可以进行await编辑,但也可以接收send()版本的consumer编辑版本,并对其进行next()版本的访问或迭代。 。可能是这样,但是...

如果只是await版,那么最后一部分可能是:

Awaitable[Any],如果您实际上正在等待某事或

Awaitable[None],如果回调不返回任何内容,而您只希望它await

注意:您的consumer不是async。它不会真的await function_,而是yield from,或者loop.run_until_complete().create_task(),或者.ensure_future()

答案 1 :(得分:0)

您正在寻找:

FuncType = Callable[[Any, Any], Coroutine[Any]]
def consumer(function_: FuncType = None):

为什么这种类型的结构如此?如果您声明一个异步函数,则实际要做的是使用给定的参数将其包装到一个新的(和正常的)函数中,该函数返回一个Coroutine

由于这可能与某些来这里的人有关,因此下面是一个await可用函数类型的示例:

OnAction = Callable[[Foo, Bar], Awaitable[FooBar]]

该函数接受FooBar并返回FooBar