From 2e5b1f6a8e7a1e5081e4bdb483653fa59cc369b7 Mon Sep 17 00:00:00 2001 From: Peter Schutt Date: Tue, 24 May 2022 12:16:29 +1000 Subject: [PATCH] Pass `FieldInfo` straight through to `create_model()` if no need to change. Where a field is neither excluded, nor mapped the least surprising thing would be that the field stays the same. --- starlite/dto.py | 14 +++++++++----- tests/test_dto_factory.py | 5 +++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/starlite/dto.py b/starlite/dto.py index 0254549437..e7445bdccb 100644 --- a/starlite/dto.py +++ b/starlite/dto.py @@ -137,12 +137,16 @@ def create_obj(data: MyClassDTO) -> MyClass: field_name, field_type = mapping else: field_name = mapping - if model_field.field_info.default not in (Undefined, None, ...): - field_definitions[field_name] = (field_type, model_field.default) - elif model_field.required or not model_field.allow_none: - field_definitions[field_name] = (field_type, ...) + if model_field.field_info.default not in (Undefined, None, ...): + field_definitions[field_name] = (field_type, model_field.default) + elif model_field.required or not model_field.allow_none: + field_definitions[field_name] = (field_type, ...) + else: + field_definitions[field_name] = (field_type, None) else: - field_definitions[field_name] = (field_type, None) + # prevents losing Optional + field_type = Optional[field_type] if model_field.allow_none else field_type + field_definitions[field_name] = (field_type, model_field.field_info) dto = cast(Type[DTO[T]], create_model(name, __base__=DTO, **field_definitions)) # type: ignore dto.dto_source_model = source dto.dto_source_plugin = plugin diff --git a/tests/test_dto_factory.py b/tests/test_dto_factory.py index cdecc7fc7f..674754294e 100644 --- a/tests/test_dto_factory.py +++ b/tests/test_dto_factory.py @@ -195,3 +195,8 @@ def test_dto_factory_preserves_field_allow_none_false() -> None: assert Example.__fields__["password"].allow_none is False ExampleDTO = DTOFactory()("ExampleDTO", Example) assert ExampleDTO.__fields__["password"].allow_none is False + + +def test_dto_factory_preserves_field_info_where_unnecessary_to_change() -> None: + ExampleDTO = DTOFactory(plugins=[])("ExampleDTO", PydanticPet, exclude=[], field_mapping={}, field_definitions={}) + assert PydanticPet.__fields__["name"].field_info is ExampleDTO.__fields__["name"].field_info