Skip to content

Commit 4882687

Browse files
authored
[python] Fix empty example value for siblings that share a model (#25106)
toExampleValueRecursive tracks the ancestors of the current schema in includedSchemas to stop on cycles, but the same list was passed to every property of an object. When three or more sibling properties referenced the same model (e.g. inline objects the generator deduplicates into one model), the third one was mistaken for a cycle and got an empty value, producing 'prop4 = ,' in the generated tests. Give each property its own copy of the ancestor list. Fixes #25047
1 parent 21c2f86 commit 4882687

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,11 @@ private String toExampleValueRecursive(Schema schema, List<Schema> includedSchem
610610
if (StringUtils.isBlank(refTitle) || "null".equals(refTitle)) {
611611
schema2.setTitle(propname);
612612
}
613+
// Each property gets its own copy of the path: includedSchemas tracks the
614+
// ancestors of the current schema for cycle detection, so siblings that
615+
// reference the same model must not count as a cycle (#25047).
613616
example += "\n" + indentationString + underscore(propname) + " = " +
614-
toExampleValueRecursive(schema2, includedSchemas, indentation + 1) + ", ";
617+
toExampleValueRecursive(schema2, new ArrayList<>(includedSchemas), indentation + 1) + ", ";
615618
}
616619
}
617620
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,29 @@ public void testGeneratedExampleValues() {
217217
Assert.assertTrue(codegen.escapeQuotationMark(codegen.toExampleValue(addressSchema)).matches(addressPattern));
218218
}
219219

220+
@Test(description = "sibling properties that share a model are not treated as a cycle (#25047)")
221+
public void testExampleValueForSiblingsSharingAModel() {
222+
final Schema shared = new ObjectSchema().addProperty("prop", new StringSchema());
223+
final Schema holder = new ObjectSchema()
224+
.addProperty("prop1", new Schema<>().$ref("#/components/schemas/Shared"))
225+
.addProperty("prop2", new Schema<>().$ref("#/components/schemas/Shared"))
226+
.addProperty("prop3", new Schema<>().$ref("#/components/schemas/Shared"));
227+
holder.setTitle("Holder");
228+
final OpenAPI openAPI = new OpenAPI().components(new io.swagger.v3.oas.models.Components()
229+
.addSchemas("Shared", shared)
230+
.addSchemas("Holder", holder));
231+
final PythonClientCodegen codegen = new PythonClientCodegen();
232+
codegen.setOpenAPI(openAPI);
233+
234+
final String example = codegen.toExampleValue(holder);
235+
236+
Assert.assertFalse(example.matches("(?s).*=\\s*,.*"), "empty example value in:\n" + example);
237+
for (String prop : Arrays.asList("prop1", "prop2", "prop3")) {
238+
Assert.assertTrue(example.contains(prop + " = openapi_client.models.shared.Shared("),
239+
prop + " missing its example in:\n" + example);
240+
}
241+
}
242+
220243
@Test(description = "test single quotes escape")
221244
public void testSingleQuotes() {
222245
final PythonClientCodegen codegen = new PythonClientCodegen();

0 commit comments

Comments
 (0)