Skip to content

refactor(python): drop Python 3.10 support - #810

Merged
vishal-bala merged 6 commits into
mainfrom
refactor/drop-python-3-10
Nov 11, 2026
Merged

vishal-bala merged 6 commits into
mainfrom
refactor/drop-python-3-10

Conversation

@vishal-bala

@vishal-bala vishal-bala commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

Python 3.10 reached end of life in October 2026, and its share of redisvl downloads has fallen from 6.2% in April 2026 to 1.1% in October 2026 (pypistats.org). The 3.9 drop in #587 shipped at 0.5%. Raising the floor to 3.11 removes a whole resolution fork from the lockfile and lets follow-up work use 3.11-only features such as enum.StrEnum, asyncio.timeout and asyncio.TaskGroup.

Changes

Support floor

pyproject.toml now declares requires-python = ">=3.11,<3.16", drops the 3.10 classifier and removes py310 from black's target versions. The lint and test matrices in .github/workflows/ start at 3.11; the single-version jobs already ran on 3.11 and are unchanged.

Lockfile

uv.lock was re-locked with uv lock and no upgrade flags. The python_full_version < '3.11' fork is gone, taking 31 package versions that only 3.10 installed with it (numpy 2.2.6, scipy 1.15.3, torch 2.14.1, the CUDA 13.0 wheels, tomli and others). No new package version enters the lock. One resolution moves: Python 3.13 now resolves protobuf 6.33.6, grpcio 1.85.1 and grpcio-status 1.85.1, the versions 3.14 and 3.15 already used, instead of 5.29.6, 1.80.0 and 1.71.2. Nothing changes for 3.11, 3.12, 3.14 or 3.15. exceptiongroup and async-timeout stay, because fastmcp-slim needs the first on every version and redis-py needs the second below 3.11.3.

typing.Self

Self now comes from typing rather than typing_extensions, which was never a declared dependency. Methods that return their own class are annotated -> Self: the alternative constructors on IndexSchema, SemanticRouter, MCPSettings, BackupHeader, VectorBackup and MultiWorkerBackupManifest; the pydantic model_validator(mode="after") methods in redisvl/mcp/config.py and redisvl/migration/models.py; and BaseQuery.sort_by and BaseQuery.query. Runtime behaviour is unchanged. Type checkers now infer the subclass in chains such as VectorQuery(...).sort_by(...).

Minor changes

  • tests/unit/test_cli_mcp.py drops its sys.version_info monkeypatching, which has been dead since the 3.9 drop removed the version check in redisvl/cli/mcp.py.
  • redisvl/version.py drops its Python 3.7 fallback to importlib_metadata, a package RedisVL never declared, so the branch could only raise.
  • README.md, CONTRIBUTING.md, docs/user_guide/installation.md, docs/user_guide/how_to_guides/mcp.md and the LangCache notebook state 3.11 as the minimum.

Notes

This PR builds on #768 (Python 3.15 support), now merged, and targets main. Python 3.10 is dropped without a deprecation release, as 3.9 was.

Release Notes

Python 3.10 is no longer supported; RedisVL now requires Python 3.11 or later. Installs on Python 3.10 resolve to the last release that supported it.

Reviewer Brief

Start here: uv.lock. The re-lock is the only part of the change that alters what CI and contributors install (published installs resolve from pyproject.toml, not the lock), and its one effect beyond removing 3.10 is that Python 3.13 moves to protobuf 6.33.6 and grpcio 1.85.1.

Where it could fail

  • Python 3.13 with redisvl[vertexai] or redisvl[all]: protobuf 6 on 3.13 is new, though 3.14 and 3.15 already run it; check that the Vertex AI vectorizer has no protobuf<6 assumption.
  • redisvl/query/query.py:139: BaseQuery.sort_by now returns Self, so a subclass that overrides it with a narrower return type would now fail type-checking; none exists today.

Not verified: live provider APIs on 3.13, where Vertex AI now runs under protobuf 6 (CI's Service Tests run them on 3.11 only); cluster tests; Python 3.11.0 to 3.11.2, where redis-py still pulls in async-timeout.

Beyond CI: a per-version parse of the old and new lockfiles shows the protobuf/grpc move on 3.13 is the only version change for 3.11 and later.

Reviewed 036e323f (rebased onto main from fdf0b578, with uv.lock re-locked against main's), fixes in 0d6c0ce1 · Claude Code (claude-opus-5-5) · lenses: correctness, security, design, tests, docs, Redis behaviour


Note

Medium Risk
Breaking change for Python 3.10 users; dependency lockfile shifts (e.g. protobuf/grpc on 3.13) may affect optional Google/Vertex stacks though runtime behavior is mostly typing and packaging.

Overview
RedisVL now requires Python 3.11+. pyproject.toml raises requires-python, drops the 3.10 Trove classifier, and removes py310 from Black's targets; lint and test CI matrices no longer run 3.10. User-facing docs (README, CONTRIBUTING, installation, MCP, LangCache notebook) state the new floor.

Return types move to stdlib typing.Self on factory methods, Pydantic model_validators, and fluent query APIs (SemanticRouter, MCP config models, migration backup types, IndexSchema, BaseQuery, etc.), replacing quoted class names and typing_extensions.Self where it appeared.

Housekeeping: redisvl/version.py always uses importlib.metadata (no pre-3.8 fallback); MCP CLI unit tests no longer mock sys.version_info after the runtime version gate was removed.

Reviewed by Cursor Bugbot for commit f0048fb. Bugbot is set up for automated code reviews on this repo. Configure here.

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
@vishal-bala
vishal-bala force-pushed the refactor/drop-python-3-10 branch from 61effbf to 0d6c0ce Compare November 3, 2026 12:08
@vishal-bala
vishal-bala marked this pull request as ready for review November 3, 2026 12:09
@vishal-bala vishal-bala added the auto:minor Increment the minor version when merged label Nov 5, 2026
@vishal-bala
vishal-bala requested a review from limjoobin November 6, 2026 16:55
importlib.metadata has been in the standard library since 3.8, and
importlib_metadata was never a declared dependency, so the fallback
branch could only ever raise.

@limjoobin limjoobin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. This PR removes the Python 3.10 support, which is consistent across packaging, CI, docs, typing, and the lockfile.

One non-blocking process note: please refresh the Reviewer Brief against the current head before merging.

@vishal-bala vishal-bala added the auto:release Create a release when this PR is merged label Nov 11, 2026
@vishal-bala
vishal-bala merged commit d605907 into main Nov 11, 2026
58 checks passed
@vishal-bala
vishal-bala deleted the refactor/drop-python-3-10 branch November 11, 2026 10:20
@applied-ai-release-bot

Copy link
Copy Markdown

🚀 PR was released in v0.32.0 🚀

@applied-ai-release-bot applied-ai-release-bot Bot added the released This issue/pull request has been released. label Nov 11, 2026
vishal-bala added a commit that referenced this pull request Nov 11, 2026
The stack below was rebased onto main after #768 and #810 merged. Every file except the four PYTHON_VERSION lines takes the base's version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto:minor Increment the minor version when merged auto:release Create a release when this PR is merged released This issue/pull request has been released.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants