diff --git a/mypy/checker.py b/mypy/checker.py index 5ed1c792778b..2a9fdcb375ac 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -4592,7 +4592,10 @@ def analyze_iterable_item_type(self, expr: Expression) -> tuple[Type, Type]: if int_type: return iterator, int_type - if isinstance(iterable, TupleType): + if ( + isinstance(iterable, TupleType) + and iterable.partial_fallback.type.fullname == "builtins.tuple" + ): joined: Type = UninhabitedType() for item in iterable.items: joined = join_types(joined, item) diff --git a/test-data/unit/check-plugin-attrs.test b/test-data/unit/check-plugin-attrs.test index 3d1e2d730af8..5a64d4aadef8 100644 --- a/test-data/unit/check-plugin-attrs.test +++ b/test-data/unit/check-plugin-attrs.test @@ -1570,6 +1570,9 @@ reveal_type(f(A)[0]) # N: Revealed type is "attr.Attribute[builtins.int]" reveal_type(f(A).b) # N: Revealed type is "attr.Attribute[builtins.int]" f(A).x # E: "____main___A_AttrsAttributes__" has no attribute "x" +for ff in f(A): + reveal_type(ff) # N: Revealed type is "attr.Attribute[Any]" + [builtins fixtures/plugin_attrs.pyi] [case testAttrsGenericFields] diff --git a/test-data/unit/fixtures/plugin_attrs.pyi b/test-data/unit/fixtures/plugin_attrs.pyi index f62104809e74..57e5ecd1b2bc 100644 --- a/test-data/unit/fixtures/plugin_attrs.pyi +++ b/test-data/unit/fixtures/plugin_attrs.pyi @@ -1,5 +1,5 @@ # Builtins stub used to support attrs plugin tests. -from typing import Union, overload +from typing import Union, overload, Generic, Sequence, TypeVar, Type, Iterable, Iterator class object: def __init__(self) -> None: pass @@ -24,6 +24,13 @@ class complex: class str: pass class ellipsis: pass -class tuple: pass class list: pass class dict: pass + +T = TypeVar("T") +Tco = TypeVar('Tco', covariant=True) +class tuple(Sequence[Tco], Generic[Tco]): + def __new__(cls: Type[T], iterable: Iterable[Tco] = ...) -> T: ... + def __iter__(self) -> Iterator[Tco]: pass + def __contains__(self, item: object) -> bool: pass + def __getitem__(self, x: int) -> Tco: pass