Skip to content

generator-return-from-iter-method (PYI058)#

Derived from the flake8-pyi linter.

Fix is sometimes available.

What it does#

Checks for simple __iter__ methods that return Generator, and for simple __aiter__ methods that return AsyncGenerator.

Why is this bad?#

Using (Async)Iterator for these methods is simpler and more elegant. More importantly, it also reflects the fact that the precise kind of iterator returned from an __iter__ method is usually an implementation detail that could change at any time. Type annotations help define a contract for a function; implementation details should not leak into that contract.

For example:

from collections.abc import AsyncGenerator, Generator
from typing import Any


class CustomIterator:
    def __iter__(self) -> Generator:
        yield from range(42)


class CustomIterator2:
    def __iter__(self) -> Generator[str, Any, None]:
        yield from "abcdefg"

Use instead:

from collections.abc import Iterator


class CustomIterator:
    def __iter__(self) -> Iterator:
        yield from range(42)


class CustomIterator2:
    def __iter__(self) -> Iterator[str]:
        yield from "abdefg"

Fix safety#

This rule tries hard to avoid false-positive errors, and the rule's fix should always be safe for .pyi stub files. However, there is a slightly higher chance that a false positive might be emitted by this rule when applied to runtime Python (.py files). As such, the fix is marked as unsafe for any __iter__ or __aiter__ method in a .py file that has more than two statements (including docstrings) in its body.