Open lord-haffi opened 1 year ago
Thanks for reporting, as you suggested this is unique to model "after" validators.
The reason is that model after validators are applied outside the model, rather than between the model and the model fields like model "before" validators.
So model after validators look something like:
modelAfterValidator(
function=check_a,
validator=modelValidator(
fieldsValidator(...)
)
)
Whereas "before" model validators look more like
modelValidator(
validator=modelBeforeValidator(
function=check_a,
validator=fieldsValidator(...)
)
)
You can see this if you (pretty)print B.__pydantic_validator__
.
Unfortunately I don't see an easy way to solve/change this without significantly impacting performance and/or breaking existing behaviour.
What's your use case, may there's another way to get the behaviour you need?
Thanks for your reply!
In my case I should be able to do this with mode="before"
. With mode="after"
I just would have saved some instance checks - luckily there are no colliding validators getting in the way.
I think that there may be situations in which it could be quite difficult though. But for now and for me it has no priority.
Btw, thanks for your explanation :) Was trying to get trough the code but with the new Rust-core (I'm entirely new to Rust) I was a bit lost ^^
worth noting that wrap
validators probably perform the same as after
validators.
I'll leave this open in case other run into it - there may be some clever way for pydantic-core to detect a validator directly wrapping a model and applying the logic used by model validators, but I can't promise anything.
Initial Checks
Description
Initially I thought it's more general and created a discussion here: #6975 But after playing around a bit more I discovered, that this issue appears only when using
model_validator(mode="after")
. So I believe that this is a bug rather than intended behaviour.I think the code example below explains the issue better than text. Notice that the validation does not fail because
a
is not defined (I usedmodel_construct
to intentionally bypass it) which is good. But it fails because the custom validator ofA
(which is constructed) is executed byB
"again" - which is bad. At least for my unittests ^^Example Code
Python, Pydantic & OS Version
Selected Assignee: @samuelcolvin