Skip to content

Commit 67af02c

Browse files
authored
python-pydantic-v1: Keep trailing commas for enum validation tuples (OpenAPITools#19985)
* python-pydantic-v1: Keep trailing commas for tuples when enum has just single member * Update samples * Add test for single member enums * Refactor test name
1 parent 66c7b2f commit 67af02c

File tree

35 files changed

+188
-54
lines changed

35 files changed

+188
-54
lines changed

modules/openapi-generator/src/main/resources/python-fastapi/model_generic.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,11 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}
6969
{{/required}}
7070
{{#isArray}}
7171
for i in value:
72-
if i not in ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}):
72+
if i not in ({{#allowableValues}}{{#enumVars}}{{{value}}},{{^-last}} {{/-last}}{{/enumVars}}{{/allowableValues}}):
7373
raise ValueError("each list item must be one of ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})")
7474
{{/isArray}}
7575
{{^isArray}}
76-
if value not in ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}):
76+
if value not in ({{#allowableValues}}{{#enumVars}}{{{value}}},{{^-last}} {{/-last}}{{/enumVars}}{{/allowableValues}}):
7777
raise ValueError("must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})")
7878
{{/isArray}}
7979
return value

modules/openapi-generator/src/main/resources/python-pydantic-v1/model_generic.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}BaseModel{{/parent}}
7474
{{/required}}
7575
{{#isArray}}
7676
for i in value:
77-
if i not in ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}):
77+
if i not in ({{#allowableValues}}{{#enumVars}}{{{value}}},{{^-last}} {{/-last}}{{/enumVars}}{{/allowableValues}}):
7878
raise ValueError("each list item must be one of ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})")
7979
{{/isArray}}
8080
{{^isArray}}
81-
if value not in ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}):
81+
if value not in ({{#allowableValues}}{{#enumVars}}{{{value}}},{{^-last}} {{/-last}}{{/enumVars}}{{/allowableValues}}):
8282
raise ValueError("must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})")
8383
{{/isArray}}
8484
return value

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,15 @@ components:
21242124
- FOOVar
21252125
- BarVar
21262126
- bazVar
2127+
enum_string_single_member:
2128+
type: string
2129+
enum:
2130+
- 'abc'
2131+
enum_integer_single_member:
2132+
type: integer
2133+
format: int32
2134+
enum:
2135+
- 100
21272136
outerEnum:
21282137
$ref: '#/components/schemas/OuterEnum'
21292138
outerEnumInteger:

samples/client/echo_api/python-pydantic-v1/openapi_client/models/default_value.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def array_string_enum_default_validate_enum(cls, value):
4444
return value
4545

4646
for i in value:
47-
if i not in ('success', 'failure', 'unclassified'):
47+
if i not in ('success', 'failure', 'unclassified',):
4848
raise ValueError("each list item must be one of ('success', 'failure', 'unclassified')")
4949
return value
5050

samples/client/echo_api/python-pydantic-v1/openapi_client/models/pet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def status_validate_enum(cls, value):
4242
if value is None:
4343
return value
4444

45-
if value not in ('available', 'pending', 'sold'):
45+
if value not in ('available', 'pending', 'sold',):
4646
raise ValueError("must be one of enum values ('available', 'pending', 'sold')")
4747
return value
4848

samples/client/echo_api/python-pydantic-v1/openapi_client/models/query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def outcomes_validate_enum(cls, value):
3737
return value
3838

3939
for i in value:
40-
if i not in ('SUCCESS', 'FAILURE', 'SKIPPED'):
40+
if i not in ('SUCCESS', 'FAILURE', 'SKIPPED',):
4141
raise ValueError("each list item must be one of ('SUCCESS', 'FAILURE', 'SKIPPED')")
4242
return value
4343

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Name | Type | Description | Notes
1212
**enum_number** | **float** | | [optional]
1313
**enum_number_vendor_ext** | **int** | | [optional]
1414
**enum_string_vendor_ext** | **str** | | [optional]
15+
**enum_string_single_member** | **str** | | [optional]
16+
**enum_integer_single_member** | **int** | | [optional]
1517
**outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional]
1618
**outer_enum_integer** | [**OuterEnumInteger**](OuterEnumInteger.md) | | [optional]
1719
**outer_enum_default_value** | [**OuterEnumDefaultValue**](OuterEnumDefaultValue.md) | | [optional] [default to OuterEnumDefaultValue.PLACED]

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
@@ -37,11 +37,13 @@ class EnumTest(BaseModel):
3737
enum_number: Optional[float] = None
3838
enum_number_vendor_ext: Optional[StrictInt] = None
3939
enum_string_vendor_ext: Optional[StrictStr] = None
40+
enum_string_single_member: Optional[StrictStr] = None
41+
enum_integer_single_member: Optional[StrictInt] = None
4042
outer_enum: Optional[OuterEnum] = Field(default=None, alias="outerEnum")
4143
outer_enum_integer: Optional[OuterEnumInteger] = Field(default=None, alias="outerEnumInteger")
4244
outer_enum_default_value: Optional[OuterEnumDefaultValue] = Field(default=OuterEnumDefaultValue.PLACED, alias="outerEnumDefaultValue")
4345
outer_enum_integer_default_value: Optional[OuterEnumIntegerDefaultValue] = Field(default=OuterEnumIntegerDefaultValue.NUMBER_0, alias="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"]
46+
__properties: ClassVar[List[str]] = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "enum_number_vendor_ext", "enum_string_vendor_ext", "enum_string_single_member", "enum_integer_single_member", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"]
4547

4648
@field_validator('enum_string')
4749
def enum_string_validate_enum(cls, value):
@@ -110,6 +112,26 @@ def enum_string_vendor_ext_validate_enum(cls, value):
110112
raise ValueError("must be one of enum values ('FOO', 'Bar', 'baz')")
111113
return value
112114

115+
@field_validator('enum_string_single_member')
116+
def enum_string_single_member_validate_enum(cls, value):
117+
"""Validates the enum"""
118+
if value is None:
119+
return value
120+
121+
if value not in set(['abc']):
122+
raise ValueError("must be one of enum values ('abc')")
123+
return value
124+
125+
@field_validator('enum_integer_single_member')
126+
def enum_integer_single_member_validate_enum(cls, value):
127+
"""Validates the enum"""
128+
if value is None:
129+
return value
130+
131+
if value not in set([100]):
132+
raise ValueError("must be one of enum values (100)")
133+
return value
134+
113135
model_config = ConfigDict(
114136
populate_by_name=True,
115137
validate_assignment=True,
@@ -173,6 +195,8 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
173195
"enum_number": obj.get("enum_number"),
174196
"enum_number_vendor_ext": obj.get("enum_number_vendor_ext"),
175197
"enum_string_vendor_ext": obj.get("enum_string_vendor_ext"),
198+
"enum_string_single_member": obj.get("enum_string_single_member"),
199+
"enum_integer_single_member": obj.get("enum_integer_single_member"),
176200
"outerEnum": obj.get("outerEnum"),
177201
"outerEnumInteger": obj.get("outerEnumInteger"),
178202
"outerEnumDefaultValue": obj.get("outerEnumDefaultValue") if obj.get("outerEnumDefaultValue") is not None else OuterEnumDefaultValue.PLACED,

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
@@ -11,6 +11,8 @@ Name | Type | Description | Notes
1111
**enum_number** | **float** | | [optional]
1212
**enum_number_vendor_ext** | **int** | | [optional]
1313
**enum_string_vendor_ext** | **str** | | [optional]
14+
**enum_string_single_member** | **str** | | [optional]
15+
**enum_integer_single_member** | **int** | | [optional]
1416
**outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional]
1517
**outer_enum_integer** | [**OuterEnumInteger**](OuterEnumInteger.md) | | [optional]
1618
**outer_enum_default_value** | [**OuterEnumDefaultValue**](OuterEnumDefaultValue.md) | | [optional]

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ class Bathing(BaseModel):
3333
@validator('task_name')
3434
def task_name_validate_enum(cls, value):
3535
"""Validates the enum"""
36-
if value not in ('cleaning_deep'):
36+
if value not in ('cleaning_deep',):
3737
raise ValueError("must be one of enum values ('cleaning_deep')")
3838
return value
3939

4040
@validator('function_name')
4141
def function_name_validate_enum(cls, value):
4242
"""Validates the enum"""
43-
if value not in ('care_nourish'):
43+
if value not in ('care_nourish',):
4444
raise ValueError("must be one of enum values ('care_nourish')")
4545
return value
4646

0 commit comments

Comments
 (0)