Skip to content

Commit

Permalink
Fix model json schema with config types (#9287)
Browse files Browse the repository at this point in the history
  • Loading branch information
NeevCohen committed Apr 22, 2024
1 parent a0f18e3 commit 82e4664
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
4 changes: 2 additions & 2 deletions pydantic/json_schema.py
Expand Up @@ -2037,13 +2037,13 @@ def encode_default(self, dft: Any) -> Any:
Returns:
The encoded default value.
"""
from .type_adapter import TypeAdapter
from .type_adapter import TypeAdapter, _type_has_config

config = self._config
try:
default = (
dft
if hasattr(dft, '__pydantic_serializer__')
if _type_has_config(type(dft))
else TypeAdapter(type(dft), config=config.config_dict).dump_python(dft, mode='json')
)
except PydanticSchemaGenerationError:
Expand Down
106 changes: 106 additions & 0 deletions tests/test_json_schema.py
@@ -1,3 +1,4 @@
import dataclasses
import json
import math
import re
Expand Down Expand Up @@ -6030,3 +6031,108 @@ class Model(BaseModel):

schema = Model.model_json_schema()
assert schema == expected_schema


@dataclasses.dataclass
class BuiltinDataclassParent:
name: str


@pydantic.dataclasses.dataclass
class PydanticDataclassParent:
name: str


class TypedDictParent(TypedDict):
name: str


class ModelParent(BaseModel):
name: str


@pytest.mark.parametrize(
'pydantic_type,expected_json_schema',
[
pytest.param(
BuiltinDataclassParent,
{
'$defs': {
'BuiltinDataclassParent': {
'properties': {'name': {'title': 'Name', 'type': 'string'}},
'required': ['name'],
'title': 'BuiltinDataclassParent',
'type': 'object',
}
},
'properties': {
'parent': {'allOf': [{'$ref': '#/$defs/BuiltinDataclassParent'}], 'default': {'name': 'Jon Doe'}}
},
'title': 'child',
'type': 'object',
},
id='builtin-dataclass',
),
pytest.param(
PydanticDataclassParent,
{
'$defs': {
'PydanticDataclassParent': {
'properties': {'name': {'title': 'Name', 'type': 'string'}},
'required': ['name'],
'title': 'PydanticDataclassParent',
'type': 'object',
}
},
'properties': {
'parent': {'allOf': [{'$ref': '#/$defs/PydanticDataclassParent'}], 'default': {'name': 'Jon Doe'}}
},
'title': 'child',
'type': 'object',
},
id='pydantic-dataclass',
),
pytest.param(
TypedDictParent,
{
'$defs': {
'TypedDictParent': {
'properties': {'name': {'title': 'Name', 'type': 'string'}},
'required': ['name'],
'title': 'TypedDictParent',
'type': 'object',
}
},
'properties': {
'parent': {'allOf': [{'$ref': '#/$defs/TypedDictParent'}], 'default': {'name': 'Jon Doe'}}
},
'title': 'child',
'type': 'object',
},
id='typeddict',
),
pytest.param(
ModelParent,
{
'$defs': {
'ModelParent': {
'properties': {'name': {'title': 'Name', 'type': 'string'}},
'required': ['name'],
'title': 'ModelParent',
'type': 'object',
}
},
'properties': {'parent': {'allOf': [{'$ref': '#/$defs/ModelParent'}], 'default': {'name': 'Jon Doe'}}},
'title': 'child',
'type': 'object',
},
id='model',
),
],
)
def test_pydantic_types_as_default_values(pydantic_type, expected_json_schema):
class Child(BaseModel):
model_config = ConfigDict(title='child')
parent: pydantic_type = pydantic_type(name='Jon Doe')

assert Child.model_json_schema() == expected_json_schema

0 comments on commit 82e4664

Please sign in to comment.