The author of the dataclasses
module made a conscious decision to not implement validators that are present in similar third party projects like attrs
, pydantic
, or marshmallow
. And if your actual problem is within the scope of the one you posted, then doing the validation in the __post_init__
is completely fine.
But if you have more complex validation procedures or play with stuff like inheritance you might want to use one of the more powerful libraries I mentioned instead of dataclass
. Just to have something to look at, this is what your example could look like using pydantic
:
>>> from pydantic import BaseModel, validator
>>> class MyClass(BaseModel):
... is_good: bool = False
... is_bad: bool = False
...
... @validator('is_bad')
... def check_something(cls, v, values):
... if values['is_good'] and v:
... raise ValueError("Can not be both good and bad now, can it?")
... return v
...
>>> MyClass(is_good=True, is_bad=False) # this would be a valid instance
MyClass(is_good=True, is_bad=False)
>>> MyClass(is_good=True, is_bad=True) # this wouldn't
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "pydantic/main.py", line 283, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for MyClass
is_bad
Can not be both good and bad now, can it? (type=value_error)