Skip to content

Is there a way annotate types based on class attributes? #4109

Closed
@leandropls

Description

@leandropls

Take this snippet, for example:

from typing import Iterable, Iterator, Type, TypeVar

T = TypeVar('T')

class GenericNumberIterable(Iterable[T]):
    itemtype: Type[T]

    def __iter__(self) -> Iterator[T]:
        itemtype = self.itemtype
        yield from (itemtype(x) for x in range(10))

class FloatIterable(GenericNumberIterable, Iterable[float]):
    itemtype = float

class IntIterable(GenericNumberIterable, Iterable[int]):
    itemtype = int

An attempt with this with mypy yields:

$ mypy scratch_21.py 
scratch_21.py:11: error: Too many arguments for "object"

And further attempts to have itemtype recognized as a placeholder for a class only generates other errors, for exemple:

from typing import Iterable, Iterator, Type, List


class GenericNumberIterable(Iterable[float]):
    itemtype: Type[float]

    def __iter__(self) -> Iterator[float]:
        itemtype = self.itemtype
        yield from (itemtype(x) for x in range(10))


class FloatIterable(GenericNumberIterable, Iterable[float]):
    itemtype = float


class IntIterable(GenericNumberIterable, Iterable[int]):
    itemtype = int

x: List[int] = list(IntIterable())

Leads mypy to return:

$ mypy scratch_21.py 
scratch_21.py:19: error: Argument 1 to "list" has incompatible type "IntIterable"; expected "Iterable[int]"

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions