You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If there is a bad model_validator that forgets to return self then SomeModel.model_validate(dict_obj) returns None while SomeModel(**dict_obj) continues to return the validated model.
This makes it seem like there is an issue with the .model_validate method, but obviously it's because of the bad validator...
This might have been the cause of #7055 (that's what I found when I first had the issue).
So, not quite a bug given that the code all works correctly if the user doesn't do something stupid... But, it would have been nice to be told I was stupid via a meaningful error or warning :)
Example Code
frompydanticimportBaseModel, model_validator, ValidationErrorclassSomeModel(BaseModel):
a: int@model_validator(mode="after")defvalidate_a(self):
ifself.a==10:
raiseValueError("Bad")
# Should return `self` here... but "accidentally" ommitting it to show confusing behaviour that results from this.if__name__=="__main__":
# Confusing behaviour is that model_validate returns None while direct instantiation does notgets_none=SomeModel.model_validate({"a": 5})
assertgets_noneisNone, "This is somewhat surprising (although obviously the result of a bad validator)"gets_value=SomeModel(**{"a": 5})
assertisinstance(gets_value, SomeModel), "This confuses the matter by still returning a value..."# Both correctly raise validation errors stilltry:
SomeModel.model_validate({"a": 10})
print("Does not get to here")
exceptValidationErrorase:
print("Correctly raises validation")
try:
SomeModel(**{"a": 10})
print("Does not get to here")
exceptValidationErrorase:
print("Correctly raises validation")
Python, Pydantic & OS Version
pydantic version: 2.7.1
pydantic-core version: 2.18.2
pydantic-core build: profile=release pgo=true
install path: /home/tim/.cache/pypoetry/virtualenvs/backend-dvWTEZau-py3.12/lib/python3.12/site-packages/pydantic
python version: 3.12.1 | packaged by Anaconda, Inc. | (main, Jan 19 2024, 15:51:05) [GCC 11.2.0]
platform: Linux-5.15.146.1-microsoft-standard-WSL2-x86_64-with-glibc2.35
related packages: typing_extensions-4.11.0 pydantic-settings-2.2.1 fastapi-0.109.2
commit: unknown
The text was updated successfully, but these errors were encountered:
Taking a look at it, we could error here on the pydantic-core side:
implFunctionAfterValidator{fn_validate<'py,I:Input<'py> + ?Sized>(&self,call:implFnOnce(&I,&mutValidationState<'_,'py>) -> ValResult<PyObject>,py:Python<'py>,input:&I,state:&mutValidationState<'_,'py>,) -> ValResult<PyObject>{let v = call(input, state)?;let r = ifself.info_arg{let info = ValidationInfo::new(py, state.extra(),&self.config,self.field_name.clone());self.func.call1(py,(v.to_object(py), info))}else{self.func.call1(py,(v.to_object(py),))};
r.map_err(|e| convert_err(py, e, input))// Check if the value is `None`}}
However, I'm unsure if the FunctionAfterValidator is also used in other places, e.g. with field validators where None would be a valid value returned by the validator?
As a side note, this can be prevented by using a type checker (and I'll implement a rule in flake8-pydantic soon), plus you will notice during development (as opposed to during runtime if adding an explicit check as suggested)
Initial Checks
Description
If there is a bad
model_validator
that forgets to returnself
thenSomeModel.model_validate(dict_obj)
returnsNone
whileSomeModel(**dict_obj)
continues to return the validated model.This makes it seem like there is an issue with the
.model_validate
method, but obviously it's because of the bad validator...This might have been the cause of #7055 (that's what I found when I first had the issue).
So, not quite a bug given that the code all works correctly if the user doesn't do something stupid... But, it would have been nice to be told I was stupid via a meaningful error or warning :)
Example Code
Python, Pydantic & OS Version
The text was updated successfully, but these errors were encountered: