Skip to content

Commit cff13b4

Browse files
authored
Merge pull request #215 from dapper91/model-validator-bugfix
- multiple pydantic model validators bug fixed
2 parents 9a2f5c1 + e880382 commit cff13b4

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

pydantic_xml/serializers/factories/model.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def from_core_schema(cls, schema: pcs.ModelSchema, ctx: Serializer.Context) -> '
5757
model_cls = schema['cls']
5858
fields_schema = schema['schema']
5959

60-
if fields_schema['type'] == 'function-before':
60+
while fields_schema['type'] == 'function-before':
6161
fields_schema = fields_schema['schema']
6262

6363
assert issubclass(model_cls, pxml.BaseXmlModel), "model class must be a BaseXmlModel subclass"

tests/test_preprocessors.py

+50-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
from typing import List
1+
from typing import Any, Dict, List
22

3+
import pydantic as pd
4+
import pytest
35
from helpers import assert_xml_equal
46

5-
from pydantic_xml import BaseXmlModel, element, xml_field_serializer, xml_field_validator
7+
from pydantic_xml import BaseXmlModel, attr, element, xml_field_serializer, xml_field_validator
68
from pydantic_xml.element import XmlElementReader, XmlElementWriter
79

810

@@ -54,3 +56,49 @@ def serialize_element(self, element: XmlElementWriter, value: List[int], field_n
5456

5557
actual_xml = obj.to_xml()
5658
assert_xml_equal(actual_xml, expected_xml)
59+
60+
61+
def test_pydantic_model_validator():
62+
class TestModel(BaseXmlModel, tag='model1'):
63+
text: str
64+
attr1: str = attr()
65+
attr2: str = attr()
66+
67+
@pd.model_validator(mode='before')
68+
def validate_before_attr1(cls, values: Dict[str, Any]) -> Dict[str, Any]:
69+
if values.get('attr1') != "expected attr value":
70+
raise ValueError('attr1')
71+
72+
return values
73+
74+
@pd.model_validator(mode='before')
75+
def validate_before_attr2(cls, values: Dict[str, Any]) -> Dict[str, Any]:
76+
if values.get('attr2') != "expected attr value":
77+
raise ValueError('attr2')
78+
79+
return values
80+
81+
@pd.model_validator(mode='after')
82+
def validate_model(self) -> 'TestModel':
83+
if self.text != "expected text value":
84+
raise ValueError('text')
85+
86+
return self
87+
88+
xml = '<model1 attr1="expected attr value" attr2="expected attr value">expected text value</model1>'
89+
TestModel.from_xml(xml)
90+
91+
xml = '<model1 attr1="unexpected attr value" attr2="expected attr value">expected text value</model1>'
92+
with pytest.raises(ValueError) as err:
93+
TestModel.from_xml(xml)
94+
assert err.value.errors()[0]['ctx']['orig'] == 'Value error, attr1'
95+
96+
xml = '<model1 attr1="expected attr value" attr2="unexpected attr value">expected text value</model1>'
97+
with pytest.raises(ValueError) as err:
98+
TestModel.from_xml(xml)
99+
assert err.value.errors()[0]['ctx']['orig'] == 'Value error, attr2'
100+
101+
xml = '<model1 attr1="expected attr value" attr2="expected attr value">unexpected text value</model1>'
102+
with pytest.raises(ValueError) as err:
103+
TestModel.from_xml(xml)
104+
assert err.value.errors()[0]['ctx']['orig'] == 'Value error, text'

0 commit comments

Comments
 (0)