From a9fc9e3e76d3d99d432e4d1fde9b57e0faa2da6d Mon Sep 17 00:00:00 2001 From: priya-sundaram-dev Date: Fri, 28 Aug 2026 05:57:55 +0000 Subject: [PATCH 1/7] ci: switch default Python to free-threaded 3.14t Change the interpreter used across CI workflows from 3.14 to the free-threaded build 3.14t to surface which dependencies and tests are not yet free-threading compatible. Opened as DRAFT for documentation purposes per maintainer request (#15081). --- .github/workflows/build.yml | 2 +- .github/workflows/directory_writer.yml | 2 +- .github/workflows/project_euler.yml | 4 ++-- .github/workflows/sphinx.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a40f32c2afaf..88f12142db07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: cache-dependency-glob: uv.lock - uses: actions/setup-python@v7 with: - python-version-file: pyproject.toml + python-version: 3.14t allow-prereleases: true - run: uv sync --group=test - name: Run tests diff --git a/.github/workflows/directory_writer.yml b/.github/workflows/directory_writer.yml index 9df64222cd56..4201b31c755b 100644 --- a/.github/workflows/directory_writer.yml +++ b/.github/workflows/directory_writer.yml @@ -11,7 +11,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v7 with: - python-version-file: pyproject.toml + python-version: 3.14t allow-prereleases: true - name: Write DIRECTORY.md run: | diff --git a/.github/workflows/project_euler.yml b/.github/workflows/project_euler.yml index 06f865f0bcdf..0c2486716743 100644 --- a/.github/workflows/project_euler.yml +++ b/.github/workflows/project_euler.yml @@ -25,7 +25,7 @@ jobs: - uses: astral-sh/setup-uv@v7 - uses: actions/setup-python@v7 with: - python-version-file: pyproject.toml + python-version: 3.14t allow-prereleases: true - run: uv sync --group=euler-validate --group=test - run: uv run pytest --doctest-modules --cov-report=term-missing:skip-covered --cov=project_euler/ project_euler/ @@ -43,7 +43,7 @@ jobs: - uses: astral-sh/setup-uv@v7 - uses: actions/setup-python@v7 with: - python-version-file: pyproject.toml + python-version: 3.14t allow-prereleases: true - run: uv sync --group=euler-validate --group=test - run: uv run pytest scripts/validate_solutions.py diff --git a/.github/workflows/sphinx.yml b/.github/workflows/sphinx.yml index 3828bea0eaf0..b7e3303f321b 100644 --- a/.github/workflows/sphinx.yml +++ b/.github/workflows/sphinx.yml @@ -36,7 +36,7 @@ jobs: - uses: astral-sh/setup-uv@v7 - uses: actions/setup-python@v7 with: - python-version-file: pyproject.toml + python-version: 3.14t allow-prereleases: true - run: uv sync --group=docs - uses: actions/configure-pages@v6 From 265c8a7daad763a59dfc1f439704464452c1bdb0 Mon Sep 17 00:00:00 2001 From: Priya Sundaram Date: Fri, 28 Aug 2026 09:29:38 +0000 Subject: [PATCH 2/7] ci(3.14t): gate opencv-python into optional 'cv' group + skip cv2 files opencv-python has no cp314t wheel yet and fails to build from source under free-threaded 3.14t (CMake), blocking uv sync for every job. Move it to an optional [dependency-groups] cv group so the ft CI installs everything else and runs pytest-run-parallel on the pure-Python algorithms. Skip the 20 files that import cv2 (computer_vision augmentations, data_compression PSNR, and the mostly-cv2 digital_image_processing/ tree). Re-fold once a cp314t wheel ships (upstream: opencv/opencv#27933). --- .github/workflows/build.yml | 9 +++++++++ pyproject.toml | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 88f12142db07..2f450fde08e2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,9 +21,18 @@ jobs: allow-prereleases: true - run: uv sync --group=test - name: Run tests + # opencv-python is gated out on 3.14t (no cp314t wheel yet), so skip the + # files that import cv2. Pure-Python algorithms in computer_vision/ and + # data_compression/ still run; digital_image_processing/ is almost entirely + # cv2-based so it is skipped as a tree. Re-enable when a cp314t wheel ships. run: uv run --with=pytest-run-parallel pytest --iterations=8 --parallel-threads=auto --ignore=computer_vision/cnn_classification.py + --ignore=computer_vision/flip_augmentation.py + --ignore=computer_vision/harris_corner.py + --ignore=computer_vision/mosaic_augmentation.py + --ignore=data_compression/peak_signal_to_noise_ratio.py + --ignore=digital_image_processing/ --ignore=docs/conf.py --ignore=dynamic_programming/k_means_clustering_tensorflow.py --ignore=machine_learning/lstm/lstm_prediction.py diff --git a/pyproject.toml b/pyproject.toml index f6eb2e5e562f..760d9c5522ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,6 @@ dependencies = [ "lxml>=6", "matplotlib>=3.9.3", "numpy>=2.1.3", - "opencv-python>=4.10.0.84", "pandas>=2.3.3", "pillow>=11.3", "qiskit>=2", @@ -33,6 +32,14 @@ dependencies = [ ] [dependency-groups] +# opencv-python has no free-threaded (cp314t) wheel yet and fails to build from +# source under 3.14t (CMake), which blocks `uv sync` for every job. Keep it in an +# optional group so the free-threaded CI can install everything else and actually +# run pytest-run-parallel on the pure-Python algorithms. Re-fold into core deps +# once a cp314t wheel ships (upstream: opencv/opencv#27933). +cv = [ + "opencv-python>=4.10.0.84", +] test = [ "pytest>=8.4.1", "pytest-cov>=6", From 53d6a7405a3d2fd77266aac81682c37cfc6554e5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 28 Aug 2026 09:30:02 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyproject.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 760d9c5522ed..043286991232 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,14 +32,6 @@ dependencies = [ ] [dependency-groups] -# opencv-python has no free-threaded (cp314t) wheel yet and fails to build from -# source under 3.14t (CMake), which blocks `uv sync` for every job. Keep it in an -# optional group so the free-threaded CI can install everything else and actually -# run pytest-run-parallel on the pure-Python algorithms. Re-fold into core deps -# once a cp314t wheel ships (upstream: opencv/opencv#27933). -cv = [ - "opencv-python>=4.10.0.84", -] test = [ "pytest>=8.4.1", "pytest-cov>=6", @@ -49,6 +41,14 @@ docs = [ "sphinx>=8.2", "sphinx-autoapi>=3.4", ] +# opencv-python has no free-threaded (cp314t) wheel yet and fails to build from +# source under 3.14t (CMake), which blocks `uv sync` for every job. Keep it in an +# optional group so the free-threaded CI can install everything else and actually +# run pytest-run-parallel on the pure-Python algorithms. Re-fold into core deps +# once a cp314t wheel ships (upstream: opencv/opencv#27933). +cv = [ + "opencv-python>=4.10.0.84", +] euler-validate = [ "httpx>=0.28.1", "numpy>=2.1.3", From 981259c7d481034bcc7a27b32a3474787200dbe0 Mon Sep 17 00:00:00 2001 From: priya-sundaram-dev Date: Fri, 28 Aug 2026 09:58:59 +0000 Subject: [PATCH 4/7] ci(3.14t): add --ignore-gil-enabled so sklearn/xgboost imports don't abort the run --- .github/workflows/build.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2f450fde08e2..9e1a00b5bad6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,8 +25,13 @@ jobs: # files that import cv2. Pure-Python algorithms in computer_vision/ and # data_compression/ still run; digital_image_processing/ is almost entirely # cv2-based so it is skipped as a tree. Re-enable when a cp314t wheel ships. + # --ignore-gil-enabled: some compiled deps (sklearn, xgboost, ...) don't + # yet ship the Py_mod_gil slot, so importing them re-enables the GIL under + # 3.14t. That's an upstream-wheel gap, not our code; the flag lets the suite + # run anyway and pytest-run-parallel still reports which tests are not + # thread-safe. Drop the flag once the scientific stack ships free-threaded wheels. run: uv run --with=pytest-run-parallel pytest - --iterations=8 --parallel-threads=auto + --iterations=8 --parallel-threads=auto --ignore-gil-enabled --ignore=computer_vision/cnn_classification.py --ignore=computer_vision/flip_augmentation.py --ignore=computer_vision/harris_corner.py From c12f697a68e563cbe9945a4c1532cfea1958937c Mon Sep 17 00:00:00 2001 From: priya-sundaram-dev Date: Mon, 31 Aug 2026 16:56:34 +0000 Subject: [PATCH 5/7] ci(3.14t): gate qiskit into an optional group like opencv qiskit re-enables the GIL under free-threaded CPython and the team is still scoping free-threading support (Qiskit/qiskit#16893), so move it out of the core deps into an optional 'quantum' group and ignore the one algorithm that imports it (quantum/q_fourier_transform.py) in the 3.14t test run. Mirrors the existing opencv 'cv' carve-out. Per cclauss: default all workflows to 3.14t except tests depending on OpenCV or Qiskit. --- .github/workflows/build.yml | 3 +++ pyproject.toml | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9e1a00b5bad6..d042d59ee343 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,6 +30,8 @@ jobs: # 3.14t. That's an upstream-wheel gap, not our code; the flag lets the suite # run anyway and pytest-run-parallel still reports which tests are not # thread-safe. Drop the flag once the scientific stack ships free-threaded wheels. + # qiskit is likewise gated out of the 3.14t deps (Qiskit/qiskit#16893), so the + # single file that imports it (quantum/q_fourier_transform.py) is skipped too. run: uv run --with=pytest-run-parallel pytest --iterations=8 --parallel-threads=auto --ignore-gil-enabled --ignore=computer_vision/cnn_classification.py @@ -43,6 +45,7 @@ jobs: --ignore=machine_learning/lstm/lstm_prediction.py --ignore=neural_network/input_data.py --ignore=project_euler/ + --ignore=quantum/q_fourier_transform.py --ignore=scripts/validate_solutions.py --ignore=web_programming/current_stock_price.py --ignore=web_programming/fetch_anime_and_play.py diff --git a/pyproject.toml b/pyproject.toml index 043286991232..8816fdd9a10d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,6 @@ dependencies = [ "numpy>=2.1.3", "pandas>=2.3.3", "pillow>=11.3", - "qiskit>=2", "rich>=13.9.4", "scikit-learn>=1.5.2", "scipy>=1.16.2", @@ -49,6 +48,15 @@ docs = [ cv = [ "opencv-python>=4.10.0.84", ] +# qiskit does not yet run on free-threaded CPython: its compiled core re-enables +# the GIL under 3.14t and the team is still scoping free-threading support +# (upstream: Qiskit/qiskit#16893). Keep it in an optional group so the +# free-threaded CI can install everything else; only quantum/q_fourier_transform.py +# imports it, and that file is ignored in the 3.14t test run. Re-fold into core +# deps once qiskit supports free-threading. +quantum = [ + "qiskit>=2", +] euler-validate = [ "httpx>=0.28.1", "numpy>=2.1.3", From 09d228ba95f7886099877a50011cf6102cfde93d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 16:56:59 +0000 Subject: [PATCH 6/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pyproject.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8816fdd9a10d..be5ff9aee2ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,10 @@ docs = [ cv = [ "opencv-python>=4.10.0.84", ] +euler-validate = [ + "httpx>=0.28.1", + "numpy>=2.1.3", +] # qiskit does not yet run on free-threaded CPython: its compiled core re-enables # the GIL under 3.14t and the team is still scoping free-threading support # (upstream: Qiskit/qiskit#16893). Keep it in an optional group so the @@ -57,10 +61,6 @@ cv = [ quantum = [ "qiskit>=2", ] -euler-validate = [ - "httpx>=0.28.1", - "numpy>=2.1.3", -] [tool.ruff] target-version = "py314" From 64e8e320d499a0ddaf1e5649b870e78beaea8287 Mon Sep 17 00:00:00 2001 From: Priya Sundaram Date: Mon, 31 Aug 2026 18:24:52 +0000 Subject: [PATCH 7/7] ci: single-source 3.14t via .python-version; declare Free Threading :: 2 - Beta Un-ignore .python-version and pin it to 3.14t, then point all four workflows at python-version-file: .python-version so the free-threaded interpreter is selected from one place. Also add the 'Programming Language :: Python :: Free Threading :: 2 - Beta' trove classifier to document our free-threaded support status per https://py-free-threading.github.io/porting/#define-and-document-thread-safety-guarantees --- .github/workflows/build.yml | 2 +- .github/workflows/directory_writer.yml | 2 +- .github/workflows/project_euler.yml | 4 ++-- .github/workflows/sphinx.yml | 2 +- .gitignore | 1 - .python-version | 1 + pyproject.toml | 1 + 7 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 .python-version diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d042d59ee343..f8e03186bb19 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: cache-dependency-glob: uv.lock - uses: actions/setup-python@v7 with: - python-version: 3.14t + python-version-file: .python-version allow-prereleases: true - run: uv sync --group=test - name: Run tests diff --git a/.github/workflows/directory_writer.yml b/.github/workflows/directory_writer.yml index 4201b31c755b..93864635bc04 100644 --- a/.github/workflows/directory_writer.yml +++ b/.github/workflows/directory_writer.yml @@ -11,7 +11,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-python@v7 with: - python-version: 3.14t + python-version-file: .python-version allow-prereleases: true - name: Write DIRECTORY.md run: | diff --git a/.github/workflows/project_euler.yml b/.github/workflows/project_euler.yml index 0c2486716743..a3b7df52b002 100644 --- a/.github/workflows/project_euler.yml +++ b/.github/workflows/project_euler.yml @@ -25,7 +25,7 @@ jobs: - uses: astral-sh/setup-uv@v7 - uses: actions/setup-python@v7 with: - python-version: 3.14t + python-version-file: .python-version allow-prereleases: true - run: uv sync --group=euler-validate --group=test - run: uv run pytest --doctest-modules --cov-report=term-missing:skip-covered --cov=project_euler/ project_euler/ @@ -43,7 +43,7 @@ jobs: - uses: astral-sh/setup-uv@v7 - uses: actions/setup-python@v7 with: - python-version: 3.14t + python-version-file: .python-version allow-prereleases: true - run: uv sync --group=euler-validate --group=test - run: uv run pytest scripts/validate_solutions.py diff --git a/.github/workflows/sphinx.yml b/.github/workflows/sphinx.yml index b7e3303f321b..e1762646869b 100644 --- a/.github/workflows/sphinx.yml +++ b/.github/workflows/sphinx.yml @@ -36,7 +36,7 @@ jobs: - uses: astral-sh/setup-uv@v7 - uses: actions/setup-python@v7 with: - python-version: 3.14t + python-version-file: .python-version allow-prereleases: true - run: uv sync --group=docs - uses: actions/configure-pages@v6 diff --git a/.gitignore b/.gitignore index baea84b8d1f1..192f37798f5d 100644 --- a/.gitignore +++ b/.gitignore @@ -73,7 +73,6 @@ target/ .ipynb_checkpoints # pyenv -.python-version # celery beat schedule file celerybeat-schedule diff --git a/.python-version b/.python-version new file mode 100644 index 000000000000..a469d8fe8548 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.14t diff --git a/pyproject.toml b/pyproject.toml index be5ff9aee2ad..13c439fbb678 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,7 @@ requires-python = ">=3.14" classifiers = [ "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Free Threading :: 2 - Beta", ] dependencies = [ "beautifulsoup4>=4.15",