Skip to content

Commit

Permalink
Fix __pydantic_config__ ignored for TypedDict (#8734)
Browse files Browse the repository at this point in the history
  • Loading branch information
13sin committed Feb 6, 2024
1 parent ace0e53 commit b1bb24e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 7 deletions.
24 changes: 17 additions & 7 deletions pydantic/json_schema.py
Expand Up @@ -1214,18 +1214,24 @@ def typed_dict_schema(self, schema: core_schema.TypedDictSchema) -> JsonSchemaVa
]
if self.mode == 'serialization':
named_required_fields.extend(self._name_required_computed_fields(schema.get('computed_fields', [])))

config = _get_typed_dict_config(schema)
cls = _get_typed_dict_cls(schema)
config = _get_typed_dict_config(cls)
with self._config_wrapper_stack.push(config):
json_schema = self._named_required_fields_schema(named_required_fields)

json_schema_extra = config.get('json_schema_extra')
extra = schema.get('extra_behavior')
if extra is None:
extra = config.get('extra', 'ignore')
if extra == 'forbid':
json_schema['additionalProperties'] = False
elif extra == 'allow':
json_schema['additionalProperties'] = True

if cls is not None:
title = config.get('title') or cls.__name__
json_schema = self._update_class_schema(json_schema, title, extra, cls, json_schema_extra)
else:
if extra == 'forbid':
json_schema['additionalProperties'] = False
elif extra == 'allow':
json_schema['additionalProperties'] = True

return json_schema

Expand Down Expand Up @@ -2414,9 +2420,13 @@ def __hash__(self) -> int:
return hash(type(self))


def _get_typed_dict_config(schema: core_schema.TypedDictSchema) -> ConfigDict:
def _get_typed_dict_cls(schema: core_schema.TypedDictSchema) -> type[Any] | None:
metadata = _core_metadata.CoreMetadataHandler(schema).metadata
cls = metadata.get('pydantic_typed_dict_cls')
return cls


def _get_typed_dict_config(cls: type[Any] | None) -> ConfigDict:
if cls is not None:
try:
return _decorators.get_attribute_from_bases(cls, '__pydantic_config__')
Expand Down
40 changes: 40 additions & 0 deletions tests/test_json_schema.py
Expand Up @@ -2545,6 +2545,46 @@ def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHa
}


def test_typeddict_with_title():
class Model(TypedDict):
__pydantic_config__ = ConfigDict(title='Test') # type: ignore
a: str

assert TypeAdapter(Model).json_schema() == {
'title': 'Test',
'type': 'object',
'properties': {'a': {'title': 'A', 'type': 'string'}},
'required': ['a'],
}


def test_typeddict_with_json_schema_extra():
class Model(TypedDict):
__pydantic_config__ = ConfigDict(title='Test', json_schema_extra={'foobar': 'hello'}) # type: ignore
a: str

assert TypeAdapter(Model).json_schema() == {
'title': 'Test',
'type': 'object',
'properties': {'a': {'title': 'A', 'type': 'string'}},
'required': ['a'],
'foobar': 'hello',
}


def test_typeddict_with__callable_json_schema_extra():
def json_schema_extra(schema, model_class):
schema.pop('properties')
schema['type'] = 'override'
assert model_class is Model

class Model(TypedDict):
__pydantic_config__ = ConfigDict(title='Test', json_schema_extra=json_schema_extra) # type: ignore
a: str

assert TypeAdapter(Model).json_schema() == {'title': 'Test', 'type': 'override', 'required': ['a']}


@pytest.mark.parametrize(
'annotation,kwargs,field_schema',
[
Expand Down

0 comments on commit b1bb24e

Please sign in to comment.