Skip to content

Commit

Permalink
Fix schema-building bug with TypeAliasType for types with refs
Browse files Browse the repository at this point in the history
  • Loading branch information
dmontagu committed Jan 12, 2024
1 parent 25471ed commit 66c13d8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
8 changes: 8 additions & 0 deletions pydantic/_internal/_core_utils.py
Expand Up @@ -228,6 +228,14 @@ def _handle_ser_schemas(self, ser_schema: core_schema.SerSchema, f: Walk) -> cor
def handle_definitions_schema(self, schema: core_schema.DefinitionsSchema, f: Walk) -> core_schema.CoreSchema:
new_definitions: list[core_schema.CoreSchema] = []
for definition in schema['definitions']:
if 'schema_ref' and 'ref' in definition:
# This indicates a purposely indirect reference
# We want to keep such references around for implications related to JSON schema, etc.:
new_definitions.append(definition)
# However, we still need to walk the referenced definition:
self.walk(definition, f)
continue

updated_definition = self.walk(definition, f)
if 'ref' in updated_definition:
# If the updated definition schema doesn't have a 'ref', it shouldn't go in the definitions
Expand Down
24 changes: 23 additions & 1 deletion tests/test_type_alias_type.py
Expand Up @@ -4,7 +4,7 @@

import pytest
from annotated_types import MaxLen
from typing_extensions import Annotated, TypeAliasType
from typing_extensions import Annotated, Literal, TypeAliasType

from pydantic import BaseModel, Field, ValidationError
from pydantic.type_adapter import TypeAdapter
Expand Down Expand Up @@ -366,3 +366,25 @@ class MyOuterModel(BaseModel):

data = {'inner': {'x': 'hello'}, 'y': 1}
assert MyOuterModel.model_validate(data).model_dump() == data


def test_type_alias_to_type_with_ref():
class Div(BaseModel):
type: Literal['Div'] = 'Div'
components: List['AnyComponent']

AnyComponent = TypeAliasType('AnyComponent', Div)

adapter = TypeAdapter(AnyComponent)
adapter.validate_python({'type': 'Div', 'components': [{'type': 'Div', 'components': []}]})
with pytest.raises(ValidationError) as exc_info:
adapter.validate_python({'type': 'Div', 'components': [{'type': 'NotDiv', 'components': []}]})
assert exc_info.value.errors(include_url=False) == [
{
'ctx': {'expected': "'Div'"},
'input': 'NotDiv',
'loc': ('components', 0, 'type'),
'msg': "Input should be 'Div'",
'type': 'literal_error',
}
]

0 comments on commit 66c13d8

Please sign in to comment.