键入提示 @asynccontextmanager 的 return 值的正确方法是什么?

What is the proper way to type hint the return value of an @asynccontextmanager?

使用 @asynccontextmanager 装饰器为函数的 return 添加类型提示的正确方法是什么?这是我做过的两次尝试,但都失败了。

from contextlib import asynccontextmanager
from typing import AsyncContextManager


async def caller():
    async with return_str() as i:
        print(i)

    async with return_AsyncContextManager() as j:
        print(j)


@asynccontextmanager
async def return_str() -> str:
    yield "hello"


@asynccontextmanager
async def return_AsyncContextManager() -> AsyncContextManager[str]:
    yield "world"

对于 ij vscode 中的 Pylance 显示类型 Any。我考虑过的其他想法:

这是我悬停在 return_AsyncContextManager() 函数上的屏幕截图,并显示 Pylance 弹出窗口说它 returns AsyncContextManager[_T]

您必须将 AsyncIterator 提示为 return 类型,如下所示:

@asynccontextmanager
async def my_acm() -> AsyncIterator[str]:
    yield "this works"


async def caller():
    async with my_acm() as val:
        print(val)

这是因为 yield 关键字用于创建生成器。考虑:

def a_number_generator():
    for x in range(10):  # type: int
        yield x

g = a_number_generator() # g is type Generator[int]

考虑到 type hints for @asynccontextgenerator:
,这是有道理的 asynccontextmanager(func: Callable[..., AsyncIterator[_T]]) -> Callable[..., AsyncContextManager[_T]]

需要解析的内容很多,但它表示 asynccontextgenerator 接受一个 returns AsyncIterator 的函数并将其转换为 returns AsyncContextManager 通用类型 _T 也被保留。

这是一个屏幕截图,显示类型提示转移到调用函数中。