Skip to content

Commit 002502a

Browse files
authored
Fix inference for attrs.fields (#15688)
1 parent 710ad44 commit 002502a

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

mypy/checker.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -4632,7 +4632,10 @@ def analyze_iterable_item_type(self, expr: Expression) -> tuple[Type, Type]:
46324632
if int_type:
46334633
return iterator, int_type
46344634

4635-
if isinstance(iterable, TupleType):
4635+
if (
4636+
isinstance(iterable, TupleType)
4637+
and iterable.partial_fallback.type.fullname == "builtins.tuple"
4638+
):
46364639
joined: Type = UninhabitedType()
46374640
for item in iterable.items:
46384641
joined = join_types(joined, item)

test-data/unit/check-plugin-attrs.test

+3
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,9 @@ reveal_type(f(A)[0]) # N: Revealed type is "attr.Attribute[builtins.int]"
15681568
reveal_type(f(A).b) # N: Revealed type is "attr.Attribute[builtins.int]"
15691569
f(A).x # E: "____main___A_AttrsAttributes__" has no attribute "x"
15701570

1571+
for ff in f(A):
1572+
reveal_type(ff) # N: Revealed type is "attr.Attribute[Any]"
1573+
15711574
[builtins fixtures/plugin_attrs.pyi]
15721575

15731576
[case testAttrsGenericFields]

test-data/unit/fixtures/plugin_attrs.pyi

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Builtins stub used to support attrs plugin tests.
2-
from typing import Union, overload
2+
from typing import Union, overload, Generic, Sequence, TypeVar, Type, Iterable, Iterator
33

44
class object:
55
def __init__(self) -> None: pass
@@ -24,6 +24,13 @@ class complex:
2424

2525
class str: pass
2626
class ellipsis: pass
27-
class tuple: pass
2827
class list: pass
2928
class dict: pass
29+
30+
T = TypeVar("T")
31+
Tco = TypeVar('Tco', covariant=True)
32+
class tuple(Sequence[Tco], Generic[Tco]):
33+
def __new__(cls: Type[T], iterable: Iterable[Tco] = ...) -> T: ...
34+
def __iter__(self) -> Iterator[Tco]: pass
35+
def __contains__(self, item: object) -> bool: pass
36+
def __getitem__(self, x: int) -> Tco: pass

0 commit comments

Comments
 (0)