From faee3301eb2c0d4157150a2f4cde2b4edb32ac8e Mon Sep 17 00:00:00 2001 From: Luis R Date: Wed, 11 May 2022 20:02:37 +0200 Subject: [PATCH] Fix regression in handling of nested dataclasses in `get_flat_models_from_field` (#3819) * add test for nested python dataclass schema generation * fix handling of dataclasses in `get_flat_models_from_field` * add change note --- changes/3819-himbeles.md | 1 + pydantic/schema.py | 5 ++++- tests/test_schema.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 changes/3819-himbeles.md diff --git a/changes/3819-himbeles.md b/changes/3819-himbeles.md new file mode 100644 index 0000000..7845d7b --- /dev/null +++ b/changes/3819-himbeles.md @@ -0,0 +1 @@ +Fix nested Python dataclass schema regression in version 1.9 diff --git a/pydantic/schema.py b/pydantic/schema.py index e979678..b608d54 100644 --- a/pydantic/schema.py +++ b/pydantic/schema.py @@ -419,10 +419,13 @@ def get_flat_models_from_field(field: ModelField, known_models: TypeModelSet) -> # Handle dataclass-based models if is_builtin_dataclass(field.type_): field.type_ = dataclass(field.type_) + was_dataclass = True + else: + was_dataclass = False field_type = field.type_ if lenient_issubclass(getattr(field_type, '__pydantic_model__', None), BaseModel): field_type = field_type.__pydantic_model__ - if field.sub_fields and not lenient_issubclass(field_type, BaseModel): + if field.sub_fields and (not lenient_issubclass(field_type, BaseModel) or was_dataclass): flat_models |= get_flat_models_from_fields(field.sub_fields, known_models=known_models) elif lenient_issubclass(field_type, BaseModel) and field_type not in known_models: flat_models |= get_flat_models_from_model(field_type, known_models=known_models) diff --git a/tests/test_schema.py b/tests/test_schema.py index 8388831..4d3d4a4 100644 --- a/tests/test_schema.py +++ b/tests/test_schema.py @@ -2884,3 +2884,34 @@ def test_alias_same(): }, }, } + + +def test_nested_python_dataclasses(): + """ + Test schema generation for nested python dataclasses + """ + + from dataclasses import dataclass as python_dataclass + + @python_dataclass + class ChildModel: + name: str + + @python_dataclass + class NestedModel: + child: List[ChildModel] + + assert model_schema(dataclass(NestedModel)) == { + 'title': 'NestedModel', + 'type': 'object', + 'properties': {'child': {'title': 'Child', 'type': 'array', 'items': {'$ref': '#/definitions/ChildModel'}}}, + 'required': ['child'], + 'definitions': { + 'ChildModel': { + 'title': 'ChildModel', + 'type': 'object', + 'properties': {'name': {'title': 'Name', 'type': 'string'}}, + 'required': ['name'], + } + }, + }