datamodel-code-generator icon indicating copy to clipboard operation
datamodel-code-generator copied to clipboard

Referenced basic types (like strings) are converted to classes

Open Trolldemorted opened this issue 1 year ago • 2 comments

Describe the bug If a string is referenced, it is turned into a separate class that wraps the string.

To Reproduce

Given this schema:

{
  "openapi" : "3.0.0",
  "components" : {
    "schemas" : {
      "UserId" : {
        "type" : "string",
      },
      "Tweet" : {
        "type" : "object",
        "properties" : {
          "author_id" : {
            "$ref" : "#/components/schemas/UserId"
          }
        }
      }
    }
  }
}

datamodel-code-generator emits:

# generated by datamodel-codegen:
#   filename:  minimal.json
#   timestamp: 2022-08-10T13:22:26+00:00

from __future__ import annotations

from typing import Optional

from pydantic import BaseModel, constr


class UserId(BaseModel):
    __root__: str


class Tweet(BaseModel):
    author_id: Optional[UserId] = None

Would it be difficult to directly use a string in those cases?

Version:

  • OS: Ubuntu 20.04
  • Python version: 3.8.10
  • datamodel-code-generator version: 0.13.0

Trolldemorted avatar Aug 10 '22 13:08 Trolldemorted

@Trolldemorted The CLI doesn't provide a solution. We should implement a new option. What do you expect?

class Tweet(BaseModel):
    author_id: Optional[str] = None

Or,

UserId = str
class Tweet(BaseModel):
    author_id: Optional[UserId] = None

🤔

koxudaxi avatar Aug 13 '22 13:08 koxudaxi

The first one looks way better, keeping things simple is always good :)

Trolldemorted avatar Aug 19 '22 08:08 Trolldemorted

This works fine for single references, but if a definition is referenced multiple times it causes all field attributes (e.g. Annotated[str, Field(regex='...', description='...')]) to be duplicated unnecessarily for each field. This makes keeping the output model internally consistent more difficult when editing it manually.

While i think this change has some uses, I'd prefer a choice between "force inline", "force class" and potentially "auto", which would check the reference count to decide on a case by case basis.

Dominic-Walther avatar Nov 04 '22 13:11 Dominic-Walther

@Trolldemorted @Trolldemorted @Dominic-Walther

I have released the new version as 0.14.1. The version has this option.

 --collapse-root-models
                        Models generated with a root-type field will be
                        merged into the models using that root-type model

koxudaxi avatar Dec 31 '22 02:12 koxudaxi

@koxudaxi Thank you for implementing the feature. With the given test scheme everything works as expected. We tried the slightly larger Twitter API specification as source and get the following error:

Traceback (most recent call last):
  File "/home/username/.local/lib/python3.8/site-packages/datamodel_code_generator/__main__.py", line 626, in main
    generate(
  File "/home/username/.local/lib/python3.8/site-packages/datamodel_code_generator/__init__.py", line 384, in generate
    results = parser.parse()
  File "/home/username/.local/lib/python3.8/site-packages/datamodel_code_generator/parser/base.py", line 802, in parse
    model_to_models[unused_model].remove(unused_model)
ValueError: list.remove(x): x not in list

We used this command with the 0.15.0 release: datamodel-codegen --input openapi.json --input-file-type openapi --output model.py --collapse-root-models. Without --collapse-root-models the code is created successfully.

Should we create a new issue?

anneum avatar Jan 09 '23 11:01 anneum

@anneum Thank you for testing the new version. Yes, this is a bug. I fixed the problem https://github.com/koxudaxi/datamodel-code-generator/pull/997/files#diff-34a68196dba5b4f2cef091ddb835f794178254d4c94bff4a84f84e546f2f6db7R802-R803 I merged the PR. But I have not released it yet. you can try it with pip install git+https://github.com/koxudaxi/datamodel-code-generator.git

Also, I checked the Twitter API specification with the master branch, and some root models have gone. But, some type-hint references the deleted root model. I will fix it soon.

koxudaxi avatar Jan 09 '23 12:01 koxudaxi

@anneum I have released the fixed version 0.16.0 Thank you very much!!

koxudaxi avatar Jan 16 '23 14:01 koxudaxi