Issue
Below are two functions with different typing. Code runs as expected. PyCharm and mypy shows no warnings or errors also.
But VS Code shows alert on gen1() function:
Return type of async generator function must be "AsyncGenerator" or "AsyncIterable" Pylance (reportGeneralTypeIssues)
So the questions are:
- is "Optional" typing redundant in gen1() definition? (I believe it is as there is no way to receive anything except AsyncGenerator as return value)
- is there problem in Pylance in VS Code with async typing ?
Code discussed:
import asyncio
from typing import AsyncGenerator, Optional
async def gen1() -> Optional[AsyncGenerator[str, None]]:
while True:
return
yield "t"
async def gen2() -> AsyncGenerator[str, None]:
while True:
return
yield "t"
async def main():
print(f"{type(gen1())=}")
print(f"{type(gen2())=}")
async for d in gen1():
print(d)
asyncio.run(main())
BTW, typing like in gen1 is used in some popular packages. Pyrogram example: https://github.com/pyrogram/pyrogram/blob/master/pyrogram/methods/chats/get_chat_members.py
async def get_chat_members(
self: "pyrogram.Client",
chat_id: Union[int, str],
query: str = "",
limit: int = 0,
filter: "enums.ChatMembersFilter" = enums.ChatMembersFilter.SEARCH
) -> Optional[AsyncGenerator["types.ChatMember", None]]:
Solution
You can safely remove Optional
from that code:
What does return an AsyncGenerator in this case is not any code you write: from the point the function is defined as async
and have a yield
in its body, the Python language itself will make it an Async Generator Function
which sole possible return type, hardcoded in the language, is an AsyncGenerator - regardless of how the code is organized, or what will actually be executed when the code in the def
block is actually run.
It indicates that the function is suitable to be used in an async for
statement - or manually driven with anext
and/or send
, throw
. Python itself will never return None
when the function is called: instead the shortcircuit to the empty return
only indicates the generator itself will be empty when iterated. As far as I know, there is no existing typing markup to indicate that a generator will be empty.
That would also be irrelevant as far as annotations are concerned, but for the fact that a Generator that would be marked as "will always be empty" could safely be thrown away without one trying to iterate over it: checking this kind of logic is beyond what static type annotation have to do (although some checkers are nice and do that - this is in the same category of "unused variable").
Answered By - jsbueno
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.