将 mypy 与等待一起使用

Posted

技术标签:

【中文标题】将 mypy 与等待一起使用【英文标题】:Using mypy with await 【发布时间】:2020-01-17 15:59:49 【问题描述】:

考虑以下使用asyncio/async/await的基本脚本:

import asyncio
from typing import List

async def foo(x) -> int:
    await asyncio.sleep(x / 2)
    return x

async def main() -> List[int]:
    return await asyncio.gather(*(foo(i) for i in (1, 2, 3)))

if __name__ == "__main__":
    print(asyncio.run(main()))

这个运行查找,打印[1, 2, 3]await asyncio.gather() 产生一个List[int]

然而,mypy 不喜欢这个文件;它提出:

mypytest.py:9: 错误:

赋值中不兼容的类型(表达式的类型为“Tuple[Any, ...]”,变量的类型为“List[int]”)

我假设这是因为 asyncio.gather() annotations 在排版中。

但是,从用户的角度来看,这仍然有点令人困惑。 我可以在这里做些什么不同的事情来让 mypy 开心?为什么会存在这种歧义?


对于它的价值,mypy 文档的 Typing async/await 部分对此没有太多说明。

【问题讨论】:

看起来像类型注释中的一个错误,尽管可能是故意使多个返回值看起来正常(因此您可以分解返回值)- List 不支持这样的类型参数。可能值得在 typeshed 上提出问题 【参考方案1】:

此差异已在向 typeshed 存储库提交 412b9e7 中得到解决,该存储库添加了最终的 @overload 以说明潜在的 List 结果。

【讨论】:

【参考方案2】:

要么用 # type: ignore 注释该行,要么再次转换为 list

return list(await asyncio.gather(*(foo(i) for i in (1, 2, 3))))

【讨论】:

我知道我可以将# type: ignore 扔到某物上并让它消失。那不回答为什么asyncio.gather()的注解和await asyncio.gather()的类型不一样 不太清楚你的问题是什么。我已经回答了我知道的答案,“我能做些什么来让 mypy 开心”

以上是关于将 mypy 与等待一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何将异步等待与 https 发布请求一起使用

将 HttpContext.Current.User 与异步等待一起使用的正确方法

是否可以将 Flask RestX 与 Flask 2.0+ 异步等待一起使用?

mypy 与 virtualenv

Spring 使用 Mypy 检查 30 万行代码,总结出 3 大痛点与 6 个技巧

Spring 使用 Mypy 检查 30 万行代码,总结出 3 大痛点与 6 个技巧