datamodel-code-generator
datamodel-code-generator copied to clipboard
Enum defaults haves have broken import path prefix when using `dataclasses.dataclass`
Describe the bug
When I use --output-model-type=dataclasses.dataclass, datamodel-codegen generates enums with invalid defaults. The defaults are invalid because they refer to enums defined in the same package by their full import path.
To Reproduce
Example schema:
The above file was produced by running:
curl http://localhost:8001/openapi/v3/apis/s3.aws.upbound.io/v1beta2>openapi.json
Used commandline:
datamodel-codegen \
--url http://localhost:8001/openapi/v3/apis/s3.aws.upbound.io/v1beta2 \
--target-python-version=3.12 \
--output generated \
--output-model-type=dataclasses.dataclass \
--use-field-description
Expected behavior I expect valid code to be generated, but it seems that the default values of enum fields are including the full import prefix, even though the types are defined in the same package.
class Resolution(Enum):
Required = 'Required'
Optional = 'Optional'
class Resolve(Enum):
Always = 'Always'
IfNotPresent = 'IfNotPresent'
@dataclass
class Policy:
resolution: Optional[Resolution] = io.upbound.aws.s3.v1beta2.Resolution.Required
"""
Resolution specifies whether resolution of this reference is required.
The default is 'Required', which means the reconcile will fail if the
reference cannot be resolved. 'Optional' means this reference will be
a no-op if it cannot be resolved.
"""
resolve: Optional[Resolve] = None
"""
Resolve specifies when this reference should be resolved. The default
is 'IfNotPresent', which will attempt to resolve the reference only when
the corresponding field is not present. Use 'Always' to resolve the
reference on every reconcile.
"""
Here both the Resolution and Policy classes are part of the the io.upbound.aws.s3.v1beta2 package, defined in the same file. Note that the default for the resolution field is io.upbound.aws.s3.v1beta2.Resolution.Required. If I edit it to remove the io.upbound.aws.s3.v1beta2. prefix, the code works. If I try to run the code as generated I get this error:
$ ./.fn/bin/python composition.py
Traceback (most recent call last):
File "/home/negz/experiment/python-composition/composition.py", line 7, in <module>
from generated.io.upbound.aws.s3 import v1beta2
File "/home/negz/experiment/python-composition/generated/io/upbound/aws/s3/v1beta2.py", line 76, in <module>
class Policy:
File "/home/negz/experiment/python-composition/generated/io/upbound/aws/s3/v1beta2.py", line 77, in Policy
resolution: Optional[Resolution] = io.upbound.aws.s3.v1beta2.Resolution.Required
^^
NameError: name 'io' is not defined. Did you mean: 'id'? Or did you forget to import 'io'?
Version:
- OS:
Linux mael 6.10.10 #1-NixOS SMP Thu Sep 12 09:13:13 UTC 2024 aarch64 GNU/Linux - Python version:
Python 3.12.5 - datamodel-code-generator version: [e.g. 22]
0.26.0
Additional context Add any other context about the problem here.
This issue only occurs for me with --output-model-type=dataclasses.dataclass. I have a slight preference for data classes to avoid the dependency on Pydantic.