I have a trivial dataclass (from pydantic)
from pydantic.dataclasses import dataclass
from abc import ABCMeta
from abc import abstractmethod
from pydantic.dataclasses import dataclass
@dataclass
class BaseEntity(metaclass=ABCMeta):
@classmethod
@abstractmethod
def from_dict(cls, other: dict):
...
@abstractmethod
def dict(self):
...
@dataclass
class UserEntity(BaseEntity):
id: Optional[str]
name: str
email: str
avatar: str
@classmethod
def from_dict(cls, other: dict):
return cls(
id=other.get("id"),
name=other.get("name"),
email=other.get("email"),
avatar=other.get("avatar"),
)
When I run mypy, I get this set of errors:
app/entities/user.py:25: error: Unexpected keyword argument "id" for "UserEntity" [call-arg]
app/entities/user.py:25: error: Unexpected keyword argument "name" for "UserEntity" [call-arg]
app/entities/user.py:25: error: Unexpected keyword argument "email" for "UserEntity" [call-arg]
app/entities/user.py:25: error: Unexpected keyword argument "avatar" for "UserEntity" [call-arg]
What I’m doing wrong? The code is fine; it runs. Or is it a mypy bug?
$ mypy --version
mypy 1.0.0 (compiled: yes)
EDIT: MRE https://github.com/skhaz/fastapi-restful
>Solution :
The same code with the standard library dataclasses
module is fine.
The problem is that given the class definition alone, there is no indication that UserEntity.__init__
will accept any arguments, positional or keyword, because the only statically defined __init__
for mypy
to check against is object.__init__
.
However, mypy
is coded to know about dataclasses
from the standard library, and in particular what to expect from the decorator dataclasses.dataclass
, so that it can recognize that there will be an __init__
method that has id
, name
, etc. as parameters.
This special treatment does not apply to pydantic.dataclasses
, however.