Repository navigation
ci: use Python 3.12 as the default for single-version jobs - #815
Draft
vishal-bala wants to merge 14 commits into
Draft
vishal-bala wants to merge 14 commits into
vishal-bala wants to merge 14 commits into
Conversation
Lift the Requires-Python cap to <3.16 and add 3.15 to the classifiers, black target versions and the test and lint CI matrices. - Floor beartype at 0.23.1 in the mcp extra. Earlier releases import typing.no_type_check_decorator, which 3.15 removed, so fastmcp failed to import and the MCP server fell back to its stub. - Relock: rpds-py 2026.9.1 (0.30.0 cannot build on 3.15) and beartype 0.23.1. The re-split forks also move 3.14 onto google-cloud-aiplatform 1.154.0, grpcio 1.84.0 and protobuf 6.33.6. - Bump uv to 0.13.1, the first line that ships CPython 3.15.0 final. - torch has no cp315 wheels on PyPI yet, so the 3.15 legs install every extra except sentence-transformers and all. Tests marked requires_hf now skip when sentence-transformers is not installed, and the HF tests that lacked the marker carry it. - Loosen the ** TypeError assertion; 3.15 reworded the message. - Ignore pytest-asyncio 0.23's asyncio deprecation warnings. On 3.15 they number in the millions and slow the suite about twentyfold.
- Mark test_different_vector_dtypes requires_hf. It builds the default HF vectorizer, and its bare except turned the ImportError on 3.15 into a misleading "Redis version too low" skip. - Give the SemanticRouter repr tests a stub vectorizer instead of the requires_hf marker, so they keep running on 3.15. __repr__ never touches the vectorizer; only the field's HFTextVectorizer default needed it. - Note in the installation guide and CONTRIBUTING that the sentence-transformers and all extras cannot install on 3.15 yet, with the uv sync command that leaves them out.
torch 2.15.0 publishes cp315 wheels, so relock torch, scipy and scikit-learn (the locked scipy 1.17.1 had no cp315 wheel either). Python 3.11+ now resolves torch 2.15.0, scipy 1.18.1 (3.12+) and scikit-learn 1.9.1; 3.10 keeps its existing versions. With sentence-transformers installable everywhere, the 3.15-only CI exclusion of the sentence-transformers and all extras goes, as does the conftest skip for missing sentence-transformers, so requires_hf is an informational marker again and the HF tests run on 3.15. The install-guide note now covers only the upstream Python bounds that make pip refuse voyageai (<3.15) and sql-redis (<3.14).
Make Python 3.11 the minimum supported version. Python 3.10 reached end of life in October 2026, and its share of redisvl downloads has fallen to about 1%. - pyproject.toml: requires-python >=3.11,<3.16, drop the 3.10 classifier and black's py310 target - CI: remove 3.10 from the lint and test matrices - uv.lock: re-lock without upgrades, removing the python < 3.11 fork - Use typing.Self instead of typing_extensions.Self, and for methods that return their own class - Drop the dead sys.version_info monkeypatching in the MCP CLI tests - Docs: state 3.11 as the minimum
str() and f-strings on a (str, Enum) member give "Cls.MEMBER" on Python 3.11+, so error messages and query strings built from members printed the class name. StrEnum returns the value. Serialisation, YAML output and the FT.CREATE arguments sent to Redis already used the value and are unchanged. Drops the getattr(..., "value", ...) workarounds in the MCP tools and the .value calls that existed only to format a member, and pins the visible string form in tests/unit/test_str_enums.py.
The hybrid-policy, stored-role and MCP error-code checks passed under (str, Enum) as well and duplicate existing coverage; the integration test already pins the stored ChatRole bytes.
_connect_redis_client wrapped the connection and the first INFO in separate asyncio.wait_for calls, so a slow server could hold startup for up to twice runtime.startup_timeout_seconds before failing. Both now run under one asyncio.timeout block. The raised exception is still TimeoutError, which map_exception already handles. A client that connected but then failed or timed out on INFO was never closed; it is now closed before the error propagates.
async_multi_worker_quantize ran its workers under asyncio.gather, which raised the first worker's exception while the others kept reading from and writing to Redis after the caller had been told the run failed. It now runs them in an asyncio.TaskGroup, so the siblings are cancelled and have closed their connections before the error propagates. Callers keep the old contract. The TaskGroup's ExceptionGroup is unwrapped and the first worker exception is raised as is; any others that failed in the same instant are logged. Without that, the async executor's report would read 'unhandled errors in a TaskGroup' instead of the worker's own message. A cancelled worker stops at an awaited pipeline call, and every backup write between those awaits is synchronous, so its shard records only whole batches. Resume re-reads an unrecorded dump batch and re-converts an unrecorded quantize batch from the stored originals, which is idempotent. Tests cover both cancellation points and the resume.
The MCP guide now names the three startup steps that runtime.startup_timeout_seconds bounds, since the native-hybrid probe runs without one. The migration guide says cancellation applies with --async and that the sync executor lets sibling workers finish. The shared-deadline test drops a wall-clock bound that the TimeoutError already proves, and the simultaneous-failure test pins that the first worker's error is the one raised.
make test passes --log-level=CRITICAL, which hid the ERROR records the simultaneous-failure test counts. The test now sets the level itself.
The service tests, notebook validation, docs build, fork-PR service tests, release builds and Read the Docs now run on 3.12 instead of 3.11. 3.12 accounts for the largest share of redisvl installs; the test and lint matrices still cover 3.10 to 3.14.
This branch has not been deployed
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.
Motivation
The jobs that run on a single Python version use 3.11, which is no longer where most
redisvlinstalls are. 3.12 now holds the largest share of downloads and is not close to end of life, while 3.11 has fallen to third. The figures below are from pypistats.org, with mirrors excluded, checked on 2026-11-02:Each column is a share of all downloads in that window, and versions not listed make up the remainder. 3.11's share is lower over the last 30 days than over 208, so it is shrinking.
The service tests and notebook validation are the only CI runs that call live provider APIs, so they should run on the version most users have.
Changes
Default Python version moves from 3.11 to 3.12
Each workflow sets one
PYTHON_VERSIONfor its single-version jobs. This PR changes that value, and the Read the Docs interpreter, from 3.11 to 3.12:.github/workflows/test.yml: the service tests (make test-all, which calls external provider APIs), notebook validation and thedocsbuild job..github/workflows/test-fork-pr.yml: the maintainer-triggered service tests for fork PRs..github/workflows/auto-release.yml: the canary build, the version bump step (uv lock --check) and the release build. The wheel is pure Python (py3-none-any), so this one only keeps the workflows consistent..readthedocs.yaml:build.tools.python.The test matrix in
test.ymland the style-check matrix inlint.ymlstill cover every supported version, 3.11 to 3.15, so no version loses coverage.Notes
This PR is stacked on top of the Python version stack (#768, #810, #811, #812) rather than branched from
main, so it lands after the 3.10 drop and the version-range changes it sits with. It does not depend on any code in those PRs: the diff against #812 is the four lines above.The Makefile's
black --target-version py311stays as it is. That flag is not a runtime default: it tells black which Python grammars its output must stay valid for, and it overrides thetarget-versionlist inpyproject.toml. With 3.10 dropped,py311is exactly the supported minimum, and raising it topy312would let black emit syntax that 3.11 cannot parse. On the current tree black 26.5.1 produces identical output forpy311andpy312.Reviewer Brief
Start here:
.github/workflows/test.yml,env.PYTHON_VERSION. It drives the service tests and notebook validation, the only CI runs that call live provider APIs, as well as thedocsjob.Where it could fail
uv.lockthat misbehaves on 3.12 only when it calls its live API would surface here first, since the matrix legs on 3.12 skip the API tests.Not verified: the service tests and the API-dependent notebook cells, because no provider keys were available locally; the Read the Docs build on Read the Docs itself; the release workflow, which runs only after merge.
Beyond CI: on Python 3.12.12,
tests.test_importspasses with only the base dependencies installed, anduv buildsucceeds (the wheel ispy3-none-any);uv lock --checkpasses under the pinned uv 0.13.1. The docs build in auv sync --group docsenvironment gives the same 12 Sphinx warnings on 3.11.9 and 3.12.12. The notebooks against a localredis:8.4give identical per-cell results on 3.11.9 and 3.12.12. Fifteen cells in03_llmcache,04_vectorizersand06_rerankersfail on both for want of provider API keys; six!rvlCLI cells hit the 60-second cell timeout on both while the two runs shared the machine, and pass when their six notebooks are re-run alone on 3.12.Reviewed
ad90047· Claude Code (claude-opus-5-5) · lenses: correctness, security, design, tests, docs, Redis behaviour