Pydantic: How to properly do Pair-Wise Validation?

Created on 25 Sep 2019  路  4Comments  路  Source: samuelcolvin/pydantic

How can I use pydantic to raise a ValueError if two specific bools are True?
I would need this to enforce mutually exclusivity.

AFAIK there is not anything in the current API allowing to pass a tuple of fields to a validator.
(See example below.). This leaves us with the only possibility to pass field and values to the validator, meaning the validation will be run twice.
1) either_i_am_true -> or_i_am
2) or_i_am ->either_i_am_true

from pydantic import BaseModel

class MyModel(BaseModel):
    either_i_am_true: bool = False
    or_i_am: bool = False

    @validator(('either_i_am_true', 'or_i_am'))  # note the tuple here
    def mutually_exclusive(cls, v):
        if v[0] and v[1]:
            raise ValueError("either_i_am_true and' are 'or_i_am' mututally exclusive.")
        return v
question

Most helpful comment

@dmontagu Thank you, this answers my question!
The missing piece was to know that values only contains those fields "prior to the one being validated". It neither contains all fields nor the field to validate itself.

All 4 comments

Try this:

    @validator('or_i_am', always=True)
    def mutually_exclusive(cls, v, values):
        if values["either_i_am_true"] and v:
            raise ValueError("either_i_am_true and' are 'or_i_am' mututally exclusive.")
        return v

(The always=True means the validator should be called even if the field isn't specified. Since the default value is False, you actually don't even need to use always=True, since you'd have to have provided the value for validation to fail. But using always=True might be safer in case of future refactors; you can decide.)

@dmontagu Thanks.
Can we generalize this example for checking more than two values against each other?
Like 3, 4, ... n?

Yes, values will contain the values of all fields prior to the one being validated.

@dmontagu Thank you, this answers my question!
The missing piece was to know that values only contains those fields "prior to the one being validated". It neither contains all fields nor the field to validate itself.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

drpoggi picture drpoggi  路  3Comments

ashpreetbedi picture ashpreetbedi  路  3Comments

ashears picture ashears  路  3Comments

bartekbrak picture bartekbrak  路  3Comments

timonbimon picture timonbimon  路  3Comments