Is your feature request related to a problem? Please describe.
Enums generate classes to represent the the type, for example the following JSONSchema:
"kind": {
"type": "string",
"enum": [
"RoleBindingList"
]
},
will generate:
class Kind155(Enum):
role_binding_list = "RoleBindingList"
This is a common case in APIs as there often is a type or kind field which is a constant value. Having hundreds of classes called Kind* results in several
kind: Optional[Kind155] = Field(...) is not a helpful type annotationDescribe the solution you'd like
It would be great if dcg would recognize these as constants instead of an enum.
This way they could be named after the value instead of the key.
class Kind155(Enum):
role_binding_list = "RoleBindingList"
Could become:
class RoleBindingList(Enum):
role_binding_list = "RoleBindingList"
Describe alternatives you've considered
Even better might be:
RoleBindingList = typing.Literal["RoleBindingList"]
But that would only be python 3.8 compatible.
Additional improvement
As an added bonus when implementing this, merging constants (having the same constant twice, merge into one type deceleration). Currently I get one enum class for every use of a constant - evne if it is the same constant, e.g.:
class Kind139(Enum):
role_binding_list = "RoleBindingList"
# ...
class Kind155(Enum):
role_binding_list = "RoleBindingList"
Implementation
I have not yet looked into it how much work it would be / how to implement it. Was looking for your @koxudaxi comments first. Is this something you would support?
@FlorianLudwig
I'm sorry. I overlooked a notification for this issue.
I add an option --reuse-model that is reusing the same content model. https://github.com/koxudaxi/datamodel-code-generator/issues/170
The option may cover your-case.
{
"definitions": {
"cat": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"animal"
]
}
}
},
"dog": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"animal"
]
}
}
},
"snake": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"animal"
]
}
}
}
}
}
...
class Kind(Enum):
animal = 'animal'
class Cat(BaseModel):
kind: Optional[Kind] = None
class Kind1(Enum):
animal = 'animal'
class Dog(BaseModel):
kind: Optional[Kind] = None
class Kind2(Enum):
animal = 'animal'
class Snake(BaseModel):
kind: Optional[Kind] = None
class RoleBindingList(Enum):
role_binding_list = "RoleBindingList"
Did you expect the enum is only one when you want to change class name?
If I know the rule when class name is changed then, I can implement it.
RoleBindingList = typing.Literal["RoleBindingList"]
But that would only be python 3.8 compatible.
I feel it's a good idea 馃槃
I guess this option should be provide with --target-python-version 3.8 or later.
Hey,
thanks for the detailed explanation. --reuse-model sounds awesome.
Regarding changing the class name: My idea was to change it when an enum has only one possible value. Because in this case it is not really a enum but a constant.
The idea with the --target-python-version 3.8 sounds perfect to me too.
@FlorianLudwig
I have added a new option --enum-field-as-literal on 0.6.23.
I provide two values are all or one for the option.
_all enum field type is Literal_
--target-python-version 3.8 --enum-field-as-literal all
https://github.com/koxudaxi/datamodel-code-generator/blob/f9b64e0a214d9ecbe583289c6e8d6752e1d9cbb4/tests/data/expected/main/main_openapi_enum_models_all/output.py#L13-L18
_the field type is Literal when an enum has only one possible value_
--target-python-version 3.8 --enum-field-as-literal one
https://github.com/koxudaxi/datamodel-code-generator/blob/f9b64e0a214d9ecbe583289c6e8d6752e1d9cbb4/tests/data/expected/main/main_openapi_enum_models_one/output.py#L13-L23
Most helpful comment
@FlorianLudwig
I have added a new option
--enum-field-as-literalon0.6.23.I provide two values are
alloronefor the option.all
_all enum field type is Literal_
--target-python-version 3.8 --enum-field-as-literal allhttps://github.com/koxudaxi/datamodel-code-generator/blob/f9b64e0a214d9ecbe583289c6e8d6752e1d9cbb4/tests/data/expected/main/main_openapi_enum_models_all/output.py#L13-L18
one
_the field type is Literal when an enum has only one possible value_
--target-python-version 3.8 --enum-field-as-literal onehttps://github.com/koxudaxi/datamodel-code-generator/blob/f9b64e0a214d9ecbe583289c6e8d6752e1d9cbb4/tests/data/expected/main/main_openapi_enum_models_one/output.py#L13-L23