Search code examples
pythonvalidationpython-attrs

Attrs validation checking when an attribute is another attrs object


I have two attrs classes, where one is an attribute of the other. I want to ensure that if a particular value is given to one, there's a particular value in the other.

I've looked at validators, and don't think there's anything that captures this.

Here's what I've written:

@attr.s
class C:
    a = attr.ib(validator=attr.validators.instance_of(str))

@attr.s
class D:
    x = attr.ib(validator=attr.validators.instance_of(str))
    z = attr.ib(validator=attr.validators.instance_of(C))

    def __attrs_post_init__(self):
        if self.x == "a":
            assert self.z.a == "a12"
        elif self.x == "b":
            assert self.z.a == "b12"
        elif self.x == "c":
            assert self.z.a == "c12"


d = D(x="a", z=C("a12"))

I think this works, but i sense perhaps I'm missing something obvious.


Solution

  • Your approach is fine, except that you probably shouldn't use assert in production code (they get optimized out when you run python -O).

    If z came after x, you could also use a decorator validator that get a partially initialized instance as an argument, but I find you solution more robust, since it doesn't depend on the order of the attribute definitions.