Skip to content

Commit

Permalink
feat: support schema with TypedDict
Browse files Browse the repository at this point in the history
  • Loading branch information
PrettyWood committed Jan 21, 2021
1 parent 3fe8ff9 commit 08868ab
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 2 deletions.
2 changes: 1 addition & 1 deletion pydantic/annotated_types.py
Expand Up @@ -40,7 +40,7 @@ def create_model_from_typeddict(typeddict_cls: Type['TypedDict'], **kwargs: Any)
field_name: (field_type, default_value) for field_name, field_type in typeddict_cls.__annotations__.items()
}

return create_model(f'{typeddict_cls.__name__}Model', **kwargs, **field_definitions)
return create_model(typeddict_cls.__name__, **kwargs, **field_definitions)


def create_model_from_namedtuple(namedtuple_cls: Type['NamedTuple'], **kwargs: Any) -> Type['BaseModel']:
Expand Down
2 changes: 1 addition & 1 deletion pydantic/schema.py
Expand Up @@ -795,7 +795,7 @@ def field_singleton_schema( # noqa: C901 (ignore complexity)
f_schema, schema_overrides = get_field_info_schema(field)
f_schema.update(get_schema_ref(enum_name, ref_prefix, ref_template, schema_overrides))
definitions[enum_name] = enum_process_schema(field_type)
else:
elif not hasattr(field_type, '__pydantic_model__'):
add_field_type_to_schema(field_type, f_schema)

modify_schema = getattr(field_type, '__modify_schema__', None)
Expand Down
1 change: 1 addition & 0 deletions pydantic/validators.py
Expand Up @@ -562,6 +562,7 @@ def make_typeddict_validator(
from .annotated_types import create_model_from_typeddict

TypedDictModel = create_model_from_typeddict(typeddict_cls, __config__=config)
typeddict_cls.__pydantic_model__ = TypedDictModel # type: ignore[attr-defined]

def typeddict_validator(values: 'TypedDict') -> Dict[str, Any]:
return TypedDictModel(**values).dict(exclude_unset=True)
Expand Down
34 changes: 34 additions & 0 deletions tests/test_annotated_types.py
Expand Up @@ -173,3 +173,37 @@ class Config:
assert exc_info.value.errors() == [
{'loc': ('u', 'rank'), 'msg': 'extra fields not permitted', 'type': 'value_error.extra'},
]


@pytest.mark.skipif(not TypedDict, reason='typing_extensions not installed')
def test_typeddict_schema():
class Data(BaseModel):
a: int

class DataTD(TypedDict):
a: int

class Model(BaseModel):
data: Data
data_td: DataTD

assert Model.schema() == {
'title': 'Model',
'type': 'object',
'properties': {'data': {'$ref': '#/definitions/Data'}, 'data_td': {'$ref': '#/definitions/DataTD'}},
'required': ['data', 'data_td'],
'definitions': {
'Data': {
'type': 'object',
'title': 'Data',
'properties': {'a': {'title': 'A', 'type': 'integer'}},
'required': ['a'],
},
'DataTD': {
'type': 'object',
'title': 'DataTD',
'properties': {'a': {'title': 'A', 'type': 'integer'}},
'required': ['a'],
},
},
}

0 comments on commit 08868ab

Please sign in to comment.