Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default value should be from type RootModel and not string #2116

Open
ubaumann opened this issue Oct 15, 2024 · 0 comments
Open

Default value should be from type RootModel and not string #2116

ubaumann opened this issue Oct 15, 2024 · 0 comments

Comments

@ubaumann
Copy link

Describe the bug
When I use --use-annotated, the default value for a RootModel field is a string. I would expect it to be the RootModel("value")

To Reproduce

Example schema:

{
    "$defs": {
        "AdminStateLeaf": {
            "$ref": "#/$defs/AdminStateType",
            "title": "AdminStateLeaf"
        },
        "AdminStateType": {
            "$ref": "#/$defs/EnumerationEnum",
            "title": "AdminStateType"
        },
        "EnumerationEnum": {
            "enum": [
                "enable",
                "disable"
            ],
            "title": "EnumerationEnum",
            "type": "string"
        }
    },
    "description": "List of configured device interfaces",
    "properties": {
        "interfaces:admin-state": {
            "$ref": "#/$defs/AdminStateLeaf",
            "default": "enable"
        }
    },
    "title": "InterfacesListEntry",
    "type": "object"
}

Used commandline:

$ datamodel-codegen --input-file-type jsonschema --input simple.json --output-model-type pydantic_v2.BaseModel --output model_simple.py --use-annotated

Expected behavior
I expect the default value to be the RootModel. Expected model (difference is in InterfacesListEntry):

from __future__ import annotations

from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field, RootModel
from typing_extensions import Annotated


class EnumerationEnum(Enum):
    enable = 'enable'
    disable = 'disable'


class AdminStateType(RootModel[EnumerationEnum]):
    root: Annotated[EnumerationEnum, Field(title='AdminStateType')]


class AdminStateLeaf(RootModel[AdminStateType]):
    root: Annotated[AdminStateType, Field(title='AdminStateLeaf')]


class InterfacesListEntry(BaseModel):
    interfaces_admin_state: Annotated[
        AdminStateLeaf, Field(AdminStateLeaf("enable"), alias="interfaces:admin-state")
    ]

Generated model:

from __future__ import annotations

from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field, RootModel
from typing_extensions import Annotated


class EnumerationEnum(Enum):
    enable = 'enable'
    disable = 'disable'


class AdminStateType(RootModel[EnumerationEnum]):
    root: Annotated[EnumerationEnum, Field(title='AdminStateType')]


class AdminStateLeaf(RootModel[AdminStateType]):
    root: Annotated[AdminStateType, Field(title='AdminStateLeaf')]


class InterfacesListEntry(BaseModel):
    interfaces_admin_state: Annotated[
        Optional[AdminStateLeaf], Field(alias='interfaces:admin-state')
    ] = 'enable'

Version:

  • OS: Ubunut
  • Python version: 3.10.14
  • datamodel-code-generator version: develop branch

Additional context
The following are examples of the generated model (in the first part, the value is a string and not a RootModel):

>>> import model_simple
>>> model_simple.InterfacesListEntry.parse_obj({})
InterfacesListEntry(interfaces_admin_state='enable')
>>> model_simple.InterfacesListEntry.parse_obj({"interfaces:admin-state":"disable"})
InterfacesListEntry(interfaces_admin_state=AdminStateLeaf(root=AdminStateType(root=<EnumerationEnum.disable: 'disable'>)))
>>> model_simple.InterfacesListEntry.parse_obj({"interfaces:admin-state":"enable"})
InterfacesListEntry(interfaces_admin_state=AdminStateLeaf(root=AdminStateType(root=<EnumerationEnum.enable: 'enable'>)))
>>> 

This is the same test using the expected code.

>>> import model_simple
>>> model_simple.InterfacesListEntry.parse_obj({})
InterfacesListEntry(interfaces_admin_state=AdminStateLeaf(root=AdminStateType(root=<EnumerationEnum.enable: 'enable'>)))
>>> model_simple.InterfacesListEntry.parse_obj({"interfaces:admin-state":"disable"})
InterfacesListEntry(interfaces_admin_state=AdminStateLeaf(root=AdminStateType(root=<EnumerationEnum.disable: 'disable'>)))
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

No branches or pull requests

2 participants
@ubaumann and others