Pydantic: Wrong error raised in sequential validation

Created on 16 Jun 2020  路  4Comments  路  Source: samuelcolvin/pydantic

Bug

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

             pydantic version: 1.5.1
            pydantic compiled: True
                 install path: .../python3.8/site-packages/pydantic
               python version: 3.8.3 (default, May 19 2020, 18:47:26)  [GCC 7.3.0]
                     platform: Linux-4.4.0-18362-Microsoft-x86_64-with-glibc2.10
     optional deps. installed: []

from pydantic import BaseModel, validator

class Person(BaseModel):
    name: str
    full_name: str

    @validator("name")
    def _check_name(cls, v, values):
        if "John" == v:
            raise ValueError("John is forbidden")
        return v

    @validator("full_name")
    def _check_full_name(cls, v, values):
        if not values["name"] in v:
            raise ValueError()
        return v

# this is fine
Person(name="Jane", full_name="Jane Doe")

# expected "John is forbidden" 
Person(name="John", full_name="John Doe")

However, instead of the custom defined ValueError we will get the highly confusing message

Traceback (most recent call last):
  File "pydantic/main.py", line 336, in pydantic.main.BaseModel.__init__
  File "pydantic/main.py", line 887, in pydantic.main.validate_model
  File "pydantic/fields.py", line 563, in pydantic.fields.ModelField.validate
  File "pydantic/fields.py", line 711, in pydantic.fields.ModelField._apply_validators
  File "pydantic/class_validators.py", line 282, in pydantic.class_validators._generic_validator_cls.lambda3
  File "<ipython-input-2-8caa8155fe19>", line 16, in _check_full_name
    if not values["name"] in v:
KeyError: 'name'

This seems to suggest that the problem is the code validating full_name rather than an invalid name. I guess the reason is that since name validation failed, name is no longer included in the values dict when validating full_name which leads to the KeyError. The raised ValueError from name validation has been lost along the way

bug

Most helpful comment

Hi @MischaPanch
All the validators are indeed run even with an error to create a whole validation error. But the KeyError stops this process and fails early.
You can just change your full_name validator with

if 'name' in values and values['name'] in v:

All 4 comments

Hi @MischaPanch
All the validators are indeed run even with an error to create a whole validation error. But the KeyError stops this process and fails early.
You can just change your full_name validator with

if 'name' in values and values['name'] in v:

Hi @MischaPanch
All the validators are indeed run even with an error to create a whole validation error. But the KeyError stops this process and fails early.
You can just change your full_name validator with

if 'name' in values and values['name'] in v:

Cool, thanks! Maybe you can include it somewhere in the docu? I couldn't find this in your examples but maybe I just haven't found the right spot 馃槄

It's in the very first validation example:

if 'password1' in values and v != values['password1']:

Sorry, I was blind indeed

Was this page helpful?
0 / 5 - 0 ratings