From 22fccb536644c2a82db0ae169ea20c19a64cca13 Mon Sep 17 00:00:00 2001 From: Serge Matveenko Date: Fri, 23 Jun 2023 12:35:18 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Raise=20`PydanticSerializationUn?= =?UTF-8?q?expectedValue`=20in=20root=20model=20serializer=20only=20if=20s?= =?UTF-8?q?trict=20check=20is=20enabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/serializers/type_serializers/model.rs | 10 ++++++--- tests/serializers/test_model_root.py | 26 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/serializers/type_serializers/model.rs b/src/serializers/type_serializers/model.rs index edb7d42ce..bd3777318 100644 --- a/src/serializers/type_serializers/model.rs +++ b/src/serializers/type_serializers/model.rs @@ -166,9 +166,13 @@ impl TypeSerializer for ModelSerializer { if self.root_model { extra.field_name = Some(ROOT_FIELD); let py = value.py(); - let root = value - .getattr(intern!(py, ROOT_FIELD)) - .map_err(|_| PydanticSerializationUnexpectedValue::new_err(None))?; + let root = value.getattr(intern!(py, ROOT_FIELD)).map_err(|original_err| { + if extra.check.enabled() { + PydanticSerializationUnexpectedValue::new_err(None) + } else { + original_err + } + })?; self.serializer.to_python(root, include, exclude, &extra) } else if self.allow_value(value, &extra)? { let inner_value = self.get_inner_value(value, &extra)?; diff --git a/tests/serializers/test_model_root.py b/tests/serializers/test_model_root.py index f4f582994..05600b5b6 100644 --- a/tests/serializers/test_model_root.py +++ b/tests/serializers/test_model_root.py @@ -179,3 +179,29 @@ class Model(RootModel): assert s.to_python(m) == [1, 2, {'value': 'abc'}] assert s.to_json(m) == b'[1,2,{"value":"abc"}]' + + +def test_construct_nested(): + class RModel(RootModel): + root: int + + class BModel(BaseModel): + value: RModel + + s = SchemaSerializer( + core_schema.model_schema( + BModel, + core_schema.model_fields_schema( + { + 'value': core_schema.model_field( + core_schema.model_schema(RModel, core_schema.int_schema(), root_model=True) + ) + } + ), + ) + ) + + m = BModel(value=42) + + with pytest.raises(AttributeError, match="'int' object has no attribute 'root'"): + s.to_python(m)