Drop Python 3.10 support
Merged
FA
21d ago+345+345+012345678901234567890123456789-1491-1491-0123456789012345678901234567890123456789
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.lockis regenerated, which drops the 3.10-only resolution splits along withexceptiongroup,backports-asyncio-runnerand thetomlifallback dependency.
Runtime shims removed
- The import-time deprecation warning in
reflex/__init__.py, with its test and changelog fragment. tomli/tomllibfallbacks in reflex-release and the repo scripts.sys.version_infoguards aroundadd_note, the asynciocancelling()check in the redis lease lookup, the TypedDictNotRequiredworkaround in form validation, theget_type_hintsOptionalunwrapping in memo parameter analysis, theBaseExceptionGrouplookup throughbuiltins, and theForwardRefis_classbranch.- Version-gated test skips and comments that only applied to 3.10.
Lint target
tool.ruff.target-versionmoves topy311and its fixes are applied:datetime.UTC,typingimports that no longer needtyping_extensions, theTimeoutErroralias, PEP 646*Tsunpacking, andfromisoformatparsingZnatively.ASYNC109andUP042are added to the ignore list with reasons: timeouts are explicit parameters of the testing and state-manager APIs, andStrEnumwould change how(str, Enum)members render instr()and f-strings.
Docs and changelog
- Installation and AI-builder docs now state the 3.11 requirement.
- A
breakingnews fragment is added to every published package, since each one ships with the new floor. - The playground
.content-hashandpyi_hashes.jsonare regenerated.
Test Plan
uv run ruff check .anduv run ruff format --check .pass.uv run pyright reflex testsand 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 --checkpasses against the regenerated lock, andreflex-release changelog-check --base-ref origin/mainreports fragments present for every affected package.