From bce37cfd07edb4a80915f3ea6131fcdff90b174b Mon Sep 17 00:00:00 2001 From: Samuel Colvin Date: Tue, 15 Aug 2023 10:49:20 +0100 Subject: [PATCH] add tests from @MarkusSintonen --- tests/test_config.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/test_config.py b/tests/test_config.py index 9e4bfccd8ea..da241d2af26 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -26,6 +26,7 @@ from pydantic.config import ConfigDict from pydantic.dataclasses import dataclass as pydantic_dataclass from pydantic.errors import PydanticUserError +from pydantic.fields import FieldInfo from pydantic.type_adapter import TypeAdapter from pydantic.warnings import PydanticDeprecationWarning @@ -712,3 +713,39 @@ class M2(BaseModel, defer_build=True): m = M2.model_validate({'b': {'a': 'foo'}}) assert m.b.model_dump() == {'a': 'foo'} + + +def test_defer_build_json_schema(): + class M(BaseModel, defer_build=True): + a: int + + assert M.model_json_schema() == { + 'title': 'M', + 'type': 'object', + 'properties': {'a': {'title': 'A', 'type': 'integer'}}, + 'required': ['a'], + } + + +def test_partial_creation_with_defer_build(): + class M(BaseModel): + a: int + b: int + + def create_partial(model: type[BaseModel], optionals: set[str]) -> type[BaseModel]: + override_fields = {} + model.model_rebuild() + for name, field in model.model_fields.items(): + if field.is_required() and name in optionals: + assert field.annotation is not None + override_fields[name] = ((field.annotation | None), FieldInfo.merge_field_infos(field, default=None)) + + return create_model(f'Partial{model.__name__}', __base__=model, **override_fields) + + partial = create_partial(M, {'a'}) + + # Comment this away and the last assertion works + assert M.model_json_schema()['required'] == ['a', 'b'] + + # AssertionError: assert ['a', 'b'] == ['b'] + assert partial.model_json_schema()['required'] == ['b']