英文:
mypy complains about classmethod
问题
我有一个简单的数据类(来自pydantic)
```python
from pydantic.dataclasses import dataclass
from abc import ABCMeta
from abc import abstractmethod
@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"),
)
当我运行mypy时,我得到了一系列的错误:
>app/entities/user.py:25: error: 意外的关键字参数"id",用于"UserEntity" [call-arg]
>app/entities/user.py:25: error: 意外的关键字参数"name",用于"UserEntity" [call-arg]
>app/entities/user.py:25: error: 意外的关键字参数"email",用于"UserEntity" [call-arg]
>app/entities/user.py:25: error: 意外的关键字参数"avatar",用于"UserEntity" [call-arg]
我做错了什么?代码是正确的;它可以运行。还是这是一个mypy的bug?
$ mypy --version
mypy 1.0.0 (compiled: yes)
英文:
I have a trivial dataclass (from pydantic)
from pydantic.dataclasses import dataclass
from abc import ABCMeta
from abc import abstractmethod
@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)
答案1
得分: 2
相同的代码在标准库dataclasses
模块中是可以的。
问题在于,仅凭类定义本身,无法得知UserEntity.__init__
会接受任何参数,无论是位置参数还是关键字参数,因为唯一静态定义的__init__
是mypy
要检查的object.__init__
。
然而,mypy
被编写成了了解标准库中的dataclasses
,特别是知道从装饰器dataclasses.dataclass
可以预期会有一个__init__
方法,其中有id
、name
等参数。
然而,这种特殊处理不适用于pydantic.dataclasses
。
英文:
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.
答案2
得分: 0
你缺少了构造函数 from_dict
应该调用的部分。
def __init__(self, id, name, email, avatar):
self.id = id
self.name = name
self.email = email
self.avatar = avatar
英文:
You're missing the constructor from_dict
is supposed to call.
def __init__(self, id, name, email, avatar):
self.id = id
self.name = name
self.email = email
self.avatar = avatar
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论