I’m trying to use pydantic
together with ABC
. I created a base class Datasource
and four subclasses:
from pydantic import BaseModel
from typing import Literal, Union, TypeVar
from devtools import debug
from abc import ABC, abstractmethod
class Datasource(ABC, BaseModel):
source: str
frequency: str
@abstractmethod
def hello():
pass
class FirstStaticDatasource(Datasource):
source: Literal["first"] = "first"
frequency: Literal["static"] = "static"
a: int
def hello():
pass
class FirstDynamicDatasource(Datasource):
source: Literal["first"] = "first"
frequency: Literal["daily"] = "daily"
b: int
def hello():
pass
class SecondStaticDatasource(Datasource):
source: Literal["second"] = "second"
frequency: Literal["static"] = "static"
c: int
def hello():
pass
class SecondDynamicDatasource(Datasource):
source: Literal["second"] = "second"
frequency: Literal["yearly"] = "yearly"
d: int
def hello():
pass
DatasourceInterface = TypeVar('DatasourceInterface', bound=Datasource)
# DatasourceInterface = Union[tuple(Datasource.__subclasses__())]
class Settings(BaseModel):
datas: list[DatasourceInterface]
if __name__ == "__main__":
settings = Settings(datas=[
FirstStaticDatasource(a=1),
FirstDynamicDatasource(b=2),
SecondStaticDatasource(c=3),
SecondDynamicDatasource(d=4)
])
debug(settings)
json = settings.model_dump_json()
debug(json)
new_settings = Settings.model_validate_json(json)
debug(new_settings)
If I try to run this I got the following error
TypeError: Can't instantiate abstract class Datasource without an implementation for abstract method 'hello'
Now, if I try to remove the abstract method, the code runs, but, in new_settings
, datas
results to be a list of the base class DataSource
(i.e.: I cannot see a
, b
, c
and d
class members specified in the derived subclasses).
All the problems seems solved if, instead of
DatasourceInterface = TypeVar('DatasourceInterface', bound=Datasource)
I place
DatasourceInterface = Union[tuple(Datasource.__subclasses__())]
Is there a way to reach the same result without using “metaprogramming”?
4