I want to use attrs
to run validators on values inside my class. Here is an example:
from attrs import define, field
@define(kw_only=True)
class Foo:
x: float = field()
min_x: float = field()
max_x: float = field()
@x.validator
def validate_x(self, _, value) -> None:
if value < self.min_x:
raise ValueError(f"x must be greater than {self.min_x}")
if value > self.max_x:
raise ValueError(f"x must be less than {self.max_x}")
@min_x.validator
def validate_min_x(self, _, value) -> None:
if value > self.max_x:
raise ValueError("Min x must be less than max x")
@max_x.validator
def validate_max_x(self, _, value) -> None:
if value < self.min_x:
raise ValueError("Max x must be greater than min x")
All three values x
, min_x
and max_x
are important to me and need to be stored. As I want to be able to get all three values and change them when needed. The problem I have is how these three validator
functions can work together.
For basic usage, like creating a new instance, it works fine.
foo = Foo(x=5, min_x=0, max_x=10)
But say I wanted to change the values. I might want to do it like this:
foo.min_x = 11
foo.max_x = 15
foo.x = 12
But foo.min_x
will throw an error because it will compare to max_x = 10
. Yes, if I swap the order and set foo.max_x
first it will solve it. But next time I might want to make foo.max_x
smaller than foo.min_x
so I need a robust way to handle all cases.
Is there a good way to handle this kind of situation?