Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions docs/generators/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>for</li>
<li>form_params</li>
<li>from</li>
<li>from_dict</li>
<li>from_json</li>
<li>global</li>
<li>header_params</li>
<li>if</li>
Expand All @@ -110,6 +112,22 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>json</li>
<li>lambda</li>
<li>local_var_files</li>
<li>model_computed_fields</li>
<li>model_config</li>
<li>model_construct</li>
<li>model_copy</li>
<li>model_dump</li>
<li>model_dump_json</li>
<li>model_extra</li>
<li>model_fields</li>
<li>model_fields_set</li>
<li>model_json_schema</li>
<li>model_parametrized_name</li>
<li>model_post_init</li>
<li>model_rebuild</li>
<li>model_validate</li>
<li>model_validate_json</li>
<li>model_validate_strings</li>
<li>none</li>
<li>nonlocal</li>
<li>not</li>
Expand All @@ -124,6 +142,9 @@ These options may be applied as additional-properties (cli) or configOptions (pl
<li>return</li>
<li>schema</li>
<li>self</li>
<li>to_dict</li>
<li>to_json</li>
<li>to_str</li>
<li>true</li>
<li>try</li>
<li>while</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,17 @@ public PythonClientCodegen() {
.stability(Stability.STABLE)
.build();

// fields with these names would clash with the helper methods generated on every
// model (a field named from_dict shadows the classmethod) or with pydantic's
// model_* namespace (a field named model_config is clobbered by the ConfigDict
// assignment and silently dropped), so mangle them like any other reserved word
reservedWords.addAll(GENERATED_MODEL_MEMBER_NAMES);
for (String memberName : PYDANTIC_BASE_MODEL_MEMBER_NAMES) {
if (memberName.startsWith("model_")) {
reservedWords.add(memberName);
}
}

// clear import mapping (from default generator) as python does not use it
// at the moment
importMapping.clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1267,9 +1267,11 @@ public void testUnmappedMemberCollisionsRemainOutsideNameMappingValidation()
"src/test/resources/3_0/python/model-attribute-alias.yaml");
final Path model = Paths.get(outputPath + "openapi_client/models/alias_model.py");

// unmapped collisions are not rejected; they fall back to reserved-word
// mangling and keep their wire name through the alias
assertFileContains(model,
" model_dump: Optional[StrictStr]",
" to_dict: Optional[StrictStr]");
" var_model_dump: Optional[StrictStr] = Field(default=None, alias=\"model_dump\")",
" var_to_dict: Optional[StrictStr] = Field(default=None, alias=\"to_dict\")");
}

@Test
Expand Down Expand Up @@ -1358,6 +1360,22 @@ public void testModelNameMappingDoesNotRenameParameters() {
Assert.assertEquals(codegen.toParamName("some-value"), "parameter_value");
}

@Test
public void testGeneratedHelperAndPydanticNamesAreReserved() {
final PythonClientCodegen codegen = new PythonClientCodegen();

// names of the helper methods generated on every model
Assert.assertEquals(codegen.toVarName("to_dict"), "var_to_dict");
Assert.assertEquals(codegen.toVarName("from_dict"), "var_from_dict");
Assert.assertEquals(codegen.toVarName("to_json"), "var_to_json");
// pydantic BaseModel namespace
Assert.assertEquals(codegen.toVarName("model_config"), "var_model_config");
Assert.assertEquals(codegen.toVarName("model_fields"), "var_model_fields");
Assert.assertEquals(codegen.toVarName("model_dump"), "var_model_dump");
// similar-looking names must not be mangled
Assert.assertEquals(codegen.toVarName("model_configuration"), "model_configuration");
}

@Test(dataProvider = "numberMappings")
public void testMapNumberTo(String mapToNumber, String expectedType) throws IOException {
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
Expand Down
Loading