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)