pydantic-xml icon indicating copy to clipboard operation
pydantic-xml copied to clipboard

Model Validation Order is Not Respected

Open lja5262 opened this issue 5 months ago • 3 comments

Hello! I am working in Python 3.9.18 and am on the latest version of the library. I discovered recently that something about the from_xml call prevents pydantic model validators from executing in the correct order.

Take this minimal example (also true of "before" validators):

from pydantic import Field, model_validator, ModelWrapValidatorHandler
from pydantic_xml import BaseXmlModel, element
from typing import Any
from typing_extensions import Self

class Bar(BaseXmlModel):
	baz: int = Field()

class Foo(BaseXmlModel):
	bar: list[Bar] = element()

	@model_validator(mode="wrap")
	@classmethod
	def test_validation_order(
		cls,
		data: Any,
		handler: ModelWrapValidatorHandler[Self],
	) -> Self:
		print("hello world")
		return handler(data)

When I use a dict input and use pydantic's constructor:

input = {
	"bar": [
		{"baz": 1},
		{"baz": 2},
		{"baz": "hi"},
		{"baz": 3},
	]
}

Foo.model_validate(input)
#> hello world
#> ValidationError: ...

versus an xml input and the pydantic-xml constructor:

input_xml = """
<Foo>
	<bar>1</bar>
	<bar>1</bar>
	<bar>hi</bar>
	<bar>1</bar>
</Foo>
"""

Foo.from_xml(input_xml)
#> ValidationError: ... # print statement is skipped

I would expect the print statement to execute before validation begins, in the same way it does with the base library. Without that, it isn't possible to capture nested errors or perform any model-modifying actions in the same way one would with pydantic.

If I am missing a configuration or something, please let me know. This library has saved me an uncountable amount of time for my project.

lja5262 avatar Oct 01 '25 14:10 lja5262

@lja5262 Hi!

Due to internal implementation model_validator is called after all sub-models validators are succeeded.

dapper91 avatar Oct 02 '25 15:10 dapper91

Would it be possible to figure out a way to change that? One of the benefits of validators in pydantic is to be able to modify sub values as they come in, or to alert the user of something pre or mid validation. That isn't possible if parent validators are only called after the fact.

lja5262 avatar Oct 02 '25 15:10 lja5262

If it isn’t possible, this should be mentioned in the list of unsupported items in the readme.

lja5262 avatar Oct 07 '25 01:10 lja5262