fix(python): guard generated typing_extensions imports for python 3.11+#3
Open
v-tan wants to merge 2 commits into
Open
fix(python): guard generated typing_extensions imports for python 3.11+#3v-tan wants to merge 2 commits into
v-tan wants to merge 2 commits into
Conversation
openapi-python-client@0.28 emits an unconditional `from typing_extensions import Self` in every generated model, but typing-extensions is declared as a runtime dep only on python_version < '3.11'. Fresh installs on 3.11+ raise ModuleNotFoundError at `import kreuzberg_cloud` because the dep isn't pulled in but the bare import still tries to resolve it. CI hasn't surfaced this because ci-python.yml runs only on 3.10. Add a post-codegen rewrite that swaps the bare import for a guarded try/except falling back through stdlib typing.Self (PEP 673) before typing-extensions, plus a regression test asserting no _generated/ file still has the unconditional import.
CI mypy on Python 3.10 decayed JobResponse.from_dict's `-> Self` return to `Any` when the import was guarded by `try/except ImportError`, because mypy only narrows imports via PEP 484 `sys.version_info` checks. The decay propagated through _parse_job and tripped no-any-return on client.py:119. Switch the post-codegen rewrite to the sys.version_info >= (3, 11) form — matches the existing pattern in the handwritten client.py, lets mypy bind Self to the stdlib alias on 3.11+ and to typing_extensions on 3.10. Also resolves the prek ruff failures on the script: drop the print() calls in favour of sys.stderr.write (T201), add docstrings to every function (D103), and tag the file as a script (INP001).
Goldziher
reviewed
May 30, 2026
Goldziher
left a comment
Member
There was a problem hiding this comment.
This fix is unnecessary I think.
| expected output for the openapi-python-client version in use. | ||
| """ | ||
|
|
||
| from __future__ import annotations |
Member
There was a problem hiding this comment.
Unnecessary - this is only required for python lower than 3.10, which is anyhow unsupported
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
openapi-python-client@0.28emits an unconditionalfrom typing_extensions import Selfin every generated model.packages/python/pyproject.tomldeclarestyping-extensionsas a runtime dep only onpython_version < '3.11'. On 3.11+ a freshpip install kreuzberg-cloud-sdkproduces a package whereimport kreuzberg_cloudraisesModuleNotFoundError: No module named 'typing_extensions'. CI hasn't caught this becauseci-python.ymlruns only on Python 3.10, where the marker matches and the dep is installed.This PR adds a post-codegen rewrite that swaps the unconditional import for a guarded
try/exceptfalling back through stdlibtyping.Self(PEP 673, added in 3.11) beforetyping-extensions. Stays compatible on 3.10 via the existing dep marker; resolves cleanly on 3.11+ without ever needing the runtime dep.Reproduce on
mainChanges
packages/python/scripts/postprocess_generated.py— rewritesfrom typing_extensions import Selftotry: from typing import Self / except ImportError: from typing_extensions import Self. Idempotent.tasks/python.yml::generate— runs the script after the codegen output is in place.packages/python/tests/test_generated_imports.py— static regression check asserting no_generated/*file still has a bare unconditional import.Verification
End-to-end against the v0.1.1 installed wheel on Python 3.13:
typing-extensions_generated/ModuleNotFoundErroronbounding_box.py:8(the bug)_generated/BoundingBox{'x0': 0.0, 'x1': 0.0, 'y0': 0.0, 'y1': 0.0}Locally with the fix applied,
task python:generatefollowed by the new regression test passes; existing test suite untouched.Out of scope
ci-python.ymlcurrently tests only on Python 3.10. Worth extending the matrix to 3.11/3.12/3.13 so this class of bug never ships again, but that's a separate PR.Refs
openapi-python-client@0.28.4typing.Self(Python 3.11+)