Skip to content

Support for async comprehensions is broken #2924

@gvanrossum

Description

@gvanrossum

Here's a simple example:

from typing import AsyncIterable

class bar(AsyncIterable[int]):
    def __aiter__(self):
        self.count = 3
        return self
    async def __anext__(self):
        self.count -= 1
        if self.count >= 0:
            return self.count
        raise StopAsyncIteration

async def foo() -> None:
    x = [i async for i in bar()]
    for i in x:
        print(i)

def main():
    a = foo()
    try:
        print(a.__await__().send(None))
    except StopIteration as e:
        print("stop with value =", e.value)

main()

When run with Python 3 this prints

2
1
0
stop with value = None

However when type-checked with mypy we get an error on the async comprehension in foo():

__tmp__.py:14: error: Iterable expected
__tmp__.py:14: error: "bar" has no attribute "__iter__"; maybe "__aiter__"?

(Note the irony in the error message. :-)

This makes me think that mypy doesn't check the async flag on the comprehension's AST node. If we replace foo() with

async def foo() -> None:
    async for i in bar():
        print(i)

the output is the same and mypy accepts it, strengthening my diagnosis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions