OpenAPITools / OpenAPITools/openapi-generator

[BUG] Python client return type incorrect, should be list[str] but is list[Optional[str]]

Open
#20,875 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)? (I used https://editor-next.swagger.io/)
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

I've trying to build a Python client from an openapi spec similar to the one below. However it's producing the wrong return type. However I think this must be an obscure bug because making a trivial change to the json (eg altering one of the description fields) results in the correct return type being generated.

openapi-generator version

I'm using 7.12.0 and I tried 7.10.0 and 7.11.0 and the issue was also present in those versions.

OpenAPI declaration file content or url

https://gist.github.com/paulhirst-cb/42d81177ecc4d93d2bf73a818bca3bca

Generation Details

See the steps to reproduce

Steps to reproduce
# Make a temporary folder to work in
mkdir /tmp/foobar
cd /tmp/foobar

# Download the spec
curl -o spec.json https://gist.githubusercontent.com/paulhirst-cb/42d81177ecc4d93d2bf73a818bca3bca/raw/78ccb6e42acc3b3030d5e3004c0224161d085535/gistfile1.txt

# Grab OpenAPI generator
curl -o openapi-generator.jar  https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/7.12.0/openapi-generator-cli-7.12.0.jar

# Run the generation
java -jar openapi-generator.jar generate -o code -i spec.json -g python --package-name client

# See the return type of the function
grep -A 20 -r -F 'def bar(' code

code/client/api/default_api.py:    def bar(
code/client/api/default_api.py-        self,
code/client/api/default_api.py-        _request_timeout: Union[
code/client/api/default_api.py-            None,
code/client/api/default_api.py-            Annotated[StrictFloat, Field(gt=0)],
code/client/api/default_api.py-            Tuple[
code/client/api/default_api.py-                Annotated[StrictFloat, Field(gt=0)],
code/client/api/default_api.py-                Annotated[StrictFloat, Field(gt=0)]
code/client/api/default_api.py-            ]
code/client/api/default_api.py-        ] = None,
code/client/api/default_api.py-        _request_auth: Optional[Dict[StrictStr, Any]] = None,
code/client/api/default_api.py-        _content_type: Optional[StrictStr] = None,
code/client/api/default_api.py-        _headers: Optional[Dict[StrictStr, Any]] = None,
code/client/api/default_api.py-        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
code/client/api/default_api.py-    ) -> List[Optional[str]]:

# Notice the return type is List[Optional[str]]

# Change the description from "a" to "foo"

sed -i 's/"title": "a"/"title": "foo"/' spec.json

# Rerun the generation
java -jar openapi-generator.jar generate -o code -i spec.json -g python --package-name client

# See the return type of the function
grep -A 20 -r -F 'def bar(' code

code/client/api/default_api.py:    def bar(
code/client/api/default_api.py-        self,
code/client/api/default_api.py-        _request_timeout: Union[
code/client/api/default_api.py-            None,
code/client/api/default_api.py-            Annotated[StrictFloat, Field(gt=0)],
code/client/api/default_api.py-            Tuple[
code/client/api/default_api.py-                Annotated[StrictFloat, Field(gt=0)],
code/client/api/default_api.py-                Annotated[StrictFloat, Field(gt=0)]
code/client/api/default_api.py-            ]
code/client/api/default_api.py-        ] = None,
code/client/api/default_api.py-        _request_auth: Optional[Dict[StrictStr, Any]] = None,
code/client/api/default_api.py-        _content_type: Optional[StrictStr] = None,
code/client/api/default_api.py-        _headers: Optional[Dict[StrictStr, Any]] = None,
code/client/api/default_api.py-        _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
code/client/api/default_api.py-    ) -> List[str]:

# Notice the return type is now List[str] as expected

I tried running on a few different versions of Java including the amazoncoretto:23 docker image but nothing seemed to help.

I also tried docker.io/openapitools/openapi-generator-cli:latest and it was no different.

Related issues/PRs

Couldn't find anything

Suggest a fix

Sorry, no idea. I managed to replicate it other ways too. My original spec is much larger and removing certain bits of it seemed to also cause the bug to vanish.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the supplied spec.json and reproduce generation through the openapi-generator CLI using the Python generator. Inspect the generated code/client/api/default_api.py and the generator path that determines the return annotation; done means the same spec consistently produces List[str] for bar regardless of the description text.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, python
Domain
api, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.