Skip to content

[Attrs] Invalid typing of init arguments in subclasses of generics #5744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
galcik opened this issue Oct 5, 2018 · 3 comments · Fixed by #9383
Closed

[Attrs] Invalid typing of init arguments in subclasses of generics #5744

galcik opened this issue Oct 5, 2018 · 3 comments · Fixed by #9383
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-attrs

Comments

@galcik
Copy link

galcik commented Oct 5, 2018

from typing import Generic, List, TypeVar
import attr

T_BASE_ITEM = TypeVar("T_BASE_ITEM", bound="BaseItem")


class BaseItem(object):
    pass


class ConcreteItem(BaseItem):
    pass


@attr.s
class Container(Generic[T_BASE_ITEM]):
    items = attr.ib(type=List[T_BASE_ITEM], factory=list)


@attr.s
class ConcreteContainer(Container[ConcreteItem]):
    pass


container1 = ConcreteContainer()
container1.items.append(ConcreteItem())
container1.items.extend([ConcreteItem()])
container1.items = [ConcreteItem()]

container2 = ConcreteContainer(items=[ConcreteItem()])

fails ONLY on the last line:

List item 0 has incompatible type "ConcreteItem"; expected "T_BASE_ITEM"

It seems that typing for the attribute items works as expected. However, if items is used as a keyword argument of the __init__ generated by attrs, typing fails.

Note also that if the following class is added:

@attr.s
class ItemWrapper(Generic[T_BASE_ITEM]):
    item = attr.ib(type=T_BASE_ITEM)

mypy fails with error:

'T_BASE_ITEM' is a type variable and only valid in type context
@ilevkivskyi
Copy link
Member

Yes, this is clearly a bug. The cause is that __init__ is generated for every subclass that is an attrs class. When __init__ (or any other attribute) is accessed on a superclass of a normal class, mypy takes care to map_instance_to_supertype/expand_type_by_instance, while the plugin doesn't do this.

@euresti will you have time to work on this?

@ilevkivskyi ilevkivskyi added bug mypy got something wrong priority-1-normal topic-attrs false-positive mypy gave an error on correct code labels Oct 8, 2018
@ilevkivskyi
Copy link
Member

Btw, most likely dataclasses have the same problem.

@natemcmaster
Copy link
Contributor

Thanks for the tip about map_instance_to_supertype. I have proposed a fix in #9383 which uses that API to resolve typevars.

hauntsaninja pushed a commit that referenced this issue Nov 28, 2020
Fixes #5744

Updates the attrs plugin. Instead of directly copying attribute type along the MRO, this first resolves typevar in the context of the subtype.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong false-positive mypy gave an error on correct code priority-1-normal topic-attrs
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants