Reputation: 4787
If I have the following dataclass:
@dataclasses.dataclass
class Something:
first: str
last: str
age: int = 0
...
What would be a good general purpose way to check the types of all of the arguments? Currently I have something like:
def verify_types(dataclass_obj):
for field_name, field_info in dataclass_obj.__dataclass_fields__.items():
value = getattr(obj, field_name)
expected_type = field_info.type
actual_type = type(value)
print (f"Field: {field_name} | Value: {value} "
f"Type: {actual_type} | ExpectedType: {expected_type}"
)
if expected_type != actual_type:
print ('Type error')
Is there a bettery way to do it than this (maybe something like a mixin
that I could add in every time I initialize a dataclass?).
Upvotes: 0
Views: 575
Reputation: 918
The other way to do enforce type hints at runtime is using mature solution something that already exists - pydantic package. It wraps dataclass and your exemplary code with using pydantic would be:
from pydantic import BaseModel
class Something(BaseModel):
first: str
last: str
age: int = 0
...
As authors says:
pydantic enforces type hints at runtime, and provides user friendly errors when data is invalid.
Upvotes: 1
Reputation: 4787
One option is to use the __post_init__
method:
class StrictTypes:
def __post_init__(self):
for field_name, field_info in self.__dataclass_fields__.items():
value = getattr(self, field_name)
if type(value) != field_info.type:
raise SystemExit(f"Invalid type of '{type(value).__name__}' on field {field_name}")
@dataclasses.dataclass
class Something(StrictTypes):
...
Upvotes: 1