From 0a8fd54fcc9e45e2efde39a5d6320d58bc82b531 Mon Sep 17 00:00:00 2001 From: RJ Ascani Date: Tue, 23 Jun 2026 09:58:07 -0700 Subject: [PATCH] Add Python 3.14 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Raise requires-python upper bound from <3.14 to <3.15 and add 3.14 to wheel build matrices. coremltools has no cp314 wheels yet, so its dependency gets a python_version < '3.14' marker — the CoreML backend is unavailable on 3.14 until Apple ships compatible wheels. scikit-learn is loosened from ==1.7.1 to >=1.7.1 since 1.7.2+ has cp314 wheels. Bump black from 24.4.2 to 26.3.0 so the linter recognizes py314 as a valid target-version. Bridge PYTHON_EXECUTABLE to Python_EXECUTABLE in CMakeLists.txt in preparation for a future pybind11 3.0 upgrade. pybind11 is kept at v2.13.6 for now — v3.0.x causes runtime segfaults in the pybindings. Python 3.14 is not added to the QNN wheel test matrix because PyTorch's torch.export has a typing introspection bug on 3.14 (typing.Union.__module__). Both are tracked for follow-up. This PR was authored with Claude. Test Plan: - cmake configure and pybinding build succeed (--preset pybind) - lintrunner passes with updated black 26.3.0 - Full CI validation on Python 3.14 will run via the updated wheel build workflows --- .claude/skills/building/SKILL.md | 7 +++---- .github/workflows/build-wheels-aarch64-linux.yml | 2 +- .github/workflows/build-wheels-linux.yml | 2 +- .github/workflows/build-wheels-macos.yml | 2 +- .github/workflows/build-wheels-windows.yml | 2 +- CMakeLists.txt | 7 +++++++ pyproject.toml | 5 +++-- requirements-lintrunner.txt | 2 +- setup.py | 4 ++-- 9 files changed, 20 insertions(+), 13 deletions(-) diff --git a/.claude/skills/building/SKILL.md b/.claude/skills/building/SKILL.md index d1322cdecae..70cc440e6b7 100644 --- a/.claude/skills/building/SKILL.md +++ b/.claude/skills/building/SKILL.md @@ -23,9 +23,8 @@ conda activate executorch **Path B — no conda (fall back to venv):** ```bash -# Find a compatible Python (3.10–3.13). On macOS with only Homebrew Python 3.14+, -# install a compatible version first: brew install python@3.12 -python3.12 -m venv .executorch-venv # or python3.11, python3.10, python3.13 +# Find a compatible Python (3.10–3.14). +python3.12 -m venv .executorch-venv # or python3.11, python3.10, python3.13, python3.14 source .executorch-venv/bin/activate pip install --upgrade pip ``` @@ -33,7 +32,7 @@ pip install --upgrade pip **Then verify (either path):** Run `python --version` and `cmake --version`. Fix automatically: -- **Python not 3.10–3.13**: recreate the env with a correct Python version. +- **Python not 3.10–3.14**: recreate the env with a correct Python version. - **cmake missing or < 3.24**: run `pip install 'cmake>=3.24'` inside the env. - **cmake >= 4.0**: works in practice, no action needed. diff --git a/.github/workflows/build-wheels-aarch64-linux.yml b/.github/workflows/build-wheels-aarch64-linux.yml index b5eb14f076a..b0b9a9c0fee 100644 --- a/.github/workflows/build-wheels-aarch64-linux.yml +++ b/.github/workflows/build-wheels-aarch64-linux.yml @@ -30,7 +30,7 @@ jobs: test-infra-ref: main with-cuda: disabled with-rocm: disabled - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' build: needs: generate-matrix diff --git a/.github/workflows/build-wheels-linux.yml b/.github/workflows/build-wheels-linux.yml index a4c737e3ce3..1a89079e428 100644 --- a/.github/workflows/build-wheels-linux.yml +++ b/.github/workflows/build-wheels-linux.yml @@ -30,7 +30,7 @@ jobs: test-infra-ref: main with-cuda: disabled with-rocm: disabled - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' build: needs: generate-matrix diff --git a/.github/workflows/build-wheels-macos.yml b/.github/workflows/build-wheels-macos.yml index 06603ed42e3..3fddb8e6d26 100644 --- a/.github/workflows/build-wheels-macos.yml +++ b/.github/workflows/build-wheels-macos.yml @@ -30,7 +30,7 @@ jobs: test-infra-ref: main with-cuda: disabled with-rocm: disabled - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' build: needs: generate-matrix diff --git a/.github/workflows/build-wheels-windows.yml b/.github/workflows/build-wheels-windows.yml index 6d986c82592..9b1f8663bd2 100644 --- a/.github/workflows/build-wheels-windows.yml +++ b/.github/workflows/build-wheels-windows.yml @@ -33,7 +33,7 @@ jobs: test-infra-ref: main with-cuda: disabled with-rocm: disabled - python-versions: '["3.10", "3.11", "3.12", "3.13"]' + python-versions: '["3.10", "3.11", "3.12", "3.13", "3.14"]' build: needs: generate-matrix diff --git a/CMakeLists.txt b/CMakeLists.txt index abd032e3e30..6ed2bc716ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,6 +157,13 @@ if(NOT PYTHON_EXECUTABLE) endif() announce_configured_options(PYTHON_EXECUTABLE) +# pybind11 >=3.0 uses find_package(Python) which looks for Python_EXECUTABLE, +# not the legacy PYTHON_EXECUTABLE variable. Bridge the two so pybind11 picks up +# the interpreter that setup.py (or the user) specified. +if(PYTHON_EXECUTABLE AND NOT Python_EXECUTABLE) + set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}") +endif() + announce_configured_options(CMAKE_CXX_COMPILER_ID) announce_configured_options(CMAKE_TOOLCHAIN_FILE) announce_configured_options(BUILD_TESTING) diff --git a/pyproject.toml b/pyproject.toml index ddcb0b7bdc3..b4246be1530 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,9 +51,10 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] -requires-python = ">=3.10,<3.14" +requires-python = ">=3.10,<3.15" # Runtime dependencies are declared dynamically (see `dynamic` above) and # computed in setup.py, so the EXECUTORCH_BUILD_MINIMAL wheel can ship a slimmer @@ -143,7 +144,7 @@ first_party_detection = false # Emit syntax compatible with older versions of python instead of only the range # specified by `requires-python`. TODO: Remove this once we support these older # versions of python and can expand the `requires-python` range. -target-version = ["py38", "py39", "py310", "py311", "py312", "py313"] +target-version = ["py38", "py39", "py310", "py311", "py312", "py313", "py314"] [tool.docformatter] black = true diff --git a/requirements-lintrunner.txt b/requirements-lintrunner.txt index 27e10f0318d..c7c8b29d1d3 100644 --- a/requirements-lintrunner.txt +++ b/requirements-lintrunner.txt @@ -9,7 +9,7 @@ pycodestyle==2.11.1 torchfix==0.6.0 # UFMT -black==24.4.2 +black==26.3.0 ufmt==2.8.0 usort==1.0.8.post1 diff --git a/setup.py b/setup.py index 28cc8ba8e72..6c4a939a74a 100644 --- a/setup.py +++ b/setup.py @@ -190,9 +190,9 @@ def _base_dependencies() -> List[str]: # See also third-party/TARGETS for buck's typing-extensions version. "typing-extensions>=4.10.0", # Keep this version in sync with: ./backends/apple/coreml/scripts/install_requirements.sh - "coremltools==9.0; platform_system == 'Darwin' or platform_system == 'Linux'", + "coremltools==9.0; (platform_system == 'Darwin' or platform_system == 'Linux') and python_version < '3.14'", # scikit-learn is used to support palettization in the coreml backend. - "scikit-learn==1.7.1", + "scikit-learn>=1.7.1", "hydra-core>=1.3.0", "omegaconf>=2.3.0", ]