From 0e42edc95b44f19bf4262ec05aba8ede8cf18635 Mon Sep 17 00:00:00 2001 From: keepConcentration Date: Wed, 10 Sep 2025 16:35:10 +0900 Subject: [PATCH] [#21619] fix(python): update pyproject.toml license format with poetry1 fallback (#21931) * Add support for both string and object license formats in `pyproject.toml` for Python and Python-Pydantic generators. (#21619) * Generate the samples (#21698) * Generate the samples (#21698) * Remove Python-Pydantic-v1 license format tests (#21619) * Revert license format to string in Python-Pydantic-v1 samples (#21619) --- .../main/resources/python/pyproject.mustache | 5 ++ .../python/PythonClientCodegenTest.java | 74 +++++++++++++++++++ .../src/test/resources/bugs/issue_21619.yaml | 31 ++++++++ .../pyproject.toml | 2 +- samples/client/echo_api/python/pyproject.toml | 2 +- .../client/petstore/python/pyproject.toml | 2 +- 6 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/bugs/issue_21619.yaml diff --git a/modules/openapi-generator/src/main/resources/python/pyproject.mustache b/modules/openapi-generator/src/main/resources/python/pyproject.mustache index d5b2826be9a2..5f7f15811368 100644 --- a/modules/openapi-generator/src/main/resources/python/pyproject.mustache +++ b/modules/openapi-generator/src/main/resources/python/pyproject.mustache @@ -16,7 +16,12 @@ authors = [ ] {{/poetry1}} {{#licenseInfo}} +{{#poetry1}} license = "{{{licenseInfo}}}" +{{/poetry1}} +{{^poetry1}} +license = { text = "{{{licenseInfo}}}" } +{{/poetry1}} {{/licenseInfo}} readme = "README.md" {{#poetry1}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java index 0735ccc4f6f7..a18f2f40d11b 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonClientCodegenTest.java @@ -25,6 +25,7 @@ import io.swagger.v3.oas.models.media.*; import io.swagger.v3.parser.core.models.ParseOptions; import io.swagger.v3.parser.util.SchemaTypeUtil; import org.openapitools.codegen.*; +import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.languages.PythonClientCodegen; import org.openapitools.codegen.languages.features.CXFServerFeatures; import org.testng.Assert; @@ -611,4 +612,77 @@ public class PythonClientCodegenTest { assertFileContains(initFilePath, "from openapi_client.models.tag import Tag as Tag"); assertFileContains(initFilePath, "from openapi_client.models.user import User as User"); } + + @Test(description = "Verify default license format uses object notation when poetry1 is false") + public void testLicenseFormatInPyprojectToml() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("python") + .setInputSpec("src/test/resources/bugs/issue_21619.yaml") + .setOutputDir(output.getAbsolutePath()) + .addAdditionalProperty("licenseInfo", "MIT"); + + DefaultGenerator generator = new DefaultGenerator(); + List files = generator.opts(configurator.toClientOptInput()).generate(); + files.forEach(File::deleteOnExit); + + TestUtils.assertFileExists(Paths.get(output.getAbsolutePath(), "pyproject.toml")); + // When poetry1=false (default), license should use object notation: { text = "MIT" } + TestUtils.assertFileContains(Paths.get(output.getAbsolutePath(), "pyproject.toml"), + "license = { text = \"MIT\" }"); + } + + @Test(description = "Verify poetry1 mode uses string notation for license") + public void testPoetry1LicenseFormat() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("python") + .setInputSpec("src/test/resources/bugs/issue_21619.yaml") + .setOutputDir(output.getAbsolutePath()) + .addAdditionalProperty("licenseInfo", "Apache-2.0") + .addAdditionalProperty("poetry1", true); // Enable legacy poetry1 mode + + DefaultGenerator generator = new DefaultGenerator(); + List files = generator.opts(configurator.toClientOptInput()).generate(); + files.forEach(File::deleteOnExit); + + Path pyprojectPath = Paths.get(output.getAbsolutePath(), "pyproject.toml"); + TestUtils.assertFileExists(pyprojectPath); + + // In poetry1 mode, license should use simple string format: "Apache-2.0" + TestUtils.assertFileContains(pyprojectPath, "license = \"Apache-2.0\""); + + // Verify it does NOT use the new object format + TestUtils.assertFileNotContains(pyprojectPath, "license = { text = \"Apache-2.0\" }"); + } + + @Test(description = "Verify non-poetry1 mode uses object notation for license") + public void testNonPoetry1LicenseFormat() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("python") + .setInputSpec("src/test/resources/bugs/issue_21619.yaml") + .setOutputDir(output.getAbsolutePath()) + .addAdditionalProperty("licenseInfo", "BSD-3-Clause") + .addAdditionalProperty("poetry1", false); // Explicitly disable poetry1 mode + + DefaultGenerator generator = new DefaultGenerator(); + List files = generator.opts(configurator.toClientOptInput()).generate(); + files.forEach(File::deleteOnExit); + + Path pyprojectPath = Paths.get(output.getAbsolutePath(), "pyproject.toml"); + TestUtils.assertFileExists(pyprojectPath); + + // In non-poetry1 mode, license should use object format: { text = "BSD-3-Clause" } + TestUtils.assertFileContains(pyprojectPath, "license = { text = \"BSD-3-Clause\" }"); + + // Verify it does NOT use the legacy string format + TestUtils.assertFileNotContains(pyprojectPath, "license = \"BSD-3-Clause\""); + } } diff --git a/modules/openapi-generator/src/test/resources/bugs/issue_21619.yaml b/modules/openapi-generator/src/test/resources/bugs/issue_21619.yaml new file mode 100644 index 000000000000..a257599d4414 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/bugs/issue_21619.yaml @@ -0,0 +1,31 @@ +openapi: 3.0.0 +info: + title: License Format Test API + version: 1.0.0 + description: Simple API for testing pyproject.toml license format changes +paths: + /test: + get: + operationId: getTest + summary: Simple test endpoint + responses: + '200': + description: Success + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: "Hello World" +components: + schemas: + TestModel: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml index 25952c26ec86..fcf9c73b1528 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/pyproject.toml @@ -5,7 +5,7 @@ description = "Echo Server API" authors = [ {name = "OpenAPI Generator Community",email = "team@openapitools.org"}, ] -license = "Apache 2.0" +license = { text = "Apache 2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "Echo Server API"] requires-python = ">=3.9" diff --git a/samples/client/echo_api/python/pyproject.toml b/samples/client/echo_api/python/pyproject.toml index 25952c26ec86..fcf9c73b1528 100644 --- a/samples/client/echo_api/python/pyproject.toml +++ b/samples/client/echo_api/python/pyproject.toml @@ -5,7 +5,7 @@ description = "Echo Server API" authors = [ {name = "OpenAPI Generator Community",email = "team@openapitools.org"}, ] -license = "Apache 2.0" +license = { text = "Apache 2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "Echo Server API"] requires-python = ">=3.9" diff --git a/samples/openapi3/client/petstore/python/pyproject.toml b/samples/openapi3/client/petstore/python/pyproject.toml index c5d3669a6ff9..a466656e8b6e 100644 --- a/samples/openapi3/client/petstore/python/pyproject.toml +++ b/samples/openapi3/client/petstore/python/pyproject.toml @@ -5,7 +5,7 @@ description = "OpenAPI Petstore" authors = [ {name = "OpenAPI Generator Community",email = "team@openapitools.org"}, ] -license = "Apache-2.0" +license = { text = "Apache-2.0" } readme = "README.md" keywords = ["OpenAPI", "OpenAPI-Generator", "OpenAPI Petstore"] requires-python = ">=3.9"