From 0a0e4d7b91833994f7c939991a4edcc712b6e4b2 Mon Sep 17 00:00:00 2001 From: Tadas Barzdzius Date: Tue, 3 Nov 2026 16:57:53 +0200 Subject: [PATCH] fix(python): serialize an enum path or query parameter passed as its value The generated serializer read `.value` from an enum reference path or query parameter, so passing the enum's value instead of the enum raised AttributeError: 'str' object has no attribute 'value'. A nullable enum reference (`allOf: [$ref]` with `nullable: true`) is typed `Optional[Any]`, which invites passing the value. ApiClient.param_serialize already turns an Enum into its value through sanitize_for_serialization, so the template now passes the parameter as given. Fixes #16071 --- .../src/main/resources/python/api.mustache | 4 ++-- .../openapi_client/api/path_api.py | 2 +- .../openapi_client/api/query_api.py | 2 +- .../echo_api/python/openapi_client/api/path_api.py | 2 +- .../echo_api/python/openapi_client/api/query_api.py | 2 +- .../python-aiohttp/petstore_api/api/fake_api.py | 2 +- .../python-httpx-sync/petstore_api/api/fake_api.py | 2 +- .../python-httpx/petstore_api/api/fake_api.py | 2 +- .../python-httpx2-sync/petstore_api/api/fake_api.py | 2 +- .../python-httpx2/petstore_api/api/fake_api.py | 2 +- .../python-lazyImports/petstore_api/api/fake_api.py | 2 +- .../petstore/python/petstore_api/api/fake_api.py | 2 +- .../client/petstore/python/tests/test_fake_api.py | 12 ++++++++++++ 13 files changed, 25 insertions(+), 13 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/python/api.mustache b/modules/openapi-generator/src/main/resources/python/api.mustache index c771516a8a49..9cfd91f43770 100644 --- a/modules/openapi-generator/src/main/resources/python/api.mustache +++ b/modules/openapi-generator/src/main/resources/python/api.mustache @@ -318,7 +318,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb # process the path parameters {{#pathParams}} if {{paramName}} is not None: - _path_params['{{baseName}}'] = {{paramName}}{{#isEnumRef}}.value{{/isEnumRef}} + _path_params['{{baseName}}'] = {{paramName}} {{/pathParams}} # process the query parameters {{#queryParams}} @@ -378,7 +378,7 @@ https://github.com/OpenAPITools/openapi-generator/blob/c84b949df1a9ec04ba75989cb {{/isModel}} {{^isMap}} {{^isModel}} - _query_params.append(('{{baseName}}', {{paramName}}{{#isEnumRef}}.value{{/isEnumRef}})) + _query_params.append(('{{baseName}}', {{paramName}})) {{/isModel}} {{/isMap}} {{/isDate}}{{/isDateTime}} diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py index d3e2de0529f9..e53e3af4b94c 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/path_api.py @@ -304,7 +304,7 @@ def _tests_path_string_path_string_integer_path_integer_enum_nonref_string_path_ if enum_nonref_string_path is not None: _path_params['enum_nonref_string_path'] = enum_nonref_string_path if enum_ref_string_path is not None: - _path_params['enum_ref_string_path'] = enum_ref_string_path.value + _path_params['enum_ref_string_path'] = enum_ref_string_path # process the query parameters # process the header parameters # process the form parameters diff --git a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py index d8271833134e..74f3412c17d6 100644 --- a/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py +++ b/samples/client/echo_api/python-disallowAdditionalPropertiesIfNotPresent/openapi_client/api/query_api.py @@ -282,7 +282,7 @@ def _test_enum_ref_string_serialize( if enum_ref_string_query is not None: - _query_params.append(('enum_ref_string_query', enum_ref_string_query.value)) + _query_params.append(('enum_ref_string_query', enum_ref_string_query)) # process the header parameters # process the form parameters diff --git a/samples/client/echo_api/python/openapi_client/api/path_api.py b/samples/client/echo_api/python/openapi_client/api/path_api.py index d3e2de0529f9..e53e3af4b94c 100644 --- a/samples/client/echo_api/python/openapi_client/api/path_api.py +++ b/samples/client/echo_api/python/openapi_client/api/path_api.py @@ -304,7 +304,7 @@ def _tests_path_string_path_string_integer_path_integer_enum_nonref_string_path_ if enum_nonref_string_path is not None: _path_params['enum_nonref_string_path'] = enum_nonref_string_path if enum_ref_string_path is not None: - _path_params['enum_ref_string_path'] = enum_ref_string_path.value + _path_params['enum_ref_string_path'] = enum_ref_string_path # process the query parameters # process the header parameters # process the form parameters diff --git a/samples/client/echo_api/python/openapi_client/api/query_api.py b/samples/client/echo_api/python/openapi_client/api/query_api.py index d8271833134e..74f3412c17d6 100644 --- a/samples/client/echo_api/python/openapi_client/api/query_api.py +++ b/samples/client/echo_api/python/openapi_client/api/query_api.py @@ -282,7 +282,7 @@ def _test_enum_ref_string_serialize( if enum_ref_string_query is not None: - _query_params.append(('enum_ref_string_query', enum_ref_string_query.value)) + _query_params.append(('enum_ref_string_query', enum_ref_string_query)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py index 99e4031552c1..036c27eb948a 100644 --- a/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-aiohttp/petstore_api/api/fake_api.py @@ -558,7 +558,7 @@ def _fake_enum_ref_query_parameter_serialize( # process the query parameters if enum_ref is not None: - _query_params.append(('enum_ref', enum_ref.value)) + _query_params.append(('enum_ref', enum_ref)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py index 4a6f7b7183da..2a52895d6deb 100644 --- a/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx-sync/petstore_api/api/fake_api.py @@ -744,7 +744,7 @@ def _fake_enum_ref_query_parameter_serialize( # process the query parameters if enum_ref is not None: - _query_params.append(('enum_ref', enum_ref.value)) + _query_params.append(('enum_ref', enum_ref)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py index 8c7dc59ccaac..283849fe2697 100644 --- a/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx/petstore_api/api/fake_api.py @@ -539,7 +539,7 @@ def _fake_enum_ref_query_parameter_serialize( # process the query parameters if enum_ref is not None: - _query_params.append(('enum_ref', enum_ref.value)) + _query_params.append(('enum_ref', enum_ref)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py index 4a6f7b7183da..2a52895d6deb 100644 --- a/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx2-sync/petstore_api/api/fake_api.py @@ -744,7 +744,7 @@ def _fake_enum_ref_query_parameter_serialize( # process the query parameters if enum_ref is not None: - _query_params.append(('enum_ref', enum_ref.value)) + _query_params.append(('enum_ref', enum_ref)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py index 8c7dc59ccaac..283849fe2697 100644 --- a/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-httpx2/petstore_api/api/fake_api.py @@ -539,7 +539,7 @@ def _fake_enum_ref_query_parameter_serialize( # process the query parameters if enum_ref is not None: - _query_params.append(('enum_ref', enum_ref.value)) + _query_params.append(('enum_ref', enum_ref)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py index b7d2c36217b7..d043aa5ad583 100644 --- a/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python-lazyImports/petstore_api/api/fake_api.py @@ -559,7 +559,7 @@ def _fake_enum_ref_query_parameter_serialize( # process the query parameters if enum_ref is not None: - _query_params.append(('enum_ref', enum_ref.value)) + _query_params.append(('enum_ref', enum_ref)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py index 020ebbfa43ae..7bec55ff9038 100755 --- a/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py +++ b/samples/openapi3/client/petstore/python/petstore_api/api/fake_api.py @@ -539,7 +539,7 @@ def _fake_enum_ref_query_parameter_serialize( # process the query parameters if enum_ref is not None: - _query_params.append(('enum_ref', enum_ref.value)) + _query_params.append(('enum_ref', enum_ref)) # process the header parameters # process the form parameters diff --git a/samples/openapi3/client/petstore/python/tests/test_fake_api.py b/samples/openapi3/client/petstore/python/tests/test_fake_api.py index 58daa705cb58..a0d215feef6b 100644 --- a/samples/openapi3/client/petstore/python/tests/test_fake_api.py +++ b/samples/openapi3/client/petstore/python/tests/test_fake_api.py @@ -198,3 +198,15 @@ def testTopLevelEnumJson(self): ): returned = self.fake_api.fake_return_enum() self.assertEqual("a", returned) + + def testEnumRefQueryParameterAcceptsEnumOrValue(self): + """An enum reference query parameter serializes the same as the enum or its value""" + for enum_ref in (petstore_api.EnumClass.MINUS_EFG, "-efg"): + _, url, _, _, _ = self.fake_api._fake_enum_ref_query_parameter_serialize( + enum_ref=enum_ref, + _request_auth=None, + _content_type=None, + _headers=None, + _host_index=0, + ) + self.assertTrue(url.endswith("?enum_ref=-efg"), url)