Skip to content

Multiple types in array not well supported -> buggy parser #2488

@pierresouchay

Description

@pierresouchay

Describe the bug

When having multiple types (and one is object), the other types are discarded, so the generated parser does not work.

To Reproduce

Example schema:

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "id": "compose_spec.json",
  "type": "object",
  "title": "Compose Specification",
  "description": "The Compose file is a YAML file defining a multi-containers based application.",

  "properties": {

    "volumes": {
      "id": "#/properties/volumes",
      "type": "object",
      "patternProperties": {
        "^[a-zA-Z0-9._-]+$": {
          "$ref": "#/definitions/volume"
        }
      },
      "additionalProperties": false
    }
  },

  "patternProperties": {"^x-": {}},
  "additionalProperties": false,

  "definitions": {

    "volume": {
      "id": "#/definitions/volume",
      "type": ["object", "null"],
      "properties": {
        "name": {"type": "string"},
        "external": {
          "type": ["boolean", "object"],
          "properties": {
            "name": {
              "deprecated": true,
              "type": "string"
            }
          },
          "additionalProperties": false,
          "patternProperties": {"^x-": {}}
        }
      },
      "additionalProperties": false,
      "patternProperties": {"^x-": {}}
    }
  }
}

Used commandline:

datamodel-codegen --input compose-spec-small.json --output-model-type pydantic_v2.BaseModel --field-constraints --output compose.py

Expected behavior

Generated code for external should be a union of boolean, object, something like:

external: Optional[Union[bool, External]] = None

But it is actually:

class External(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: Optional[str] = None


class Volume(BaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    name: Optional[str] = None
    external: Optional[External] = None

=> I expect "type": ["boolean", "object"], to be mapped as external: Optional[Union[bool, External]] = None

=> Likely a bug in https://github.com/koxudaxi/datamodel-code-generator/blob/main/src/datamodel_code_generator/parser/jsonschema.py#L1113 where if object has properties, other types are simply discarded and only object is kept

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions