fix(python-flask, python-blueplanet): emitted tests are invalid Python when an operation has no cookie params
Generated test_*.py files for python-flask (including useConnexion3=true) and python-blueplanet are invalid Python — python3 -m py_compile fails with IndentationError: unexpected indent — for every operation that does not declare cookie parameters.
Reproducer
java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate \
-c bin/configs/python-flask.yaml -o /tmp/oag-flask
python3 -m py_compile /tmp/oag-flask/openapi_server/test/test_pet_controller.py
# Sorry: IndentationError: unexpected indent (test_pet_controller.py, line 20)
Broken output — the 8 leaked spaces (see Cause) attach to the next statement the template emits. For an operation without in: cookie parameters that is normally the response = ... line (for an operation with form parameters it is the data = {... line), which ends up indented by 16 columns instead of 8:
headers = {
'Accept': 'application/json',
}
response = self.client.open(
Measured on master with the official sample configs (bin/configs/python-flask.yaml, python-flask-connexion3.yaml, python-blueplanet.yaml), generating into a fresh output directory: the controller test file of every API fails py_compile — 4 files for python-flask, 4 for useConnexion3=true, 3 for python-blueplanet (a test_*.py glob over the python-flask / connexion3 output matches 7 files; 4 are the per-API controller tests, the other 3 are generated model modules for the spec's Test* schemas, which are unaffected). The checked-in samples do not show this because generated test files are never overwritten on regeneration once they exist (DefaultGenerator skips existing model/API test files), and the sample test files predate the {{#cookieParams}} statement block (#25487) — which is also why the Samples up-to-date CI job cannot surface the bug.
Cause
In both controller_test.mustache templates the {{#cookieParams}} section opened mid-line, after 8 literal spaces:
{{#cookieParams}}{{#-first}}headers['Cookie'] = '; '.join([{{/-first}}...
{{/cookieParams}}
A section tag that is not standalone leaves the text before it — here the 8 spaces — in the output even when the section renders nothing. With an empty section the open line emits just those spaces, and the standalone {{/cookieParams}} swallows its own line break, so the dangling indent merges into the next emitted statement: response = self.client.open( → IndentationError at py_compile/import/pytest collection.
The fix moves the section tags onto their own lines so an empty section emits nothing. Operations with cookie params render the same statement as before; only for an operation with two or more cookie parameters do the continuation lines of the headers['Cookie'] = '; '.join([... expression move from column 0 to column 8 (both are valid Python).
python-aiohttp is not affected: its cookie block already opens {{#cookieParams}} on its own line. The remaining {{#cookieParams}}{{#-first}} usages (aiohttp's cookies=cookies, request argument, blueplanet's headers=headers open() argument, and the Java jersey2/jersey3 cookie-arg lists) are inline inside call expressions — they only emit a continuation argument when the section renders, so they cannot leak indentation into the next statement.
Tests added
AbstractPythonConnexionServerCodegenTest.testGeneratedTestsStatementIndentWithAndWithoutCookieParams — Java-only, no python3 toolchain needed. It generates both shapes — /ping (no parameters at all) and get_cookie_only (cookie params only) — for python-flask, python-flask useConnexion3=true, and python-blueplanet, reads the generated test_default_controller.py, and pins response = self.client.open( and self.assert200( to column 8, plus the Cookie statement for the cookie operation: headers['Cookie'] = '; '.join([... (flask), headers = [] + headers += [('Cookie', ... (blueplanet). Reverting the template fix makes the test fail with expected: 8 but was: 16; the assertions are fail-fast, so the failure is reported for the first variant checked.
Verification results
./mvnw -pl modules/openapi-generator -am -Dtest=AbstractPythonConnexionServerCodegenTest,PythonFlaskConnexionServerCodegenTest testrun withpython3absent fromPATH: 25 + 22 = 47 tests, 0 failures, 0 skipped.- The new test fails when the template fix alone is reverted (
git apply -R):expected: 8 but was: 16(reported for the first variant checked, since the assertions are fail-fast) — i.e. it reproduces the exact IndentationError shape. - With the fix, every test file generated by the three official configs passes
python3 -m py_compile: 7/7 python-flask, 7/7 connexion3, 3/3 blueplanet (was 4/7, 4/7, 3/3 broken). bin/generate-samples.shfor the three configs leavesgit statusunchanged (existing generated test files are skipped byDefaultGenerator, and no other file changes).
Note on conflicts
git merge-tree reports a content conflict with open PR #25457 (quoted-name handling) in the python-blueplanet controller_test.mustache — both changes touch the same cookie-param lines and whichever merges second will need a small manual resolution (keep the quoted-name rendering inside the now-standalone {{#cookieParams}} section). The python-flask template and the Java test file merge cleanly.
cc @cbornet @tomplus @krjakbrjak @fa0311 (Python technical committee)
PR checklist
- Read the contribution guidelines.
- Run the following to build the project and update samples:
(Scope actually run for this change:./mvnw clean package || exit ./bin/generate-samples.sh ./bin/configs/*.yaml || exit ./bin/utils/export_docs_generators.sh || exitbin/generate-samples.shfor the three affected configs —python-flask,python-flask-connexion3,python-blueplanet— which leavesgit statusunchanged.)
(For Windows users, please run the script in WSL)
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example./bin/generate-samples.sh bin/configs/java*.
IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed. - If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.
🤖 Generated with Claude Code
Summary by cubic
Fixes generated test_*.py files for python-flask (including useConnexion3=true) and python-blueplanet being invalid Python for operations without cookie parameters. A mid-line {{#cookieParams}} section tag left its 8 leading spaces behind when empty, merging into the next statement and producing an IndentationError at py_compile/import/pytest collection. The section tags now sit on their own lines so an empty section emits nothing; operations with cookie params render the same statements as before.
- Adds a Java-only regression test pinning generated statement indentation for operations with and without cookie params, so the fix is verified without a Python toolchain.
python-aiohttpis unaffected since its cookie block already opens the section on its own line.