mypy v0.910 rejects abstract dataclasses in Python 3.9. Here's the Minimal Reproducible Example:
from abc import ABC, abstractmethod
from dataclasses import dataclass
@dataclass
class Liquid(ABC):
@abstractmethod
def drip(self) -> None:
pass
Here's the error message:
$ 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)
How do I get this code to pass mypy?
Notes
I gather from mypy issue #5374 that this is a bug in mypy, first noticed in 2018 and still not corrected. I figure that people must be using mypy with abstract dataclasses, though, so there must be a workaround or a correct way to define or annotate the class. What is recommended?
The basis for the error message seems to be that mypy assumes that any object of type Type can be instantiated, but abstract classes cannot be instantiated. This appears to be the error since Type is defined to mean a class object, not necessarily a concrete class object (i.e. one that can be instantiated).
Adding # type: ignore to the line containing class Liquid does not block the error message. Since the code does not contain Type[Liquid], I figure it must be in the code generated by dataclass. Type is deprecated in Python 3.9, but apparently the dataclass code generator still generates it.
Create a dataclass as a mixin and let the ABC inherit from it:
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
This works with mypy type checking as well. I recommend against using # type: ignore as that defeats the point of type-checking. Taken from this GitHub issue.
Add # type: ignore to the decorator line. So in your case it would be:
from abc import ABC, abstractmethod
from dataclasses import dataclass
@dataclass # type: ignore[misc]
class Liquid(ABC):
@abstractmethod
def drip(self) -> None:
pass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With