Skip to content

Commit 6783b90

Browse files
authored
[Python][Client] Fix delimiter collision issue #5981 (#6451)
* [python][client] Fix delimiter collision (#5981) * [python][client] Fix delimiter collision (#5981) update samples * [python][client] Fix delimiter collision (#5981) update samples * [python][client] Fix convert to enum var name (#5981) * [python][client] Fix convert to enum var name (#5981) update samples
1 parent 15be875 commit 6783b90

2 files changed

Lines changed: 121 additions & 21 deletions

File tree

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

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -683,8 +683,12 @@ public String toDefaultValue(Schema p) {
683683
if (p.getDefault() != null) {
684684
if (Pattern.compile("\r\n|\r|\n").matcher((String) p.getDefault()).find())
685685
return "'''" + p.getDefault() + "'''";
686+
else if (p.getEnum() == null)
687+
// wrap using double quotes to avoid the need to escape any embedded single quotes
688+
return "\"" + p.getDefault() + "\"";
686689
else
687-
return "'" + ((String) p.getDefault()).replaceAll("'", "\'") + "'";
690+
// convert to enum var name later in postProcessModels
691+
return (String) p.getDefault();
688692
}
689693
} else if (ModelUtils.isArraySchema(p)) {
690694
if (p.getDefault() != null) {
@@ -728,7 +732,8 @@ private String toExampleValueRecursive(Schema schema, List<String> included_sche
728732

729733
if (StringUtils.isNotBlank(example) && !"null".equals(example)) {
730734
if (ModelUtils.isStringSchema(schema)) {
731-
example = "'" + example + "'";
735+
// wrap using double quotes to avoid the need to escape any embedded single quotes
736+
example = "\"" + example + "\"";
732737
}
733738
return example;
734739
}
@@ -902,43 +907,45 @@ public void setParameterExampleValue(CodegenParameter p) {
902907
type = p.dataType;
903908
}
904909

905-
if ("String".equalsIgnoreCase(type) || "str".equalsIgnoreCase(type)) {
910+
if (type != null) {
911+
if ("String".equalsIgnoreCase(type) || "str".equalsIgnoreCase(type)) {
906912
if (example == null) {
907-
example = p.paramName + "_example";
913+
example = p.paramName + "_example";
908914
}
909915
example = "'" + escapeText(example) + "'";
910-
} else if ("Integer".equals(type) || "int".equals(type)) {
916+
} else if ("Integer".equals(type) || "int".equals(type)) {
911917
if (example == null) {
912-
example = "56";
918+
example = "56";
913919
}
914-
} else if ("Float".equalsIgnoreCase(type) || "Double".equalsIgnoreCase(type)) {
920+
} else if ("Float".equalsIgnoreCase(type) || "Double".equalsIgnoreCase(type)) {
915921
if (example == null) {
916-
example = "3.4";
922+
example = "3.4";
917923
}
918-
} else if ("BOOLEAN".equalsIgnoreCase(type) || "bool".equalsIgnoreCase(type)) {
924+
} else if ("BOOLEAN".equalsIgnoreCase(type) || "bool".equalsIgnoreCase(type)) {
919925
if (example == null) {
920-
example = "True";
926+
example = "True";
921927
}
922-
} else if ("file".equalsIgnoreCase(type)) {
928+
} else if ("file".equalsIgnoreCase(type)) {
923929
if (example == null) {
924-
example = "/path/to/file";
930+
example = "/path/to/file";
925931
}
926932
example = "'" + escapeText(example) + "'";
927-
} else if ("Date".equalsIgnoreCase(type)) {
933+
} else if ("Date".equalsIgnoreCase(type)) {
928934
if (example == null) {
929-
example = "2013-10-20";
935+
example = "2013-10-20";
930936
}
931937
example = "'" + escapeText(example) + "'";
932-
} else if ("DateTime".equalsIgnoreCase(type)) {
938+
} else if ("DateTime".equalsIgnoreCase(type)) {
933939
if (example == null) {
934-
example = "2013-10-20T19:20:30+01:00";
940+
example = "2013-10-20T19:20:30+01:00";
935941
}
936942
example = "'" + escapeText(example) + "'";
937-
} else if (!languageSpecificPrimitives.contains(type)) {
943+
} else if (!languageSpecificPrimitives.contains(type)) {
938944
// type is a model class, e.g. User
939945
example = this.packageName + "." + type + "()";
940-
} else {
946+
} else {
941947
LOGGER.warn("Type " + type + " not handled properly in setParameterExampleValue");
948+
}
942949
}
943950

944951
if (example == null) {

modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java

Lines changed: 96 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919

2020
import io.swagger.v3.oas.models.OpenAPI;
2121
import io.swagger.v3.oas.models.Operation;
22+
import io.swagger.v3.oas.models.media.Schema;
2223
import io.swagger.v3.oas.models.media.StringSchema;
24+
import java.util.HashSet;
2325
import org.openapitools.codegen.CodegenConstants;
26+
import org.openapitools.codegen.CodegenModelFactory;
27+
import org.openapitools.codegen.CodegenModelType;
2428
import org.openapitools.codegen.CodegenOperation;
29+
import org.openapitools.codegen.CodegenParameter;
2530
import org.openapitools.codegen.TestUtils;
2631
import org.openapitools.codegen.languages.PythonClientCodegen;
32+
import org.openapitools.codegen.utils.ModelUtils;
2733
import org.testng.Assert;
2834
import org.testng.annotations.Test;
2935

@@ -93,12 +99,99 @@ public void testRegularExpressionOpenAPISchemaVersion3() {
9399
Assert.assertEquals(op.allParams.get(5).pattern, "/^pattern\\d{3}$/i");
94100
}
95101

96-
@Test(description = "test single quotes escape")
97-
public void testSingleQuotes() {
102+
@Test(description = "test default value with single quotes")
103+
public void testSingleQuotesDefaultValue() {
98104
final PythonClientCodegen codegen = new PythonClientCodegen();
99105
StringSchema schema = new StringSchema();
100106
schema.setDefault("Text containing 'single' quote");
101107
String defaultValue = codegen.toDefaultValue(schema);
102-
Assert.assertEquals("'Text containing \'single\' quote'", defaultValue);
108+
Assert.assertEquals(defaultValue, "\"Text containing 'single' quote\"");
109+
}
110+
111+
@Test(description = "test example value with single quotes")
112+
public void testSingleQuotesExampleValue() {
113+
final PythonClientCodegen codegen = new PythonClientCodegen();
114+
StringSchema schema = new StringSchema();
115+
schema.setExample("Text containing 'single' quote");
116+
String exampleValue = codegen.toExampleValue(schema);
117+
Assert.assertEquals(exampleValue, "\"Text containing 'single' quote\"");
118+
}
119+
120+
@Test
121+
public void testFormParameterHasDefaultValue() {
122+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml");
123+
final PythonClientCodegen codegen = new PythonClientCodegen();
124+
codegen.setOpenAPI(openAPI);
125+
126+
Schema requestBodySchema = ModelUtils.getSchemaFromRequestBody(openAPI.getPaths().get("/fake").getGet().getRequestBody());
127+
CodegenParameter codegenParameter = codegen.fromFormProperty("enum_form_string", (Schema) requestBodySchema.getProperties().get("enum_form_string"), new HashSet<String>());
128+
129+
Assert.assertEquals(codegenParameter.defaultValue, "-efg");
130+
}
131+
132+
@Test
133+
public void testExample1() {
134+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/examples.yaml");
135+
final PythonClientCodegen codegen = new PythonClientCodegen();
136+
137+
Operation operation = openAPI.getPaths().get("/example1/singular").getGet();
138+
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
139+
codegen.setParameterExampleValue(codegenParameter, operation.getParameters().get(0));
140+
141+
Assert.assertEquals(codegenParameter.example, "example1 value");
142+
143+
Operation operation2 = openAPI.getPaths().get("/example1/plural").getGet();
144+
CodegenParameter codegenParameter2 = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
145+
codegen.setParameterExampleValue(codegenParameter2, operation2.getParameters().get(0));
146+
147+
Assert.assertEquals(codegenParameter2.example, "An example1 value");
148+
}
149+
150+
@Test
151+
public void testExample2() {
152+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/examples.yaml");
153+
final PythonClientCodegen codegen = new PythonClientCodegen();
154+
155+
Operation operation = openAPI.getPaths().get("/example2/singular").getGet();
156+
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
157+
codegen.setParameterExampleValue(codegenParameter, operation.getParameters().get(0));
158+
159+
Assert.assertEquals(codegenParameter.example, "example2 value");
160+
}
161+
162+
@Test
163+
public void testExample3() {
164+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/examples.yaml");
165+
final PythonClientCodegen codegen = new PythonClientCodegen();
166+
167+
Operation operation = openAPI.getPaths().get("/example3/singular").getGet();
168+
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
169+
codegen.setParameterExampleValue(codegenParameter, operation.getParameters().get(0));
170+
171+
Assert.assertEquals(codegenParameter.example, "example3: parameter value");
172+
173+
Operation operation2 = openAPI.getPaths().get("/example3/plural").getGet();
174+
CodegenParameter codegenParameter2 = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
175+
codegen.setParameterExampleValue(codegenParameter2, operation2.getParameters().get(0));
176+
177+
Assert.assertEquals(codegenParameter2.example, "example3: parameter value");
178+
}
179+
180+
@Test
181+
public void testExample4() {
182+
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/examples.yaml");
183+
final PythonClientCodegen codegen = new PythonClientCodegen();
184+
185+
Operation operation = openAPI.getPaths().get("/example4/singular").getPost();
186+
CodegenParameter codegenParameter = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
187+
codegen.setParameterExampleValue(codegenParameter, operation.getRequestBody());
188+
189+
Assert.assertEquals(codegenParameter.example, "example4 value");
190+
191+
Operation operation2 = openAPI.getPaths().get("/example4/plural").getPost();
192+
CodegenParameter codegenParameter2 = CodegenModelFactory.newInstance(CodegenModelType.PARAMETER);
193+
codegen.setParameterExampleValue(codegenParameter2, operation2.getRequestBody());
194+
195+
Assert.assertEquals(codegenParameter2.example, "An example4 value");
103196
}
104197
}

0 commit comments

Comments
 (0)