'What is the right way of annotating constructor of abstract class to make Mypy happy?
I have an abstract base class BsaeFoo that my dataclasses such as ChildFoo is inheriting from.
from abc import ABCMeta
from typing import Dict, Any, TypeVar, Type
from dataclasses import dataclass
Foo = TypeVar("Foo", bound="BaseFoo")
class BaseFoo(metaclass=ABCMeta):
@classmethod
def from_dict(cls: Type[Foo], data: Dict[str, Any]) -> Foo:
init_data = {key: data.get(key, None) for key in cls.__annotations__}
return cls(**init_data)
@dataclass
class ChildFoo(BaseFoo):
x: int
y: int
Running Mypy gives me
main.py:12: error: Too many arguments for "BaseFoo"
Found 1 error in 1 file (checked 1 source file)
from_dict would be an alternative constructor of the child dataclasses. It reads the input dict based on the cls.__annotations__ attribute, so it won't raise in the child classes. As for BaseFoo itself, it does not make sense to check initialization since it is an abstract class.
How do I make BaseFoo.from_dict pass Mypy without using # type: ignore ?
Solution 1:[1]
Add explicit definition of __init__ in BaseFoo
class BaseFoo(ABC):
def __init__(self, **kwargs: Any) -> None:
raise NotImplementedError
@classmethod
def from_dict(cls: type[Foo], data: Dict[str, Any]) -> Foo:
init_data = {key: data.get(key, None) for key in cls.__annotations__}
return cls(**init_data)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Paweł Rubin |
