python-attrs / attrs

Python Classes Without Boilerplate
https://www.attrs.org/
MIT License
5.3k stars 374 forks source link

mypy infers `attrs.fields(type(attrs_instance))` as `Any` #1297

Closed injust closed 5 months ago

injust commented 5 months ago
import attrs
from attrs import define

@define
class Foo:
    bar: int

foo = Foo(1)

mypy infers attrs.fields(type(foo)) as Any

fields = attrs.fields(type(foo))
reveal_type(fields)
reveal_type(fields.bar)
reveal_type(fields.not_bar)

"""
demo.py:13: note: Revealed type is "Any"
demo.py:14: note: Revealed type is "Any"
demo.py:15: note: Revealed type is "Any"
Success: no issues found in 1 source file
"""

But mypy infers attrs.fields(Foo) just fine

other_fields = attrs.fields(Foo)
reveal_type(other_fields)
reveal_type(other_fields.bar)
reveal_type(other_fields.not_bar)

"""
demo.py:13: note: Revealed type is "tuple[attr.Attribute[builtins.int], fallback=demo.Foo.__demo_Foo_AttrsAttributes__]"
demo.py:14: note: Revealed type is "attr.Attribute[builtins.int]"
demo.py:15: error: "__demo_Foo_AttrsAttributes__" has no attribute "not_bar"  [attr-defined]
demo.py:15: note: Revealed type is "Any"
Found 1 error in 1 file (checked 1 source file)
"""

Is it possible to have mypy infer the type of attrs.fields(type(foo))?

Tinche commented 5 months ago

There's probably a difference between Foo and type(foo) - the latter can be any arbitrary subclass of Foo. I would reopen this over at the mypy tracker though; that's a better place for it.

Will close this here.