# file test.py
import asyncio
from inspect import iscoroutine
from typing import Any
async def a():
print('run a')
asyncio.sleep(1)
return 1
async def b():
# type: () -> Any
print('run b')
return a()
async def g():
# type: () -> Any
print('run g')
s = b()
while iscoroutine(s):
print('in g', s)
s = await s
return s
if __name__ == '__main__':
loop = asyncio.get_event_loop()
a = loop.run_until_complete(g())
print('finish ', a)
使用python3.6.6运行上述代码时,我得到了:
run g
in g <coroutine object b at 0x10a980938>
run b
in g <coroutine object a at 0x10a95d620>
run a
finish 1
Process finished with exit code 0
似乎一切都很好。但是运行mypy test.py
时,我得到了test.py:24: error: invalid syntax
。这是什么意思?
我的代码有问题吗?
我的python解释器版本为3.6.6,mypy版本为0.620。
答案 0 :(得分:2)
嗯,这很奇怪!
我认为这是typed_ast
中的一个错误,mypy库用于将Python源代码转换为抽象语法树。
我能够将您的问题简化为以下内容:
import asyncio
async def g():
# type: () -> None
await asyncio.sleep(1)
这还会在包含“ await”的行上出现语法错误。
但是,如果执行此操作,错误消息就会消失:
import asyncio
async def g() -> None:
await asyncio.sleep(1)
相同的解决方法(使用类型提示语法而不是注释语法也可以解决原始程序的问题)。似乎由于某种原因,基于注释的类型签名语法和'await'关键字不能很好地交互。
我怀疑这个问题没有早发现的原因是因为大多数使用异步/等待的人也在使用Python 3的内置注释语法-类型注释语法通常在您希望与Python兼容时使用2,但async / await仅适用于Python 3 ...
无论如何,我建议在mypy或typed_ast的问题跟踪器上提交问题-mypy团队监视并维护这两个存储库。 (或者,如果您愿意并且有一些空闲时间,甚至可以尝试自己解决typed_ast
中的问题?这感觉上像是一个疏忽,对我来说是一个棘手的错误。)