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

Error when generating --enum-field-as-literal all from multiple files with same schema names

Open igorbanfi opened this issue 2 years ago • 1 comments

Describe the bug When generating models from openapi yaml that references multiple files with same schemas, and setting --enum-field-as-literal all following Exception is raised:

python3.10/site-packages/datamodel_code_generator/parser/base.py", line 595, in __delete_duplicate_models child.replace_reference(model.reference) AttributeError: 'BaseModel' object has no attribute 'replace_reference'

To Reproduce

test_openapi.yaml:

openapi: 3.0.1
info:
  title: Test
  description: Test
  version: 0.0.1
servers:
- url: 'https'
paths:
  /test:
    post:
      description: "Test"
      operationId: "Test"
      parameters: []
      requestBody:
        description: ""
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Test"
      responses:
        default:
          description: ""

components:
  schemas:
    Test:
      title: "Test"
      type: object
      description: ""
      properties:
        obj1:
          $ref: "./schemas1.yaml#/components/schemas/Schema1"
        obj2:
          $ref: "./schemas2.yaml#/components/schemas/Schema1"

schemas1.yaml:

openapi: 3.0.0
info:
  title: Schemas
  description: Schemas
  version: 1.0.0
paths:
  /:
    get:
      responses:
        default:
          description: x

components:
  schemas:
    Object:
      description: ""
      type: object
      properties:
        "type":
          type: string
          enum:
          - A1
          - A2
          - A3
      required:
      - type
      discriminator:
        propertyName: type

    Schema1:
      description: ""
      allOf:
      - $ref: "#/components/schemas/Object"
      - type: "object"
        properties:
          sth:
            type: string

schemas2.yaml:

openapi: 3.0.0
info:
  title: Schemas
  description: Schemas
  version: 1.0.0
paths:
  /:
    get:
      responses:
        default:
          description: x

components:
  schemas:
    Object:
      description: ""
      type: object
      properties:
        "type":
          type: string
          enum:
          - A1
          - A2
          - A3
      required:
      - type
      discriminator:
        propertyName: type

    Schema1:
      description: ""
      allOf:
      - $ref: "#/components/schemas/Object"
      - type: "object"
        properties:
          sth:
            type: string

Used commandline:

$ datamodel-codegen --input test_openapi.yaml --output test.py --target-python-version 3.10 --enum-field-as-literal all

Expected behavior Expected the generation of a pydantic schema

Version:

  • OS: Ubuntu 22
  • Python version: 3.10
  • datamodel-code-generator version: 0.21.5

igorbanfi avatar Sep 13 '23 13:09 igorbanfi

I'm getting the same exception, but is not related to the --enum-field-as-literal value. In fact I am running the process with the attribute set to one or without the attribute set at all. Python version 3.12.1 and datamodel-code-generator version 0.25.2

Traceback:

Traceback (most recent call last):
  File "/home/lupo/DevOps/NWU/netbox-scripts/generate_datamodel.py", line 45, in <module>
    generate(
  File "/home/lupo/.pyenv/versions/dcg/lib/python3.12/site-packages/datamodel_code_generator/__init__.py", line 463, in generate
    results = parser.parse()
              ^^^^^^^^^^^^^^
  File "/home/lupo/.pyenv/versions/dcg/lib/python3.12/site-packages/datamodel_code_generator/parser/base.py", line 1194, in parse
    self.__delete_duplicate_models(models)
  File "/home/lupo/.pyenv/versions/dcg/lib/python3.12/site-packages/datamodel_code_generator/parser/base.py", line 635, in __delete_duplicate_models
    child.replace_reference(model.reference)
    ^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'BaseModel' object has no attribute 'replace_reference'

Code being run

from pathlib import Path
from datamodel_code_generator import InputFileType, generate
from datamodel_code_generator import DataModelType

with open("data/openapi.json", "r") as schema:

    generate(
        schema.read(),
        input_file_type=InputFileType.OpenAPI,
        input_filename="openapi.json",
        output=Path("model.py"),
        # set up the output model types
        output_model_type=DataModelType.PydanticV2BaseModel,
        enum_field_as_literal="one"
    )

openapi document available at https://docs.nvidia.com/networking-ethernet-software/cumulus-linux-57/api/openapi.json

LuPo avatar Jan 11 '24 14:01 LuPo