Feature Request: Include Model class in ValidationError's line errors
See original GitHub issueThis is a feature request to include the model class for the specific error in a ValidationError’s line errors; the rework for pydantic v2 seems like an ideal opportunity for it. A use-case for this feature is enabling pydantic consumers to surface better errors to their, non-developer, end-users.
Consider the following simplified example:
from typing import Union
from pydantic import BaseModel, ValidationError
class Sub1(BaseModel):
f1: str
f2: str
f3: str
f4: str
class Sub2(BaseModel):
f1: str
a1: str
a2: str
a3: str
class Model(BaseModel):
field: Union[Sub1,Sub2]
try:
Model.parse_obj({
"field": {
"f1": "foo",
"f2": "bar"
}
})
except ValidationError as e:
for err in e.errors():
print(err)
we get the following errors:
{'loc': ('field', 'f3'), 'msg': 'field required', 'type': 'value_error.missing'}
{'loc': ('field', 'f4'), 'msg': 'field required', 'type': 'value_error.missing'}
{'loc': ('field', 'a1'), 'msg': 'field required', 'type': 'value_error.missing'}
{'loc': ('field', 'a2'), 'msg': 'field required', 'type': 'value_error.missing'}
{'loc': ('field', 'a3'), 'msg': 'field required', 'type': 'value_error.missing'}
which if simply pretty-printed looks like:
field -> f3
field required (type=value_error.missing)
field -> f4
field required (type=value_error.missing)
field -> a1
field required (type=value_error.missing)
field -> a2
field required (type=value_error.missing)
field -> a3
field required (type=value_error.missing)
The problem here is that an end-user trying to figure out what was wrong with their input has to have the experience and presence of mind to look through the model definitions to understand that they’re seeing errors from trying to match against two different model classes and only the first 2 errors are actually relevant to them.
Including the model class in the line errors would allow an application that is using pydantic to do some processing on the list of line errors to provide more meaningful error messages to end users. For example, if the line error dictionaries were actually something like:
{'loc': ('field', 'f3'), 'msg': 'field required', 'type': 'value_error.missing', model: <class 'Sub1'> }
{'loc': ('field', 'f4'), 'msg': 'field required', 'type': 'value_error.missing', model: <class 'Sub1'> }
{'loc': ('field', 'a1'), 'msg': 'field required', 'type': 'value_error.missing', model: <class 'Sub2'> }
{'loc': ('field', 'a2'), 'msg': 'field required', 'type': 'value_error.missing', model: <class 'Sub2'> }
{'loc': ('field', 'a3'), 'msg': 'field required', 'type': 'value_error.missing', model: <class 'Sub2'> }
Then the application could, say, collect the errors from the list that match within line_error['loc'][:-1]
, group them by model class, figure out that the end-user was most likely trying to write a Sub1
model in this case because they matched the most fields from it (2 matched fields vs 1 match for Sub2
), and surface a more directed error like:
field (model: Sub1)
f3: field required
f4: field required
Thank you for your consideration.
Issue Analytics
- State:
- Created 10 months ago
- Comments:7 (4 by maintainers)
This is done 😃.
In the example in the readme, you’ll see
input_value=11
- the input value is included in the error asinput
, There are many examples in the docs, e.g. here it’s also included in the the type in for the new validation error:https://github.com/pydantic/pydantic-core/blob/a084f30d915f557107e297215e2ca68c6e55a099/pydantic_core/_pydantic_core.pyi#L80-L85
Let me know if anything is still unclear.
Pydantic’s logic for generating pydantic-core schema is much more sophisticated thank
generate_self_schema.py
, but it’s somewhat similar. Most of the logic is inpydantic/_internal/_generate_schema.py
.