Skip to content

Commit 74c01ee

Browse files
authored
chore: added fix for snake case nested attributes and import keywork … (#779)
Added fix for snake case nested attributes and import keywork error added the test generation for memory/v1 here to preview twilio/twilio-python#917 snake case https://github.com/twilio/twilio-python/pull/917/changes#diff-777836e65412325fc37488cd2666c3c5a395f055d5dddee403544a8386dfebf7R48 import keyword generation : https://github.com/twilio/twilio-python/pull/917/changes#diff-116f38979d5ea6f70e7b59044645b2666073bb9259c94a51492bff8ca69f5574 <!-- We appreciate the effort for this pull request but before that please make sure you read the contribution guidelines, then fill out the blanks below. Please format the PR title appropriately based on the type of change: <type>[!]: <description> Where <type> is one of: docs, chore, feat, fix, test, misc. Add a '!' after the type for breaking changes (e.g. feat!: new breaking feature). **All third-party contributors acknowledge that any contributions they provide will be made under the same open-source license that the open-source project is provided under.** Please enter each Issue number you are resolving in your PR after one of the following words [Fixes, Closes, Resolves]. This will auto-link these issues and close them when this PR is merged! e.g. Fixes #1 Closes #2 --> # Fixes # A short description of what this PR does. ### Checklist - [x] I acknowledge that all my contributions will be made under the project's license - [ ] Run `make test-docker` - [ ] Verify affected language according to the code change: - [ ] Generate [twilio-java](https://github.com/twilio/twilio-java) from our [OpenAPI specification](https://github.com/twilio/twilio-oai) using the [scripts/build_twilio_library.py](./scripts/build_twilio_library.py) using `python scripts/build_twilio_library.py path/to/twilio-oai/spec/yaml path/to/twilio-java -l java` and inspect the diff - [ ] Run `make test` in `twilio-java` - [ ] Create a pull request in `twilio-java` - [ ] Provide a link below to the pull request, this ensures that the generated code has been verified - [ ] I have made a material change to the repo (functionality, testing, spelling, grammar) - [ ] I have read the [Contribution Guidelines](https://github.com/twilio/twilio-oai-generator/blob/main/CONTRIBUTING.md) and my PR follows them - [ ] I have titled the PR appropriately - [ ] I have updated my branch with the main branch - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] I have added the necessary documentation about the functionality in the appropriate .md file - [ ] I have added inline documentation to the code I modified If you have questions, please create a GitHub Issue in this repository.
1 parent 81b0255 commit 74c01ee

3 files changed

Lines changed: 45 additions & 17 deletions

File tree

src/main/java/com/twilio/oai/common/Utility.java

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public String populateCrudOperations(final CodegenOperation operation) {
9393

9494
return method.name();
9595
}
96-
96+
9797
/*
9898
responses:
9999
'200':
@@ -129,16 +129,22 @@ public Optional<CodegenModel> getModel(final List<CodegenModel> models,
129129
final CodegenOperation codegenOperation) {
130130
if (recordKey != null &&
131131
(boolean) codegenOperation.vendorExtensions.getOrDefault("x-is-read-operation", false)) {
132-
return models
132+
Optional<CodegenModel> nestedModel = models
133133
.stream()
134134
.filter(model -> model.getClassname().equals(className))
135135
.map(CodegenModel::getVars)
136136
.flatMap(Collection::stream)
137137
.filter(prop -> prop.baseName.equals(recordKey))
138138
.map(CodegenProperty::getComplexType)
139+
.filter(Objects::nonNull) // Filter out null complex types (e.g., arrays of primitives)
139140
.map(classname -> getModelByClassname(models, classname))
140141
.findFirst()
141-
.orElse(null);
142+
.orElse(Optional.empty());
143+
144+
// If we found a nested model, return it; otherwise fall back to top-level model
145+
if (nestedModel.isPresent()) {
146+
return nestedModel;
147+
}
142148
}
143149

144150
return getModelByClassname(models, className);
@@ -191,7 +197,7 @@ public static String replaceDatatypeInContainer(String input, String replacement
191197
// Return the input unchanged if no match is found
192198
return input;
193199
}
194-
200+
195201
public static String appendResourceNameToEnum(String name) {
196202
if (name == null || name.isEmpty()) {
197203
return null;
@@ -202,7 +208,7 @@ public static String appendResourceNameToEnum(String name) {
202208
}
203209
return prefix + com.twilio.oai.common.StringUtils.toPascalCase(name);
204210
}
205-
211+
206212
public static String getEnumNameFromRef(final String ref) {
207213
String schemaName = ref.replaceFirst("#/components/schemas/", "");
208214
String[] enumNameArray = schemaName.split("_enum_");
@@ -213,7 +219,7 @@ public static String getEnumNameFromRef(final String ref) {
213219
Example1:
214220
singleBodyRef:
215221
$ref: '#/components/schemas/singleReusable'
216-
222+
217223
Example2:
218224
status:
219225
$ref: '#/components/schemas/message_enum_status'
@@ -228,23 +234,23 @@ public static String getEnumNameFromDefaultDatatype(final String ref) {
228234
String[] enumNameArray = schemaName.split("_enum_");
229235
return enumNameArray[enumNameArray.length - 1];
230236
}
231-
237+
232238
public static String getEnumNameFromDatatype(final String datatype) {
233239
if (datatype == null || datatype.isEmpty()) {
234240
return null;
235241
}
236242
String[] enumNameArray = datatype.split("Enum");
237243
return enumNameArray[enumNameArray.length - 1];
238244
}
239-
245+
240246
/*
241-
Type1:
247+
Type1:
242248
types:
243249
$ref: '#/components/schemas/types'
244-
250+
245251
*/
246252
public static CodegenModel getModelFromOpenApiType(CodegenProperty codegenProperty) {
247-
// Ref occurs for 2 cases,
253+
// Ref occurs for 2 cases,
248254
// 1. one when there is no ref, in that case the name will contain parent names.
249255
// 2. When model is defined using ref(reusable), name will not contain parent names.
250256
if (StringUtils.isBlank(codegenProperty.openApiType)) {
@@ -261,7 +267,7 @@ public static CodegenModel getModelFromOpenApiType(CodegenProperty codegenProper
261267

262268
public static void main(String[] args) {
263269
String ref = "#/components/schemas/api.v2010.account.message";
264-
270+
265271
System.out.println(getModelFromRef(ref));
266272
}
267273
public static CodegenModel getModelFromRef(String ref) {

src/main/java/com/twilio/oai/resolver/python/PythonCaseResolver.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,41 @@
44

55
import org.openapitools.codegen.utils.StringUtils;
66

7+
import java.util.Arrays;
8+
import java.util.HashSet;
9+
import java.util.Set;
10+
711
public class PythonCaseResolver implements CaseResolver {
12+
// Python reserved keywords that cannot be used as filenames
13+
private static final Set<String> PYTHON_RESERVED_KEYWORDS = new HashSet<>(Arrays.asList(
14+
"import", "from", "class", "def", "return", "if", "else", "elif", "for", "while",
15+
"break", "continue", "pass", "try", "except", "finally", "raise", "with", "as",
16+
"assert", "del", "global", "lambda", "yield", "None", "True", "False", "and",
17+
"or", "not", "in", "is"
18+
));
19+
820
@Override //not sure
921
public String productOperation(final String product) {
1022
return StringUtils.underscore(product);
1123
}
1224

1325
@Override //flex_flow.py
1426
public String pathOperation(final String pathPart) {
15-
return StringUtils.underscore(pathPart);
27+
String result = StringUtils.underscore(pathPart);
28+
// If the result is a Python reserved keyword, append underscore
29+
if (PYTHON_RESERVED_KEYWORDS.contains(result.toLowerCase())) {
30+
return result + "_";
31+
}
32+
return result;
1633
}
1734

1835
@Override
1936
public String filenameOperation(final String filename) {
20-
return pathOperation(filename);
37+
String result = pathOperation(filename);
38+
// If the filename (without extension) is a Python reserved keyword, append underscore
39+
if (PYTHON_RESERVED_KEYWORDS.contains(result.toLowerCase())) {
40+
return result + "_";
41+
}
42+
return result;
2143
}
2244
}

src/main/resources/twilio-python/responseInstance.handlebars

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
Response model for {{name}} operations
44
"""
55
class {{name}}Resource:
6-
def __init__(self,{{#vars}}{{baseName}}: {{{baseType}}}{{#unless @last}}, {{/unless}}{{/vars}}):
6+
def __init__(self,{{#vars}}{{name}}: {{{baseType}}}{{#unless @last}}, {{/unless}}{{/vars}}):
77
"""
88
Initialize the {{name}}Resource
9-
{{#vars}}:param {{baseName}}: {{{description}}}
9+
{{#vars}}:param {{name}}: {{{description}}}
1010
{{/vars}}
1111
"""
12-
{{#vars}}self.{{baseName}} = {{baseName}}
12+
{{#vars}}self.{{name}} = {{name}}
1313
{{/vars}}
1414
{{/responseInstanceModels}}

0 commit comments

Comments
 (0)