[BUG][PYTHON][PLUSS OTHERS] Enum variable names not update in all python converters
Bug Report Checklist
- [ ] Have you provided a full/minimal spec to reproduce the issue?
- [ ] Have you validated the input using an OpenAPI validator (example)?
- [ ] Have you tested with the latest master to confirm the issue still exists?
- [ ] Have you searched for related issues/PRs?
- [ ] What's the actual output vs expected output?
- [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
There is no need for a detailed report. This is a simple problem with a simple fix and it applies to all versions.
Description
There is a problem with the Python family of converters when processing enums.
Basically none of them substitutes the enum var extensions.
So using a simple scheme definition
maitred_format:
type: integer
title: Message Format
enum:
- 1
- -1
- 0
x-enum-varnames:
- JSON
- Unknown
- SIBEC
x-enum-descriptions:
- JSON Descriptions
- Unknown stuff
- SIBEC Description
The python converter creates this:
class MaitredFormat(int, Enum):
"""
Encoding format of Payload.
"""
"""
allowed enum values
"""
NUMBER_1 = 1
NUMBER_MINUS_1 = -1
NUMBER_0 = 0
@classmethod
def from_json(cls, json_str: str) -> MaitredFormat:
"""Create an instance of MaitredFormat from a JSON string"""
return MaitredFormat(json.loads(json_str))
If you look at the generated model info, the relevant part is found to be.
{
...,
"model" : {
...,
"classname" : "MaitredFormat",
...,
"allowableValues" : {
"values" : [ 1, -1, 0 ],
"enumVars" : [ {
"name" : "NUMBER_1",
"isString" : false,
"enumDescription" : "JSON Descriptions",
"value" : "1"
}, {
"name" : "NUMBER_MINUS_1",
"isString" : false,
"enumDescription" : "Unknown stuff",
"value" : "-1"
}, {
"name" : "NUMBER_0",
"isString" : false,
"enumDescription" : "SIBEC Descriptions.",
"value" : "0"
} ]
},
...
}
}
This is because updateEnumVarsWithExtensions() is never called and to fix it, its a simple matter of adding
@Override
public ModelsMap postProcessModels(ModelsMap objs) {
// process enum in models
return postProcessModelsEnum(objs);
}
to the relevant Python????Codegen.java module.
There are a fair number of other language models that don't include a postProcessModels override, not sure if it matters, or not, but it probably does.
Taking a language that does include the call, in this case, csharp, you generate the correct form of enum, i.e.
namespace Org.OpenAPITools.Model
{
public enum MaitredFormat
{
JSON = 1,
Unknown = -1,
SIBEC = 0,
}
}
This is because the model has been processed and looks like this.
{
...,
"model" : {
...,
"classname" : "MaitredFormat",
...,
"allowableValues" : {
"values" : [ 1, -1, 0 ],
"enumVars" : [ {
"name" : "JSON",
"isString" : false,
"enumDescription" : "JSON Descriptions",
"value" : "1"
}, {
"name" : "Unknown",
"isString" : false,
"enumDescription" : "Unknown stuff",
"value" : "-1"
}, {
"name" : "SIBEC",
"isString" : false,
"enumDescription" : "SIBEC Descriptions.",
"value" : "0"
} ]
},
...
}
}
Suggest a fix
Repeat adding
@Override
public ModelsMap postProcessModels(ModelsMap objs) {
// process enum in models
return postProcessModelsEnum(objs);
}
to the relevant Python????Codegen.java module.
This is because updateEnumVarsWithExtensions() is never called and to fix it, its a simple matter of adding
can you please file a PR with the suggested fix?
@wing328 @mwilby
Any updates on a fix for this issue? I'm encountering this as well.
I'm encountering the same problem and this is very annoying. It would be great to have some news 😄
openapi: 3.0.0
info:
version: 1.0.0
title: Weather API
paths: {}
components:
schemas:
WeatherType:
type: integer
format: int32
enum:
- 42
- 18
- 56
x-enum-descriptions:
- 'Blue sky'
- 'Slightly overcast'
- 'Take an umbrella with you'
x-enum-varnames:
- Sunny
- Cloudy
- Rainy
The command i used
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate -i /local/mon_api.yaml -g python-flask -o /local/dist
The generated python file:
from datetime import date, datetime # noqa: F401
from typing import List, Dict # noqa: F401
from openapi_server.models.base_model import Model
from openapi_server import util
class WeatherType(Model):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
"""
"""
allowed enum values
"""
NUMBER_42 = 42
NUMBER_18 = 18
NUMBER_56 = 56
def __init__(self): # noqa: E501
"""WeatherType - a model defined in OpenAPI
"""
self.openapi_types = {
}
self.attribute_map = {
}
@classmethod
def from_dict(cls, dikt) -> 'WeatherType':
"""Returns the dict as a model
:param dikt: A dict.
:type: dict
:return: The WeatherType of this WeatherType. # noqa: E501
:rtype: WeatherType
"""
return util.deserialize_model(dikt, cls)
While postProcessModelsEnum is called here: https://github.com/OpenAPITools/openapi-generator/blob/73f2d8289b2d4069675c79ea5375d9c58ea1853c/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java#L870
its effects are overwritten by the code block further down: https://github.com/OpenAPITools/openapi-generator/blob/73f2d8289b2d4069675c79ea5375d9c58ea1853c/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java#L986C1-L998C14
I created PR #18566 preventing the NUMBER_X transformation to run if x-enum-varnames is provided.