Drop Python 3.10 support

Merged
FA
21d ago
+345-1491

Type of change

  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Changes To Core Features

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your core changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Description

Python 3.10 reaches end of life in October 2026, and Reflex has warned about it on import since 0.8.15 (#5868). This PR removes 3.10 support outright so 0.10.0 requires Python 3.11 or newer, rather than carrying the deprecation into 0.11.0.

Version floors and CI

  • requires-python = ">=3.11" in the root package and every workspace package, plus the docs and playground projects; the 3.10 classifier is removed.
  • The 3.10 legs are dropped from both unit-test matrices, the package build matrix starts at 3.11, and the init-test Docker image moves to python:3.11.
  • uv.lock is regenerated, which drops the 3.10-only resolution splits along with exceptiongroup, backports-asyncio-runner and the tomli fallback dependency.

Runtime shims removed

  • The import-time deprecation warning in reflex/__init__.py, with its test and changelog fragment.
  • tomli/tomllib fallbacks in reflex-release and the repo scripts.
  • sys.version_info guards around add_note, the asyncio cancelling() check in the redis lease lookup, the TypedDict NotRequired workaround in form validation, the get_type_hints Optional unwrapping in memo parameter analysis, the BaseExceptionGroup lookup through builtins, and the ForwardRef is_class branch.
  • Version-gated test skips and comments that only applied to 3.10.

Lint target

  • tool.ruff.target-version moves to py311 and its fixes are applied: datetime.UTC, typing imports that no longer need typing_extensions, the TimeoutError alias, PEP 646 *Ts unpacking, and fromisoformat parsing Z natively.
  • ASYNC109 and UP042 are added to the ignore list with reasons: timeouts are explicit parameters of the testing and state-manager APIs, and StrEnum would change how (str, Enum) members render in str() and f-strings.

Docs and changelog

  • Installation and AI-builder docs now state the 3.11 requirement.
  • A breaking news fragment is added to every published package, since each one ships with the new floor.
  • The playground .content-hash and pyi_hashes.json are regenerated.

Test Plan

  • uv run ruff check . and uv run ruff format --check . pass.
  • uv run pyright reflex tests and pyright over every changed package file report no errors.
  • uv run pytest tests/units: 12217 passed, 180 skipped. The only failures are the bench browser-driver tests, which need a Playwright browser that is not installed in the sandbox and are unaffected by this change.
  • uv lock --check passes against the regenerated lock, and reflex-release changelog-check --base-ref origin/main reports fragments present for every affected package.