Test on Python 3.15, and fix the typing._eval_type call it breaks - #87
Merged
Conversation
Adds Python 3.15 to the CI matrix, both the default and the free-threaded
build. `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 when it ships, with no further change here. Setting it does
not disturb the stable rows: 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 rows are advisory (`experimental: true` -> `continue-on-error`) while
3.15 is a pre-release, so a CPython-side regression in rc2 or final cannot
block merges on a version nothing runs in production. The comment records
how to promote them.
The suite did not pass as-is. `typing._eval_type` gained a `type_params`
argument in 3.13, where omitting it only warned and defaulted to `()`; in
3.15 it is a required positional, so every call raised
TypeError: _eval_type() missing 1 required positional argument: 'type_params'
which took out all five annotation tests -- and, because faust resolves
every Record model's annotations through `mode.utils.objects.annotations`,
stopped faust importing at all on 3.15.
Nothing resolved here carries PEP 695 type parameters of its own, so `()`
is both what 3.13/3.14 already substituted and what 3.15 wants; passing it
explicitly keeps behaviour identical across versions and silences the
3.13/3.14 deprecation warning. The signature is inspected once at import
rather than caught per call, because `_eval_type` also raises TypeError for
annotations `typing._type_check` rejects and `eval_type` relies on telling
those two apart.
Verified against the 3.15.0rc1 build the runners use: 866 passed on 3.15
and on 3.15t, unchanged on 3.11, with ruff and the mypy typecheck test
clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jr6Lsfd3fULmP1Gi4b6nDK
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.
Description
Adds Python 3.15 to the CI matrix, and fixes the one thing that stopped the suite passing on it.
CI
Two new rows —
3.15and3.15t(default and free-threaded builds), matching the coverage the 3.14 rows get.allow-prereleases: trueonsetup-pythonresolves3.15to whatever pre-release the runner image publishes — 3.15.0rc1 today — and will pick up 3.15.0 final in October with no further change here. Setting it does not disturb the stable rows: it widens3.Xto~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. I verified this 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; and without it3.15resolves to nothing at all, which is the "Version 3.15 was not found in the local cache" failure.The new rows are advisory (
experimental: true→continue-on-error) while 3.15 is a pre-release, so a CPython-side regression in rc2 or final can't block merges on a version nothing runs in production. The comment in the workflow records how to promote them to required once 3.15.0 ships.The fix
The suite did not pass as-is.
typing._eval_typegained atype_paramsargument in 3.13, where omitting it only emitted aDeprecationWarningand defaulted to(). In 3.15 it is a required positional, so every call raised:That took out all five annotation tests here. It also stopped faust importing at all on 3.15 — every faust Record model resolves its annotations through
mode.utils.objects.annotations, so collection died before the first test ran. See faust-streaming/faust#770, which is blocked on this landing and being released.Nothing resolved through
eval_typecarries PEP 695 type parameters of its own, so()is both what 3.13/3.14 already substituted when the argument was omitted and what 3.15 requires — passing it explicitly keeps behaviour identical across versions and silences the 3.13/3.14 deprecation warning on the way.The signature is inspected once at import rather than caught per call on purpose:
_eval_typealso raisesTypeErrorfor annotationstyping._type_checkrejects, andeval_typedepends on being able to tell those two apart (that's theClassVarbranch right below it).Verification
Ran against the actual 3.15.0rc1 build the runners use, not a proxy:
3.15t)ruff check+ruff format --checkGenerated by Claude Code