Skip to content

Fix OpenAPI discriminator with allOf when no container references parent#102

Open
staging-devin-ai-integration[bot] wants to merge 1 commit intomainfrom
evalon/datamodel--b007582a
Open

Fix OpenAPI discriminator with allOf when no container references parent#102
staging-devin-ai-integration[bot] wants to merge 1 commit intomainfrom
evalon/datamodel--b007582a

Conversation

@staging-devin-ai-integration
Copy link

Summary

This PR fixes issue koxudaxi#2528 - OpenAPI polymorphism with discriminator and allOf not working.

Problem

When a discriminator is used with allOf (as described in the OpenAPI spec), the discriminator literal types were not applied to subtype schemas if there was no container schema referencing the parent.

For example, given:

Pet:
  discriminator:
    propertyName: petType
    mapping:
      cat: '#/components/schemas/Cat'
Cat:
  allOf:
    - $ref: '#/components/schemas/Pet'
    - type: object
      properties:
        name:
          type: string

The generated Cat class would not have pet_type: Literal['cat'] unless there was another schema like PetContainer with a field referencing Pet.

Solution

  • Added _get_discriminator_info_for_subtype() hook method in the base Parser class that returns None by default
  • Overrode this hook in OpenAPIParser to return discriminator info for known subtypes (schemas that use allOf to inherit from a discriminated parent)
  • Extended __apply_discriminator_type() in the base parser to also process models that are known subtypes, applying the discriminator literal types even when not referenced by a field

Changes

  • src/datamodel_code_generator/parser/base.py: Added hook method and extended discriminator processing logic
  • src/datamodel_code_generator/parser/openapi.py: Implemented hook to provide discriminator info for subtypes
  • tests/main/openapi/test_main_openapi.py: Added test case
  • tests/data/openapi/discriminator_allof_no_container.yaml: Test input schema (exact example from OpenAPI spec)
  • tests/data/expected/main/openapi/discriminator/allof_no_container.py: Expected output

Testing

All discriminator-related tests pass:

pytest tests/main/openapi/test_main_openapi.py -k discriminator
# 29 passed

Example

Input schema (from OpenAPI spec example):

Pet:
  type: object
  required:
    - petType
  properties:
    petType:
      type: string
  discriminator:
    propertyName: petType
    mapping:
      cat: '#/components/schemas/Cat'
      dog: '#/components/schemas/Dog'
      lizard: '#/components/schemas/Lizard'
Cat:
  allOf:
    - $ref: '#/components/schemas/Pet'
    - type: object
      properties:
        name:
          type: string

Generated output (now correct):

class Pet(BaseModel):
    pet_type: Annotated[str, Field(alias='petType')]

class Cat(Pet):
    name: str | None = None
    pet_type: Literal['cat'] = Field(..., alias='petType')

This fixes the issue where discriminator literal types were not applied to
subtype schemas when using allOf inheritance without a container schema
that references the parent.

When a parent schema (like Pet) has a discriminator and subtypes (like Cat,
Dog, Lizard) inherit from it via allOf, the discriminator literal types
should be applied to the subtypes' discriminator field (e.g., petType
should become Literal['cat'] in Cat).

Previously, this only worked when there was a container schema (like
PetContainer) that referenced the parent schema with a field. Now the
discriminator types are applied even without such a container.

Changes:
- Added _get_discriminator_info_for_subtype() hook in base Parser class
- Overrode the hook in OpenAPIParser to return discriminator info for subtypes
- Extended __apply_discriminator_type() to process known subtypes directly
- Added test case for discriminator+allOf without container reference

Fixes koxudaxi#2528
@staging-devin-ai-integration
Copy link
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants