Test and build wheels on Python 3.15 - #770
Conversation
Adds Python 3.15 to the test matrix in the same shape a stable version gets -- Cython on and off, plus a confluent-driver leg -- and moves the release wheel build from cibuildwheel 4.1.0 to 4.2.0, the first release that knows about CPython 3.15. 4.2.0 builds cp315 by default: cibuildwheel gates a Python behind the `cpython-prerelease` enable group only until its first release candidate, because the ABI is frozen at rc1, so a wheel built against 3.15.0rc1 is forward-compatible with 3.15.0 final. The existing `cp31?t-*` skip keeps this to cp315 without cp315t, matching the other versions. `allow-prereleases` on setup-python resolves `3.15` to the newest pre-release the runner image publishes (3.15.0rc1 today) and will pick up 3.15.0 final with no further change. It leaves the stable rows alone: it widens `3.X` to `~3.X.0-0`, and a pre-release only wins when no stable release satisfies the spec, so 3.10-3.14 still resolve to their newest stable patch. The 3.15 rows are advisory (`experimental: true` -> `continue-on-error`) and will stay red for now. faust does not import on 3.15 until mode-streaming ships the fix for `typing._eval_type`, whose `type_params` argument became a required positional in 3.15: every Record model resolves its annotations through `mode.utils.objects.annotations`, so collection dies before the first test runs. With that fix applied locally the suite is clean on 3.15.0rc1 -- 2207 passed in unit+functional, 17 in integration/meticulous/regression, bandit clean, Cython extensions built. The workflow comment records what to change once a mode-streaming release carries the fix. tox.ini's envlist stopped at 3.12; it now mirrors the CI matrix. Its basepython block repeated the whole check-env list on all three lines, so those factors matched every line at once and tox resolved `base_python` to nothing, leaving flake8/typecheck/bandit and friends on whatever interpreter happened to be running tox. They now pin to 3.12, the PYTHON_LATEST the lint job uses. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jr6Lsfd3fULmP1Gi4b6nDK
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #770 +/- ##
==========================================
- Coverage 96.07% 96.05% -0.02%
==========================================
Files 103 103
Lines 11081 11081
Branches 1189 1189
==========================================
- Hits 10646 10644 -2
- Misses 343 345 +2
Partials 92 92 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
CI statusTwo red checks, neither of which I can fix from this PR. Details so nobody has to dig through logs. The three 3.15 legs — blocked on a
|
| re-fire | HEAD uploads | BASE uploads |
|---|---|---|
| 16:09 | 2 | 31 |
| 16:10 | 3 | 31 |
| 16:10 | 4 | 31 |
Files, Lines and Branches are all identical to base (103 / 11081 / 1189) and codecov/patch is green — nothing in this diff touches coverable code. Once the remaining legs finish uploading it should settle back at ~96%: the 3.15 legs fail before their upload step, so they contribute nothing, and base had no 3.15 legs either — HEAD ends up with the same upload set base had.
I'll confirm that once the run completes and follow up here only if it does not recover.
Generated by Claude Code
|
Run complete: 20 success / 4 failure / 3 skipped (the 3 skips are the release-only wheel/sdist/publish jobs). Follow-up on the two items from my last comment, plus the one new red check. ✅ The required
|
Description
Adds Python 3.15 to the test matrix and to the release wheel build.
Important
The 3.15 legs will be red until faust-streaming/mode#87 lands and a
mode-streamingrelease carries it. faust does not import at all on 3.15:typing._eval_type'stype_paramsargument became a required positional, and every Record model resolves its annotations throughmode.utils.objects.annotations, so collection dies before the first test runs. This PR is safe to merge before then — the 3.15 rows are advisory and cannot block the merge queue — but it won't go green on its own.Changes
build_wheels— cibuildwheel4.1.0→4.2.0, the first release that knows about CPython 3.15. It buildscp315by default: cibuildwheel gates a Python behind thecpython-prereleaseenable group only until its first release candidate, because the ABI is frozen at rc1, so a wheel built against 3.15.0rc1 is forward-compatible with 3.15.0 final. The existingcp31?t-*skip keeps this tocp315withoutcp315t, matching the other versions — confirmed with--print-build-identifiers.tox.ini— envlist stopped at 3.12; now mirrors the CI matrix. Separately, itsbasepythonblock repeated the whole check-env list on all three lines, so factors likeflake8andtypecheckmatched every line at once and tox resolvedbase_pythonto nothing, leaving those envs on whatever interpreter happened to be running tox. I verified this with tox 4.58 (tox config -e flake8→ emptybase_python, falling through to the tox interpreter). They now pin to 3.12, thePYTHON_LATESTthe lint job uses.pyproject.toml— added theProgramming Language :: Python :: 3.15classifier (verified valid, so PyPI won't reject an upload).allow-prereleases: trueonsetup-pythonresolves3.15to whatever pre-release the runner image publishes — 3.15.0rc1 today — and picks up 3.15.0 final automatically. It leaves the stable rows alone: it widens3.Xto~3.X.0-0, and a pre-release only wins when no stable release satisfies the spec. Verified against the realactions/python-versionsmanifest:3.10→ 3.10.20,3.12→ 3.12.13,3.14→ 3.14.7, identical with and without the flag.The 3.15 rows are advisory (
experimental: true→continue-on-error), so they are excluded from the requiredcheckjob and cannot stall the merge queue.Verification
With the mode fix applied locally, against the actual 3.15.0rc1 build the runners use:
tests/unit+tests/functionaltests/integration+meticulous+regressionFollow-up once mode is released
Bump the
mode-streamingfloor inrequirements/requirements.txt, then move the three 3.15 entries out ofinclude:and into the matrix above to make them required.Generated by Claude Code