I am developing a Python3.8 project with usage of typing
and dataclasses
, and automatic tests include mypy
. This brings me in a strange behavior that I do not really understand...
In short: Mypy seems not to understand dataclass
attributes mechanics that, to my understanding, make them instance attributes.
Here's a minimal example, with a package and two modules:
__init__.py
: voidapp_events.py
:
class AppEvent:
pass
main.py
:
import dataclasses
import typing
from . import app_events
class B:
"""Class with *app_events* as instance attribute."""
def __init__(self):
self.app_events: typing.List[app_events.AppEvent] = []
def bar(self) -> app_events.AppEvent:
# no mypy complaint here: the import is correctly distinguished
# from the attribute
...
class C:
"""Class with *app_events* as class attribute."""
app_events: List[app_events.AppEvent]
def chew(self) -> app_events.AppEvent:
# mypy considers app_events to be the class attribute
...
@dataclasses.dataclass
class D:
app_events: typing.List[app_events.AppEvent] = \
dataclasses.field(default_factory=list)
def doo(self) -> app_events.AppEvent:
# same here: mypy considers app_events to be the class attribute
...
And the typecheck result:
- PyCharm complains, for methods
C.chew
andD.doo
:Unresolved attribute reference 'AppEvent' for class 'list'
mypy
complains, still for methodsC.chew
andD.doo
, thaterror: Name 'app_events.AppEvent' is not defined
.
No issue for B.bar
as written, though if app_events
attribute is declared as a class attribute (instead of being defined in self.__init__
, then mypy
raise the same complaint.)
-> any idea how to understand/solve/circumvent this elegantly?
I'd really like not to rename my module and attributes, but if you have nice names in mind, please do not hesitate to propose :-)