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 ffcbb001c49..5f29c5c909a 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 @@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.util.*; +import static org.openapitools.codegen.utils.StringUtils.escape; import static org.openapitools.codegen.utils.StringUtils.underscore; public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements CodegenConfig { @@ -208,6 +209,9 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements super.processOpts(); + // map to Dot instead of Period + specialCharReplacements.put(".", "Dot"); + if (StringUtils.isEmpty(System.getenv("PYTHON_POST_PROCESS_FILE"))) { LOGGER.info("Environment variable PYTHON_POST_PROCESS_FILE not defined so the Python code may not be properly formatted. To define it, try 'export PYTHON_POST_PROCESS_FILE=\"/usr/local/bin/yapf -i\"' (Linux/Mac)"); LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI)."); @@ -1331,38 +1335,42 @@ public class PythonNextgenClientCodegen extends AbstractPythonCodegen implements } public String toEnumVariableName(String name, String datatype) { + if ("int".equals(datatype)) { + return "NUMBER_" + name; + } + + // remove quote e.g. 'abc' => abc + name = name.substring(1, name.length() - 1); + if (name.length() == 0) { return "EMPTY"; } - if (name.trim().length() == 0) { - return "SPACE_" + name.length(); + if (" ".equals(name)) { + return "SPACE"; } - // for symbol, e.g. $, # - if (getSymbolName(name) != null) { - return (getSymbolName(name)).toUpperCase(Locale.ROOT); + if ("_".equals(name)) { + return "UNDERSCORE"; } - // number - if ("int".equals(datatype) || "float".equals(datatype)) { - String varName = name; - varName = varName.replaceAll("-", "MINUS_"); - varName = varName.replaceAll("\\+", "PLUS_"); - varName = varName.replaceAll("\\.", "_DOT_"); - return "NUMBER_" + varName; - } - - // string - String enumName = sanitizeName(underscore(name).toUpperCase(Locale.ROOT)); - enumName = enumName.replaceFirst("^_", ""); - enumName = enumName.replaceFirst("_$", ""); - - if (isReservedWord(enumName) || enumName.matches("\\d.*")) { // reserved word or starts with number - return escapeReservedWord(enumName); + if (reservedWords.contains(name)) { + name = name.toUpperCase(Locale.ROOT); + } else if (((CharSequence) name).chars().anyMatch(character -> specialCharReplacements.keySet().contains(String.valueOf((char) character)))) { + name = underscore(escape(name, specialCharReplacements, Collections.singletonList("_"), "_")).toUpperCase(Locale.ROOT); } else { - return enumName; + name = name.toUpperCase(Locale.ROOT); } + + name = name.replace(" ", "_"); + name = name.replaceFirst("^_", ""); + name = name.replaceFirst("_$", ""); + + if (name.matches("\\d.*")) { + name = "ENUM_" + name.toUpperCase(Locale.ROOT); + } + + return name; } @Override 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 615c9ff3bd2..24a7dd47d53 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 @@ -1836,6 +1836,19 @@ components: - 1 - 2 default: 0 + SpecialCharacterEnum: + type: string + enum: + - "456" + - "123abc" + - "_" + - " " + - "&" + - "$" + - ">=" + - "this_is_!" + - "import" # reserved word + - " hello world " OuterComposite: type: object properties: diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/.openapi-generator/FILES b/samples/openapi3/client/petstore/python-nextgen-aiohttp/.openapi-generator/FILES index 16c7ff73ab4..c2f43506f98 100644 --- a/samples/openapi3/client/petstore/python-nextgen-aiohttp/.openapi-generator/FILES +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/.openapi-generator/FILES @@ -61,6 +61,7 @@ docs/Pig.md docs/ReadOnlyFirst.md docs/SelfReferenceModel.md docs/SingleRefType.md +docs/SpecialCharacterEnum.md docs/SpecialModelName.md docs/SpecialName.md docs/StoreApi.md @@ -135,6 +136,7 @@ petstore_api/models/pig.py petstore_api/models/read_only_first.py petstore_api/models/self_reference_model.py petstore_api/models/single_ref_type.py +petstore_api/models/special_character_enum.py petstore_api/models/special_model_name.py petstore_api/models/special_name.py petstore_api/models/tag.py diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/README.md b/samples/openapi3/client/petstore/python-nextgen-aiohttp/README.md index 61d98d5c622..d9db0c5fce3 100644 --- a/samples/openapi3/client/petstore/python-nextgen-aiohttp/README.md +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/README.md @@ -180,6 +180,7 @@ Class | Method | HTTP request | Description - [ReadOnlyFirst](docs/ReadOnlyFirst.md) - [SelfReferenceModel](docs/SelfReferenceModel.md) - [SingleRefType](docs/SingleRefType.md) + - [SpecialCharacterEnum](docs/SpecialCharacterEnum.md) - [SpecialModelName](docs/SpecialModelName.md) - [SpecialName](docs/SpecialName.md) - [Tag](docs/Tag.md) diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/docs/SpecialCharacterEnum.md b/samples/openapi3/client/petstore/python-nextgen-aiohttp/docs/SpecialCharacterEnum.md new file mode 100644 index 00000000000..801c3b5c845 --- /dev/null +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/docs/SpecialCharacterEnum.md @@ -0,0 +1,10 @@ +# SpecialCharacterEnum + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/__init__.py b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/__init__.py index ff667b0dd14..2b6fe534d7b 100644 --- a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/__init__.py +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/__init__.py @@ -88,6 +88,7 @@ from petstore_api.models.pig import Pig from petstore_api.models.read_only_first import ReadOnlyFirst from petstore_api.models.self_reference_model import SelfReferenceModel from petstore_api.models.single_ref_type import SingleRefType +from petstore_api.models.special_character_enum import SpecialCharacterEnum from petstore_api.models.special_model_name import SpecialModelName from petstore_api.models.special_name import SpecialName from petstore_api.models.tag import Tag diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/__init__.py b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/__init__.py index 47c33519b11..fe6f65f77ba 100644 --- a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/__init__.py +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/__init__.py @@ -67,6 +67,7 @@ from petstore_api.models.pig import Pig from petstore_api.models.read_only_first import ReadOnlyFirst from petstore_api.models.self_reference_model import SelfReferenceModel from petstore_api.models.single_ref_type import SingleRefType +from petstore_api.models.special_character_enum import SpecialCharacterEnum from petstore_api.models.special_model_name import SpecialModelName from petstore_api.models.special_name import SpecialName from petstore_api.models.tag import Tag diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_class.py b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_class.py index 24336123fa3..9fd2fcc13cd 100644 --- a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_class.py +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/enum_class.py @@ -31,6 +31,6 @@ class EnumClass(str, Enum): """ ABC = '_abc' - EFG = '-efg' - XYZ = '(xyz)' + MINUS_EFG = '-efg' + LEFT_PARENTHESIS_XYZ_RIGHT_PARENTHESIS = '(xyz)' diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/special_character_enum.py b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/special_character_enum.py new file mode 100644 index 00000000000..374ac242de6 --- /dev/null +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/petstore_api/models/special_character_enum.py @@ -0,0 +1,43 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from inspect import getfullargspec +import pprint +import re # noqa: F401 +from aenum import Enum, no_arg + + + + + +class SpecialCharacterEnum(str, Enum): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + """ + allowed enum values + """ + + ENUM_456 = '456' + ENUM_123ABC = '123abc' + UNDERSCORE = '_' + SPACE = ' ' + AMPERSAND = '&' + DOLLAR = '$' + GREATER_THAN_EQUAL = '>=' + THIS_IS_EXCLAMATION = 'this_is_!' + IMPORT = 'import' + HELLO_WORLD = ' hello world ' + diff --git a/samples/openapi3/client/petstore/python-nextgen-aiohttp/test/test_special_character_enum.py b/samples/openapi3/client/petstore/python-nextgen-aiohttp/test/test_special_character_enum.py new file mode 100644 index 00000000000..028f55599e4 --- /dev/null +++ b/samples/openapi3/client/petstore/python-nextgen-aiohttp/test/test_special_character_enum.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import unittest +import datetime + +import petstore_api +from petstore_api.models.special_character_enum import SpecialCharacterEnum # noqa: E501 +from petstore_api.rest import ApiException + +class TestSpecialCharacterEnum(unittest.TestCase): + """SpecialCharacterEnum unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testSpecialCharacterEnum(self): + """Test SpecialCharacterEnum""" + # inst = SpecialCharacterEnum() + +if __name__ == '__main__': + unittest.main() diff --git a/samples/openapi3/client/petstore/python-nextgen/.openapi-generator/FILES b/samples/openapi3/client/petstore/python-nextgen/.openapi-generator/FILES index b8e0a20aec6..f5e76be9e49 100755 --- a/samples/openapi3/client/petstore/python-nextgen/.openapi-generator/FILES +++ b/samples/openapi3/client/petstore/python-nextgen/.openapi-generator/FILES @@ -61,6 +61,7 @@ docs/Pig.md docs/ReadOnlyFirst.md docs/SelfReferenceModel.md docs/SingleRefType.md +docs/SpecialCharacterEnum.md docs/SpecialModelName.md docs/SpecialName.md docs/StoreApi.md @@ -135,6 +136,7 @@ petstore_api/models/pig.py petstore_api/models/read_only_first.py petstore_api/models/self_reference_model.py petstore_api/models/single_ref_type.py +petstore_api/models/special_character_enum.py petstore_api/models/special_model_name.py petstore_api/models/special_name.py petstore_api/models/tag.py diff --git a/samples/openapi3/client/petstore/python-nextgen/README.md b/samples/openapi3/client/petstore/python-nextgen/README.md index 595e187329e..0f1d86506a4 100755 --- a/samples/openapi3/client/petstore/python-nextgen/README.md +++ b/samples/openapi3/client/petstore/python-nextgen/README.md @@ -180,6 +180,7 @@ Class | Method | HTTP request | Description - [ReadOnlyFirst](docs/ReadOnlyFirst.md) - [SelfReferenceModel](docs/SelfReferenceModel.md) - [SingleRefType](docs/SingleRefType.md) + - [SpecialCharacterEnum](docs/SpecialCharacterEnum.md) - [SpecialModelName](docs/SpecialModelName.md) - [SpecialName](docs/SpecialName.md) - [Tag](docs/Tag.md) diff --git a/samples/openapi3/client/petstore/python-nextgen/docs/SpecialCharacterEnum.md b/samples/openapi3/client/petstore/python-nextgen/docs/SpecialCharacterEnum.md new file mode 100644 index 00000000000..801c3b5c845 --- /dev/null +++ b/samples/openapi3/client/petstore/python-nextgen/docs/SpecialCharacterEnum.md @@ -0,0 +1,10 @@ +# SpecialCharacterEnum + + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/samples/openapi3/client/petstore/python-nextgen/petstore_api/__init__.py b/samples/openapi3/client/petstore/python-nextgen/petstore_api/__init__.py index ff667b0dd14..2b6fe534d7b 100755 --- a/samples/openapi3/client/petstore/python-nextgen/petstore_api/__init__.py +++ b/samples/openapi3/client/petstore/python-nextgen/petstore_api/__init__.py @@ -88,6 +88,7 @@ from petstore_api.models.pig import Pig from petstore_api.models.read_only_first import ReadOnlyFirst from petstore_api.models.self_reference_model import SelfReferenceModel from petstore_api.models.single_ref_type import SingleRefType +from petstore_api.models.special_character_enum import SpecialCharacterEnum from petstore_api.models.special_model_name import SpecialModelName from petstore_api.models.special_name import SpecialName from petstore_api.models.tag import Tag diff --git a/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/__init__.py b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/__init__.py index 47c33519b11..fe6f65f77ba 100644 --- a/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/__init__.py +++ b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/__init__.py @@ -67,6 +67,7 @@ from petstore_api.models.pig import Pig from petstore_api.models.read_only_first import ReadOnlyFirst from petstore_api.models.self_reference_model import SelfReferenceModel from petstore_api.models.single_ref_type import SingleRefType +from petstore_api.models.special_character_enum import SpecialCharacterEnum from petstore_api.models.special_model_name import SpecialModelName from petstore_api.models.special_name import SpecialName from petstore_api.models.tag import Tag diff --git a/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_class.py b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_class.py index 24336123fa3..9fd2fcc13cd 100644 --- a/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_class.py +++ b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/enum_class.py @@ -31,6 +31,6 @@ class EnumClass(str, Enum): """ ABC = '_abc' - EFG = '-efg' - XYZ = '(xyz)' + MINUS_EFG = '-efg' + LEFT_PARENTHESIS_XYZ_RIGHT_PARENTHESIS = '(xyz)' diff --git a/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/special_character_enum.py b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/special_character_enum.py new file mode 100644 index 00000000000..374ac242de6 --- /dev/null +++ b/samples/openapi3/client/petstore/python-nextgen/petstore_api/models/special_character_enum.py @@ -0,0 +1,43 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from inspect import getfullargspec +import pprint +import re # noqa: F401 +from aenum import Enum, no_arg + + + + + +class SpecialCharacterEnum(str, Enum): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + """ + allowed enum values + """ + + ENUM_456 = '456' + ENUM_123ABC = '123abc' + UNDERSCORE = '_' + SPACE = ' ' + AMPERSAND = '&' + DOLLAR = '$' + GREATER_THAN_EQUAL = '>=' + THIS_IS_EXCLAMATION = 'this_is_!' + IMPORT = 'import' + HELLO_WORLD = ' hello world ' + diff --git a/samples/openapi3/client/petstore/python-nextgen/test/test_special_character_enum.py b/samples/openapi3/client/petstore/python-nextgen/test/test_special_character_enum.py new file mode 100644 index 00000000000..028f55599e4 --- /dev/null +++ b/samples/openapi3/client/petstore/python-nextgen/test/test_special_character_enum.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +""" + OpenAPI Petstore + + This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ # noqa: E501 + + The version of the OpenAPI document: 1.0.0 + Generated by: https://openapi-generator.tech +""" + + +from __future__ import absolute_import + +import unittest +import datetime + +import petstore_api +from petstore_api.models.special_character_enum import SpecialCharacterEnum # noqa: E501 +from petstore_api.rest import ApiException + +class TestSpecialCharacterEnum(unittest.TestCase): + """SpecialCharacterEnum unit test stubs""" + + def setUp(self): + pass + + def tearDown(self): + pass + + def testSpecialCharacterEnum(self): + """Test SpecialCharacterEnum""" + # inst = SpecialCharacterEnum() + +if __name__ == '__main__': + unittest.main()