Repository navigation
Mypy errors out with attrs, generics and inheritance #15658
Description
Bug Report
When checking python code that uses attrs dataclasses, Generic classes and inheritance, mypy fails to infer the actual type of a TypeVar.
Swapping attrs for std dataclasses removes the error.
Simplifying inheritance chain also removes the error.
I suspect this might be an issue in the mypy-attr plugin.
To Reproduce
can't put a playground link since it doesn't support attrs sorry.
import abc
from typing import Generic, TypeVar
from attr import frozen
# define a hierarchy of State types
class BaseState(metaclass=abc.ABCMeta):
...
T_State = TypeVar("T_State", bound=BaseState, covariant=True)
@frozen()
class JumpState(BaseState):
start: int
# define a hierarchy of signals
@frozen()
class AbstractBaseSignal(metaclass=abc.ABCMeta):
pass
T_Signal = TypeVar("T_Signal", bound=AbstractBaseSignal)
@frozen()
class SignalA(Generic[T_State], AbstractBaseSignal, metaclass=abc.ABCMeta):
state: T_State
@frozen()
class SignalAA(SignalA[T_State], metaclass=abc.ABCMeta):
pass
# this signal specializes the generic type to a well defined JumpState type
class SignalAAA(SignalAA[JumpState]):
pass
def foo(s: SignalAAA) -> None:
reveal_type(s) # SignalAAA
reveal_type(s.state) # T_State instead of JumpState
reveal_type(s.state.start) # start is not found on T_Stateif you swap all the frozen decorators for dataclass it suddendly works, s.state is correctly inferred as a JumpState.
if you remove the class SignalAA and have SignalAAA inherit directly from SignalA (i.e. short-circuit the inheritance chain) it works correctly as well.
Expected Behavior
I would expect this code to typecheck, especially since it does with standard dataclasses. I suspect a problem with the mypy-attrs plugin.
Actual Behavior
mypy output on this example:
type_test.py:47: note: Revealed type is "type_test.SignalAAA"
type_test.py:49: note: Revealed type is "T_State`1"
type_test.py:50: error: "T_State" has no attribute "start" [attr-defined]
type_test.py:50: note: Revealed type is "Any"
Found 1 error in 1 file (checked 1 source file)
Your Environment
- Mypy version used: issue confirmed at least starting from 0.991 to latest version. It was working fine with version 0.910.
- Mypy command-line flags: None
- Mypy configuration options from
mypy.ini(and other config files):
[mypy]
python_version = 3.9
warn_unused_configs = True
warn_unused_ignores = True
warn_return_any = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
follow_imports = silent
ignore_missing_imports = True
- Python version used: 3.9
attrspackage version: 23.1.0 (bug reproduced in 22.1.0 as well)
The bug was observed first while updating our mypy version from 0.910 to 0.991.
Activity
ikonst commentedon Jul 18, 2023
Thanks for the version range.
git bisectpoints to 20b0b9b (merged in #12590) as to where it starts (@JukkaL for insights).ikonst commentedon Jul 18, 2023
FWIW, replacing
attr.frozenwithattrs.mutableorattrs.definealso "fixes" it 😕Fix inheriting from generic @Frozen attrs class (#15700)
LeBoucEtMistere commentedon Aug 12, 2023
Thanks for the quick fix, much appreciated ! Do you know when will the next mypy release come out so that I can upgrade on my end and fix my code ?