Skip to content

Commit 51aaa25

Browse files
committed
fix: we have a warning for every sub-variant
Signed-off-by: Luka Peschke <[email protected]>
1 parent 287b8c9 commit 51aaa25

File tree

2 files changed

+36
-7
lines changed

2 files changed

+36
-7
lines changed

src/serializers/type_serializers/union.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,19 +132,15 @@ fn to_python(
132132
let mut new_extra = extra.clone();
133133
new_extra.check = SerCheck::Strict;
134134

135-
let res = to_python_extractor(value, include, exclude, &new_extra, choices);
136-
137-
let errors = match res {
135+
let errors = match to_python_extractor(value, include, exclude, &new_extra, choices) {
138136
ToPythonExtractorResult::Success(obj) => return Ok(obj),
139137
ToPythonExtractorResult::Errors(errs) => errs,
140138
};
141139

142140
if retry_with_lax_check {
143141
new_extra.check = SerCheck::Lax;
144-
for comb_serializer in choices {
145-
if let Ok(v) = comb_serializer.to_python(value, include, exclude, &new_extra) {
146-
return Ok(v);
147-
}
142+
if let ToPythonExtractorResult::Success(v) = to_python_extractor(value, include, exclude, &new_extra, choices) {
143+
return Ok(v);
148144
}
149145
}
150146

tests/serializers/test_union.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,11 @@ def __init__(self, type_: Literal['cat']) -> None:
790790
self.type_ = 'cat'
791791

792792

793+
class ModelAlien:
794+
def __init__(self, type_: Literal['alien']) -> None:
795+
self.type_ = 'alien'
796+
797+
793798
@pytest.fixture
794799
def model_a_b_union_schema() -> core_schema.UnionSchema:
795800
return core_schema.union_schema(
@@ -850,6 +855,20 @@ def test_union_of_unions_of_models(model_a_b_union_schema: core_schema.UnionSche
850855
assert s.to_python(ModelCat(type_='cat'), warnings='error') == {'type_': 'cat'}
851856
assert s.to_python(ModelDog(type_='dog'), warnings='error') == {'type_': 'dog'}
852857

858+
# All warnings should be available
859+
messages = [
860+
'Expected `ModelA` but got `ModelAlien`',
861+
'Expected `ModelB` but got `ModelAlien`',
862+
'Expected `ModelCat` but got `ModelAlien`',
863+
'Expected `ModelDog` but got `ModelAlien`',
864+
]
865+
866+
with warnings.catch_warnings(record=True) as w:
867+
warnings.simplefilter('always')
868+
s.to_python(ModelAlien(type_='alien'))
869+
for m in messages:
870+
assert m in str(w[0].message)
871+
853872

854873
def test_union_of_unions_of_models_with_tagged_union(model_a_b_union_schema: core_schema.UnionSchema) -> None:
855874
s = SchemaSerializer(
@@ -885,3 +904,17 @@ def test_union_of_unions_of_models_with_tagged_union(model_a_b_union_schema: cor
885904
assert s.to_python(ModelB(c='c', d='d'), warnings='error') == {'c': 'c', 'd': 'd'}
886905
assert s.to_python(ModelCat(type_='cat'), warnings='error') == {'type_': 'cat'}
887906
assert s.to_python(ModelDog(type_='dog'), warnings='error') == {'type_': 'dog'}
907+
908+
# All warnings should be available
909+
messages = [
910+
'Expected `ModelA` but got `ModelAlien`',
911+
'Expected `ModelB` but got `ModelAlien`',
912+
'Expected `ModelCat` but got `ModelAlien`',
913+
'Expected `ModelDog` but got `ModelAlien`',
914+
]
915+
916+
with warnings.catch_warnings(record=True) as w:
917+
warnings.simplefilter('always')
918+
s.to_python(ModelAlien(type_='alien'))
919+
for m in messages:
920+
assert m in str(w[0].message)

0 commit comments

Comments
 (0)