[v1.x] Support Python 3.14#2769
Conversation
8658a5e to
473c92f
Compare
Add the 3.14 trove classifier, add 3.14 to the CI test matrix, and make the dependency floors installable there: - pydantic >=2.12.0 and starlette >=0.48.0 on 3.14 only (older floors pin pydantic-core 2.33.0 / predate 3.14 support and have no cp314 wheels); floors for <3.14 are unchanged - pywin32 >=311 on 3.14 only (310 ships no cp314 wheels) - mkdocs-material[imaging] >=9.6.19: the 9.5.45 imaging extra pins pillow~=10.2, which has no cp314 wheels and fails to install on the 3.14 lowest-direct lane; 9.6.19 allows pillow 11.x - backport the coverage workarounds from #1834 (coveragepy#1987 branch misreporting on 3.14), plus one no-branch pragma for a nested async-with arc in test_sse_security.py - regenerate uv.lock with the 3.14 resolution fork The README badge lists supported versions from the classifiers of the latest PyPI release, so the badge updates at the next v1.x release. Update CONTRIBUTING.md to say 3.10 through 3.14.
473c92f to
d04ce69
Compare
There was a problem hiding this comment.
I didn't find any bugs — the runtime code changes are no-ops (a coverage pragma and a signature reformat) and the rest is CI matrix, classifier, marker-gated dependency floors, lockfile, and test coverage pragmas backported from #1834. Since this changes published package metadata (classifiers and dependency constraints) on the v1.x release branch, it's worth a maintainer's confirmation before merging.
Extended reasoning...
Overview
This PR adds Python 3.14 to the v1.x line: the trove classifier, the CI test matrix in shared.yml, marker-gated dependency floors (pydantic ≥2.12.0, starlette ≥0.48.0, pywin32 ≥311 on 3.14 only), a mkdocs-material[imaging] docs-group bump, the corresponding uv.lock resolution fork, a CONTRIBUTING.md wording update, and coverage pragmas in tests plus one # pragma: no cover comment in context_injection.py. It is described as a backport of #1834 from main, addressing #2537.
Security risks
None identified. There are no behavioral code changes — the two source-file edits are a coverage pragma comment and a whitespace-only signature reformat in server/session.py. Dependency floors are only raised for 3.14 environments, and the existing <3.0.0 pydantic cap is preserved on both marker branches.
Level of scrutiny
The change is largely mechanical and follows the pattern already merged on main, but it modifies published package metadata (classifiers and dependency markers) on the release branch and declares official 3.14 support — a release/support-policy decision that a maintainer should sign off on rather than a bot. The added # pragma: no cover/no branch markers also slightly relax coverage enforcement on a few test paths (a known coverage.py 3.14 workaround), which maintainers may want to acknowledge explicitly.
Other factors
The bug hunting system found no issues, and the author reports all four 3.14 CI lanes plus 3.10/3.13 lanes passing locally with 100% coverage. Note the test job is continue-on-error, so reviewers should check the 3.14 job conclusions directly rather than relying on the overall green check, as the author points out.
Adds the
Programming Language :: Python :: 3.14trove classifier, adds 3.14 to the v1.x CI test matrix, and makes the dependency floors installable there. Backports #1834 from main. References #2537.Motivation and Context
The README's supported-Python-versions badge (
img.shields.io/pypi/pyversions/mcp.svg) renders the classifiers of the latest PyPI release, which currently stop at 3.13 — so the badge says 3.10–3.13 even though the SDK installs and works on 3.14. #2537 asked for the classifier on the v1 line; this adds it together with the CI coverage that makes the claim tested. The badge updates automatically once the next v1.x release is published with this classifier — no README edits needed.The dependency changes are the minimal set needed for the
lowest-directlane to install on 3.14, marker-gated so floors for <3.14 are unchanged:pydantic>=2.12.0on 3.14 only — 2.11.x pins pydantic-core 2.33.0, which has no cp314 wheels (the existing<3.0.0cap is kept on both branches)starlette>=0.48.0on 3.14 only — first release supporting 3.14pywin32>=311on 3.14 only — 310 ships no cp314 wheelsmkdocs-material[imaging]>=9.5.45→>=9.6.19— 9.5.45's imaging extra pinspillow~=10.2, which has no cp314 wheels and fails to install on the 3.14 lowest-direct lane; 9.6.19 allows pillow 11.x. Dependency groups aren't published metadata, so this doesn't affect package consumers (the lockfile already pins 9.6.19).Code changes are the coverage workarounds from #1834 (coverage.py branch misreporting on 3.14, coveragepy/coveragepy#1987) plus one
# pragma: no branchfor a nested-async-with arc intest_sse_security.pythat only 3.14 flags. No runtime changes were needed — same as on main.Deliberately not carried over from #1834: the
coverage>=7.13.1bump (reverted on main by #1897;==7.10.7has cp314 wheels and passes), the mkdocstrings-python major bump (1.12.2 installs fine on 3.14), and the pillow dev-dependency (supplied transitively via the imaging extra).How Has This Been Tested?
Ran the CI lanes locally with the exact
shared.ymlcommands (uv sync --upgrade --resolution {lowest-direct,highest} --all-extras --python <ver>, then coverage run/combine/report):uv sync --frozen --group docs && mkdocs build)uv lock --checkClassifier: Programming Language :: Python :: 3.14All four 3.14 CI lanes (lowest-direct/highest × ubuntu/windows) passed at the job level on this PR's earlier run. Since the test job is
continue-on-error, reviewers should check the 3.14 job conclusions directly rather than relying on the green check.Breaking Changes
None. Floors for Python <3.14 are unchanged; the lockfile gains a resolution fork at 3.14.
Types of changes
Checklist
Additional context
On the 3.14 fork, pydantic 2.12.0 transitively requires typing-extensions>=4.14.1, so the advertised typing-extensions 4.9.0 floor is only exercised on ≤3.13 — same situation as main at #1834.
The badge has shown 3.10–3.13 since 3.14.0 was released (2025-10); cutting a release (e.g. v1.27.3) after this merges makes the badge update automatically.
AI Disclaimer