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.