samuelbrody1249
samuelbrody1249

Reputation: 4787

Writing a generic method for a dataclass to check types

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

Answers (2)

izkeros
izkeros

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

samuelbrody1249
samuelbrody1249

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

Related Questions