fix(packaging): support Python 3.14 - #30687
Conversation
Greptile SummaryThis PR adds Python 3.14 support by extending
Confidence Score: 5/5Safe to merge — changes are narrowly scoped to packaging metadata, PyO3 API renames, and async test ordering; no production logic is altered The Python version gate change, dependency marker removals, and PyO3 rename are all mechanical and well-tested locally plus via the new CI workflow. The test assertion changes faithfully preserve the same behavioral contracts with order-independent comparisons. No runtime logic in the Python layer is touched. No files require special attention beyond the minor stale doc comment in
|
| Filename | Overview |
|---|---|
| pyproject.toml | Extends requires-python to <3.15, removes stale python_version < '3.14' markers for redisvl/semantic-router/aurelio-sdk/pypdf/openapi-core, and version-splits ddtrace into 2.x (Python <3.14) and 3.x (Python ≥3.14) |
| litellm-rust/Cargo.toml | Bumps pyo3 from 0.23.5 to 0.29.0 and pyo3-async-runtimes from 0.23.0 to 0.29.0 to support Python 3.14 wheel builds |
| litellm-rust/crates/python-bridge/src/gil.rs | Updates GIL release wrapper from py.allow_threads to py.detach for PyO3 0.29, but the module-level doc comment still references the old Python::allow_threads name |
| litellm-rust/crates/ai-gateway/src/python/config.rs | Replaces Python::with_gil with Python::attach for PyO3 0.29 compatibility in the config loader |
| litellm-rust/crates/python-bridge/src/lib.rs | Replaces Python::with_gil with Python::attach for PyO3 0.29 compatibility in the async OCR result handler |
| .github/workflows/test-python-314.yml | New CI workflow that checks the lockfile, installs with Python 3.14, runs import smoke tests for key optional packages, exercises the ddtrace 3.x wrapper, and runs the UUID/S3 cache regression tests |
| tests/test_litellm/caching/test_s3_cache.py | Changes order-dependent call assertions to Counter-based multiset comparisons to accommodate Python 3.14's different async task scheduling order; coverage is preserved |
| scripts/install.sh | Removes the 3.14+ example from the comment describing unsupported Python version ranges |
| scripts/install-cli.sh | Removes the 3.14+ example from the comment describing unsupported Python version ranges |
Reviews (9): Last reviewed commit: "fix(packaging): support python 3.14 rust..." | Re-trigger Greptile
Greptile SummaryThis PR extends litellm's supported Python range to include 3.14 by bumping
Confidence Score: 4/5Safe to merge — changes are isolated to packaging metadata, installer comments, the lockfile, and two async test assertions. The packaging and workflow changes are clean and well-scoped. The only non-trivial code change is in the S3 cache tests, where the new dict-comprehension approach silently drops duplicate-key mock calls; the existing call_count assertions prevent false positives today, but the pattern is slightly less defensive than a multi-value map would be. tests/test_litellm/caching/test_s3_cache.py — review the dict-based assertion approach for the async put_object calls.
|
| Filename | Overview |
|---|---|
| .github/workflows/test-python-314.yml | New CI workflow for Python 3.14 — checks lockfile validity, frozen install, import smoke, and regression tests. Actions are SHA-pinned; uv version is pinned. Workflow fires only on pull_request, not on direct pushes to target branches (common pattern, not a defect). |
| pyproject.toml | Extends requires-python upper bound to <3.15, removes python_version < '3.14' guards from redisvl/semantic-router/aurelio-sdk/pypdf/openapi-core (all now install on 3.14), and splits ddtrace into 2.x (< 3.14) and 3.x (>= 3.14) markers. Changes are consistent and well-scoped. |
| tests/test_litellm/caching/test_s3_cache.py | Replaced positional-order assertions with key-based dict lookups to handle async call-ordering non-determinism under Python 3.14. Assertion equivalence holds for current tests (call_count guards prevent over/under-call regressions), but the dict comprehension drops duplicate-key calls silently. |
| scripts/install-cli.sh | Comment-only update: removes the stale "too-new (3.14+)" wording now that 3.14 is supported. |
| scripts/install.sh | Same comment-only update as install-cli.sh — no behavioural change. |
| uv.lock | Auto-generated lockfile regenerated to include Python 3.14 resolution. No manual edits expected or required. |
Reviews (2): Last reviewed commit: "fix(packaging): support python 3.14" | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Thanks for the PR! A couple of things to get this over the finish line:
Once those are addressed we'll take another look — appreciate the contribution! |
|
@Sameerlite Thanks, I checked the failing checks The Python 3.14 check added in this PR is passing, as are lint and Codecov The remaining failures look unrelated:
So I don’t see a code/test failure caused by this PR |
93f694c to
9078231
Compare
|
Rebased on latest Local verification passed:
Current non-code failures:
|
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
cc54d68 to
79dd070
Compare
|
Thanks for rebasing and keeping this up to date, @Technolog796! The CI explanation (Block fork dependency changes is expected for a fork PR touching uv.lock; osv-scan failures are pre-existing) makes sense. Triggering a fresh Greptile review against the latest head.\n\n@greptileai |
79dd070 to
9ea8d62
Compare
|
@Sameerlite I pushed one more rebase on top of the latest |
9ea8d62 to
c5081f4
Compare
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
## Summary - Bump `litellm` from `1.83.7` to `1.89.3` to fix [GHSA-4xpc-pv4p-pm3w / CVE-2026-49468](GHSA-4xpc-pv4p-pm3w) (Critical, CVSS 9.5). - Cap project Python at `>=3.10,<3.14` because litellm `>=1.84.0` declares the same upper bound. A comment in `pyproject.toml` documents why, and points to the upstream PR that will let us revert the cap. - Regenerate `poetry.lock`. ## CVE details (GHSA-4xpc-pv4p-pm3w) | Field | Value | |---|---| | **Identifiers** | CVE-2026-49468 / GHSA-4xpc-pv4p-pm3w | | **Severity** | Critical, CVSS v4 9.5 | | **Type** | CWE-290 — Authentication Bypass by Spoofing (Host Header Injection) | | **Affected** | litellm `< 1.84.0` | | **Fixed in** | litellm `1.84.0` | The LiteLLM proxy's auth layer used `request.url.path` (rebuilt from the `Host` header by Starlette) to decide which route's auth rules to evaluate. A crafted `Host` header could make the auth check evaluate a different route than FastAPI actually dispatched, allowing an unauthenticated attacker to reach protected management endpoints. Deployments fronted by a CDN/WAF or reverse proxy that normalizes the `Host` header are not affected; the safe fix is to upgrade. ## Why we limit the Python version Starting with litellm `1.84.0` (the version that contains the CVE fix), upstream tightened its declared `Requires-Python` from `<4.0,>=3.9` to `<3.14,>=3.10`. Our project still declared `python = "^3.10"` (i.e. `>=3.10,<4.0`), so Poetry can't find a Python range that satisfies both and `poetry lock` fails. There is nothing fundamentally broken about litellm on Python 3.14 — the cap is mostly a packaging-policy choice plus a few transitive deps that had stale `<3.14` markers. The upstream fix to lift the cap lives in [BerriAI/litellm#30687](BerriAI/litellm#30687), still open. Once that ships in a release (expected `1.90.x`), we can revert this project's cap back to `^3.10`. A comment in `pyproject.toml` records this so we don't forget. ## Test plan - [x] `poetry lock` resolves cleanly - [ ] `make test-without-llm` passes - [ ] CI green <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated the supported Python version constraint to `>=3.10, <3.14`, including comments documenting the temporary upper bound. * Bumped the `litellm` dependency to `1.89.0`, with notes explaining the temporary cap relationship. * **Tests** * Refreshed an internet-related test fixture to include additional GitHub session/page UI text so automated checks match current rendering. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Qingchuan Hao <qingchuan.hao@microsoft.com> Signed-off-by: Claude <noreply@anthropic.com>
c5081f4 to
1bae20c
Compare
|
@Sameerlite Hi! Is there any news about my PR? |
1bae20c to
23b985b
Compare
|
Hi! It'd be great to support Python 3.14. Is there any update on this? |
23b985b to
83f585d
Compare
0ff8949 to
953c862
Compare
|
@Sameerlite Hi! Is there any news about my PR? |
953c862 to
7dc863a
Compare
|
@Technolog796 heads-up I opened #33264 before finding this PR, apologies for the overlap. Mine is a strict subset of yours (just the pyo3 0.29 bump + rename migration, against |
Relevant issues
Fixes #26343
Linear ticket
Pre-Submission checklist
Block fork dependency changesis expected because this PR updatesuv.lockLocal note:
make test-unitpreviously stopped ontests/test_litellm/proxy/test_proxy_server.py::test_login_v3_exchange_happy_pathbecause the existing_FakeRedisCachetest double is missing_circuit_breaker. This is unrelated to the Python 3.14 packaging changes in this PRDelays in PR merge?
N/A
Screenshots / Proof of Fix
Before this change, at base commit
3e9e52042a,pyproject.tomlblocks Python 3.14 withrequires-python = ">=3.10, <3.14". The same base uses the restoredmaturinbackend withpyo3 0.23.5, which fails on Python 3.14 because PyO3 0.23 only supports up to Python 3.13After this change, at commit
7dc863a86b:uv lock --check Resolved 418 packages in 5msuv run --no-sync pytest tests/test_litellm/test_uuid_helper.py tests/test_litellm/caching/test_s3_cache.py --tb=short -q 19 passed in 1.00sType
Bug Fix
Infrastructure
Test
Changes
This PR expands the supported Python range to include Python 3.14 while preserving the existing Python 3.10 through 3.13 support window. It removes stale
<3.14dependency markers for packages that now install and import on Python 3.14, keepsddtraceon the existing 2.x range for Python <3.14, and uses the Python 3.14-compatible 3.x range only on Python 3.14+The lockfile was regenerated so Python 3.14 resolution is represented explicitly. The installer comments were updated so Python 3.14 is no longer described as too new. The S3 cache async tests now assert unordered call multisets instead of relying on async call ordering. A targeted Python 3.14 workflow checks lockfile validity, frozen installation, import smoke for
litellm,fastuuid, and the previously gated optional dependencies, Datadog tracing wrapper smoke for theddtrace3.x path, plus the UUID and S3 cache regression testsThe current staging base uses the
maturinbackend for the Rust bridge, so this PR also updates the Rust bridge topyo3 0.29.0/pyo3-async-runtimes 0.29.0and the matching PyO3 API names. Without that, Python 3.14 wheel builds fail before LiteLLM can install