Describe the bug
Arrays + polymorphism via discriminator probably lead to invalid pydantic model.
I am getting
TL DR: the generated code:
external_attributes: Optional[
List[Union[ExternalAttributeString, ExternalAttributeNumber]]
] = Field(None, alias='externalAttributes', discriminator='type')
should be
external_attributes: Optional[
List[Annotated[Union[ExternalAttributeString, ExternalAttributeNumber], Field(discriminator='type')]]
] = Field(None, alias='externalAttributes')
I am getting
class External(BaseModel):
.venv/lib/python3.12/site-packages/pydantic/_internal/_model_construction.py:255: in __new__
complete_model_class(
.venv/lib/python3.12/site-packages/pydantic/_internal/_model_construction.py:648: in complete_model_class
schema = gen_schema.generate_schema(cls)
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:729: in generate_schema
schema = self._generate_schema_inner(obj)
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:1023: in _generate_schema_inner
return self._model_schema(obj)
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:856: in _model_schema
{k: self._generate_md_field_schema(k, v, decorators) for k, v in fields.items()},
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:1228: in _generate_md_field_schema
schema, metadata = self._common_field_schema(name, field_info, decorators)
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:1278: in _common_field_schema
schema = self._apply_annotations(
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:2227: in _apply_annotations
schema = get_inner_schema(source_type)
.venv/lib/python3.12/site-packages/pydantic/_internal/_schema_generation_shared.py:83: in __call__
schema = self._handler(source_type)
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:2213: in inner_handler
return transform_inner_schema(schema)
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:1267: in set_discriminator
schema = self._apply_discriminator_to_union(schema, field_info.discriminator)
.venv/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py:675: in _apply_discriminator_to_union
return _discriminated_union.apply_discriminator(
.venv/lib/python3.12/site-packages/pydantic/_internal/_discriminated_union.py:70: in apply_discriminator
return _ApplyInferredDiscriminator(discriminator, definitions or {}).apply(schema)
.venv/lib/python3.12/site-packages/pydantic/_internal/_discriminated_union.py:164: in apply
schema = self._apply_to_root(schema)
.venv/lib/python3.12/site-packages/pydantic/_internal/_discriminated_union.py:177: in _apply_to_root
wrapped = self._apply_to_root(schema['schema'])
.venv/lib/python3.12/site-packages/pydantic/_internal/_discriminated_union.py:200: in _apply_to_root
self._handle_choice(choice)
.venv/lib/python3.12/site-packages/pydantic/_internal/_discriminated_union.py:268: in _handle_choice
raise TypeError(err_str)
E TypeError: The core schema type 'list' is not a valid discriminated union variant. If you are making use of a list of union types, make sure the discriminator is applied to the union type and not the list (e.g. `list[Annotated[<T> | <U>, Field(discriminator=...)]]`).
To Reproduce
Example schema:
components:
schemas:
External:
type: object
properties:
externalAttributes:
type: array
items:
$ref: '#/components/schemas/ExternalAttribute'
ExternalAttributeBase:
type: object
title: ExternalAttributeBase
properties:
key:
description: "Attribute key"
type: string
type:
description: "Attribute type (e.g. string, number, date, etc.)"
enum:
- string
- number
type: string
required:
- key
- type
ExternalAttributeString:
allOf:
- $ref: '#/components/schemas/ExternalAttributeBase'
- type: object
title: ExternalAttributeString
properties:
value:
description: "Attribute value"
type: string
required:
- value
ExternalAttributeNumber:
allOf:
- $ref: '#/components/schemas/ExternalAttributeBase'
- type: object
title: ExternalAttributeNumber
properties:
value:
description: "Attribute value"
type: number
required:
- value
ExternalAttribute:
oneOf:
- $ref: '#/components/schemas/ExternalAttributeString'
- $ref: '#/components/schemas/ExternalAttributeNumber'
discriminator:
propertyName: type
mapping:
string: '#/components/schemas/ExternalAttributeString'
number: '#/components/schemas/ExternalAttributeNumber'
Used commandline:
$ poetry run datamodel-codegen --input src/common/openapi/codegen/domain_types.part.openapi.yaml --input-file-type openapi --openapi-scopes schemas paths --capitalise-enum-members --snake-case-field --use-field-description --allow-population-by-field-name --collapse-root-models --output-model-type=pydantic_v2.BaseModel --use-operation-id-as-name --enum-field-as-literal all --output src/common/openapi/codegen/domain_types.part_model.py
Expected behavior
The generated module (domain_types.part_model.py in this case) to contain:
List[Annotated[Union[<T1>, <T2>....], Field(discriminator=<discriminator>)]
] = Field(None, alias=<whatever>)
instead of:
List[Union[<T1>, <T2>....]]
] = Field(None, alias=<whatever>, discriminator=<discriminator>)
Version:
- OS: [e.g. iOS] macOS 15.7.2
- Python version: 3.12.7
- datamodel-code-generator version: 0.25.9 - latest version 0.51.0 doesn't generate the discriminator in the Field spec for the list at all (I tried updating to the latest version after I wrote all of this and just found out)
Additional context
Describe the bug
Arrays + polymorphism via discriminator probably lead to invalid pydantic model.
I am getting
TL DR: the generated code:
should be
I am getting
To Reproduce
Example schema:
Used commandline:
Expected behavior
The generated module (domain_types.part_model.py in this case) to contain:
instead of:
Version:
Additional context