Skip to content

Commit 365fcd3

Browse files
authored
Fix the post processing of enums in the Python generator, such that it uses the proper variable namesfrom x-enum-varnames (#18566)
Remove sample
1 parent eec30f2 commit 365fcd3

File tree

10 files changed

+141
-5
lines changed

10 files changed

+141
-5
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,10 @@ private ModelsMap postProcessModelsMap(ModelsMap objs) {
992992
enumVars.put("name", toEnumVariableName((String) enumVars.get("value"), "str"));
993993
} else {
994994
model.vendorExtensions.putIfAbsent("x-py-enum-type", "int");
995-
enumVars.put("name", toEnumVariableName((String) enumVars.get("value"), "int"));
995+
// Do not overwrite the variable name if already set through x-enum-varnames
996+
if (model.vendorExtensions.get("x-enum-varnames") == null) {
997+
enumVars.put("name", toEnumVariableName((String) enumVars.get("value"), "int"));
998+
}
996999
}
9971000
}
9981001
}

modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,35 @@ components:
20602060
enum:
20612061
- 1.1
20622062
- -1.2
2063+
enum_number_vendor_ext:
2064+
type: integer
2065+
format: int32
2066+
enum:
2067+
- 42
2068+
- 18
2069+
- 56
2070+
x-enum-descriptions:
2071+
- 'Description for 42'
2072+
- 'Description for 18'
2073+
- 'Description for 56'
2074+
x-enum-varnames:
2075+
- FortyTwo
2076+
- Eigtheen
2077+
- FiftySix
2078+
enum_string_vendor_ext:
2079+
type: string
2080+
enum:
2081+
- FOO
2082+
- Bar
2083+
- baz
2084+
x-enum-descriptions:
2085+
- 'Description for FOO'
2086+
- 'Description for Bar'
2087+
- 'Description for baz'
2088+
x-enum-varnames:
2089+
- FOOVar
2090+
- BarVar
2091+
- bazVar
20632092
outerEnum:
20642093
$ref: '#/components/schemas/OuterEnum'
20652094
outerEnumInteger:

samples/openapi3/client/petstore/python-aiohttp/docs/EnumTest.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Name | Type | Description | Notes
1010
**enum_integer_default** | **int** | | [optional] [default to 5]
1111
**enum_integer** | **int** | | [optional]
1212
**enum_number** | **float** | | [optional]
13+
**enum_number_vendor_ext** | **int** | | [optional]
14+
**enum_string_vendor_ext** | **str** | | [optional]
1315
**outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional]
1416
**outer_enum_integer** | [**OuterEnumInteger**](OuterEnumInteger.md) | | [optional]
1517
**outer_enum_default_value** | [**OuterEnumDefaultValue**](OuterEnumDefaultValue.md) | | [optional]

samples/openapi3/client/petstore/python-aiohttp/petstore_api/models/enum_test.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ class EnumTest(BaseModel):
3535
enum_integer_default: Optional[StrictInt] = 5
3636
enum_integer: Optional[StrictInt] = None
3737
enum_number: Optional[float] = None
38+
enum_number_vendor_ext: Optional[StrictInt] = None
39+
enum_string_vendor_ext: Optional[StrictStr] = None
3840
outer_enum: Optional[OuterEnum] = Field(default=None, alias="outerEnum")
3941
outer_enum_integer: Optional[OuterEnumInteger] = Field(default=None, alias="outerEnumInteger")
4042
outer_enum_default_value: Optional[OuterEnumDefaultValue] = Field(default=None, alias="outerEnumDefaultValue")
4143
outer_enum_integer_default_value: Optional[OuterEnumIntegerDefaultValue] = Field(default=None, alias="outerEnumIntegerDefaultValue")
42-
__properties: ClassVar[List[str]] = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
44+
__properties: ClassVar[List[str]] = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "enum_number_vendor_ext", "enum_string_vendor_ext", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
4345

4446
@field_validator('enum_string')
4547
def enum_string_validate_enum(cls, value):
@@ -88,6 +90,26 @@ def enum_number_validate_enum(cls, value):
8890
raise ValueError("must be one of enum values (1.1, -1.2)")
8991
return value
9092

93+
@field_validator('enum_number_vendor_ext')
94+
def enum_number_vendor_ext_validate_enum(cls, value):
95+
"""Validates the enum"""
96+
if value is None:
97+
return value
98+
99+
if value not in set([42, 18, 56]):
100+
raise ValueError("must be one of enum values (42, 18, 56)")
101+
return value
102+
103+
@field_validator('enum_string_vendor_ext')
104+
def enum_string_vendor_ext_validate_enum(cls, value):
105+
"""Validates the enum"""
106+
if value is None:
107+
return value
108+
109+
if value not in set(['FOO', 'Bar', 'baz']):
110+
raise ValueError("must be one of enum values ('FOO', 'Bar', 'baz')")
111+
return value
112+
91113
model_config = ConfigDict(
92114
populate_by_name=True,
93115
validate_assignment=True,
@@ -149,6 +171,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
149171
"enum_integer_default": obj.get("enum_integer_default") if obj.get("enum_integer_default") is not None else 5,
150172
"enum_integer": obj.get("enum_integer"),
151173
"enum_number": obj.get("enum_number"),
174+
"enum_number_vendor_ext": obj.get("enum_number_vendor_ext"),
175+
"enum_string_vendor_ext": obj.get("enum_string_vendor_ext"),
152176
"outerEnum": obj.get("outerEnum"),
153177
"outerEnumInteger": obj.get("outerEnumInteger"),
154178
"outerEnumDefaultValue": obj.get("outerEnumDefaultValue"),

samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/docs/EnumTest.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Name | Type | Description | Notes
99
**enum_integer_default** | **int** | | [optional] [default to 5]
1010
**enum_integer** | **int** | | [optional]
1111
**enum_number** | **float** | | [optional]
12+
**enum_number_vendor_ext** | **int** | | [optional]
13+
**enum_string_vendor_ext** | **str** | | [optional]
1214
**outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional]
1315
**outer_enum_integer** | [**OuterEnumInteger**](OuterEnumInteger.md) | | [optional]
1416
**outer_enum_default_value** | [**OuterEnumDefaultValue**](OuterEnumDefaultValue.md) | | [optional]

samples/openapi3/client/petstore/python-pydantic-v1-aiohttp/petstore_api/models/enum_test.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ class EnumTest(BaseModel):
3434
enum_integer_default: Optional[StrictInt] = 5
3535
enum_integer: Optional[StrictInt] = None
3636
enum_number: Optional[float] = None
37+
enum_number_vendor_ext: Optional[StrictInt] = None
38+
enum_string_vendor_ext: Optional[StrictStr] = None
3739
outer_enum: Optional[OuterEnum] = Field(default=None, alias="outerEnum")
3840
outer_enum_integer: Optional[OuterEnumInteger] = Field(default=None, alias="outerEnumInteger")
3941
outer_enum_default_value: Optional[OuterEnumDefaultValue] = Field(default=None, alias="outerEnumDefaultValue")
4042
outer_enum_integer_default_value: Optional[OuterEnumIntegerDefaultValue] = Field(default=None, alias="outerEnumIntegerDefaultValue")
41-
__properties = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
43+
__properties = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "enum_number_vendor_ext", "enum_string_vendor_ext", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
4244

4345
@validator('enum_string')
4446
def enum_string_validate_enum(cls, value):
@@ -87,6 +89,26 @@ def enum_number_validate_enum(cls, value):
8789
raise ValueError("must be one of enum values (1.1, -1.2)")
8890
return value
8991

92+
@validator('enum_number_vendor_ext')
93+
def enum_number_vendor_ext_validate_enum(cls, value):
94+
"""Validates the enum"""
95+
if value is None:
96+
return value
97+
98+
if value not in (42, 18, 56):
99+
raise ValueError("must be one of enum values (42, 18, 56)")
100+
return value
101+
102+
@validator('enum_string_vendor_ext')
103+
def enum_string_vendor_ext_validate_enum(cls, value):
104+
"""Validates the enum"""
105+
if value is None:
106+
return value
107+
108+
if value not in ('FOO', 'Bar', 'baz'):
109+
raise ValueError("must be one of enum values ('FOO', 'Bar', 'baz')")
110+
return value
111+
90112
class Config:
91113
"""Pydantic configuration"""
92114
allow_population_by_field_name = True
@@ -133,6 +155,8 @@ def from_dict(cls, obj: dict) -> EnumTest:
133155
"enum_integer_default": obj.get("enum_integer_default") if obj.get("enum_integer_default") is not None else 5,
134156
"enum_integer": obj.get("enum_integer"),
135157
"enum_number": obj.get("enum_number"),
158+
"enum_number_vendor_ext": obj.get("enum_number_vendor_ext"),
159+
"enum_string_vendor_ext": obj.get("enum_string_vendor_ext"),
136160
"outer_enum": obj.get("outerEnum"),
137161
"outer_enum_integer": obj.get("outerEnumInteger"),
138162
"outer_enum_default_value": obj.get("outerEnumDefaultValue"),

samples/openapi3/client/petstore/python-pydantic-v1/docs/EnumTest.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ Name | Type | Description | Notes
99
**enum_integer_default** | **int** | | [optional] [default to 5]
1010
**enum_integer** | **int** | | [optional]
1111
**enum_number** | **float** | | [optional]
12+
**enum_number_vendor_ext** | **int** | | [optional]
13+
**enum_string_vendor_ext** | **str** | | [optional]
1214
**outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional]
1315
**outer_enum_integer** | [**OuterEnumInteger**](OuterEnumInteger.md) | | [optional]
1416
**outer_enum_default_value** | [**OuterEnumDefaultValue**](OuterEnumDefaultValue.md) | | [optional]

samples/openapi3/client/petstore/python-pydantic-v1/petstore_api/models/enum_test.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ class EnumTest(BaseModel):
3434
enum_integer_default: Optional[StrictInt] = 5
3535
enum_integer: Optional[StrictInt] = None
3636
enum_number: Optional[StrictFloat] = None
37+
enum_number_vendor_ext: Optional[StrictInt] = None
38+
enum_string_vendor_ext: Optional[StrictStr] = None
3739
outer_enum: Optional[OuterEnum] = Field(default=None, alias="outerEnum")
3840
outer_enum_integer: Optional[OuterEnumInteger] = Field(default=None, alias="outerEnumInteger")
3941
outer_enum_default_value: Optional[OuterEnumDefaultValue] = Field(default=None, alias="outerEnumDefaultValue")
4042
outer_enum_integer_default_value: Optional[OuterEnumIntegerDefaultValue] = Field(default=None, alias="outerEnumIntegerDefaultValue")
4143
additional_properties: Dict[str, Any] = {}
42-
__properties = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
44+
__properties = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "enum_number_vendor_ext", "enum_string_vendor_ext", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
4345

4446
@validator('enum_string')
4547
def enum_string_validate_enum(cls, value):
@@ -88,6 +90,26 @@ def enum_number_validate_enum(cls, value):
8890
raise ValueError("must be one of enum values (1.1, -1.2)")
8991
return value
9092

93+
@validator('enum_number_vendor_ext')
94+
def enum_number_vendor_ext_validate_enum(cls, value):
95+
"""Validates the enum"""
96+
if value is None:
97+
return value
98+
99+
if value not in (42, 18, 56):
100+
raise ValueError("must be one of enum values (42, 18, 56)")
101+
return value
102+
103+
@validator('enum_string_vendor_ext')
104+
def enum_string_vendor_ext_validate_enum(cls, value):
105+
"""Validates the enum"""
106+
if value is None:
107+
return value
108+
109+
if value not in ('FOO', 'Bar', 'baz'):
110+
raise ValueError("must be one of enum values ('FOO', 'Bar', 'baz')")
111+
return value
112+
91113
class Config:
92114
"""Pydantic configuration"""
93115
allow_population_by_field_name = True
@@ -140,6 +162,8 @@ def from_dict(cls, obj: dict) -> EnumTest:
140162
"enum_integer_default": obj.get("enum_integer_default") if obj.get("enum_integer_default") is not None else 5,
141163
"enum_integer": obj.get("enum_integer"),
142164
"enum_number": obj.get("enum_number"),
165+
"enum_number_vendor_ext": obj.get("enum_number_vendor_ext"),
166+
"enum_string_vendor_ext": obj.get("enum_string_vendor_ext"),
143167
"outer_enum": obj.get("outerEnum"),
144168
"outer_enum_integer": obj.get("outerEnumInteger"),
145169
"outer_enum_default_value": obj.get("outerEnumDefaultValue"),

samples/openapi3/client/petstore/python/docs/EnumTest.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Name | Type | Description | Notes
1010
**enum_integer_default** | **int** | | [optional] [default to 5]
1111
**enum_integer** | **int** | | [optional]
1212
**enum_number** | **float** | | [optional]
13+
**enum_number_vendor_ext** | **int** | | [optional]
14+
**enum_string_vendor_ext** | **str** | | [optional]
1315
**outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional]
1416
**outer_enum_integer** | [**OuterEnumInteger**](OuterEnumInteger.md) | | [optional]
1517
**outer_enum_default_value** | [**OuterEnumDefaultValue**](OuterEnumDefaultValue.md) | | [optional]

samples/openapi3/client/petstore/python/petstore_api/models/enum_test.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@ class EnumTest(BaseModel):
3535
enum_integer_default: Optional[StrictInt] = 5
3636
enum_integer: Optional[StrictInt] = None
3737
enum_number: Optional[StrictFloat] = None
38+
enum_number_vendor_ext: Optional[StrictInt] = None
39+
enum_string_vendor_ext: Optional[StrictStr] = None
3840
outer_enum: Optional[OuterEnum] = Field(default=None, alias="outerEnum")
3941
outer_enum_integer: Optional[OuterEnumInteger] = Field(default=None, alias="outerEnumInteger")
4042
outer_enum_default_value: Optional[OuterEnumDefaultValue] = Field(default=None, alias="outerEnumDefaultValue")
4143
outer_enum_integer_default_value: Optional[OuterEnumIntegerDefaultValue] = Field(default=None, alias="outerEnumIntegerDefaultValue")
4244
additional_properties: Dict[str, Any] = {}
43-
__properties: ClassVar[List[str]] = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
45+
__properties: ClassVar[List[str]] = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "enum_number_vendor_ext", "enum_string_vendor_ext", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
4446

4547
@field_validator('enum_string')
4648
def enum_string_validate_enum(cls, value):
@@ -89,6 +91,26 @@ def enum_number_validate_enum(cls, value):
8991
raise ValueError("must be one of enum values (1.1, -1.2)")
9092
return value
9193

94+
@field_validator('enum_number_vendor_ext')
95+
def enum_number_vendor_ext_validate_enum(cls, value):
96+
"""Validates the enum"""
97+
if value is None:
98+
return value
99+
100+
if value not in set([42, 18, 56]):
101+
raise ValueError("must be one of enum values (42, 18, 56)")
102+
return value
103+
104+
@field_validator('enum_string_vendor_ext')
105+
def enum_string_vendor_ext_validate_enum(cls, value):
106+
"""Validates the enum"""
107+
if value is None:
108+
return value
109+
110+
if value not in set(['FOO', 'Bar', 'baz']):
111+
raise ValueError("must be one of enum values ('FOO', 'Bar', 'baz')")
112+
return value
113+
92114
model_config = ConfigDict(
93115
populate_by_name=True,
94116
validate_assignment=True,
@@ -157,6 +179,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
157179
"enum_integer_default": obj.get("enum_integer_default") if obj.get("enum_integer_default") is not None else 5,
158180
"enum_integer": obj.get("enum_integer"),
159181
"enum_number": obj.get("enum_number"),
182+
"enum_number_vendor_ext": obj.get("enum_number_vendor_ext"),
183+
"enum_string_vendor_ext": obj.get("enum_string_vendor_ext"),
160184
"outerEnum": obj.get("outerEnum"),
161185
"outerEnumInteger": obj.get("outerEnumInteger"),
162186
"outerEnumDefaultValue": obj.get("outerEnumDefaultValue"),

0 commit comments

Comments
 (0)