Skip to content

fix(python): guard generated typing_extensions imports for python 3.11+#3

Open
v-tan wants to merge 2 commits into
mainfrom
fix/python-typing-extensions-conditional-import
Open

fix(python): guard generated typing_extensions imports for python 3.11+#3
v-tan wants to merge 2 commits into
mainfrom
fix/python-typing-extensions-conditional-import

Conversation

@v-tan

@v-tan v-tan commented May 29, 2026

Copy link
Copy Markdown
Member

Summary

openapi-python-client@0.28 emits an unconditional from typing_extensions import Self in every generated model. packages/python/pyproject.toml declares typing-extensions as a runtime dep only on python_version < '3.11'. On 3.11+ a fresh pip install kreuzberg-cloud-sdk produces a package where import kreuzberg_cloud raises ModuleNotFoundError: No module named 'typing_extensions'. CI hasn't caught this because ci-python.yml runs 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/except falling back through stdlib typing.Self (PEP 673, added in 3.11) before typing-extensions. Stays compatible on 3.10 via the existing dep marker; resolves cleanly on 3.11+ without ever needing the runtime dep.

Reproduce on main

uv venv --python 3.13
uv pip install kreuzberg-cloud-sdk
uv run python -c "import kreuzberg_cloud"
# ModuleNotFoundError: No module named 'typing_extensions'

Changes

  • packages/python/scripts/postprocess_generated.py — rewrites from typing_extensions import Self to try: 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:

Stage Result
Uninstall typing-extensions done
Import unpatched _generated/ ModuleNotFoundError on bounding_box.py:8 (the bug)
Import patched _generated/ OK
Instantiate + serialize BoundingBox {'x0': 0.0, 'x1': 0.0, 'y0': 0.0, 'y1': 0.0}

Locally with the fix applied, task python:generate followed by the new regression test passes; existing test suite untouched.

Out of scope

ci-python.yml currently 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

  • Codegen tool: openapi-python-client@0.28.4
  • PEP 673 — typing.Self (Python 3.11+)

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.
@v-tan v-tan self-assigned this May 29, 2026
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).
@v-tan v-tan moved this from Todo to In Review in Kreuzberg.dev Kanban May 29, 2026
@v-tan v-tan requested a review from Goldziher May 29, 2026 19:44
@v-tan v-tan added the bug Something isn't working label May 29, 2026

@Goldziher Goldziher left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fix is unnecessary I think.

expected output for the openapi-python-client version in use.
"""

from __future__ import annotations

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary - this is only required for python lower than 3.10, which is anyhow unsupported

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

2 participants