microsoft / pylance-release

Documentation and issues for Pylance
Creative Commons Attribution 4.0 International
1.71k stars 765 forks source link

Async functions without yields which return async iterables have wrong signature #1140

Closed audoh-tickitto closed 3 years ago

audoh-tickitto commented 3 years ago

Environment data

Expected behaviour

Non-generator (no yield) async functions which return async iterables, generators etc should have a return type of Coroutine[Any, Any, AsyncIterable] (replace AsyncIterable with AsyncGenerator or other relevant type)

Actual behaviour

Non-generator (no yield) async functions which return async iterables, generators etc have a return type of AsyncIterable (replace AsyncIterable with AsyncGenerator or other relevant type)

Logs

Code Snippet / Additional information

import asyncio
from typing import AsyncGenerator, AsyncIterable, List

async def get_data() -> List[int]:
    await asyncio.sleep(1)
    return [1, 2, 3]

async def generate(nums: List[int]) -> AsyncGenerator[str, None]:
    for n in nums:
        await asyncio.sleep(1)
        yield f"The number is {n}"

async def get_generator() -> AsyncGenerator[str, None]:
    data = await get_data()
    return generate(data)

async def demo_bug() -> None:
    gen = await get_generator()  # Pylance: "AsyncGenerator[str, None]" is not awaitable
    async for s in gen:
        print(s)

loop = asyncio.get_event_loop()
loop.run_until_complete(demo_bug())

When run in Python, the expected output is produced:

The number is 1
The number is 2
The number is 3
erictraut commented 3 years ago

Thanks for the bug report. Pylance wasn't correctly handling the case where an async method had a declared return type of AsyncGenerator but was not itself a generator (i.e. had no yield statement). In that case, the effective return type of the method needs to be wrapped in a Coroutine type.

erictraut commented 3 years ago

This will be fixed in the next release of Pylance.

jakebailey commented 3 years ago

This issue has been fixed in version 2021.4.1, which we've just released. You can find the changelog here: https://github.com/microsoft/pylance-release/blob/main/CHANGELOG.md#202141-14-april-2021