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

Dataclass code gen error: TypeError: non-default argument 'XYZ' follows default argument

Open JoanPuig opened this issue 1 year ago • 0 comments

Describe the bug Generated classes create code that errors with TypeError: non-default argument 'XYZ' follows default argument.

To Reproduce

Example schema:
openapi: 3.0.0
components:
  schemas:
    Error:
      type: object
      description: Parent error component inherited by all error types.
      properties:
        message:
          type: string
    InternalServerError:
      description: Internal Server Error
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          required: [code]
          properties:
            code:
              $ref: '#/components/schemas/InternalServerErrorCode'
    InternalServerErrorCode:
      type: string
      enum: [INTERNAL_SERVER_ERROR]
    ServiceUnavailableError:
      description: Service Unavailable Error
      allOf:
        - $ref: '#/components/schemas/Error'
        - type: object
          required: [code]
          properties:
            code:
              $ref: '#/components/schemas/ServiceUnavailableErrorCode'
    ServiceUnavailableErrorCode:
      type: string
      enum: [SERVICE_UNAVAILABLE]

Used commandline:

datamodel-codegen --input .\spec.yml --input-file-type openapi --output .\model.py --output-model-type dataclasses.dataclass --use-generic-container-types --use-generic-container-types --enable-version-header --target-python-version 3.11 --field-constraints --use-annotated  --use-default

Generated code:

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum
from typing import Optional


@dataclass
class Error:
    message: Optional[str] = None


class InternalServerErrorCode(Enum):
    INTERNAL_SERVER_ERROR = 'INTERNAL_SERVER_ERROR'


class ServiceUnavailableErrorCode(Enum):
    SERVICE_UNAVAILABLE = 'SERVICE_UNAVAILABLE'


@dataclass
class InternalServerError(Error):
    code: InternalServerErrorCode


@dataclass
class ServiceUnavailableError(Error):
    code: ServiceUnavailableErrorCode

Which is inconsistent and will lead to the following error:

TypeError: non-default argument 'code' follows default argument

This can be solved by adding kw_only argument as to the dataclass annotation as follows: @dataclass(kw_only=True) as described in: https://stackoverflow.com/questions/69711886/python-dataclasses-inheritance-and-default-values

JoanPuig avatar May 16 '24 07:05 JoanPuig