0

Let's compare two Model objects and the following dictionary.

class A(BaseModel):
    field1: StrictStr
    field2: StrictStr

    @validator('field2', always=True)
    def check_field2_not_dupliated(cls, field2, values):
        if field2 == values['field1'] + 'x':
            raise ValueError(f'{field2=} is the same as field1!')
        return field2

class B(BaseModel):
    field1: StrictStr
    field2: StrictStr

    @validator('field2', always=True)
    def check_field2_not_dupliated(cls, field2, values):
        if 'field1' in values:
            if field2 == values['field1'] + 'x':
                raise ValueError(f'{field2=} is the same as field1!')
        return field2

d = {
    'field1': 1,
    'field2': 'hello'
}

If you run parse_obj, you get

> A.parse_obj(d)

      5 @validator('field2', always=True)
      6 def check_field2_not_dupliated(cls, field2, values):
----> 7     if field2 == values['field1']:
      8         raise ValueError(f'{field2=} is the same as field1!')
      9     return field2

KeyError: 'field1'
> B.parse_obj(d)
ValidationError: 1 validation error for B
field1
  str type expected (type=type_error.str)

I would like the error message of B without needing to have to wrap the validator for field2 in "if 'field1' in values", that is, with code looking like A.

One possible approach I'm not sure whether is possible is throwing an error once pydantic realizes field1 has invalid input.

extremeaxe5
  • 723
  • 3
  • 13
  • Does this answer your question? [Why dict.get(key) instead of dict\[key\]?](https://stackoverflow.com/questions/11041405/why-dict-getkey-instead-of-dictkey) – JonSG Aug 17 '23 at 17:57
  • Edited my question. There are more complicated instances where essentially I expect either `field1` to be a valid string or an error to already have been thrown – extremeaxe5 Aug 17 '23 at 18:02

1 Answers1

2

You can use .get to safely read a value from a dict, so in this case

if field2 == values.get('field1', None):  # or whatever default value if not found
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218