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
?
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)