koxudaxi/datamodel-code-generator

Incompatible Default Value When Field is Generated as RootModel

mengxiFH opened this issue · 0 comments

Describe the bug

class Timeout(RootModel[int]):
    root: int = Field(examples=[3600], gt=0, le=14400, title='Timeout')
    """
    Timeout for the crawler run in seconds
    """


class CrawlConfiguration(BaseModel):
    timeout: Timeout | None = Field(default=3600, examples=[3600], title='Timeout')
    """
    Timeout for the crawler run in seconds
    """

Above code is automatically generated. The CrawlConfiguration class has a timeout field, which is defined as Timeout | None. However, the default value for this field is set to an int, which is incompatible with the Timeout type. This inconsistency causes issues when calling module_dump(), as it will result in an error because the timeout field is expected to be of type Timeout or None, not an int.

To Reproduce

Example schema:

{
    "openapi": "3.1.0",
    "info":
    {
        "title": "UI API",
        "version": "0.1.0"
    },
    ...
    "CrawlConfiguration":
    {
        "properties":
        {
            "timeout":
            {
                "anyOf":
                [
                    {
                        "type": "integer",
                        "maximum": 14400,
                        "exclusiveMinimum": 0
                    },
                    {
                        "type": "null"
                    }
                ],
                "title": "Timeout",
                "description": "Timeout for the crawler run in seconds",
                "default": 3600,
                "examples":
                [
                    3600
                ]
            }
        }
    }
}

Used commandline:

datamodel-codegen \
    --output-model-type pydantic_v2.BaseModel \
    --url https://xxx/openapi.json \
    --input-file-type openapi \
    --output ./src/ui_api_schemas.py \
    --target-python-version 3.11 \
    --use-schema-description \
    --strict-nullable \
    --use-union-operator \
    --use-field-description \
    --use-standard-collections \
    --field-constraints \
    --use-subclass-enum \
    --use-default-kwarg \
    --openapi-scopes {schemas,paths,parameters} \
    --set-default-enum-member \
    --additional-imports enum.StrEnum,pydantic.ConfigDict;

Expected behavior

class Timeout(RootModel[int]):
    root: int = Field(examples=[3600], gt=0, le=14400, title='Timeout')
    """
    Timeout for the crawler run in seconds
    """


class CrawlConfiguration(BaseModel):
    timeout: Timeout | None = Field(default=Timeout(3600), examples=[3600], title='Timeout')
    """
    Timeout for the crawler run in seconds
    """

or

class CrawlConfiguration(BaseModel):
    timeout: int | None = Field(
        default=3600,
        description="Timeout for the crawler run in seconds",
        gt=0,
        le=14400,  # 4 hours
        examples=[3600],
    )

Version:

  • OS: macOS Ventura, version 13.5
  • Python version: 3.11
  • datamodel-code-generator version: 0.25.5

Additional context
Add any other context about the problem here.