9

mypy v0.910 拒绝 Python 3.9 中的抽象数据类。这是最小的可重现示例:

from abc import ABC, abstractmethod
from dataclasses import dataclass

@dataclass
class Liquid(ABC):

    @abstractmethod
    def drip(self) -> None:
        pass

这是错误消息:

$ mypy --python-version 3.9 so.py
so.py:4: error: Only concrete class can be given where "Type[Liquid]" is expected
Found 1 error in 1 file (checked 1 source file)

如何让此代码通过mypy


笔记

我从mypy 问题 #5374中得知这是mypy中的一个错误,于 2018 年首次发现,但仍未得到纠正。不过,我认为人们必须将mypy与抽象数据类一起使用,因此必须有一种解决方法或正确的方法来定义或注释该类。推荐什么?

错误消息的基础似乎是mypy假设Type可以实例化任何类型的对象,但不能实例化抽象类。这似乎是错误,因为Type它被定义为一个类对象,不一定是一个具体的类对象(即可以实例化的对象)。

添加# type: ignore到包含的行class Liquid不会阻止错误消息。由于代码中不包含Type[Liquid],我想它一定是在生成的代码中dataclassType在 Python 3.9 中已弃用,但显然dataclass代码生成器仍会生成它。

4

2 回答 2

6

创建一个数据类作为 mixin 并让 ABC 类从它继承:

from abc import ABC, abstractmethod
from dataclasses import dataclass    

@dataclass
class LiquidDataclassMixin:
    my_var: str

class Liquid(ABC, LiquidDataclassMixin):
    @abstractmethod
    def drip(self) -> None:
        pass

这也适用于 mypy 类型检查。我建议不要使用# type: ignore,因为这会破坏类型检查的意义。取自这个 GitHub 问题

于 2021-09-27T09:56:53.343 回答
1

添加# type: ignore到装饰器行。因此,在您的情况下,它将是:

from abc import ABC, abstractmethod
from dataclasses import dataclass

@dataclass  # type: ignore
class Liquid(ABC):

    @abstractmethod
    def drip(self) -> None:
        pass
于 2021-09-27T09:53:25.303 回答