Skip to content
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

Commit d25cdbb

Browse files
authored
[python-experimental] removes enum cls factory (#13491)
* Movs enum info, changes cls factory to base class + updates samples * Fixed docs for enums, they show the allowed bool and None values now
1 parent e146afb commit d25cdbb

File tree

101 files changed

+647
-768
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+647
-768
lines changed

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

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
import java.io.File;
5757
import java.io.IOException;
58+
import java.math.BigDecimal;
5859
import java.nio.file.Path;
5960
import java.time.OffsetDateTime;
6061
import java.time.ZoneOffset;
@@ -1226,6 +1227,8 @@ public String toEnumVarName(String value, String datatype) {
12261227
// our enum var names are keys in a python dict, so change spaces to underscores
12271228
if (value.length() == 0) {
12281229
return "EMPTY";
1230+
} else if (value.equals("null")) {
1231+
return "NONE";
12291232
}
12301233

12311234
String intPattern = "^[-\\+]?\\d+$";
@@ -1289,26 +1292,80 @@ private String charNameToVarName(String charName) {
12891292
return varName;
12901293
}
12911294

1292-
/**
1293-
* Return the enum value in the language specified format
1294-
* e.g. status becomes "status"
1295-
*
1296-
* @param value enum variable name
1297-
* @param datatype data type
1298-
* @return the sanitized value for enum
1299-
*/
1300-
public String toEnumValue(String value, String datatype) {
1301-
if ("int".equals(datatype) || "float".equals(datatype) || datatype.equals("int, float")) {
1302-
return value;
1303-
} else if ("bool".equals(datatype)) {
1304-
if (value.equals("true")) {
1305-
return "schemas.BoolClass.TRUE";
1295+
protected List<Map<String, Object>> buildEnumVars(List<Object> values, String dataType) {
1296+
List<Map<String, Object>> enumVars = new ArrayList<>();
1297+
int truncateIdx = 0;
1298+
1299+
if (isRemoveEnumValuePrefix()) {
1300+
String commonPrefix = findCommonPrefixOfVars(values);
1301+
truncateIdx = commonPrefix.length();
1302+
}
1303+
1304+
for (Object value : values) {
1305+
Map<String, Object> enumVar = new HashMap<>();
1306+
String enumName;
1307+
if (truncateIdx == 0) {
1308+
enumName = String.valueOf(value);
1309+
} else {
1310+
enumName = value.toString().substring(truncateIdx);
1311+
if (enumName.isEmpty()) {
1312+
enumName = value.toString();
1313+
}
13061314
}
1307-
return "schemas.BoolClass.FALSE";
1308-
} else {
1309-
String fixedValue = (String) processTestExampleData(value);
1310-
return ensureQuotes(fixedValue);
1315+
1316+
enumVar.put("name", toEnumVarName(enumName, dataType));
1317+
if (value instanceof Integer) {
1318+
enumVar.put("value", value);
1319+
} else if (value instanceof Double) {
1320+
enumVar.put("value", value);
1321+
} else if (value instanceof Long) {
1322+
enumVar.put("value", value);
1323+
} else if (value instanceof Float) {
1324+
enumVar.put("value", value);
1325+
} else if (value instanceof BigDecimal) {
1326+
enumVar.put("value", value);
1327+
} else if (value == null) {
1328+
enumVar.put("value", "schemas.NoneClass.NONE");
1329+
} else if (value instanceof Boolean) {
1330+
if (value.equals(Boolean.TRUE)) {
1331+
enumVar.put("value", "schemas.BoolClass.TRUE");
1332+
} else {
1333+
enumVar.put("value", "schemas.BoolClass.FALSE");
1334+
}
1335+
} else {
1336+
String fixedValue = (String) processTestExampleData(value);
1337+
enumVar.put("value", ensureQuotes(fixedValue));
1338+
}
1339+
enumVar.put("isString", isDataTypeString(dataType));
1340+
enumVars.add(enumVar);
1341+
}
1342+
1343+
if (enumUnknownDefaultCase) {
1344+
// If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.
1345+
// With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.
1346+
Map<String, Object> enumVar = new HashMap<>();
1347+
String enumName = enumUnknownDefaultCaseName;
1348+
1349+
String enumValue;
1350+
if (isDataTypeString(dataType)) {
1351+
enumValue = enumUnknownDefaultCaseName;
1352+
} else {
1353+
// This is a dummy value that attempts to avoid collisions with previously specified cases.
1354+
// Int.max / 192
1355+
// The number 192 that is used to calculate this random value, is the Swift Evolution proposal for frozen/non-frozen enums.
1356+
// [SE-0192](https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md)
1357+
// Since this functionality was born in the Swift 5 generator and latter on broth to all generators
1358+
// https://github.com/OpenAPITools/openapi-generator/pull/11013
1359+
enumValue = String.valueOf(11184809);
1360+
}
1361+
1362+
enumVar.put("name", toEnumVarName(enumName, dataType));
1363+
enumVar.put("value", toEnumValue(enumValue, dataType));
1364+
enumVar.put("isString", isDataTypeString(dataType));
1365+
enumVars.add(enumVar);
13111366
}
1367+
1368+
return enumVars;
13121369
}
13131370

13141371
@Override

modules/openapi-generator/src/main/resources/python-experimental/model_templates/enum_value_to_name.handlebars

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1-
{{#if isNull}}
2-
3-
@schemas.classproperty
4-
def NONE(cls):
5-
return cls(None)
6-
{{/if}}
71
{{#with allowableValues}}
82
{{#each enumVars}}
93

104
@schemas.classproperty
115
def {{name}}(cls):
6+
{{#eq value "schemas.NoneClass.NONE"}}
7+
return cls(None)
8+
{{else}}
9+
{{#eq value "schemas.BoolClass.TRUE"}}
10+
return cls(True)
11+
{{else}}
12+
{{#eq value "schemas.BoolClass.FALSE"}}
13+
return cls(False)
14+
{{else}}
1215
return cls({{{value}}})
16+
{{/eq}}
17+
{{/eq}}
18+
{{/eq}}
1319
{{/each}}
1420
{{/with}}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{{#unless isArray}}{{#unless complexType}}{{#with allowableValues}}must be one of [{{#each enumVars}}{{{value}}}, {{/each}}] {{/with}}{{#if defaultValue}}{{#unless hasRequired}}if omitted the server will use the default value of {{{defaultValue}}}{{/unless}}{{/if}}{{#eq getFormat "uuid"}}value must be a uuid{{/eq}}{{#eq getFormat "date"}}value must conform to RFC-3339 full-date YYYY-MM-DD{{/eq}}{{#eq getFormat "date-time"}}value must conform to RFC-3339 date-time{{/eq}}{{#eq getFormat "number"}}value must be numeric and storable in decimal.Decimal{{/eq}}{{#eq getFormat "int32"}}value must be a 32 bit integer{{/eq}}{{#eq getFormat "int64"}}value must be a 64 bit integer{{/eq}}{{#eq getFormat "double"}}value must be a 64 bit float{{/eq}}{{#eq getFormat "float"}}value must be a 32 bit float{{/eq}}{{/unless}}{{/unless}}
1+
{{#unless isArray}}{{#unless complexType}}{{#with allowableValues}}must be one of [{{#each enumVars}}{{#eq value "schemas.NoneClass.NONE"}}None{{else}}{{#eq value "schemas.BoolClass.TRUE"}}True{{else}}{{#eq value "schemas.BoolClass.FALSE"}}False{{else}}{{{value}}}{{/eq}}{{/eq}}{{/eq}}, {{/each}}] {{/with}}{{#if defaultValue}}{{#unless hasRequired}}if omitted the server will use the default value of {{{defaultValue}}}{{/unless}}{{/if}}{{#eq getFormat "uuid"}}value must be a uuid{{/eq}}{{#eq getFormat "date"}}value must conform to RFC-3339 full-date YYYY-MM-DD{{/eq}}{{#eq getFormat "date-time"}}value must conform to RFC-3339 date-time{{/eq}}{{#eq getFormat "number"}}value must be numeric and storable in decimal.Decimal{{/eq}}{{#eq getFormat "int32"}}value must be a 32 bit integer{{/eq}}{{#eq getFormat "int64"}}value must be a 64 bit integer{{/eq}}{{#eq getFormat "double"}}value must be a 64 bit float{{/eq}}{{#eq getFormat "float"}}value must be a 32 bit float{{/eq}}{{/unless}}{{/unless}}

modules/openapi-generator/src/main/resources/python-experimental/model_templates/schema_composed_or_anytype.handlebars

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class {{#if this.classname}}{{classname}}{{else}}{{#if nameInSnakeCase}}{{name}}
1515
schemas.ComposedBase,
1616
{{/if}}
1717
{{#if isEnum}}
18-
{{> model_templates/enum_value_to_name }}
18+
schemas.EnumBase,
1919
{{/if}}
2020
{{> model_templates/xbase_schema }}
2121
{{/if}}
@@ -31,13 +31,22 @@ class {{#if this.classname}}{{classname}}{{else}}{{#if nameInSnakeCase}}{{name}}
3131
{{/if}}
3232
"""
3333
{{/if}}
34-
{{#or hasValidation composedSchemas getItems additionalProperties getRequiredVarsMap getHasDiscriminatorWithNonEmptyMapping vars getFormat}}
34+
{{#or hasValidation composedSchemas getItems additionalProperties getRequiredVarsMap getHasDiscriminatorWithNonEmptyMapping vars getFormat isEnum}}
3535

3636

3737
class MetaOapg:
3838
{{#if getFormat}}
3939
format = '{{getFormat}}'
4040
{{/if}}
41+
{{#if isEnum}}
42+
{{#with allowableValues}}
43+
enum_value_to_name = {
44+
{{#each enumVars}}
45+
{{{value}}}: "{{name}}",
46+
{{/each}}
47+
}
48+
{{/with}}
49+
{{/if}}
4150
{{#if getItems}}
4251
{{> model_templates/list_partial }}
4352
{{/if}}

modules/openapi-generator/src/main/resources/python-experimental/model_templates/schema_simple.handlebars

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
class {{#if this.classname}}{{classname}}{{else}}{{#if nameInSnakeCase}}{{name}}{{else}}{{baseName}}{{/if}}{{/if}}(
44
{{#if isEnum}}
5-
{{> model_templates/enum_value_to_name }}
5+
schemas.EnumBase,
66
{{/if}}
77
{{> model_templates/xbase_schema }}
88
):
@@ -18,12 +18,24 @@ class {{#if this.classname}}{{classname}}{{else}}{{#if nameInSnakeCase}}{{name}}
1818
"""
1919
{{/if}}
2020
{{#unless isStub}}
21-
{{#if hasValidation}}
21+
{{#or hasValidation isEnum getFormat}}
2222

2323

2424
class MetaOapg:
25+
{{#if getFormat}}
26+
format = '{{getFormat}}'
27+
{{/if}}
2528
{{> model_templates/validations }}
29+
{{#if isEnum}}
30+
{{#with allowableValues}}
31+
enum_value_to_name = {
32+
{{#each enumVars}}
33+
{{{value}}}: "{{name}}",
34+
{{/each}}
35+
}
36+
{{/with}}
2637
{{/if}}
38+
{{/or}}
2739
{{/unless}}
2840
{{#if isEnum}}
2941
{{> model_templates/enums }}

modules/openapi-generator/src/main/resources/python-experimental/schemas.handlebars

Lines changed: 17 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ class Schema:
404404
"""
405405
cls._process_schema_classes_oapg(schema_classes)
406406
enum_schema = any(
407-
hasattr(this_cls, '_enum_value_to_name') for this_cls in schema_classes)
407+
issubclass(this_cls, EnumBase) for this_cls in schema_classes)
408408
inheritable_primitive_type = schema_classes.intersection(cls.__inheritable_primitive_types_set)
409409
chosen_schema_classes = schema_classes - inheritable_primitive_type
410410
suffix = tuple(inheritable_primitive_type)
@@ -873,41 +873,22 @@ class ValidatorBase:
873873
)
874874

875875

876-
class EnumMakerBase:
877-
pass
878-
879-
880-
def SchemaEnumMakerClsFactory(enum_value_to_name: typing.Dict[typing.Union[str, decimal.Decimal, bool, none_type], str]) -> 'SchemaEnumMaker':
881-
class SchemaEnumMaker(EnumMakerBase):
882-
@classmethod
883-
def _enum_value_to_name(
884-
cls
885-
) -> typing.Dict[typing.Union[str, decimal.Decimal, bool, none_type], str]:
886-
pass
887-
try:
888-
super_enum_value_to_name = super()._enum_value_to_name()
889-
except AttributeError:
890-
return enum_value_to_name
891-
intersection = dict(enum_value_to_name.items() & super_enum_value_to_name.items())
892-
return intersection
893-
894-
@classmethod
895-
def _validate_oapg(
896-
cls,
897-
arg,
898-
validation_metadata: ValidationMetadata,
899-
) -> typing.Dict[typing.Tuple[typing.Union[str, int], ...], typing.Set[typing.Union['Schema', str, decimal.Decimal, BoolClass, NoneClass, frozendict.frozendict, tuple]]]:
900-
"""
901-
SchemaEnumMaker _validate_oapg
902-
Validates that arg is in the enum's allowed values
903-
"""
904-
try:
905-
cls._enum_value_to_name()[arg]
906-
except KeyError:
907-
raise ApiValueError("Invalid value {} passed in to {}, {}".format(arg, cls, cls._enum_value_to_name()))
908-
return super()._validate_oapg(arg, validation_metadata=validation_metadata)
909-
910-
return SchemaEnumMaker
876+
class EnumBase:
877+
@classmethod
878+
def _validate_oapg(
879+
cls,
880+
arg,
881+
validation_metadata: ValidationMetadata,
882+
) -> typing.Dict[typing.Tuple[typing.Union[str, int], ...], typing.Set[typing.Union['Schema', str, decimal.Decimal, BoolClass, NoneClass, frozendict.frozendict, tuple]]]:
883+
"""
884+
EnumBase _validate_oapg
885+
Validates that arg is in the enum's allowed values
886+
"""
887+
try:
888+
cls.MetaOapg.enum_value_to_name[arg]
889+
except KeyError:
890+
raise ApiValueError("Invalid value {} passed in to {}, allowed_values={}".format(arg, cls, cls.MetaOapg.enum_value_to_name.keys()))
891+
return super()._validate_oapg(arg, validation_metadata=validation_metadata)
911892

912893

913894
class BoolBase:

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,7 @@ components:
22242224
multiple
22252225
lines
22262226
- "double quote \n with newline"
2227+
- null
22272228
IntegerEnum:
22282229
type: integer
22292230
enum:

samples/openapi3/client/3_0_3_unit_test/python-experimental/docs/models/EnumWithFalseDoesNotMatch0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Model Type Info
44
Input Type | Accessed Type | Description | Notes
55
------------ | ------------- | ------------- | -------------
6-
bool, | BoolClass, | | must be one of [schemas.BoolClass.FALSE, ]
6+
bool, | BoolClass, | | must be one of [False, ]
77

88
[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md)
99

samples/openapi3/client/3_0_3_unit_test/python-experimental/docs/models/EnumWithTrueDoesNotMatch1.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## Model Type Info
44
Input Type | Accessed Type | Description | Notes
55
------------ | ------------- | ------------- | -------------
6-
bool, | BoolClass, | | must be one of [schemas.BoolClass.TRUE, ]
6+
bool, | BoolClass, | | must be one of [True, ]
77

88
[[Back to Model list]](../../README.md#documentation-for-models) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to README]](../../README.md)
99

0 commit comments

Comments
 (0)