From 60e2d605c4e4a85e3eed6c0fda330bd785080571 Mon Sep 17 00:00:00 2001 From: William Cheng Date: Thu, 2 Mar 2023 17:36:38 +0800 Subject: [PATCH] [python-nextgen] fix enum default value (#14846) * fix enum value * add test for default value * update samples, better code format --- .../languages/AbstractPythonCodegen.java | 7 ++--- .../languages/PythonNextgenClientCodegen.java | 26 +++++++++++++++---- ...ith-fake-endpoints-models-for-testing.yaml | 8 ++++++ .../python-nextgen-aiohttp/docs/EnumTest.md | 1 + .../petstore_api/models/enum_test.py | 13 +++++++++- .../petstore/python-nextgen/docs/EnumTest.md | 1 + .../petstore_api/models/enum_test.py | 13 +++++++++- .../python-nextgen/tests/test_model.py | 5 ++++ 8 files changed, 64 insertions(+), 10 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java index b523fe3a808..b3141ce9b03 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractPythonCodegen.java @@ -125,7 +125,6 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co } - /** * Return the default value of the property * @@ -285,7 +284,7 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co } private String toExampleValueRecursive(Schema schema, List includedSchemas, int indentation) { - boolean cycleFound = includedSchemas.stream().filter(s->schema.equals(s)).count() > 1; + boolean cycleFound = includedSchemas.stream().filter(s -> schema.equals(s)).count() > 1; if (cycleFound) { return ""; } @@ -716,5 +715,7 @@ public abstract class AbstractPythonCodegen extends DefaultCodegen implements Co } @Override - public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.PYTHON; } + public GeneratorLanguage generatorLanguage() { + return GeneratorLanguage.PYTHON; + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonNextgenClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonNextgenClientCodegen.java index 5ad71ac6511..ffcbb001c49 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonNextgenClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PythonNextgenClientCodegen.java @@ -1129,15 +1129,17 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements modelImports.add(model.parent); } - // set enum type in extensions + // set enum type in extensions and update `name` in enumVars if (model.isEnum) { for (Map enumVars : (List>) model.getAllowableValues().get("enumVars")) { if ((Boolean) enumVars.get("isString")) { - model.vendorExtensions.put("x-py-enum-type", "str"); + model.vendorExtensions.putIfAbsent("x-py-enum-type", "str"); + // update `name`, e.g. + enumVars.put("name", toEnumVariableName((String) enumVars.get("value"), "str")); } else { - model.vendorExtensions.put("x-py-enum-type", "int"); + model.vendorExtensions.putIfAbsent("x-py-enum-type", "int"); + enumVars.put("name", toEnumVariableName((String) enumVars.get("value"), "int")); } - break; } } @@ -1321,6 +1323,14 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements @Override public String toEnumVarName(String name, String datatype) { + if ("int".equals(datatype) || "float".equals(datatype)) { + return name; + } else { + return "\'" + name + "\'"; + } + } + + public String toEnumVariableName(String name, String datatype) { if (name.length() == 0) { return "EMPTY"; } @@ -1366,7 +1376,7 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements @Override public String toEnumDefaultValue(String value, String datatype) { - return "self::" + datatype + "_" + value; + return value; } /** @@ -1405,4 +1415,10 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements public void setDateFormat(String dateFormat) { this.dateFormat = dateFormat; } + + @Override + public ModelsMap postProcessModels(ModelsMap objs) { + // process enum in models + return postProcessModelsEnum(objs); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml b/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml index 6e228f38056..615c9ff3bd2 100644 --- a/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing.yaml @@ -1630,6 +1630,14 @@ components: - UPPER - lower - '' + enum_integer_default: + type: integer + format: int32 + enum: + - 1 + - 5 + - 14 + default: 5 enum_integer: type: integer format: int32 diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/docs/EnumTest.md b/samples/openapi3/client/petstore/python-nextgen-aiohttp/docs/EnumTest.md index 3c900769031..5bcb8e7027e 100644 --- a/samples/openapi3/client/petstore/python-nextgen-aiohttp/docs/EnumTest.md +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/docs/EnumTest.md @@ -6,6 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **enum_string** | **str** | | [optional] **enum_string_required** | **str** | | +**enum_integer_default** | **int** | | [optional] [default to 5] **enum_integer** | **int** | | [optional] **enum_number** | **float** | | [optional] **outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional] diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_test.py b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_test.py index b6a08b4df7f..c7cb02c5e52 100644 --- a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_test.py +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_test.py @@ -32,13 +32,14 @@ class EnumTest(BaseModel): """ enum_string: Optional[StrictStr] = None enum_string_required: StrictStr = ... + enum_integer_default: Optional[StrictInt] = 5 enum_integer: Optional[StrictInt] = None enum_number: Optional[float] = None outer_enum: Optional[OuterEnum] = Field(None, alias="outerEnum") outer_enum_integer: Optional[OuterEnumInteger] = Field(None, alias="outerEnumInteger") outer_enum_default_value: Optional[OuterEnumDefaultValue] = Field(None, alias="outerEnumDefaultValue") outer_enum_integer_default_value: Optional[OuterEnumIntegerDefaultValue] = Field(None, alias="outerEnumIntegerDefaultValue") - __properties = ["enum_string", "enum_string_required", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"] + __properties = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"] @validator('enum_string') def enum_string_validate_enum(cls, v): @@ -55,6 +56,15 @@ class EnumTest(BaseModel): raise ValueError("must validate the enum values ('UPPER', 'lower', '')") return v + @validator('enum_integer_default') + def enum_integer_default_validate_enum(cls, v): + if v is None: + return v + + if v not in (1, 5, 14): + raise ValueError("must validate the enum values (1, 5, 14)") + return v + @validator('enum_integer') def enum_integer_validate_enum(cls, v): if v is None: @@ -114,6 +124,7 @@ class EnumTest(BaseModel): _obj = EnumTest.parse_obj({ "enum_string": obj.get("enum_string"), "enum_string_required": obj.get("enum_string_required"), + "enum_integer_default": obj.get("enum_integer_default") if obj.get("enum_integer_default") is not None else 5, "enum_integer": obj.get("enum_integer"), "enum_number": obj.get("enum_number"), "outer_enum": obj.get("outerEnum"), diff --git a/samples/openapi3/client/petstore/python-nextgen/docs/EnumTest.md b/samples/openapi3/client/petstore/python-nextgen/docs/EnumTest.md index 3c900769031..5bcb8e7027e 100755 --- a/samples/openapi3/client/petstore/python-nextgen/docs/EnumTest.md +++ b/samples/openapi3/client/petstore/python-nextgen/docs/EnumTest.md @@ -6,6 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **enum_string** | **str** | | [optional] **enum_string_required** | **str** | | +**enum_integer_default** | **int** | | [optional] [default to 5] **enum_integer** | **int** | | [optional] **enum_number** | **float** | | [optional] **outer_enum** | [**OuterEnum**](OuterEnum.md) | | [optional] diff --git a/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_test.py b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_test.py index 3917e3f0312..ab30c140963 100644 --- a/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_test.py +++ b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_test.py @@ -32,6 +32,7 @@ class EnumTest(BaseModel): """ enum_string: Optional[StrictStr] = None enum_string_required: StrictStr = ... + enum_integer_default: Optional[StrictInt] = 5 enum_integer: Optional[StrictInt] = None enum_number: Optional[StrictFloat] = None outer_enum: Optional[OuterEnum] = Field(None, alias="outerEnum") @@ -39,7 +40,7 @@ class EnumTest(BaseModel): outer_enum_default_value: Optional[OuterEnumDefaultValue] = Field(None, alias="outerEnumDefaultValue") outer_enum_integer_default_value: Optional[OuterEnumIntegerDefaultValue] = Field(None, alias="outerEnumIntegerDefaultValue") additional_properties: Dict[str, Any] = {} - __properties = ["enum_string", "enum_string_required", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"] + __properties = ["enum_string", "enum_string_required", "enum_integer_default", "enum_integer", "enum_number", "outerEnum", "outerEnumInteger", "outerEnumDefaultValue", "outerEnumIntegerDefaultValue"] @validator('enum_string') def enum_string_validate_enum(cls, v): @@ -56,6 +57,15 @@ class EnumTest(BaseModel): raise ValueError("must validate the enum values ('UPPER', 'lower', '')") return v + @validator('enum_integer_default') + def enum_integer_default_validate_enum(cls, v): + if v is None: + return v + + if v not in (1, 5, 14): + raise ValueError("must validate the enum values (1, 5, 14)") + return v + @validator('enum_integer') def enum_integer_validate_enum(cls, v): if v is None: @@ -121,6 +131,7 @@ class EnumTest(BaseModel): _obj = EnumTest.parse_obj({ "enum_string": obj.get("enum_string"), "enum_string_required": obj.get("enum_string_required"), + "enum_integer_default": obj.get("enum_integer_default") if obj.get("enum_integer_default") is not None else 5, "enum_integer": obj.get("enum_integer"), "enum_number": obj.get("enum_number"), "outer_enum": obj.get("outerEnum"), diff --git a/samples/openapi3/client/petstore/python-nextgen/tests/test_model.py b/samples/openapi3/client/petstore/python-nextgen/tests/test_model.py index 25f8190c04c..e437c7b6d80 100644 --- a/samples/openapi3/client/petstore/python-nextgen/tests/test_model.py +++ b/samples/openapi3/client/petstore/python-nextgen/tests/test_model.py @@ -382,3 +382,8 @@ class ModelTests(unittest.TestCase): ## Serializing json #json_object = json.dumps(dictionary) #self.assertEqual(json_object, "") + + def test_inline_enum_default(self): + enum_test = petstore_api.EnumTest(enum_string_required="lower") + self.assertEqual(enum_test.enum_integer_default, 5) +