diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml
index 3679be79..f883b0cb 100644
--- a/.github/workflows/copilot-setup-steps.yml
+++ b/.github/workflows/copilot-setup-steps.yml
@@ -19,16 +19,16 @@ jobs:
contents: read
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.x"
allow-prereleases: true
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Install tooling
run: |
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 291a182d..dce31e30 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -13,11 +13,11 @@ jobs:
dist:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: hynek/build-and-inspect-python-package@d44ca7d91762de7a7d5436ddae667c6da6d1c3df # v2.18.0
+ - uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1
publish:
needs: [dist]
@@ -37,10 +37,10 @@ jobs:
path: dist
- name: Generate artifact attestation for sdist and wheel
- uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
+ uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: "dist/cibuildwheel-*"
- - uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
+ - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
with:
attestations: true
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ceac8d5b..cf600812 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -23,7 +23,7 @@ on:
- .travis.yml
- README.md
- azure-pipelines.yml
- - mkdocs.yml
+ - properdocs.yml
- noxfile.py
workflow_dispatch:
# allow manual runs on branches without a PR
@@ -34,19 +34,23 @@ concurrency:
group: test-${{ github.ref }}
cancel-in-progress: true
+env:
+ # runners see short DNS/network outages; uv's default of 3 retries is too few
+ UV_HTTP_RETRIES: "6"
+
jobs:
lint:
name: Linters (mypy, ruff, etc.)
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.x"
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
- - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
+ - uses: j178/prek-action@4e14d07f9231acabce116ccfca13b13dd9755ece # v3.0.0
- name: PyLint checks
run: uvx nox -s pylint -- --output-format=github
@@ -55,14 +59,14 @@ jobs:
needs: lint
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
name: Install Python
with:
python-version: "3.x"
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Generate a sample project
@@ -117,16 +121,16 @@ jobs:
test_select: android
timeout-minutes: 180
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
name: Install Python ${{ matrix.python_version }}
with:
python-version: ${{ matrix.python_version }}
allow-prereleases: true
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Free up disk space
if: runner.os == 'Linux' && matrix.test_select != 'android'
@@ -139,7 +143,7 @@ jobs:
# for oci_container unit tests
- name: Set up QEMU
if: runner.os == 'Linux'
- uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
+ uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- name: Set up Xcode
if: ${{ startsWith(matrix.os, 'macos-15') }}
@@ -168,6 +172,9 @@ jobs:
if [[ -n "$GITHUB_PR_LABEL_CI_GRAALPY" ]]; then
CIBW_ENABLE+=" graalpy"
fi
+ if [[ -n "$GITHUB_PR_LABEL_CI_PYPY_EOL" ]]; then
+ CIBW_ENABLE+=" pypy-eol"
+ fi
fi
echo "CIBW_ENABLE=${CIBW_ENABLE}" >> $GITHUB_ENV
@@ -247,13 +254,13 @@ jobs:
outputs:
archs: ${{ steps.archs.outputs.archs }}
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.x"
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Get qemu emulated architectures
@@ -272,18 +279,18 @@ jobs:
matrix:
arch: ${{ fromJSON(needs.emulated-archs.outputs.archs) }}
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.x"
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Set up QEMU
- uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
+ uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
- name: Run the emulation tests
env:
@@ -296,14 +303,14 @@ jobs:
runs-on: ubuntu-24.04
timeout-minutes: 180
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
name: Install Python 3.12
with:
python-version: '3.12'
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Install dependencies
run: uv sync --no-dev --group test
@@ -321,13 +328,13 @@ jobs:
output-dir: wheelhouse
env:
CIBW_PLATFORM: pyodide
- CIBW_ENABLE: pyodide-prerelease
+ CIBW_ENABLE: cpython-prerelease
- name: Run tests with 'CIBW_PLATFORM' set to 'pyodide'
run: uv run --no-sync ./bin/run_tests.py
env:
CIBW_PLATFORM: pyodide
- CIBW_ENABLE: pyodide-prerelease
+ CIBW_ENABLE: cpython-prerelease
test-uv-extras:
name: Test uv extra on ${{ matrix.os }} ${{ matrix.test_select }}
@@ -348,7 +355,7 @@ jobs:
- os: macos-15
test_select: android
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Download a sample project
diff --git a/.github/workflows/update-dependencies.yml b/.github/workflows/update-dependencies.yml
index 076d55cb..c7cd5334 100644
--- a/.github/workflows/update-dependencies.yml
+++ b/.github/workflows/update-dependencies.yml
@@ -37,11 +37,11 @@ jobs:
permission-contents: write
permission-pull-requests: write
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
+ - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
with:
python-version: "3.14"
@@ -69,4 +69,5 @@ jobs:
labels: |
CI: GraalPy
CI: PyPy
+ CI: PyPy EoL
dependencies
diff --git a/.github/workflows/update-major-minor-tag.yml b/.github/workflows/update-major-minor-tag.yml
index f83009a9..c2fa6eee 100644
--- a/.github/workflows/update-major-minor-tag.yml
+++ b/.github/workflows/update-major-minor-tag.yml
@@ -21,7 +21,7 @@ jobs:
permissions:
contents: write
steps:
- - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml
index 6e2e8e95..b9b1f656 100644
--- a/.github/workflows/zizmor.yml
+++ b/.github/workflows/zizmor.yml
@@ -16,9 +16,9 @@ jobs:
security-events: write
steps:
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Run zizmor π
- uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
+ uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2
diff --git a/.gitignore b/.gitignore
index d06a56b8..4070ff8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -122,3 +122,4 @@ site/
# This file should be a symlink or contain "See @AGENTS.md"
CLAUDE.md
+.claude/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 68618808..7e95ca2f 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -18,14 +18,14 @@ repos:
exclude: ^cibuildwheel/resources/android/android.patch$
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: 0671d8ab202c4ac093b78433ae5baf74f3fc7246 # frozen: v0.15.15
+ rev: 39d9ac5938dadb73df0564a45f163e25ff9fa6e2 # frozen: v0.16.1
hooks:
- id: ruff-check
args: ["--fix"]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: d2823d321df3af8f878f7ee3414dc94d037145b9 # frozen: v2.1.0
+ rev: 41e691678310dfd3833f7ab4e180ddb014310356 # frozen: v2.3.0
hooks:
- id: mypy
name: mypy 3.11 on cibuildwheel/
@@ -77,7 +77,7 @@ repos:
additional_dependencies: [cogapp>=3.5]
- repo: https://github.com/henryiii/flake8-lazy
- rev: 65b94e97b1091634368592d98072160842265fe4 # frozen: v0.8.2
+ rev: 5fed9a818f2583f0403aed779bf2b6c9aa8d25f4 # frozen: v0.8.5
hooks:
- id: flake8-lazy
args: ["--apply=set"]
@@ -85,7 +85,7 @@ repos:
exclude: "^cibuildwheel/resources/"
- repo: https://github.com/codespell-project/codespell
- rev: 2ccb47ff45ad361a21071a7eedda4c37e6ae8c5a # frozen: v2.4.2
+ rev: 57b21406f092110c18776e39b0bda50d37c945c8 # frozen: v2.4.3
hooks:
- id: codespell
args: ["-w"]
@@ -93,7 +93,7 @@ repos:
- repo: https://github.com/python-jsonschema/check-jsonschema
- rev: 943377262562a12b57292fc98fabd7dbf81451fe # frozen: 0.37.2
+ rev: 1a4bb160cab6417b3045e1b37b6b72449243e658 # frozen: 0.37.4
hooks:
- id: check-dependabot
- id: check-github-actions
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 70d3153a..606ba546 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -8,4 +8,4 @@ build:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- - NO_COLOR=1 uv run --python 3.14 --managed-python --no-dev --group docs mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html
+ - NO_COLOR=1 uv run --python 3.14 --managed-python --no-dev --group docs properdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html
diff --git a/AGENTS.md b/AGENTS.md
index 186cc65e..627dbc16 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -11,7 +11,7 @@
- `nox -s tests -- test -k before_build` β single integration test/file via pytest `-k`.
- `nox -s lint` β run all linters (pre-commit/prek).
- `nox -s pylint` β run pylint separately (not in pre-commit).
-- `nox -s docs` β mkdocs serve (interactive) or build (non-interactive).
+- `nox -s docs` β properdocs serve (interactive) or build (non-interactive).
- Set up local dev env at `.venv`: `uv sync` (dependency groups used).
## Project layout
@@ -19,7 +19,7 @@
- `test/` β **integration tests** (expensive, run actual wheel builds).
- `unit_test/` β **unit tests** (fast, no wheel builds).
- `bin/` β maintainer scripts (update pins, generate README tables, schema, etc.).
-- `docs/` β mkdocs source.
+- `docs/` β properdocs (MkDocs fork) source.
## Testing specifics
- Three test suites exist, run in this order by `bin/run_tests.py`:
diff --git a/README.md b/README.md
index 54418777..e7ec7f98 100644
--- a/README.md
+++ b/README.md
@@ -22,25 +22,24 @@ What does it do?
While cibuildwheel itself requires a recent Python version to run (we support the last three releases), it can target the following versions to build wheels:
-| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux
musllinux x86_64 | manylinux
musllinux i686 | manylinux
musllinux aarch64 | manylinux
musllinux ppc64le | manylinux
musllinux s390x | manylinux
musllinux armv7l | Android | iOS | Pyodide |
-| ------------------------ | ----------- | ------------------- | ------------- | ------------- | -------------- | ------------------------------ | ---------------------------- | ------------------------------- | ------------------------------- | ----------------------------- | ------------------------------ | ------- | --- | -------------- |
-| CPython 3.9 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | N/A |
-| CPython 3.10 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | N/A |
-| CPython 3.11 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | N/A |
-| CPython 3.12 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | β
3 |
-| CPython 3.13 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | β
| β
| β
|
-| CPython 3.14 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | β
| β
| β
|
-| CPython 3.155 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | β
| β
| N/A |
-| PyPyΒ 3.9 v7.3 | β
| β
| β
| N/A | N/A | β
1 | β
1 | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
-| PyPyΒ 3.10 v7.3 | β
| β
| β
| N/A | N/A | β
1 | β
1 | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
-| PyPyΒ 3.11 v7.3 | β
| β
| β
| N/A | N/A | β
1 | β
1 | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
-| GraalPyΒ 3.12 v25.0 | β
| β
| β
| N/A | N/A | β
1 | N/A | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
+| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux
musllinux x86_64 | manylinux
musllinux i686 | manylinux
musllinux aarch64 | manylinux
musllinux ppc64le | manylinux
musllinux s390x | manylinux
musllinux armv7l | Android | iOS | Pyodide |
+|--------------------| ----------- | ------------------- | ------------- | ------------- | -------------- | ------------------------------ | ---------------------------- | ------------------------------- | ------------------------------- | ----------------------------- | ------------------------------ | ------- | --- | -------------- |
+| CPython 3.9 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | N/A |
+| CPython 3.10 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | N/A |
+| CPython 3.11 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | N/A |
+| CPython 3.12 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | N/A | N/A | β
3 |
+| CPython 3.13 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | β
| β
| β
|
+| CPython 3.14 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | β
| β
| β
|
+| CPython 3.15 | β
| β
| β
| β
| β
2 | β
| β
| β
| β
| β
| β
4 | β
| β
| β
|
+| PyPyΒ 3.9 v7.3 | β
| β
| β
| N/A | N/A | β
1 | β
1 | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
+| PyPyΒ 3.10 v7.3 | β
| β
| β
| N/A | N/A | β
1 | β
1 | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
+| PyPyΒ 3.11 v7.3 | β
| β
| β
| N/A | N/A | β
1 | β
1 | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
+| GraalPyΒ 3.12 v25.0 | β
| β
| β
| N/A | N/A | β
1 | N/A | β
1 | N/A | N/A | N/A | N/A | N/A | N/A |
**1** PyPy & GraalPy are only supported for manylinux wheels.
**2** Windows arm64 support is experimental.
**3** Not supported on PyPI, uses old `pyodide` tag instead of `pyemscripten`. Requires `pyodide-eol` [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable).
**4** manylinux armv7l support is experimental. As there are no RHEL based image for this architecture, it's using an Ubuntu based image instead.
-**5** Python 3.15 requires opt-in using [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable).
- Builds manylinux, musllinux, macOS, Windows, pyemscripten, iOS, and Android wheels
- Supports CPython, PyPy, and GraalPy
@@ -98,7 +97,7 @@ jobs:
- uses: actions/setup-python@v6
- name: Install cibuildwheel
- run: python -m pip install cibuildwheel==4.1.0
+ run: python -m pip install cibuildwheel==4.2.0
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
@@ -189,8 +188,8 @@ Here are some repos that use cibuildwheel.
|-----------------------------------|----|----|:------|
| [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
-| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | The fundamental package for scientific computing with Python. |
+| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
@@ -200,8 +199,8 @@ Here are some repos that use cibuildwheel.
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
[duckdb]: https://github.com/duckdb/duckdb
-[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy
+[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib
[Tornado]: https://github.com/tornadoweb/tornado
@@ -239,6 +238,42 @@ Changelog
+### v4.2.0
+
+_4 August 2026_
+
+- π CPython 3.15 wheels are now built by default - without the `"cpython-prerelease"` [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable) set. It's time to build and upload these wheels to PyPI! This release includes CPython 3.15.0rc1, which is guaranteed to be ABI compatible with the final release. (#2944)
+- β¨ Adds Pyodide 3.15 support with the `cp315-pyodide_wasm32` build identifier, using Pyodide 315.0.0a2. These are also stable wrt. the final release. (#2958)
+- π Retries a failed download six times with exponential backoff, so short network outages no longer stop a build. A `4xx` response is still reported at once. (#2953)
+- π Accepts `default` as a [`build-frontend`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) value on Pyodide, and accepts `pyodide-build` in the top-level table and in overrides (#2951)
+- π Holds pip back on GraalPy, where newer pip breaks the build (#2955)
+- π Updates Pyodide to 314.0.4 (#2949, #2952)
+- π Updates dependencies and container pins (#2952, #2960)
+- πΌ Updates CI action pins (#2948, #2954)
+- π§ͺ Uses pp311 for the abi3 test, and deletes `test_overridden_pip_constraint`, which is not necessary since #2583 (#2956, #2957)
+
+### v4.1.1
+
+_24 July 2026_
+
+- β¨ Adds `pyodide-build` as a separate [`build-frontend`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend), now the default frontend for Pyodide, with verbosity flags handling. Any other frontend is ignored with a warning on Pyodide. (#2609, #2945)
+- π Uses digests instead of tags for pinned container images, strengthening supply-chain security. The human-readable tags remain as comments in `pinned_docker_images.cfg`. (#2915)
+- π Fixes platform-specific [`test-runtime`](https://cibuildwheel.pypa.io/en/stable/options/#test-runtime) environment variables (e.g. `CIBW_TEST_RUNTIME_ANDROID`) not being honored (#2941)
+- π Fixes quoting of [`test-requires`](https://cibuildwheel.pypa.io/en/stable/options/#test-requires) and [`audit-requires`](https://cibuildwheel.pypa.io/en/stable/options/#audit-requires) so PEP 508 specifiers containing spaces work (#2913)
+- π Makes [`archs`](https://cibuildwheel.pypa.io/en/stable/options/#archs) parsing case-insensitive and platform-aware, so e.g. `arm64` works on Windows (#2920)
+- π Uses an absolute path for the `{project}` placeholder in [`config-settings`](https://cibuildwheel.pypa.io/en/stable/options/#config-settings) (#2934)
+- π Validates the [`pyodide-version`](https://cibuildwheel.pypa.io/en/stable/options/#pyodide-version) option against the build identifier with a clear error (#2925)
+- π Fixes PyPy installs on macOS after PyPy switched its downloads from `.tar.bz2` to `.tar.gz` (#2939)
+- π Makes a matching `python3-config` available in the build and test venvs on macOS (#2922)
+- π Updates dependencies and container pins (#2917, #2935, #2939)
+- π Updates Android tests to current Python versions and the new test repository URL (#2933)
+- π Drops the `orjson` dependency, no longer used by mypy 2+ (#2923)
+- π Builds the docs with properdocs, a MkDocs fork (#2946)
+- π Adds the missing `cp314-pyodide_wasm32` entry to the build identifier table (#2947)
+- π Removes outdated notes about the `pip wheel` build frontend and ClearLinux (#2926)
+- πΌ Adds a "CI: PyPy EoL" PR label to run PyPy EoL tests on PRs (#2930)
+- πΌ Updates CI action pins and pre-commit hooks (#2914, #2932, #2938, #2940, #2942, #2943)
+
### v4.1.0
_12 June 2026_
@@ -316,25 +351,7 @@ _2 April 2026_
- β¨ cibuildwheel prints the selected build identifiers at the start of the build. (#2785)
- π The GitHub Action now references other actions with a full SHA (#2744)
-### v3.4.0
-
-_5 March 2026_
-
-- π You can now build wheels using `uv` as a build frontend. This should improve performance, especially if your project has lots of build dependencies. To use, set [`build-frontend`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) to `uv`. (#2322)
-- β οΈ We no longer support running on Travis CI. It may continue working but we don't run tests there anymore so we can't be sure. (#2682)
-- β¨ Improvements to building rust wheels on Android (#2650)
-- π Update Pyodide to 0.29.3 (#2719, #2733)
-- π Fix bug with the GitHub Action on Windows, where PATH was getting unnecessarily changed, causing issues with meson builds. (#2723)
-- β¨ Add support for quiet setting on `build` and `uv` from the cibuildwheel `build-verbosity` setting. (#2737)
-- π Docs updates, including guidance on using Meson on Windows (#2718)
-
-### v3.3.1
-
-_5 January 2026_
-
-- π Update dependencies and container pins, including updating to CPython 3.14.2. (#2708)
-
-
+
---
diff --git a/action.yml b/action.yml
index d03d59bb..f90b351d 100644
--- a/action.yml
+++ b/action.yml
@@ -28,7 +28,7 @@ branding:
runs:
using: composite
steps:
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
id: python
with:
python-version: "3.11 - 3.14"
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 0f2621d8..657428ff 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -12,7 +12,7 @@ pr:
- .readthedocs.yml
- .travis.yml
- README.md
- - mkdocs.yml
+ - properdocs.yml
- noxfile.py
jobs:
diff --git a/bin/generate_schema.py b/bin/generate_schema.py
index 5a1fb42f..4d25b2de 100755
--- a/bin/generate_schema.py
+++ b/bin/generate_schema.py
@@ -35,7 +35,7 @@ $defs:
- pyodide-prerelease
- pypy
- pypy-eol
- description: A Python version or flavor to enable.
+ description: A Python version or flavor to enable.
additionalProperties: false
description: cibuildwheel's settings.
type: object
@@ -84,29 +84,7 @@ properties:
default: ['*']
description: Choose the Python versions to build.
type: string_array
- build-frontend:
- default: default
- description: Set the tool to use to build, either "build" (default), "build[uv]", "uv", or "pip"
- oneOf:
- - enum: [pip, build, "build[uv]", uv, default]
- - type: string
- pattern: '^pip; ?args:'
- - type: string
- pattern: '^build; ?args:'
- - type: string
- pattern: '^build\\[uv\\]; ?args:'
- - type: string
- pattern: '^uv; ?args:'
- - type: object
- additionalProperties: false
- required: [name]
- properties:
- name:
- enum: [pip, build, "build[uv]", uv]
- args:
- type: array
- items:
- type: string
+ build-frontend: {} # filled in by build_frontend_schema below
build-verbosity:
type: integer
minimum: -3
@@ -314,6 +292,43 @@ string_table = yaml.safe_load(
"""
)
+FRONTENDS = ["pip", "build", "build[uv]", "uv"]
+
+
+def build_frontend_schema(
+ names: list[str], description: str, default: str = "default"
+) -> dict[str, Any]:
+ """
+ A frontend is a name, a "name; args: ..." string, or a table with a name and args.
+ """
+ # Only the brackets in "build[uv]" need escaping
+ patterns = [name.replace("[", r"\[").replace("]", r"\]") for name in names]
+ return {
+ "default": default,
+ "description": description,
+ "oneOf": [
+ {"enum": [*names, "default"]},
+ *({"type": "string", "pattern": f"^{pattern}; ?args:"} for pattern in patterns),
+ {
+ "type": "object",
+ "additionalProperties": False,
+ "required": ["name"],
+ "properties": {
+ "name": {"enum": names},
+ "args": {"type": "array", "items": {"type": "string"}},
+ },
+ },
+ ],
+ "title": "CIBW_BUILD_FRONTEND",
+ }
+
+
+schema["properties"]["build-frontend"] = build_frontend_schema(
+ [*FRONTENDS, "pyodide-build"],
+ 'Set the tool to use to build, either "build" (default), "build[uv]", "uv", or "pip"'
+ ' ("pyodide-build" for pyodide)',
+)
+
for value in schema["properties"].values():
match value:
case {"type": "string_array"}:
@@ -325,6 +340,8 @@ for value in schema["properties"].values():
case {"type": "string_table_array"}:
del value["type"]
value["oneOf"] = string_table_array
+ case _:
+ pass
overrides = yaml.safe_load(
"""
@@ -435,6 +452,20 @@ overrides["items"]["properties"]["inherit"] = inherit_schema(overrides["items"][
for os_schema in oses.values():
os_schema["properties"]["inherit"] = inherit_schema(os_schema["properties"])
+schema["$defs"]["build-frontend-no-pyodide"] = build_frontend_schema(
+ FRONTENDS,
+ 'Set the tool to use to build, either "build" (default), "build[uv]", "uv", or "pip"',
+)
+
+for os_val in oses.values():
+ os_val["properties"]["build-frontend"] = {"$ref": "#/$defs/build-frontend-no-pyodide"}
+
+oses["pyodide"]["properties"]["build-frontend"] = build_frontend_schema(
+ ["pyodide-build"],
+ 'On the pyodide platform, the build frontend must be "pyodide-build"',
+ default="pyodide-build",
+)
+
schema["properties"]["overrides"] = overrides
schema["properties"] |= oses
diff --git a/bin/inspect_all_known_projects.py b/bin/inspect_all_known_projects.py
index f328c09f..d0ebec92 100755
--- a/bin/inspect_all_known_projects.py
+++ b/bin/inspect_all_known_projects.py
@@ -49,7 +49,7 @@ def parse(contents: str) -> str | None:
analyzer = Analyzer()
analyzer.visit(tree)
return analyzer.requires_python or ""
- except Exception:
+ except Exception: # noqa: BLE001
return None
diff --git a/bin/update_docker.py b/bin/update_docker.py
index 8eccde3a..3cde251d 100755
--- a/bin/update_docker.py
+++ b/bin/update_docker.py
@@ -9,6 +9,7 @@
import configparser
import dataclasses
+from functools import cache
from pathlib import Path
import requests
@@ -33,7 +34,7 @@ class PyPAImage(Image):
super().__init__(manylinux_version, platforms, image_name, tag, True)
-images = [
+IMAGES = [
# manylinux2014 images
PyPAImage(
"manylinux2014",
@@ -88,49 +89,71 @@ images = [
),
]
-config = configparser.ConfigParser()
-for image in images:
- # get the tag name whose digest matches 'latest'
- if image.tag is not None:
- # image has been pinned, do not update
- tag_name = image.tag
- elif image.image_name.startswith("quay.io/"):
- _, _, repository_name = image.image_name.partition("/")
- response = requests.get(
- f"https://quay.io/api/v1/repository/{repository_name}?includeTags=true"
- )
- response.raise_for_status()
- repo_info = response.json()
- tags_dict = repo_info["tags"]
-
- latest_tag = tags_dict.pop("latest")
+@cache
+def quay_lookup(image_name: str, tag_name: str) -> tuple[str, str]:
+ _, _, repository_name = image_name.partition("/")
+ if tag_name == "latest":
+ url = f"https://quay.io/api/v1/repository/{repository_name}?includeTags=true"
+ else:
+ url = f"https://quay.io/api/v1/repository/{repository_name}/tag?specificTag={tag_name}"
+ response = requests.get(url)
+ response.raise_for_status()
+ info = response.json()
+ if tag_name == "latest":
+ tags_dict = info["tags"]
+ tag_info = tags_dict.pop(tag_name)
# find the tag whose manifest matches 'latest'
- tag_name = next(
- name
+ tag_name, digest = next(
+ (name, info["manifest_digest"])
for (name, info) in tags_dict.items()
- if info["manifest_digest"] == latest_tag["manifest_digest"]
+ if info["manifest_digest"] == tag_info["manifest_digest"]
)
- elif image.image_name.startswith("ghcr.io/"):
- repository = image.image_name[8:]
- response = requests.get(
- "https://ghcr.io/token", params={"scope": f"repository:{repository}:pull"}
- )
- response.raise_for_status()
- token = response.json()["token"]
+ else:
+ tags_list = info["tags"]
+ tag_info = next(tag for tag in tags_list if tag["name"] == tag_name)
+ digest = tag_info["manifest_digest"]
+
+ return tag_name, digest
+
+
+@cache
+def ghcr_lookup(image_name: str, tag_name: str) -> tuple[str, str]:
+ repository = image_name[8:]
+ response = requests.get(
+ "https://ghcr.io/token", params={"scope": f"repository:{repository}:pull"}
+ )
+ response.raise_for_status()
+ token = response.json()["token"]
+ if tag_name == "latest":
response = requests.get(
f"https://ghcr.io/v2/{repository}/tags/list",
headers={"Authorization": f"Bearer {token}"},
)
response.raise_for_status()
- ghcr_tags = [(Version(tag), tag) for tag in response.json()["tags"] if tag != "latest"]
+ info = response.json()
+ ghcr_tags = [(Version(tag), tag) for tag in info["tags"] if tag != "latest"]
ghcr_tags.sort(reverse=True)
tag_name = ghcr_tags[0][1]
- else:
- response = requests.get(f"https://hub.docker.com/v2/repositories/{image.image_name}/tags")
- response.raise_for_status()
- tags = response.json()["results"]
+ response = requests.head(
+ f"https://ghcr.io/v2/{repository}/manifests/{tag_name}",
+ headers={
+ "Authorization": f"Bearer {token}",
+ "Accept": "application/vnd.docker.distribution.manifest.v2+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.oci.image.index.v1+json, application/vnd.oci.artifact.manifest.v1+json",
+ },
+ )
+ response.raise_for_status()
+ digest = response.headers["Docker-Content-Digest"]
+ return tag_name, digest
+
+
+@cache
+def dockerhub_lookup(image_name: str, tag_name: str) -> tuple[str, str]:
+ response = requests.get(f"https://hub.docker.com/v2/repositories/{image_name}/tags")
+ response.raise_for_status()
+ tags = response.json()["results"]
+ if tag_name == "latest":
latest_tag = next(tag for tag in tags if tag["name"] == "latest")
# i don't know what it would mean to have multiple images per tag
assert len(latest_tag["images"]) == 1
@@ -139,15 +162,40 @@ for image in images:
pinned_tag = next(
tag for tag in tags if tag != latest_tag and tag["images"][0]["digest"] == digest
)
- tag_name = pinned_tag["name"]
+ else:
+ pinned_tag = next(tag for tag in tags if tag["name"] == tag_name)
+ digest = pinned_tag["images"][0]["digest"]
+ tag_name = pinned_tag["name"]
+ return tag_name, digest
- for platform in image.platforms:
- if not config.has_section(platform):
- config[platform] = {}
- suffix = ""
- if image.use_platform_suffix:
- suffix = f"_{platform.removeprefix('pypy_')}"
- config[platform][image.manylinux_version] = f"{image.image_name}{suffix}:{tag_name}"
-with open(RESOURCES / "pinned_docker_images.cfg", "w") as f:
- config.write(f)
+def main() -> None:
+ config = configparser.ConfigParser()
+ for image in IMAGES:
+ # get the tag name whose digest matches 'latest'
+ # if image has been pinned, do not update
+ search_tag = image.tag or "latest"
+ if image.image_name.startswith("quay.io/"):
+ lookup = quay_lookup
+ elif image.image_name.startswith("ghcr.io/"):
+ lookup = ghcr_lookup
+ else:
+ lookup = dockerhub_lookup
+
+ tag_name, digest = lookup(image.image_name, search_tag)
+ for platform in image.platforms:
+ if not config.has_section(platform):
+ config[platform] = {}
+ image_name = image.image_name
+ if image.use_platform_suffix:
+ image_name = f"{image_name}_{platform.removeprefix('pypy_')}"
+ _, digest = lookup(image_name, tag_name)
+ assert digest.startswith("sha256:")
+ config[platform][image.manylinux_version] = f"{image_name}@{digest} # {tag_name}"
+
+ with open(RESOURCES / "pinned_docker_images.cfg", "w") as f:
+ config.write(f)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/update_pythons.py b/bin/update_pythons.py
index dd6bb38c..72cad1f4 100755
--- a/bin/update_pythons.py
+++ b/bin/update_pythons.py
@@ -76,9 +76,9 @@ class WindowsVersions:
response.raise_for_status()
api_info = response.json()
- for resource in api_info["resources"]:
- if resource["@type"] == "PackageBaseAddress/3.0.0":
- endpoint = resource["@id"]
+ endpoint = next(
+ r["@id"] for r in api_info["resources"] if r["@type"] == "PackageBaseAddress/3.0.0"
+ )
ARCH_DICT = {"32": "win32", "64": "win_amd64", "ARM64": "win_arm64"}
PACKAGE_DICT = {"32": "pythonx86", "64": "python", "ARM64": "pythonarm64"}
diff --git a/cibuildwheel/__init__.py b/cibuildwheel/__init__.py
index 70397087..0fd7811c 100644
--- a/cibuildwheel/__init__.py
+++ b/cibuildwheel/__init__.py
@@ -1 +1 @@
-__version__ = "4.1.0"
+__version__ = "4.2.0"
diff --git a/cibuildwheel/extra.py b/cibuildwheel/extra.py
index 9b1abcb1..7dfbe594 100644
--- a/cibuildwheel/extra.py
+++ b/cibuildwheel/extra.py
@@ -83,7 +83,7 @@ def github_api_request(path: str, *, max_retries: int = 3) -> dict[str, Any]:
if retry_count == max_retries - 1:
print(f"GitHub API request failed (Network error: {e}). Check network connection.")
- raise e
+ raise
# Should never be reached but to keep the type checker happy
msg = "Unexpected execution path in github_api_request"
diff --git a/cibuildwheel/frontend.py b/cibuildwheel/frontend.py
index 41c53b34..b3dc58ab 100644
--- a/cibuildwheel/frontend.py
+++ b/cibuildwheel/frontend.py
@@ -16,7 +16,7 @@ if TYPE_CHECKING:
from cibuildwheel.typing import PathOrStr
-BuildFrontendName = Literal["pip", "build", "build[uv]", "uv"]
+BuildFrontendName = Literal["pip", "build", "build[uv]", "uv", "pyodide-build"]
@dataclasses.dataclass(frozen=True)
@@ -46,6 +46,11 @@ class BuildFrontendConfig:
def _get_verbosity_flags(level: int, frontend: BuildFrontendName) -> list[str]:
+ if frontend == "pyodide-build":
+ if level > 0:
+ return ["-" + min(level, 2) * "v"]
+ return []
+
if level < 0:
return ["-" + -level * "q"]
diff --git a/cibuildwheel/oci_container.py b/cibuildwheel/oci_container.py
index 49e14a93..e0844f97 100644
--- a/cibuildwheel/oci_container.py
+++ b/cibuildwheel/oci_container.py
@@ -546,9 +546,14 @@ class OCIContainer:
else:
output_io = sys.stdout.buffer
- while True:
+ return_code = None
+ while return_code is None:
line = self.bash_stdout.readline()
+ if not line:
+ msg = "Failed to read the return code, the container shell has exited"
+ raise RuntimeError(msg)
+
if line.endswith(bytes(end_of_message, encoding="utf8") + b"\n"):
# fmt: off
footer_offset = (
@@ -563,7 +568,6 @@ class OCIContainer:
# add the last line to output, without the footer
output_io.write(line[0:footer_offset])
output_io.flush()
- break
else:
output_io.write(line)
output_io.flush()
diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py
index ae8fda2f..41906abb 100644
--- a/cibuildwheel/options.py
+++ b/cibuildwheel/options.py
@@ -43,7 +43,7 @@ from packaging.specifiers import SpecifierSet
from cibuildwheel import errors
from cibuildwheel.architecture import Architecture
from cibuildwheel.environment import EnvironmentParseError, ParsedEnvironment, parse_environment
-from cibuildwheel.frontend import BuildFrontendConfig
+from cibuildwheel.frontend import BuildFrontendConfig, BuildFrontendName
from cibuildwheel.logger import log
from cibuildwheel.oci_container import OCIContainerEngineConfig
from cibuildwheel.projectfiles import get_requires_python_str, resolve_dependency_groups
@@ -957,7 +957,6 @@ class Options:
test_runtime_str = self.reader.get(
"test-runtime",
- env_plat=False,
option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
)
if not test_runtime_str:
@@ -987,8 +986,11 @@ class Options:
env_plat=False,
option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
)
+ default_frontend: BuildFrontendName = (
+ "pyodide-build" if self.platform == "pyodide" else "build"
+ )
if not build_frontend_str or build_frontend_str == "default":
- build_frontend = BuildFrontendConfig("build")
+ build_frontend = BuildFrontendConfig(default_frontend)
else:
try:
build_frontend = BuildFrontendConfig.from_config_string(build_frontend_str)
@@ -996,6 +998,18 @@ class Options:
msg = f"Failed to parse build frontend. {e}"
raise errors.ConfigurationError(msg) from e
+ if self.platform == "pyodide" and build_frontend.name != "pyodide-build":
+ # pip and uv could become an error, eventually. build -> pyodide-build is
+ # probably fine to keep as a warning
+ log.warning(
+ f"The pyodide platform ignores the {build_frontend.name!r} build "
+ "frontend; using 'pyodide-build' instead"
+ )
+ build_frontend = BuildFrontendConfig("pyodide-build", build_frontend.args)
+ if self.platform != "pyodide" and build_frontend.name == "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is only supported on the pyodide platform"
+ raise errors.ConfigurationError(msg)
+
try:
environment = parse_environment(environment_config)
except (EnvironmentParseError, ValueError) as e:
@@ -1260,6 +1274,6 @@ def _get_pinned_container_images() -> Mapping[str, Mapping[str, str]]:
'pypy_x86_64': {'manylinux2010': '...' }
... }
"""
- all_pinned_images = configparser.ConfigParser()
+ all_pinned_images = configparser.ConfigParser(inline_comment_prefixes="#")
all_pinned_images.read(resources.PINNED_DOCKER_IMAGES)
return all_pinned_images
diff --git a/cibuildwheel/platforms/android.py b/cibuildwheel/platforms/android.py
index 5e47196b..eabb87c7 100644
--- a/cibuildwheel/platforms/android.py
+++ b/cibuildwheel/platforms/android.py
@@ -222,16 +222,6 @@ def setup_target_python(config: PythonConfiguration, build_path: Path) -> Path:
python_dir = build_path / "python"
python_dir.mkdir()
shutil.unpack_archive(python_tgz, python_dir)
-
- # Patch a testbed bug. This code and the patch file can both be removed once we've
- # updated to Python versions that include the fix.
- call("patch", "-p1", "-i", RESOURCES_ANDROID / "android.patch", cwd=python_dir)
-
- # Work around https://github.com/python/cpython/issues/138800. This can be removed
- # once we've updated to Python versions that include the fix.
- pc_path = python_dir / f"prefix/lib/pkgconfig/python-{config.version}.pc"
- pc_path.write_text(pc_path.read_text().replace("$(BLDLIBRARY)", f"-lpython{config.version}"))
-
return python_dir
@@ -314,7 +304,9 @@ def setup_env(
"wheel",
parse_config_settings(
prepare_config_settings(
- build_options.config_settings, project=".", package=build_options.package_dir
+ build_options.config_settings,
+ project=Path.cwd(),
+ package=build_options.package_dir,
)
),
)
@@ -604,7 +596,7 @@ def build_wheel(state: BuildState) -> Path:
state.options.build_verbosity,
prepare_config_settings(
state.options.config_settings,
- project=".",
+ project=Path.cwd(),
package=state.options.package_dir,
),
),
@@ -625,7 +617,7 @@ def build_wheel(state: BuildState) -> Path:
state.options.build_verbosity,
prepare_config_settings(
state.options.config_settings,
- project=".",
+ project=Path.cwd(),
package=state.options.package_dir,
),
),
diff --git a/cibuildwheel/platforms/ios.py b/cibuildwheel/platforms/ios.py
index 60ee0daa..2d1fefd6 100644
--- a/cibuildwheel/platforms/ios.py
+++ b/cibuildwheel/platforms/ios.py
@@ -463,6 +463,9 @@ def setup_python(
*constraint_flags(dependency_constraint),
env=env,
)
+ case "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is not supported on this platform"
+ raise errors.FatalError(msg)
case _:
assert_never(build_frontend)
@@ -537,7 +540,7 @@ def build(options: Options, tmp_path: Path) -> None:
f"that is compatible with {config.identifier}. "
"Skipping build step..."
)
- test_wheel = compatible_wheel
+ repaired_wheel = compatible_wheel
else:
if build_options.before_build:
log.step("Running before_build...")
@@ -556,7 +559,7 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.build_verbosity,
prepare_config_settings(
build_options.config_settings,
- project=".",
+ project=Path.cwd(),
package=build_options.package_dir,
),
)
@@ -588,6 +591,9 @@ def build(options: Options, tmp_path: Path) -> None:
*extra_flags,
env=env,
)
+ case "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is not supported on this platform"
+ raise errors.FatalError(msg)
case _:
assert_never(build_frontend)
@@ -626,8 +632,6 @@ def build(options: Options, tmp_path: Path) -> None:
run_audit(tmp_dir=tmp_path, build_options=build_options, wheel=repaired_wheel)
- test_wheel = repaired_wheel
-
if build_options.test_command and build_options.test_selector(config.identifier):
if not config.is_simulator:
log.step("Skipping tests on non-simulator SDK")
@@ -687,7 +691,7 @@ def build(options: Options, tmp_path: Path) -> None:
platform_tag,
"--target",
testbed_path / "iOSTestbed" / "app_packages",
- f"{test_wheel}{build_options.test_extras}",
+ f"{repaired_wheel}{build_options.test_extras}",
*build_options.test_requires,
env=test_env,
)
diff --git a/cibuildwheel/platforms/linux.py b/cibuildwheel/platforms/linux.py
index 54f29e4e..537d4327 100644
--- a/cibuildwheel/platforms/linux.py
+++ b/cibuildwheel/platforms/linux.py
@@ -360,6 +360,9 @@ def build_in_container(
],
env=env,
)
+ case "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is not supported on this platform"
+ raise errors.FatalError(msg)
case _:
assert_never(build_frontend)
diff --git a/cibuildwheel/platforms/macos.py b/cibuildwheel/platforms/macos.py
index 5ef4a3e7..64b5d4a7 100644
--- a/cibuildwheel/platforms/macos.py
+++ b/cibuildwheel/platforms/macos.py
@@ -215,18 +215,19 @@ def install_cpython(_tmp: Path, version: str, url: str, free_threading: bool, sh
def install_pypy(tmp: Path, url: str, sha256: str) -> Path:
- pypy_tar_bz2 = url.rsplit("/", 1)[-1]
- extension = ".tar.bz2"
- assert pypy_tar_bz2.endswith(extension)
- installation_path = CIBW_CACHE_PATH / pypy_tar_bz2[: -len(extension)]
+ pypy_archive = url.rsplit("/", 1)[-1]
+ # PyPy ships .tar.bz2 for some platforms and .tar.gz for others.
+ extension = ".tar.bz2" if pypy_archive.endswith(".tar.bz2") else ".tar.gz"
+ assert pypy_archive.endswith(extension)
+ installation_path = CIBW_CACHE_PATH / pypy_archive[: -len(extension)]
with FileLock(str(installation_path) + ".lock"):
if not installation_path.exists():
- downloaded_tar_bz2 = tmp / pypy_tar_bz2
- download(url, downloaded_tar_bz2, sha256=sha256)
+ downloaded_archive = tmp / pypy_archive
+ download(url, downloaded_archive, sha256=sha256)
installation_path.parent.mkdir(parents=True, exist_ok=True)
with remove_on_error(installation_path):
- call("tar", "-C", installation_path.parent, "-xf", downloaded_tar_bz2)
- downloaded_tar_bz2.unlink()
+ call("tar", "-C", installation_path.parent, "-xf", downloaded_archive)
+ downloaded_archive.unlink()
return installation_path / "bin" / "pypy3"
@@ -449,6 +450,9 @@ def setup_python(
*constraint_flags(dependency_constraint),
env=env,
)
+ case "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is not supported on this platform"
+ raise errors.FatalError(msg)
case _:
assert_never(build_frontend)
@@ -534,7 +538,7 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.build_verbosity,
prepare_config_settings(
build_options.config_settings,
- project=".",
+ project=Path.cwd(),
package=build_options.package_dir,
),
)
@@ -585,6 +589,9 @@ def build(options: Options, tmp_path: Path) -> None:
*extra_flags,
env=build_env,
)
+ case "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is not supported on this platform"
+ raise errors.FatalError(msg)
case _:
assert_never(build_frontend)
diff --git a/cibuildwheel/platforms/pyodide.py b/cibuildwheel/platforms/pyodide.py
index 2466d59d..6de8a00d 100644
--- a/cibuildwheel/platforms/pyodide.py
+++ b/cibuildwheel/platforms/pyodide.py
@@ -426,10 +426,6 @@ def build(options: Options, tmp_path: Path) -> None:
build_options = options.build_options(config.identifier)
build_frontend = build_options.build_frontend
- if build_frontend.name == "pip":
- msg = "The pyodide platform doesn't support pip frontend"
- raise errors.FatalError(msg)
-
log.build_start(config.identifier)
identifier_tmp_dir = tmp_path / config.identifier
@@ -477,7 +473,7 @@ def build(options: Options, tmp_path: Path) -> None:
print(
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
)
- built_wheel = compatible_wheel
+ repaired_wheel = compatible_wheel
else:
if build_options.before_build:
log.step("Running before_build...")
@@ -493,7 +489,7 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.build_verbosity,
prepare_config_settings(
build_options.config_settings,
- project=".",
+ project=Path.cwd(),
package=build_options.package_dir,
),
)
diff --git a/cibuildwheel/platforms/windows.py b/cibuildwheel/platforms/windows.py
index bd6cb3a5..fe61e762 100644
--- a/cibuildwheel/platforms/windows.py
+++ b/cibuildwheel/platforms/windows.py
@@ -81,8 +81,6 @@ def get_nuget_args(
package_name,
"-Version",
version,
- "-FallbackSource",
- "https://api.nuget.org/v3/index.json",
"-OutputDirectory",
str(output_directory),
]
@@ -401,6 +399,9 @@ def setup_python(
*constraint_flags(dependency_constraint),
env=env,
)
+ case "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is not supported on this platform"
+ raise errors.FatalError(msg)
case _:
assert_never(build_frontend)
@@ -489,7 +490,7 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.build_verbosity,
prepare_config_settings(
build_options.config_settings,
- project=".",
+ project=Path.cwd(),
package=options.globals.package_dir,
),
)
@@ -539,6 +540,9 @@ def build(options: Options, tmp_path: Path) -> None:
*extra_flags,
env=env,
)
+ case "pyodide-build":
+ msg = "The 'pyodide-build' build frontend is not supported on this platform"
+ raise errors.FatalError(msg)
case _:
assert_never(build_frontend)
diff --git a/cibuildwheel/projectfiles.py b/cibuildwheel/projectfiles.py
index ecc6a213..185d2a74 100644
--- a/cibuildwheel/projectfiles.py
+++ b/cibuildwheel/projectfiles.py
@@ -60,6 +60,8 @@ class Analyzer(ast.NodeVisitor):
case ast.keyword(arg="python_requires", value=ast.Constant(value=str() as version)):
if unnested or name_main_unnested:
self.requires_python = version
+ case _:
+ pass
def setup_py_python_requires(content: str) -> str | None:
@@ -68,7 +70,7 @@ def setup_py_python_requires(content: str) -> str | None:
analyzer = Analyzer()
analyzer.visit(tree)
return analyzer.requires_python or None
- except Exception: # pylint: disable=broad-except
+ except Exception: # noqa: BLE001
return None
diff --git a/cibuildwheel/resources/android/android.patch b/cibuildwheel/resources/android/android.patch
deleted file mode 100644
index f2d6ff98..00000000
--- a/cibuildwheel/resources/android/android.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/android.py
-+++ b/android.py
-@@ -1021,7 +1021,7 @@ def main():
- context = parse_args()
-
- # Set the CROSS_BUILD_DIR if an argument was provided
-- if context.cross_build_dir:
-+ if getattr(context, "cross_build_dir", None):
- global CROSS_BUILD_DIR
- CROSS_BUILD_DIR = context.cross_build_dir.resolve()
-
diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml
index be8df333..515fb8d0 100644
--- a/cibuildwheel/resources/build-platforms.toml
+++ b/cibuildwheel/resources/build-platforms.toml
@@ -153,27 +153,27 @@ python_configurations = [
{ identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.10/python-3.12.10-macos11.pkg", sha256 = "8373e58da4ea146b3eb1c1f9834f19a319440b6b679b06050b1f9ee3237aa8e4" },
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.10/python-3.12.10-macos11.pkg", sha256 = "8373e58da4ea146b3eb1c1f9834f19a319440b6b679b06050b1f9ee3237aa8e4" },
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.10/python-3.12.10-macos11.pkg", sha256 = "8373e58da4ea146b3eb1c1f9834f19a319440b6b679b06050b1f9ee3237aa8e4" },
- { identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.13/python-3.13.13-macos11.pkg", sha256 = "a909cb655af5db67d5a90b3603437a1d58bec3446d624e4034e278ac62023cc9" },
- { identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.13/python-3.13.13-macos11.pkg", sha256 = "a909cb655af5db67d5a90b3603437a1d58bec3446d624e4034e278ac62023cc9" },
- { identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.13/python-3.13.13-macos11.pkg", sha256 = "a909cb655af5db67d5a90b3603437a1d58bec3446d624e4034e278ac62023cc9" },
- { identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg", sha256 = "b28a8dc33c456dd06c97024697d63ca916cfb494594c06fa3e4ef4d41fa82335" },
- { identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg", sha256 = "b28a8dc33c456dd06c97024697d63ca916cfb494594c06fa3e4ef4d41fa82335" },
- { identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg", sha256 = "b28a8dc33c456dd06c97024697d63ca916cfb494594c06fa3e4ef4d41fa82335" },
- { identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg", sha256 = "b28a8dc33c456dd06c97024697d63ca916cfb494594c06fa3e4ef4d41fa82335" },
- { identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg", sha256 = "b28a8dc33c456dd06c97024697d63ca916cfb494594c06fa3e4ef4d41fa82335" },
- { identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-macos11.pkg", sha256 = "b28a8dc33c456dd06c97024697d63ca916cfb494594c06fa3e4ef4d41fa82335" },
- { identifier = "cp315-macosx_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-macos11.pkg", sha256 = "29b5c95f255f846f77e1c119146836445f929de1392a3ae9ef24f559e1345418" },
- { identifier = "cp315-macosx_arm64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-macos11.pkg", sha256 = "29b5c95f255f846f77e1c119146836445f929de1392a3ae9ef24f559e1345418" },
- { identifier = "cp315-macosx_universal2", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-macos11.pkg", sha256 = "29b5c95f255f846f77e1c119146836445f929de1392a3ae9ef24f559e1345418" },
- { identifier = "cp315t-macosx_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-macos11.pkg", sha256 = "29b5c95f255f846f77e1c119146836445f929de1392a3ae9ef24f559e1345418" },
- { identifier = "cp315t-macosx_arm64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-macos11.pkg", sha256 = "29b5c95f255f846f77e1c119146836445f929de1392a3ae9ef24f559e1345418" },
- { identifier = "cp315t-macosx_universal2", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-macos11.pkg", sha256 = "29b5c95f255f846f77e1c119146836445f929de1392a3ae9ef24f559e1345418" },
- { identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2", sha256 = "fda015431621e7e5aa16359d114f2c45a77ed936992c1efff86302e768a6b21c" },
- { identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2", sha256 = "88f824e7a2d676440d09bc90fc959ae0fd3557d7e2f14bfbbe53d41d159a47fe" },
- { identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_x86_64.tar.bz2", sha256 = "2c5e5c2a33ac882551d7f28b98d19d486b8995aa50824a73b4edcc6aeec35c63" },
- { identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_arm64.tar.bz2", sha256 = "3db8a03fc496164801646844d7f3b12baa0adb3ad9a0b7cb124521bc2e168a36" },
- { identifier = "pp311-macosx_x86_64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.23-macos_x86_64.tar.bz2", sha256 = "c95363c4e87235d11a6cec8128239c291b1eb67a752778fbcfe029a71da82b5e" },
- { identifier = "pp311-macosx_arm64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.23-macos_arm64.tar.bz2", sha256 = "4747b3aceba4c1c6104cddc0fe5ea302101d32955f0957347b9ecc4fbd7aed05" },
+ { identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.15/python-3.13.15-macos11.pkg", sha256 = "3b7eaf7f29825f796e8267024435540ddf1f17fc9a97ad58095daa7a75bfdcd3" },
+ { identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.15/python-3.13.15-macos11.pkg", sha256 = "3b7eaf7f29825f796e8267024435540ddf1f17fc9a97ad58095daa7a75bfdcd3" },
+ { identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.15/python-3.13.15-macos11.pkg", sha256 = "3b7eaf7f29825f796e8267024435540ddf1f17fc9a97ad58095daa7a75bfdcd3" },
+ { identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-macos11.pkg", sha256 = "70c5239ad2d62925d2947e46921d0ddd3d35be3d2f0a2d50db33da507dbcb419" },
+ { identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-macos11.pkg", sha256 = "70c5239ad2d62925d2947e46921d0ddd3d35be3d2f0a2d50db33da507dbcb419" },
+ { identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-macos11.pkg", sha256 = "70c5239ad2d62925d2947e46921d0ddd3d35be3d2f0a2d50db33da507dbcb419" },
+ { identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-macos11.pkg", sha256 = "70c5239ad2d62925d2947e46921d0ddd3d35be3d2f0a2d50db33da507dbcb419" },
+ { identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-macos11.pkg", sha256 = "70c5239ad2d62925d2947e46921d0ddd3d35be3d2f0a2d50db33da507dbcb419" },
+ { identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-macos11.pkg", sha256 = "70c5239ad2d62925d2947e46921d0ddd3d35be3d2f0a2d50db33da507dbcb419" },
+ { identifier = "cp315-macosx_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-macos11.pkg", sha256 = "3d4e5812c66f7ea950ea91e3673f24373f4abae75333b4f705158e8d73483d6f" },
+ { identifier = "cp315-macosx_arm64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-macos11.pkg", sha256 = "3d4e5812c66f7ea950ea91e3673f24373f4abae75333b4f705158e8d73483d6f" },
+ { identifier = "cp315-macosx_universal2", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-macos11.pkg", sha256 = "3d4e5812c66f7ea950ea91e3673f24373f4abae75333b4f705158e8d73483d6f" },
+ { identifier = "cp315t-macosx_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-macos11.pkg", sha256 = "3d4e5812c66f7ea950ea91e3673f24373f4abae75333b4f705158e8d73483d6f" },
+ { identifier = "cp315t-macosx_arm64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-macos11.pkg", sha256 = "3d4e5812c66f7ea950ea91e3673f24373f4abae75333b4f705158e8d73483d6f" },
+ { identifier = "cp315t-macosx_universal2", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-macos11.pkg", sha256 = "3d4e5812c66f7ea950ea91e3673f24373f4abae75333b4f705158e8d73483d6f" },
+ { identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.gz", sha256 = "7ea762a1b0af7545a74cd4260bb3fd2812813deffef2ef8d2fddd5e03fa63ef1" },
+ { identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.gz", sha256 = "b09ce3a865c1c0f4e58c0ee4f70511f1b27dfc1f7148f4b6060cfdfd581c9e82" },
+ { identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_x86_64.tar.gz", sha256 = "63f9d30cdd9e47cfe279be941975ac3d24e46c79756cd1d1bd2c551c27d8b32c" },
+ { identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_arm64.tar.gz", sha256 = "72a74cf645e43608f7d88831581fb0f8e1f963fb38f0793bacd37d5018a9aeb8" },
+ { identifier = "pp311-macosx_x86_64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.23-macos_x86_64.tar.gz", sha256 = "798279b0f233893ae22754290aedf35a1aea1ec9013a8ad8110f166d85944c91" },
+ { identifier = "pp311-macosx_arm64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.23-macos_arm64.tar.gz", sha256 = "f837b3c203d60d7e25a31e267671a07ba0c9b9ac8081ad225571fb06fccf1b7b" },
{ identifier = "gp312_250-macosx_x86_64", version = "3.12", url = "https://github.com/oracle/graalpython/releases/download/graal-25.0.1/graalpy-25.0.1-macos-amd64.tar.gz", sha256 = "10b0721d52397f0cc85f038900318da2203711cbcfae7899e3faed49d3dc6221" },
{ identifier = "gp312_250-macosx_arm64", version = "3.12", url = "https://github.com/oracle/graalpython/releases/download/graal-25.0.3/graalpy-25.0.3-macos-aarch64.tar.gz", sha256 = "387d9f5b376860842bea4d55aae5820974f3f3b68fc36c77ae863a061a888857" },
]
@@ -188,25 +188,25 @@ python_configurations = [
{ identifier = "cp311-win_amd64", version = "3.11.9" },
{ identifier = "cp312-win32", version = "3.12.10" },
{ identifier = "cp312-win_amd64", version = "3.12.10" },
- { identifier = "cp313-win32", version = "3.13.13" },
- { identifier = "cp313-win_amd64", version = "3.13.13" },
- { identifier = "cp314-win32", version = "3.14.5" },
- { identifier = "cp314t-win32", version = "3.14.5" },
- { identifier = "cp314-win_amd64", version = "3.14.5" },
- { identifier = "cp314t-win_amd64", version = "3.14.5" },
- { identifier = "cp315-win32", version = "3.15.0-b2" },
- { identifier = "cp315t-win32", version = "3.15.0-b2" },
- { identifier = "cp315-win_amd64", version = "3.15.0-b2" },
- { identifier = "cp315t-win_amd64", version = "3.15.0-b2" },
+ { identifier = "cp313-win32", version = "3.13.15" },
+ { identifier = "cp313-win_amd64", version = "3.13.15" },
+ { identifier = "cp314-win32", version = "3.14.7" },
+ { identifier = "cp314t-win32", version = "3.14.7" },
+ { identifier = "cp314-win_amd64", version = "3.14.7" },
+ { identifier = "cp314t-win_amd64", version = "3.14.7" },
+ { identifier = "cp315-win32", version = "3.15.0-rc2" },
+ { identifier = "cp315t-win32", version = "3.15.0-rc2" },
+ { identifier = "cp315-win_amd64", version = "3.15.0-rc2" },
+ { identifier = "cp315t-win_amd64", version = "3.15.0-rc2" },
{ identifier = "cp39-win_arm64", version = "3.9.10" },
{ identifier = "cp310-win_arm64", version = "3.10.11" },
{ identifier = "cp311-win_arm64", version = "3.11.9" },
{ identifier = "cp312-win_arm64", version = "3.12.10" },
- { identifier = "cp313-win_arm64", version = "3.13.13" },
- { identifier = "cp314-win_arm64", version = "3.14.5" },
- { identifier = "cp314t-win_arm64", version = "3.14.5" },
- { identifier = "cp315-win_arm64", version = "3.15.0-b2" },
- { identifier = "cp315t-win_arm64", version = "3.15.0-b2" },
+ { identifier = "cp313-win_arm64", version = "3.13.15" },
+ { identifier = "cp314-win_arm64", version = "3.14.7" },
+ { identifier = "cp314t-win_arm64", version = "3.14.7" },
+ { identifier = "cp315-win_arm64", version = "3.15.0-rc2" },
+ { identifier = "cp315t-win_arm64", version = "3.15.0-rc2" },
{ identifier = "pp39-win_amd64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip", sha256 = "06ec12a5e964dc0ad33e6f380185a4d295178dce6d6df512f508e7aee00a1323" },
{ identifier = "pp310-win_amd64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-win64.zip", sha256 = "c0d07bba6c8fb4e5804f4a8b3f8ef07cc3d89f6ad1db42a45ffb9be60bbb7cc2" },
{ identifier = "pp311-win_amd64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.23-win64.zip", sha256 = "948b8ea58dea5b9917210fe4afd242c788fbfaba1c3f1a25e696a404f703389a" },
@@ -217,28 +217,29 @@ python_configurations = [
python_configurations = [
{ identifier = "cp312-pyodide_wasm32", version = "3.12", default_pyodide_version = "0.27.7", node_version = "v22", sha256 = "0c2e7db42efa5d1dac38b50f8b3d659a1e3885d0a233494831b8206281307d52" },
{ identifier = "cp313-pyodide_wasm32", version = "3.13", default_pyodide_version = "0.29.4", node_version = "v22", sha256 = "a29fc4a076408a18fc29eb4b280f80c6dddc95c19514c874c29e590d0931c02a" },
- { identifier = "cp314-pyodide_wasm32", version = "3.14", default_pyodide_version = "314.0.0", node_version = "v24", sha256 = "6e76cf18251bd7d046bdb7ef35c9f938c8e995f10d88397497ca4b7020f27ba6" },
+ { identifier = "cp314-pyodide_wasm32", version = "3.14", default_pyodide_version = "314.0.6", node_version = "v24", sha256 = "8ae243c193895fd200e63df38975026ab41f693381067018a1b9d4db9c3783f7" },
+ { identifier = "cp315-pyodide_wasm32", version = "3.15", default_pyodide_version = "315.0.0a2", node_version = "v24", sha256 = "d7c0d6ddf0fce807668d7413d0e0f20fbc7922128ba8361ed71d9cff048cb96a" },
]
[android]
python_configurations = [
- { identifier = "cp313-android_arm64_v8a", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.13/python-3.13.13-aarch64-linux-android.tar.gz", sha256 = "a21250c246b36eb704be096be51e40ab24cafa3ae1d7ca4c396e6bf780cf87cf" },
- { identifier = "cp313-android_x86_64", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.13/python-3.13.13-x86_64-linux-android.tar.gz", sha256 = "b021b76df2c8d64e41c76d18a2d91f27652356bd932c06f9076bac1b664c0e37" },
- { identifier = "cp314-android_arm64_v8a", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-aarch64-linux-android.tar.gz", sha256 = "f008321abf837fcaec569df143283ece0e764b18d8c75763200160553f906af1" },
- { identifier = "cp314-android_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.5/python-3.14.5-x86_64-linux-android.tar.gz", sha256 = "36184e31464b2b959d92c81ded8d025834342cc080623bced282a2a9a57bd47c" },
- { identifier = "cp315-android_arm64_v8a", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-aarch64-linux-android.tar.gz", sha256 = "de5e36ffc3c33b63a1ed53fe83db4dee16b003a3180ac35e5c4c203d3750e076" },
- { identifier = "cp315-android_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-x86_64-linux-android.tar.gz", sha256 = "e05ef9c142ea83b41b194b16014ffe2249d27783313c3b00b97f6c93d9a56b92" },
+ { identifier = "cp313-android_arm64_v8a", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.15/python-3.13.15-aarch64-linux-android.tar.gz", sha256 = "a51d1e153f68f1c40f612a5431e9f79870d993da795173b3d27564e42b056271" },
+ { identifier = "cp313-android_x86_64", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.15/python-3.13.15-x86_64-linux-android.tar.gz", sha256 = "2096ecd6e180274ad1637cf140f7d6c2a160fe5ef9bfb47fd318e3d963f2d929" },
+ { identifier = "cp314-android_arm64_v8a", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-aarch64-linux-android.tar.gz", sha256 = "6d50cc3aa66e414a439594089bcdfb5f1264358155c70c1f00471c24cfb477fb" },
+ { identifier = "cp314-android_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.7/python-3.14.7-x86_64-linux-android.tar.gz", sha256 = "2c16ce2359565cd8c24f86cfb75630768ba6607e732946b294b969797f583b60" },
+ { identifier = "cp315-android_arm64_v8a", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-aarch64-linux-android.tar.gz", sha256 = "642f40c4f12b401f4d6eed32851dec2b8d003188af6fead70ea0dc0ee0fc00ae" },
+ { identifier = "cp315-android_x86_64", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-x86_64-linux-android.tar.gz", sha256 = "a5a5f9296ba977f29025fc2391b053868a51457b229fffff1cc469f78af5bfc8" },
]
[ios]
python_configurations = [
- { identifier = "cp313-ios_arm64_iphoneos", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b13/Python-3.13-iOS-support.b13.tar.gz", sha256 = "d1f95f95137a4b91dc0cbe9b99ddfc0a78918dde883c7fbe7147074a5e715274" },
- { identifier = "cp313-ios_x86_64_iphonesimulator", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b13/Python-3.13-iOS-support.b13.tar.gz", sha256 = "d1f95f95137a4b91dc0cbe9b99ddfc0a78918dde883c7fbe7147074a5e715274" },
- { identifier = "cp313-ios_arm64_iphonesimulator", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b13/Python-3.13-iOS-support.b13.tar.gz", sha256 = "d1f95f95137a4b91dc0cbe9b99ddfc0a78918dde883c7fbe7147074a5e715274" },
- { identifier = "cp314-ios_arm64_iphoneos", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b9/Python-3.14-iOS-support.b9.tar.gz", sha256 = "8e4123b543bf17fdae2e2c6c033434487752438431014eb12e6d833aa35927a8" },
- { identifier = "cp314-ios_x86_64_iphonesimulator", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b9/Python-3.14-iOS-support.b9.tar.gz", sha256 = "8e4123b543bf17fdae2e2c6c033434487752438431014eb12e6d833aa35927a8" },
- { identifier = "cp314-ios_arm64_iphonesimulator", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b9/Python-3.14-iOS-support.b9.tar.gz", sha256 = "8e4123b543bf17fdae2e2c6c033434487752438431014eb12e6d833aa35927a8" },
- { identifier = "cp315-ios_arm64_iphoneos", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-iOS-XCframework.tar.gz", sha256 = "fd6b6fb8f82cf44622d28ea53b8197c89fb06505557d29d4d7a47f9386c1c896" },
- { identifier = "cp315-ios_x86_64_iphonesimulator", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-iOS-XCframework.tar.gz", sha256 = "fd6b6fb8f82cf44622d28ea53b8197c89fb06505557d29d4d7a47f9386c1c896" },
- { identifier = "cp315-ios_arm64_iphonesimulator", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0b2-iOS-XCframework.tar.gz", sha256 = "fd6b6fb8f82cf44622d28ea53b8197c89fb06505557d29d4d7a47f9386c1c896" },
+ { identifier = "cp313-ios_arm64_iphoneos", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b15/Python-3.13-iOS-support.b15.tar.gz", sha256 = "80175765a31babe43b0910395cf86ba4e8412adf1902b069d55b74d523ecc5d1" },
+ { identifier = "cp313-ios_x86_64_iphonesimulator", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b15/Python-3.13-iOS-support.b15.tar.gz", sha256 = "80175765a31babe43b0910395cf86ba4e8412adf1902b069d55b74d523ecc5d1" },
+ { identifier = "cp313-ios_arm64_iphonesimulator", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b15/Python-3.13-iOS-support.b15.tar.gz", sha256 = "80175765a31babe43b0910395cf86ba4e8412adf1902b069d55b74d523ecc5d1" },
+ { identifier = "cp314-ios_arm64_iphoneos", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b11/Python-3.14-iOS-support.b11.tar.gz", sha256 = "b591f3301bd22a4f423c49c746cac9e55558b909fd14d6eb8327ccc62234ab7b" },
+ { identifier = "cp314-ios_x86_64_iphonesimulator", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b11/Python-3.14-iOS-support.b11.tar.gz", sha256 = "b591f3301bd22a4f423c49c746cac9e55558b909fd14d6eb8327ccc62234ab7b" },
+ { identifier = "cp314-ios_arm64_iphonesimulator", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b11/Python-3.14-iOS-support.b11.tar.gz", sha256 = "b591f3301bd22a4f423c49c746cac9e55558b909fd14d6eb8327ccc62234ab7b" },
+ { identifier = "cp315-ios_arm64_iphoneos", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-iOS-XCframework.tar.gz", sha256 = "2496d92689da625cd349e856e17b3d540787f8d17806e21536e8d394d940adc0" },
+ { identifier = "cp315-ios_x86_64_iphonesimulator", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-iOS-XCframework.tar.gz", sha256 = "2496d92689da625cd349e856e17b3d540787f8d17806e21536e8d394d940adc0" },
+ { identifier = "cp315-ios_arm64_iphonesimulator", version = "3.15", url = "https://www.python.org/ftp/python/3.15.0/python-3.15.0rc2-iOS-XCframework.tar.gz", sha256 = "2496d92689da625cd349e856e17b3d540787f8d17806e21536e8d394d940adc0" },
]
diff --git a/cibuildwheel/resources/cibuildwheel.schema.json b/cibuildwheel/resources/cibuildwheel.schema.json
index 42e1925a..bd3d0ef5 100644
--- a/cibuildwheel/resources/cibuildwheel.schema.json
+++ b/cibuildwheel/resources/cibuildwheel.schema.json
@@ -18,9 +18,64 @@
"pyodide-prerelease",
"pypy",
"pypy-eol"
- ]
+ ],
+ "description": "A Python version or flavor to enable."
},
- "description": "A Python version or flavor to enable."
+ "build-frontend-no-pyodide": {
+ "default": "default",
+ "description": "Set the tool to use to build, either \"build\" (default), \"build[uv]\", \"uv\", or \"pip\"",
+ "oneOf": [
+ {
+ "enum": [
+ "pip",
+ "build",
+ "build[uv]",
+ "uv",
+ "default"
+ ]
+ },
+ {
+ "type": "string",
+ "pattern": "^pip; ?args:"
+ },
+ {
+ "type": "string",
+ "pattern": "^build; ?args:"
+ },
+ {
+ "type": "string",
+ "pattern": "^build\\[uv\\]; ?args:"
+ },
+ {
+ "type": "string",
+ "pattern": "^uv; ?args:"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "enum": [
+ "pip",
+ "build",
+ "build[uv]",
+ "uv"
+ ]
+ },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ ],
+ "title": "CIBW_BUILD_FRONTEND"
+ }
},
"additionalProperties": false,
"description": "cibuildwheel's settings.",
@@ -199,7 +254,7 @@
},
"build-frontend": {
"default": "default",
- "description": "Set the tool to use to build, either \"build\" (default), \"build[uv]\", \"uv\", or \"pip\"",
+ "description": "Set the tool to use to build, either \"build\" (default), \"build[uv]\", \"uv\", or \"pip\" (\"pyodide-build\" for pyodide)",
"oneOf": [
{
"enum": [
@@ -207,6 +262,7 @@
"build",
"build[uv]",
"uv",
+ "pyodide-build",
"default"
]
},
@@ -226,6 +282,10 @@
"type": "string",
"pattern": "^uv; ?args:"
},
+ {
+ "type": "string",
+ "pattern": "^pyodide-build; ?args:"
+ },
{
"type": "object",
"additionalProperties": false,
@@ -238,7 +298,8 @@
"pip",
"build",
"build[uv]",
- "uv"
+ "uv",
+ "pyodide-build"
]
},
"args": {
@@ -1021,7 +1082,7 @@
"$ref": "#/properties/before-test"
},
"build-frontend": {
- "$ref": "#/properties/build-frontend"
+ "$ref": "#/$defs/build-frontend-no-pyodide"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
@@ -1219,7 +1280,7 @@
"$ref": "#/properties/before-test"
},
"build-frontend": {
- "$ref": "#/properties/build-frontend"
+ "$ref": "#/$defs/build-frontend-no-pyodide"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
@@ -1363,7 +1424,7 @@
"$ref": "#/properties/before-test"
},
"build-frontend": {
- "$ref": "#/properties/build-frontend"
+ "$ref": "#/$defs/build-frontend-no-pyodide"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
@@ -1507,7 +1568,41 @@
"$ref": "#/properties/before-test"
},
"build-frontend": {
- "$ref": "#/properties/build-frontend"
+ "default": "pyodide-build",
+ "description": "On the pyodide platform, the build frontend must be \"pyodide-build\"",
+ "oneOf": [
+ {
+ "enum": [
+ "pyodide-build",
+ "default"
+ ]
+ },
+ {
+ "type": "string",
+ "pattern": "^pyodide-build; ?args:"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "name"
+ ],
+ "properties": {
+ "name": {
+ "enum": [
+ "pyodide-build"
+ ]
+ },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ }
+ }
+ ],
+ "title": "CIBW_BUILD_FRONTEND"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
@@ -1638,7 +1733,7 @@
"$ref": "#/properties/before-test"
},
"build-frontend": {
- "$ref": "#/properties/build-frontend"
+ "$ref": "#/$defs/build-frontend-no-pyodide"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
@@ -1782,7 +1877,7 @@
"$ref": "#/properties/before-test"
},
"build-frontend": {
- "$ref": "#/properties/build-frontend"
+ "$ref": "#/$defs/build-frontend-no-pyodide"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
diff --git a/cibuildwheel/resources/constraints-pyodide312.txt b/cibuildwheel/resources/constraints-pyodide312.txt
index df35bf08..f5da247c 100644
--- a/cibuildwheel/resources/constraints-pyodide312.txt
+++ b/cibuildwheel/resources/constraints-pyodide312.txt
@@ -1,29 +1,36 @@
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
-annotated-types==0.7.0
- # via pydantic
+attrs==26.1.0
+ # via
+ # cattrs
+ # pyodide-build
+ # pyodide-lock
auditwheel-emscripten==0.2.5
# via pyodide-build
build==1.5.0
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
-certifi==2026.5.20
+cattrs==26.1.0
+ # via
+ # pyodide-build
+ # pyodide-lock
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
click==8.1.8
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
# pyodide-cli
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via requests
leb128==1.0.9
# via auditwheel-emscripten
@@ -31,38 +38,31 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# auditwheel-emscripten
# build
# pyodide-build
# wheel
-pip==26.1.2
+pip==26.2.1
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
# pyodide-build
- # python-discovery
# virtualenv
-pydantic==2.13.4
- # via
- # pyodide-build
- # pyodide-lock
-pydantic-core==2.46.4
- # via pydantic
-pygments==2.20.0
+pygments==2.21.0
# via rich
-pyodide-build==0.35.0
+pyodide-build==0.39.0
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
pyodide-cli==0.5.0
# via
# auditwheel-emscripten
# pyodide-build
-pyodide-lock==0.1.3
+pyodide-lock==0.2.1
# via pyodide-build
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via pyodide-build
@@ -72,20 +72,15 @@ rich==15.0.0
# pyodide-cli
ruamel-yaml==0.19.1
# via pyodide-build
-typing-extensions==4.15.0
- # via
- # pydantic
- # pydantic-core
- # typing-inspection
-typing-inspection==0.4.2
- # via pydantic
+typing-extensions==4.16.0
+ # via cattrs
urllib3==2.7.0
# via requests
-virtualenv==21.4.2
+virtualenv==21.7.8
# via
# build
# pyodide-build
-wheel==0.47.0
+wheel==0.48.0
# via
# auditwheel-emscripten
# pyodide-build
diff --git a/cibuildwheel/resources/constraints-pyodide313.txt b/cibuildwheel/resources/constraints-pyodide313.txt
index df35bf08..f5da247c 100644
--- a/cibuildwheel/resources/constraints-pyodide313.txt
+++ b/cibuildwheel/resources/constraints-pyodide313.txt
@@ -1,29 +1,36 @@
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
-annotated-types==0.7.0
- # via pydantic
+attrs==26.1.0
+ # via
+ # cattrs
+ # pyodide-build
+ # pyodide-lock
auditwheel-emscripten==0.2.5
# via pyodide-build
build==1.5.0
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
-certifi==2026.5.20
+cattrs==26.1.0
+ # via
+ # pyodide-build
+ # pyodide-lock
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
click==8.1.8
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
# pyodide-cli
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via requests
leb128==1.0.9
# via auditwheel-emscripten
@@ -31,38 +38,31 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# auditwheel-emscripten
# build
# pyodide-build
# wheel
-pip==26.1.2
+pip==26.2.1
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
# pyodide-build
- # python-discovery
# virtualenv
-pydantic==2.13.4
- # via
- # pyodide-build
- # pyodide-lock
-pydantic-core==2.46.4
- # via pydantic
-pygments==2.20.0
+pygments==2.21.0
# via rich
-pyodide-build==0.35.0
+pyodide-build==0.39.0
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
pyodide-cli==0.5.0
# via
# auditwheel-emscripten
# pyodide-build
-pyodide-lock==0.1.3
+pyodide-lock==0.2.1
# via pyodide-build
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via pyodide-build
@@ -72,20 +72,15 @@ rich==15.0.0
# pyodide-cli
ruamel-yaml==0.19.1
# via pyodide-build
-typing-extensions==4.15.0
- # via
- # pydantic
- # pydantic-core
- # typing-inspection
-typing-inspection==0.4.2
- # via pydantic
+typing-extensions==4.16.0
+ # via cattrs
urllib3==2.7.0
# via requests
-virtualenv==21.4.2
+virtualenv==21.7.8
# via
# build
# pyodide-build
-wheel==0.47.0
+wheel==0.48.0
# via
# auditwheel-emscripten
# pyodide-build
diff --git a/cibuildwheel/resources/constraints-pyodide314.txt b/cibuildwheel/resources/constraints-pyodide314.txt
index df35bf08..f5da247c 100644
--- a/cibuildwheel/resources/constraints-pyodide314.txt
+++ b/cibuildwheel/resources/constraints-pyodide314.txt
@@ -1,29 +1,36 @@
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
-annotated-types==0.7.0
- # via pydantic
+attrs==26.1.0
+ # via
+ # cattrs
+ # pyodide-build
+ # pyodide-lock
auditwheel-emscripten==0.2.5
# via pyodide-build
build==1.5.0
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
-certifi==2026.5.20
+cattrs==26.1.0
+ # via
+ # pyodide-build
+ # pyodide-lock
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
click==8.1.8
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
# pyodide-cli
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via requests
leb128==1.0.9
# via auditwheel-emscripten
@@ -31,38 +38,31 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# auditwheel-emscripten
# build
# pyodide-build
# wheel
-pip==26.1.2
+pip==26.2.1
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
# pyodide-build
- # python-discovery
# virtualenv
-pydantic==2.13.4
- # via
- # pyodide-build
- # pyodide-lock
-pydantic-core==2.46.4
- # via pydantic
-pygments==2.20.0
+pygments==2.21.0
# via rich
-pyodide-build==0.35.0
+pyodide-build==0.39.0
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
pyodide-cli==0.5.0
# via
# auditwheel-emscripten
# pyodide-build
-pyodide-lock==0.1.3
+pyodide-lock==0.2.1
# via pyodide-build
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via pyodide-build
@@ -72,20 +72,15 @@ rich==15.0.0
# pyodide-cli
ruamel-yaml==0.19.1
# via pyodide-build
-typing-extensions==4.15.0
- # via
- # pydantic
- # pydantic-core
- # typing-inspection
-typing-inspection==0.4.2
- # via pydantic
+typing-extensions==4.16.0
+ # via cattrs
urllib3==2.7.0
# via requests
-virtualenv==21.4.2
+virtualenv==21.7.8
# via
# build
# pyodide-build
-wheel==0.47.0
+wheel==0.48.0
# via
# auditwheel-emscripten
# pyodide-build
diff --git a/cibuildwheel/resources/constraints-pyodide315.txt b/cibuildwheel/resources/constraints-pyodide315.txt
new file mode 100644
index 00000000..f5da247c
--- /dev/null
+++ b/cibuildwheel/resources/constraints-pyodide315.txt
@@ -0,0 +1,86 @@
+# This file was autogenerated by uv via the following command:
+# nox -s update_constraints
+attrs==26.1.0
+ # via
+ # cattrs
+ # pyodide-build
+ # pyodide-lock
+auditwheel-emscripten==0.2.5
+ # via pyodide-build
+build==1.5.0
+ # via
+ # -r .nox/update_constraints/tmp/constraints-pyodide.in
+ # pyodide-build
+cattrs==26.1.0
+ # via
+ # pyodide-build
+ # pyodide-lock
+certifi==2026.7.22
+ # via requests
+charset-normalizer==3.5.1
+ # via requests
+click==8.1.8
+ # via
+ # -r .nox/update_constraints/tmp/constraints-pyodide.in
+ # pyodide-build
+ # pyodide-cli
+distlib==0.4.3
+ # via virtualenv
+filelock==3.32.5
+ # via
+ # python-discovery
+ # virtualenv
+idna==3.19
+ # via requests
+leb128==1.0.9
+ # via auditwheel-emscripten
+markdown-it-py==4.2.0
+ # via rich
+mdurl==0.1.2
+ # via markdown-it-py
+packaging==26.3
+ # via
+ # auditwheel-emscripten
+ # build
+ # pyodide-build
+ # wheel
+pip==26.2.1
+ # via -r .nox/update_constraints/tmp/constraints-pyodide.in
+platformdirs==4.11.7
+ # via
+ # pyodide-build
+ # virtualenv
+pygments==2.21.0
+ # via rich
+pyodide-build==0.39.0
+ # via -r .nox/update_constraints/tmp/constraints-pyodide.in
+pyodide-cli==0.5.0
+ # via
+ # auditwheel-emscripten
+ # pyodide-build
+pyodide-lock==0.2.1
+ # via pyodide-build
+pyproject-hooks==1.2.0
+ # via build
+python-discovery==1.6.0
+ # via virtualenv
+requests==2.34.2
+ # via pyodide-build
+rich==15.0.0
+ # via
+ # pyodide-build
+ # pyodide-cli
+ruamel-yaml==0.19.1
+ # via pyodide-build
+typing-extensions==4.16.0
+ # via cattrs
+urllib3==2.7.0
+ # via requests
+virtualenv==21.7.8
+ # via
+ # build
+ # pyodide-build
+wheel==0.48.0
+ # via
+ # auditwheel-emscripten
+ # pyodide-build
diff --git a/cibuildwheel/resources/constraints-python310.txt b/cibuildwheel/resources/constraints-python310.txt
index ad97db8b..5b3fd726 100644
--- a/cibuildwheel/resources/constraints-python310.txt
+++ b/cibuildwheel/resources/constraints-python310.txt
@@ -10,33 +10,33 @@ attrs==26.1.0
# via
# cattrs
# requests-cache
-auditwheel==6.7.0
+auditwheel==6.8.2
# via -r cibuildwheel/resources/constraints.in
build==1.5.0
# via -r cibuildwheel/resources/constraints.in
cattrs==26.1.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
exceptiongroup==1.3.1
# via cattrs
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
-importlib-metadata==9.0.0
+importlib-metadata==9.0.1
# via build
kaitaistruct==0.11
# via abi3audit
@@ -46,48 +46,47 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# abi3audit
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
# abi3audit
# delvewheel
-pip==26.1.2
+pip==26.2.1
# via -r cibuildwheel/resources/constraints.in
-pkgconf==2.5.1.post2
+pkgconf==3.0.1.post0
# via -r cibuildwheel/resources/constraints.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.33
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via
# abi3audit
# requests-cache
-requests-cache==1.3.2
+requests-cache==1.3.3
# via abi3audit
rich==15.0.0
# via abi3audit
tomli==2.4.1
# via build
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -99,7 +98,7 @@ urllib3==2.7.0
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
zipp==4.1.0
# via importlib-metadata
diff --git a/cibuildwheel/resources/constraints-python311.txt b/cibuildwheel/resources/constraints-python311.txt
index 82caa3a3..1b574bb3 100644
--- a/cibuildwheel/resources/constraints-python311.txt
+++ b/cibuildwheel/resources/constraints-python311.txt
@@ -10,27 +10,27 @@ attrs==26.1.0
# via
# cattrs
# requests-cache
-auditwheel==6.7.0
+auditwheel==6.8.2
# via -r cibuildwheel/resources/constraints.in
build==1.5.0
# via -r cibuildwheel/resources/constraints.in
cattrs==26.1.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
@@ -42,47 +42,45 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# abi3audit
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
# abi3audit
# delvewheel
-pip==26.1.2; implementation_name != "graalpy" or platform_system != "Windows"
-pip==26.0.1; implementation_name == "graalpy" and platform_system == "Windows"
+pip==26.2.1
# via -r cibuildwheel/resources/constraints.in
-pkgconf==2.5.1.post2
+pkgconf==3.0.1.post0
# via -r cibuildwheel/resources/constraints.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.33
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via
# abi3audit
# requests-cache
-requests-cache==1.3.2
+requests-cache==1.3.3
# via abi3audit
rich==15.0.0
# via abi3audit
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -92,5 +90,5 @@ urllib3==2.7.0
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
diff --git a/cibuildwheel/resources/constraints-python312.txt b/cibuildwheel/resources/constraints-python312.txt
index 82caa3a3..f87d5a12 100644
--- a/cibuildwheel/resources/constraints-python312.txt
+++ b/cibuildwheel/resources/constraints-python312.txt
@@ -10,27 +10,28 @@ attrs==26.1.0
# via
# cattrs
# requests-cache
-auditwheel==6.7.0
+auditwheel==6.8.2
# via -r cibuildwheel/resources/constraints.in
build==1.5.0
# via -r cibuildwheel/resources/constraints.in
cattrs==26.1.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5; implementation_name != "graalpy"
+filelock==3.29.7; implementation_name == "graalpy"
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
@@ -42,47 +43,47 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# abi3audit
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
# abi3audit
# delvewheel
-pip==26.1.2; implementation_name != "graalpy" or platform_system != "Windows"
+pip==26.2.1; implementation_name != "graalpy"
+pip==26.1.2; implementation_name == "graalpy" and platform_system != "Windows"
pip==26.0.1; implementation_name == "graalpy" and platform_system == "Windows"
# via -r cibuildwheel/resources/constraints.in
-pkgconf==2.5.1.post2
+pkgconf==3.0.1.post0
# via -r cibuildwheel/resources/constraints.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.33
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via
# abi3audit
# requests-cache
-requests-cache==1.3.2
+requests-cache==1.3.3
# via abi3audit
rich==15.0.0
# via abi3audit
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -92,5 +93,5 @@ urllib3==2.7.0
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
diff --git a/cibuildwheel/resources/constraints-python313.txt b/cibuildwheel/resources/constraints-python313.txt
index dcbde5aa..1b574bb3 100644
--- a/cibuildwheel/resources/constraints-python313.txt
+++ b/cibuildwheel/resources/constraints-python313.txt
@@ -10,27 +10,27 @@ attrs==26.1.0
# via
# cattrs
# requests-cache
-auditwheel==6.7.0
+auditwheel==6.8.2
# via -r cibuildwheel/resources/constraints.in
build==1.5.0
# via -r cibuildwheel/resources/constraints.in
cattrs==26.1.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
@@ -42,46 +42,45 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# abi3audit
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
# abi3audit
# delvewheel
-pip==26.1.2
+pip==26.2.1
# via -r cibuildwheel/resources/constraints.in
-pkgconf==2.5.1.post2
+pkgconf==3.0.1.post0
# via -r cibuildwheel/resources/constraints.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.33
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via
# abi3audit
# requests-cache
-requests-cache==1.3.2
+requests-cache==1.3.3
# via abi3audit
rich==15.0.0
# via abi3audit
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -91,5 +90,5 @@ urllib3==2.7.0
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
diff --git a/cibuildwheel/resources/constraints-python314.txt b/cibuildwheel/resources/constraints-python314.txt
index dcbde5aa..1b574bb3 100644
--- a/cibuildwheel/resources/constraints-python314.txt
+++ b/cibuildwheel/resources/constraints-python314.txt
@@ -10,27 +10,27 @@ attrs==26.1.0
# via
# cattrs
# requests-cache
-auditwheel==6.7.0
+auditwheel==6.8.2
# via -r cibuildwheel/resources/constraints.in
build==1.5.0
# via -r cibuildwheel/resources/constraints.in
cattrs==26.1.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
@@ -42,46 +42,45 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# abi3audit
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
# abi3audit
# delvewheel
-pip==26.1.2
+pip==26.2.1
# via -r cibuildwheel/resources/constraints.in
-pkgconf==2.5.1.post2
+pkgconf==3.0.1.post0
# via -r cibuildwheel/resources/constraints.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.33
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via
# abi3audit
# requests-cache
-requests-cache==1.3.2
+requests-cache==1.3.3
# via abi3audit
rich==15.0.0
# via abi3audit
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -91,5 +90,5 @@ urllib3==2.7.0
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
diff --git a/cibuildwheel/resources/constraints-python315.txt b/cibuildwheel/resources/constraints-python315.txt
index dcbde5aa..1b574bb3 100644
--- a/cibuildwheel/resources/constraints-python315.txt
+++ b/cibuildwheel/resources/constraints-python315.txt
@@ -10,27 +10,27 @@ attrs==26.1.0
# via
# cattrs
# requests-cache
-auditwheel==6.7.0
+auditwheel==6.8.2
# via -r cibuildwheel/resources/constraints.in
build==1.5.0
# via -r cibuildwheel/resources/constraints.in
cattrs==26.1.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
@@ -42,46 +42,45 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# abi3audit
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
# abi3audit
# delvewheel
-pip==26.1.2
+pip==26.2.1
# via -r cibuildwheel/resources/constraints.in
-pkgconf==2.5.1.post2
+pkgconf==3.0.1.post0
# via -r cibuildwheel/resources/constraints.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.33
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via
# abi3audit
# requests-cache
-requests-cache==1.3.2
+requests-cache==1.3.3
# via abi3audit
rich==15.0.0
# via abi3audit
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -91,5 +90,5 @@ urllib3==2.7.0
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
diff --git a/cibuildwheel/resources/constraints-python39.txt b/cibuildwheel/resources/constraints-python39.txt
index bbbf0a1b..b81d690a 100644
--- a/cibuildwheel/resources/constraints-python39.txt
+++ b/cibuildwheel/resources/constraints-python39.txt
@@ -16,15 +16,15 @@ build==1.4.4
# via -r cibuildwheel/resources/constraints.in
cattrs==25.3.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
exceptiongroup==1.3.1
# via cattrs
@@ -32,7 +32,7 @@ filelock==3.19.1
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
@@ -54,7 +54,7 @@ packaging==25.0
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
@@ -66,18 +66,17 @@ pkgconf==2.4.3.post2
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.4.0
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.32
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.32.5
# via
@@ -89,7 +88,7 @@ rich==14.2.0
# via abi3audit
tomli==2.4.1
# via build
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -101,7 +100,7 @@ urllib3==2.6.3
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
zipp==3.23.1
# via importlib-metadata
diff --git a/cibuildwheel/resources/constraints.txt b/cibuildwheel/resources/constraints.txt
index dcbde5aa..1b574bb3 100644
--- a/cibuildwheel/resources/constraints.txt
+++ b/cibuildwheel/resources/constraints.txt
@@ -10,27 +10,27 @@ attrs==26.1.0
# via
# cattrs
# requests-cache
-auditwheel==6.7.0
+auditwheel==6.8.2
# via -r cibuildwheel/resources/constraints.in
build==1.5.0
# via -r cibuildwheel/resources/constraints.in
cattrs==26.1.0
# via requests-cache
-certifi==2026.5.20
+certifi==2026.7.22
# via requests
-charset-normalizer==3.4.7
+charset-normalizer==3.5.1
# via requests
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
-delvewheel==1.13.0
+delvewheel==1.13.1
# via -r cibuildwheel/resources/constraints.in
-distlib==0.4.1
+distlib==0.4.3
# via virtualenv
-filelock==3.29.1
+filelock==3.32.5
# via
# python-discovery
# virtualenv
-idna==3.18
+idna==3.19
# via
# requests
# url-normalize
@@ -42,46 +42,45 @@ markdown-it-py==4.2.0
# via rich
mdurl==0.1.2
# via markdown-it-py
-packaging==26.2
+packaging==26.3
# via
# abi3audit
# auditwheel
# build
# delocate
-patchelf==0.17.2.4
+patchelf==0.19.1.0
# via -r cibuildwheel/resources/constraints.in
pefile==2024.8.26
# via
# abi3audit
# delvewheel
-pip==26.1.2
+pip==26.2.1
# via -r cibuildwheel/resources/constraints.in
-pkgconf==2.5.1.post2
+pkgconf==3.0.1.post0
# via -r cibuildwheel/resources/constraints.in
-platformdirs==4.10.0
+platformdirs==4.11.7
# via
- # python-discovery
# requests-cache
# virtualenv
pyelftools==0.33
# via
# abi3audit
# auditwheel
-pygments==2.20.0
+pygments==2.21.0
# via rich
pyproject-hooks==1.2.0
# via build
-python-discovery==1.4.0
+python-discovery==1.6.0
# via virtualenv
requests==2.34.2
# via
# abi3audit
# requests-cache
-requests-cache==1.3.2
+requests-cache==1.3.3
# via abi3audit
rich==15.0.0
# via abi3audit
-typing-extensions==4.15.0
+typing-extensions==4.16.0
# via
# cattrs
# delocate
@@ -91,5 +90,5 @@ urllib3==2.7.0
# via
# requests
# requests-cache
-virtualenv==21.4.2
+virtualenv==21.7.8
# via -r cibuildwheel/resources/constraints.in
diff --git a/cibuildwheel/resources/defaults.toml b/cibuildwheel/resources/defaults.toml
index 0a46e945..4024697a 100644
--- a/cibuildwheel/resources/defaults.toml
+++ b/cibuildwheel/resources/defaults.toml
@@ -79,3 +79,4 @@ repair-wheel-command = "auditwheel repair --ldpaths {ldpaths} -w {dest_dir} {whe
[tool.cibuildwheel.pyodide]
audit-command = ""
+build-frontend = "pyodide-build"
diff --git a/cibuildwheel/resources/nodejs.toml b/cibuildwheel/resources/nodejs.toml
index a87ecea5..5f8a665c 100644
--- a/cibuildwheel/resources/nodejs.toml
+++ b/cibuildwheel/resources/nodejs.toml
@@ -1,4 +1,4 @@
url = "https://nodejs.org/dist/"
-v24 = "v24.16.0"
-v22 = "v22.22.3"
+v24 = "v24.20.0"
+v22 = "v22.23.2"
v20 = "v20.20.2"
diff --git a/cibuildwheel/resources/pinned_docker_images.cfg b/cibuildwheel/resources/pinned_docker_images.cfg
index 461e6bf3..67b4c7e3 100644
--- a/cibuildwheel/resources/pinned_docker_images.cfg
+++ b/cibuildwheel/resources/pinned_docker_images.cfg
@@ -1,54 +1,54 @@
[x86_64]
-manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.06.04-1
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_x86_64@sha256:493d2032114d757aaa761a9385ad8497f391503bf71acef9abeeb66682ca5d90 # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64@sha256:53390351aeb4688114b02c36a23b3e6ce1166ee9b7afc5df1a4f776354fc764c # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64@sha256:934419fa742ff922855f464203cc0ad5afe3317a8541712a00cf3dc7fb893fc8 # 2026.09.05-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64@sha256:621f8004ed526a5a6bf6a866fb415ad8da54d59a991e50b3b69167c3a768a616 # 2026.09.05-1
[i686]
-manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.06.04-1
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_i686@sha256:f86cf7e5a6daca40ddbf857e0eeb335f39ad6f45703b61dfb00fb09a6b1cf80e # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686@sha256:48790e05c01457c8a8daa0185e2c5e09d9684c017f930b3f2aa6d8afebe6784b # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686@sha256:a3f3da7d656407dd0e4721be976331493516318db8a9c51674070696ab8b05a2 # 2026.09.05-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686@sha256:7ff9262769ecadb9b889d2977f2e1fd47400a161664502ecb0eda9291d9abdfb # 2026.09.05-1
[aarch64]
-manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.06.04-1
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_aarch64@sha256:f4cd164263e4ec2b7da7ee40b319bb5e30f0d7a2abd7ad4730e716a512dfb529 # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64@sha256:ad74e53b713f3b07d8c889c526dc0c6500da9827b45e38739570875fef52e28f # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64@sha256:effc0e17319a56b2c7eaff0cb5dd81a2d2c2850410841d3f017378f52ead6442 # 2026.09.05-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64@sha256:4dffcd49f0b6fc6928a49915f3cd939f973bbecbdfe96e1e7926b6049bc0bad5 # 2026.09.05-1
[ppc64le]
-manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2026.06.04-1
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_ppc64le@sha256:1e6535d07dd0a943a4fc932243ddf1516739bc07c8adb5b42b6dfe0492492fad # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le@sha256:f1efe96ed791399d23ad3d63ba2c9b20d06139203d1f3affad4534f44d53ee0b # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le@sha256:172d9630f3d085a22da7b2ec405cb6966e4e818f4e2ab3eb3c4e582f7cac8c52 # 2026.09.05-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le@sha256:fbc1983eb04e9bf311bd743863472b3ac9840edc3f2ca4e9dd4085d26f24fc84 # 2026.09.05-1
[s390x]
-manylinux2014 = quay.io/pypa/manylinux2014_s390x:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2026.06.04-1
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_s390x@sha256:328291eab4df4c724dee04444a2ce44653d6db76d3a10cd41cb75df83aee470c # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x@sha256:d93d3fe69923df58ec8ca45a6e0bb1af915d62888f95baef6d7596e5d002646f # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x@sha256:3efbd8ad5de732ef51fad2d31fe6e35cc9dc18cc12f30552a79df9640fe92899 # 2026.09.05-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x@sha256:a7254c085d6c28ae74acb229af697133a8827535ac26b542b7be014272ba81d2 # 2026.09.05-1
[pypy_x86_64]
-manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_x86_64@sha256:493d2032114d757aaa761a9385ad8497f391503bf71acef9abeeb66682ca5d90 # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64@sha256:53390351aeb4688114b02c36a23b3e6ce1166ee9b7afc5df1a4f776354fc764c # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64@sha256:934419fa742ff922855f464203cc0ad5afe3317a8541712a00cf3dc7fb893fc8 # 2026.09.05-1
[pypy_i686]
-manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_i686@sha256:f86cf7e5a6daca40ddbf857e0eeb335f39ad6f45703b61dfb00fb09a6b1cf80e # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686@sha256:48790e05c01457c8a8daa0185e2c5e09d9684c017f930b3f2aa6d8afebe6784b # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686@sha256:a3f3da7d656407dd0e4721be976331493516318db8a9c51674070696ab8b05a2 # 2026.09.05-1
[pypy_aarch64]
-manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.06.04-1
-manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.06.04-1
-manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.06.04-1
+manylinux2014 = quay.io/pypa/manylinux2014_aarch64@sha256:f4cd164263e4ec2b7da7ee40b319bb5e30f0d7a2abd7ad4730e716a512dfb529 # 2026.09.05-1
+manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64@sha256:ad74e53b713f3b07d8c889c526dc0c6500da9827b45e38739570875fef52e28f # 2026.09.05-1
+manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64@sha256:effc0e17319a56b2c7eaff0cb5dd81a2d2c2850410841d3f017378f52ead6442 # 2026.09.05-1
[armv7l]
-manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2026.06.04-1
-manylinux_2_35 = quay.io/pypa/manylinux_2_35_armv7l:2026.06.04-1
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2026.06.04-1
+manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l@sha256:3503ad3cef1b2a35ee05048eaebdb93ad1b4a6e9426af7f43dbe7658243ab0db # 2026.09.05-1
+manylinux_2_35 = quay.io/pypa/manylinux_2_35_armv7l@sha256:c1380d53d840da13bfc90717b5e98c1ac63e305a0daf73f436718df640958076 # 2026.09.05-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l@sha256:7fa1e5ac26e79b9aa6b64aac4ca2479eadd8d00229f178eb5495edd538e9ff4b # 2026.09.05-1
[riscv64]
-manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64:2026.06.04-1
-musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64:2026.06.04-1
+manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64@sha256:000de3e1037325a6cc13615c1218061a56e1ece60ecdbe1a4572933a90654d18 # 2026.09.05-1
+musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64@sha256:f8bf1ede4138d95937a98362ce482453d717c62d22207f038619262b180d4ab8 # 2026.09.05-1
diff --git a/cibuildwheel/resources/python-build-standalone-releases.json b/cibuildwheel/resources/python-build-standalone-releases.json
index fef75740..531637aa 100644
--- a/cibuildwheel/resources/python-build-standalone-releases.json
+++ b/cibuildwheel/resources/python-build-standalone-releases.json
@@ -1,902 +1,902 @@
{
"releases": [
{
- "tag": "20260602",
+ "tag": "20260901",
"assets": [
{
- "name": "cpython-3.10.20+20260602-aarch64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-aarch64-apple-darwin-install_only.tar.gz",
- "sha256": "5b64ed3d8e565440e64521fcd497cb74566348ef2a8de1c250095f1e30456690"
+ "name": "cpython-3.10.21+20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "sha256": "cee232aabfb6790eec78f3cca935caeb7bd4eedca4dcb0a10dbcdb4302320b38"
},
{
- "name": "cpython-3.10.20+20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "a287853a2a5353907b1358ca6ab88eacdc90a48637d54658d3d5797875917730"
+ "name": "cpython-3.10.21+20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "bd9ebd39612e1ae9388983c4b89cad2c5b95a5b4eccd0f26288a4ab6a91dd50a"
},
{
- "name": "cpython-3.10.20+20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "0924a2787c29b076f9581759c9640c88688b50494b0365ecd61b4d3693e48b2a"
+ "name": "cpython-3.10.21+20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "04d94067bd4a0ea772c9baf6dfcc6ad2df1b26f60b9a34b0483ecda9d0a7e43e"
},
{
- "name": "cpython-3.10.20+20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "sha256": "93b9d7c034a36253423f58c6154109f50e5ce23132fe019ea1a58451e41aa619"
+ "name": "cpython-3.10.21+20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "sha256": "a6d355da64d92b6ce2bced14ef5d90f4b32185c41e91dc1f371cd617186e90ae"
},
{
- "name": "cpython-3.10.20+20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "sha256": "9f65129479c576d5bfc80d207cf97d5db89c1f09b36ec901f225254b49948893"
+ "name": "cpython-3.10.21+20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "sha256": "dc626af9fc39d2e8736e6110d2d2f25bbfd6ac9aef03247cb78c643a55f62b1e"
},
{
- "name": "cpython-3.10.20+20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "sha256": "b24dfabc8496f17729b9c64658e1e23075be1eb7a7c6dcedb413f1ab321ff0a6"
+ "name": "cpython-3.10.21+20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "52ccaa16d905b37996376f938fe23dcfd81a7f787a04aa1775774bbb68cdff8e"
},
{
- "name": "cpython-3.10.20+20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "86cdca8f7f5d1c76062127e547c958a4ec10d1d0992b8bd1d7d2dc89f60a0945"
+ "name": "cpython-3.10.21+20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "25a53d83eeeccd9f3ad9df694c05018fd9b5d81cbc427b5678b2545957c2f746"
},
{
- "name": "cpython-3.10.20+20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "e0564152a574e1d30eda4693390174c21603b5ee188fbce0c0d57d4bdf8f8e8d"
+ "name": "cpython-3.10.21+20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "c86d9e4db3b3b553b5e80588868223a23c3407940bb35c6f1582a88c42ea8248"
},
{
- "name": "cpython-3.10.20+20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "dae205326260e34d9d1516c3abd08229730965416eb6806d79e8e2e567ef6d84"
+ "name": "cpython-3.10.21+20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "469824b1084aa5f99104cab1f33f87bc729a623a32142c5ab26004b388ce3d26"
},
{
- "name": "cpython-3.10.20+20260602-x86_64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64-apple-darwin-install_only.tar.gz",
- "sha256": "988d3c42e5d006adf20ea1b03d372ba896c075cecbbdfe07523732d6e52159f1"
+ "name": "cpython-3.10.21+20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "sha256": "e22c8cd258c12d264261104ae8ea5ce1b8e2c5efde074e36f01b7c299c17e221"
},
{
- "name": "cpython-3.10.20+20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "3514c52a8220b39f9f5c02473c6bf236c3e7ecac137b94b8fcf92418ddef27d5"
+ "name": "cpython-3.10.21+20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "b3edb1dacad300c7117ce4d6df97cd2e411afc0d173db43c224f904deb6253b5"
},
{
- "name": "cpython-3.10.20+20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "a2b5ecfdaee583bfec05544976337b4257d2bee97efb8e39768375ea40fe05bd"
+ "name": "cpython-3.10.21+20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "73cc92db5e6fb07ba611dca3709956d57cc2ed74ebcc01515b550ea89dfe9cba"
},
{
- "name": "cpython-3.10.20+20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "23eae4592dc4f82f14d4b7a3e49787ee02ae3d01dace1f448587f6f82ae8d678"
+ "name": "cpython-3.10.21+20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "7258330b0740db50a4682c102bd0ac554c0fb500d86505a759ad9f94bc7ee565"
},
{
- "name": "cpython-3.10.20+20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "d0d2f932cd1e4bc9c05ea3a760a59640c93797e23360e11c90edaac2ac38e306"
+ "name": "cpython-3.10.21+20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "fb65acbc168d2216af6f78dbe8b1803e28c21dbe41a5c90ebd879154cdef7fa9"
},
{
- "name": "cpython-3.10.20+20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "sha256": "596f41fd4d3108ce34efa27a106065c8537ff6c4d62728244afa6f8e58111f48"
+ "name": "cpython-3.10.21+20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "a54a808daaba85c2d3346981b3209591c00762d98526572377efb842b39f9f89"
},
{
- "name": "cpython-3.10.20+20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "8a13153ca5094dda1a61dc132807ab079aaa449b03d9aae91486333a427f6ec2"
+ "name": "cpython-3.10.21+20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "164cefdd0f6ae0a7474bc29239d4f8f894c29febfc22ae3262608ae502638b87"
},
{
- "name": "cpython-3.10.20+20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "sha256": "2ff8b1cbb7fd17d345ac48f5ed4cc3283660552b191964d742d0f03354f23afe"
+ "name": "cpython-3.10.21+20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "5e98d40ec218402eb37bacd4b8ec64ef76d7a7bf279260bf6c23489fbd740d0f"
},
{
- "name": "cpython-3.10.20+20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "d5d4526b2631759d1b27e7c2f6f31a56d4fcc09f7c0883c552d0294e97857d94"
+ "name": "cpython-3.10.21+20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "f9c3126943cf6d5d65dc547ab311b5454af2a9dbdee19a47368a70b0d2187630"
},
{
- "name": "cpython-3.10.20+20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.10.20%2B20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "sha256": "be894748f30e25f9f5e6874dfebffcbdb658c84df79d7988a47546b8da0abaaa"
+ "name": "cpython-3.10.21+20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.10.21%2B20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "93dff73018257846bab319159deb5ddd0bf0351f4fce4496c3ae7cb84eac2e0b"
},
{
- "name": "cpython-3.11.15+20260602-aarch64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-aarch64-apple-darwin-install_only.tar.gz",
- "sha256": "01f0de017aacd7528084dbacd46c66cfe9a0b0cd1255be0c24854b7985dd130e"
+ "name": "cpython-3.11.16+20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "sha256": "50424fa409e8ae84b82a3052522f64695b47dff2158b70bb7358e0ebd6c085c9"
},
{
- "name": "cpython-3.11.15+20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "dccb58157715b477ae24d90c6faab9e419ede5bff16bb03307c90e88675212f5"
+ "name": "cpython-3.11.16+20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "3a983c8d8e60ac38653bce3063b1875b8deb9816b4e6f58c0623f537530b2025"
},
{
- "name": "cpython-3.11.15+20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "408474860874575864d3d6bcf44c344b6bc558730976131c9e4a9138098596f2"
+ "name": "cpython-3.11.16+20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "c1cca4af741e33d47871b298842e6c3272cd9e8f57daf8085359fcbfe2d1a5aa"
},
{
- "name": "cpython-3.11.15+20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "b1fbe943bb9603ea6ccf3d65f448978f87823df3909ea2aa57626f53d1994437"
+ "name": "cpython-3.11.16+20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "45080a783cfa64695b14d43784fdeb00a409afb72f2132a37245e7ef9cd44eb7"
},
{
- "name": "cpython-3.11.15+20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "sha256": "a9277058207656f13b8fb77c657dbc070f4776227d7b9cb45647277d3b194c4f"
+ "name": "cpython-3.11.16+20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "sha256": "1b33c43961046d0a2190b8144b0da4a49f5523cb001fb54727f0705612794b28"
},
{
- "name": "cpython-3.11.15+20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "sha256": "d17bec0f4c4c8a3af442341fa8969ae61797024f535495c361a682c5eafea5db"
+ "name": "cpython-3.11.16+20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "sha256": "829578b83beda15d260e60d30f4e4a73819755da57d4179d3195132aabe546ea"
},
{
- "name": "cpython-3.11.15+20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "sha256": "cbe57e38bd00a47fd6e8078838495418456fd66b21cc1ea970fcd8803be54daa"
+ "name": "cpython-3.11.16+20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "38ebad2970fdf6d465ee3cb00ce3f64bfe4369eaaa73357f3b8a09a903ad34d7"
},
{
- "name": "cpython-3.11.15+20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "bdd51821a0ba3040fd20738ec6bd4b89a1ddbb2ff3a0ca6502c88387c0f821af"
+ "name": "cpython-3.11.16+20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "7f9333931e489e1ef087a16356825c44e14a2473189e044636f64a53aaf55051"
},
{
- "name": "cpython-3.11.15+20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "45c36237492627fd99038e0ce7f8cf9a3e6b324f2f4eac2b4bd1dacb5fb6d5ff"
+ "name": "cpython-3.11.16+20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "1c1326ece6b62c7e0bac815c38e6ea72dcf3669f5b84e8ba82fe33aaec50fc33"
},
{
- "name": "cpython-3.11.15+20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "533be5f8ea2d0fbdc001ce3739200f03f98416186ee52fa27061113743c4a861"
+ "name": "cpython-3.11.16+20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "ac6184b2dddb05e0004a2798fe9e1a47993b447137dbdff5a9b8cf47a2899785"
},
{
- "name": "cpython-3.11.15+20260602-x86_64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64-apple-darwin-install_only.tar.gz",
- "sha256": "88b6a8ec913f5fe4cc8334a8a2f57a1c8129e6bc9f5b6ac9580d461ce542ad9c"
+ "name": "cpython-3.11.16+20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "sha256": "167cc15cf4eeb72944a67bbd2f7120c45fded17d5043d5db64b3144d7adc30ae"
},
{
- "name": "cpython-3.11.15+20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "985169a3aab1413eddaccf417c0ce36671ada2bcb8fcc0852b29963c3cfa0146"
+ "name": "cpython-3.11.16+20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "6be524fa6752af802146a4adc7d098565425b0b1c166e19a5a7a4c8cccb86bf6"
},
{
- "name": "cpython-3.11.15+20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "1702759f4b44d71d307bc876ef913495461790c9fcfa20d1f67270b22170cd09"
+ "name": "cpython-3.11.16+20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "faa0758583a63f14c5eee516af82738403b59c13edda6fc0a21d953febd89eed"
},
{
- "name": "cpython-3.11.15+20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "70d8880df7762e633fa4f4092b520e39a1e66bb0f2caec4c74f32b0f844893e3"
+ "name": "cpython-3.11.16+20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "dd9d55e2d83a90097b6c5c9d3b770e064f91278cf176a8f8369c11dcf1a4bc10"
},
{
- "name": "cpython-3.11.15+20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "0152f9ea41936cadd2daca0c618116720a7392acd4dba8ae9fe006bba0ce50e5"
+ "name": "cpython-3.11.16+20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "ab67046ca45388d6479110abd5430cad37ec78c50db8ced5d9ee6faa9b9d8628"
},
{
- "name": "cpython-3.11.15+20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "sha256": "f07736605f1073920859a562492f869e90fa0540191fa334785821983fc2a5fc"
+ "name": "cpython-3.11.16+20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "c586fff4032c052652490e29f4997f430700e0b198d57cc86ec4eb54c07f3adb"
},
{
- "name": "cpython-3.11.15+20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "4285ccd87fa2dd2adb0da7cde8c85d3f24dc6a020c61a2ffdbb8788c525decb7"
+ "name": "cpython-3.11.16+20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "67ff09451127bb33a4d3e7c600b52b6cf679a7935dec28cd16f6cd0dc64edf69"
},
{
- "name": "cpython-3.11.15+20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "sha256": "7a6a4e2bca06a5a95f5bb786462004cffa887f9b97141a2001383ac9df84a360"
+ "name": "cpython-3.11.16+20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "94a1ea52ec1fb46ce8c8292c54828a958bc7a313410e124b46b85ea8aef4dd4f"
},
{
- "name": "cpython-3.11.15+20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "ebeba38b1b64efe38fe012621a09ed74fe1d1a342030979354ebe9bb5a3f0248"
+ "name": "cpython-3.11.16+20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "5f2292ca6646c61c34cbbef44480fe6c5063ee10eabd913c7ee38d687bc664f7"
},
{
- "name": "cpython-3.11.15+20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.11.15%2B20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "sha256": "be965f14ae0d4fa678e3c86243088f11daba1bd767e8eb1aaddc0a95e87b2106"
+ "name": "cpython-3.11.16+20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.11.16%2B20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "fd587b4fc31fc0adc21e32fe5d95c9e5ee00085413bcd0123563e7f0bc9ab83e"
},
{
- "name": "cpython-3.12.13+20260602-aarch64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-aarch64-apple-darwin-install_only.tar.gz",
- "sha256": "0c21806e8690e4b20a6c2e9dc662f46196c5ba719686e8dd60f00af6ff409a75"
+ "name": "cpython-3.12.14+20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "sha256": "3ee3ee547cedfeb7c2b16b2b7156039f7b470bb8f857e226fd3d2eb11db83c76"
},
{
- "name": "cpython-3.12.13+20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "ad10ddbbd016177d6e2f1f81f91f8aea95c8b02a23fba8f81ca21587dc1985f0"
+ "name": "cpython-3.12.14+20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "4e852236277eb8f7105cbe0f5adf45592f521af238bc0f700c351856e2c2e41a"
},
{
- "name": "cpython-3.12.13+20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "f0c9ea0022b2dfdf0a4733e962ba8cc883c45d26df26116b9802b658240a25d7"
+ "name": "cpython-3.12.14+20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "b61b856c3e1a4fc65b8f6e6b0495ef975dd0924f90c59f3ea61b38a079173b84"
},
{
- "name": "cpython-3.12.13+20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "c7462a533edd126483327de8e73199b07a4893564a20d98bfa20cc1474f229aa"
+ "name": "cpython-3.12.14+20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "e6075aaa0f4deb856b170e5cc940bd37ddce90f4a1eb036b1af272d54a5ba10d"
},
{
- "name": "cpython-3.12.13+20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "sha256": "822d896ae1841c2b9c1f55cde9964682d6250e4319fe585c4ffc26adb53934ec"
+ "name": "cpython-3.12.14+20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "sha256": "23491908521de1f815f23851ab3fa8baecec99c5efe331b6405f4ffa1f40294c"
},
{
- "name": "cpython-3.12.13+20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "sha256": "5894ce2e569e901dbfdbb5d996e1138cfca09002f97fcaef75b82ad4760ae90c"
+ "name": "cpython-3.12.14+20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "sha256": "8b9441c7fd013600a98ea1d51af279c7f5e74a6ef3cd2dca36a3cf6fd46a0f97"
},
{
- "name": "cpython-3.12.13+20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "sha256": "e96273b5e96277db73c4214e4544d9a01b2c968bce216973925e9bd7ea6c9ac2"
+ "name": "cpython-3.12.14+20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "b7d69ac55fad5eba94379b909aca57ce5f96654d54a863d396ae203849be9166"
},
{
- "name": "cpython-3.12.13+20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "ca31512e0b3e871e0072dbfd8ca46331ce1309779829a6efc0dd9ed999cbac41"
+ "name": "cpython-3.12.14+20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "53952a7834d30384cb932ff21684bb011039301602f860774be3cba54118fff0"
},
{
- "name": "cpython-3.12.13+20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "13c8cecee04d4d272296b80f5fcb5c5ec370ea7e02e7182b9eead308c73a88da"
+ "name": "cpython-3.12.14+20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "6083fe37c94eab8a8e0e4e78ce816a68f48a9c9bc24f705557d08820e21e0b9b"
},
{
- "name": "cpython-3.12.13+20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "c6a43e83af84326891377742d93b4fdd9eee662d89001ac4d63dc3b0e57831fd"
+ "name": "cpython-3.12.14+20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "62873414182c69032a87ad4ae8f67d045322fd97e322159bbdfc01d17f51ba87"
},
{
- "name": "cpython-3.12.13+20260602-x86_64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64-apple-darwin-install_only.tar.gz",
- "sha256": "e6776f05a160f9d44f9c2bc8bd1e252037856808528bf910dea791bdf70a7224"
+ "name": "cpython-3.12.14+20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "sha256": "2e31b23f3f1319f707d0e620b48847a0046577541d357276821f9f1b5492e0ba"
},
{
- "name": "cpython-3.12.13+20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "f89539b0a6f1d48c655f97b7e77f3f8738bbe9d7a32c9306d0d20335dc8ae0fb"
+ "name": "cpython-3.12.14+20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "e90c1b6419da3bd812dd73bb3de40287a21abf153438147639ec5e20375ea93f"
},
{
- "name": "cpython-3.12.13+20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "9be5c21b78dbc371e739bc7faf3b007b8e607335f780bdd2e0dd44a6e3580d76"
+ "name": "cpython-3.12.14+20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "936c246dfdbbfa7cb22dd01814a21f582a892689fae96b06071a5e433baffa22"
},
{
- "name": "cpython-3.12.13+20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "2b424f05448e81c504959b8414a599345930d344f19e9cd531637498b3a061a2"
+ "name": "cpython-3.12.14+20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "12d6539cd518eaf9a2fee52d52e457e48826e6c40d3d6e490459a898d2543fcd"
},
{
- "name": "cpython-3.12.13+20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "9ec7ae4f7a02f303df1c1c0791135e49ca8743ab335ed27b99ada69c86d63701"
+ "name": "cpython-3.12.14+20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "b3964c77a4254f033c4f5e6e25d103b425ee1c952d041b20f95c55a07fbbbee0"
},
{
- "name": "cpython-3.12.13+20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "sha256": "d6a902d1e85bbe9df14be5d1057c31514bfbb2d27311f0c0bea640233f95e994"
+ "name": "cpython-3.12.14+20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "e190037abafb8ed67fb463aec332aa853eaaa1181e3ac51b3ae9d071f97a941d"
},
{
- "name": "cpython-3.12.13+20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "af732cae1fd67685116f7cecd35a1d937d7081f86ae183b437179ee15cb74b79"
+ "name": "cpython-3.12.14+20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "6b8da3bf882b0019ae6ffea81745c75928c9a289500a3d98204c4039935db6e8"
},
{
- "name": "cpython-3.12.13+20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "sha256": "3e1ff555ab19f5a8973d4b2c9ee026fcb6d13f46e0ea1378de767bc4f563dd90"
+ "name": "cpython-3.12.14+20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "4aeb629c9f9f0182db968bf58d9847dc178aa1e17d65500253cde91171b164b6"
},
{
- "name": "cpython-3.12.13+20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "b669e13163a96c53f683359ff0bafc4b9434f76edf8d19c9110696bd52a7248d"
+ "name": "cpython-3.12.14+20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "346530919071cbf1ef7bfba8b1a8a574619e874d2b37b23399d4ed6cf891052f"
},
{
- "name": "cpython-3.12.13+20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.12.13%2B20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "sha256": "eed676048b1aaf3b4a1ceafa9212df275f0cd8733f7d0f403ac7062d5f267b22"
+ "name": "cpython-3.12.14+20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.12.14%2B20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "5e6a6c62001cb2bd4f56cd42480294cc994f2a027b9514f5f82809bc2a72c73a"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
- "sha256": "b8c7058f2aa7cafb916ed99bd4a1fd8eb26102c459a8bc8094345a2abccce2b5"
+ "name": "cpython-3.13.15+20260901-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
+ "sha256": "af118c918412460b70e196d5fb82a6c8d665a61fdf8081345c56e4b65ee40c58"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-apple-darwin-install_only.tar.gz",
- "sha256": "a2aca680d1e62a189b2ca75d5028bf4c993283f91bd17a5f2fe06cf5706ebc61"
+ "name": "cpython-3.13.15+20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "sha256": "b9054a9d3d54f4cb5573d44907fddb29874b08909bde73f29f2868cf872223ee"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "42b4d3ac54aa4278bb14f310b6ca42514e04cc5c19106983efce8a21574bdba5"
+ "name": "cpython-3.13.15+20260901-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "29fbaf7bf231894ff7eedcae1aab4b910fe91d25e012c96100dcbbbb4605c67f"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "b410c99473198933726498bfe083bf39dbd120fa16818a6627013787bfae6fe9"
+ "name": "cpython-3.13.15+20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "ce87247378f43f88e0202a0fa6d3cdb5f5fb246a3bc61b2fb604bd49b7862508"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "bf60b65aab92dfe13d50ac79c20c134f88b823b72d99e8ca5ec0f047f4108d36"
+ "name": "cpython-3.13.15+20260901-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "370efdb1c6aac068d2fa1fff1ec431b9537387ad022505a813dd076dd3355cf3"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "7b663917f659b802e68a60df445015e9fa451ac4e5fd990ebab9e7dffe4961e8"
+ "name": "cpython-3.13.15+20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "76ed18125286d7dc96ce24023d1e319dbd55a89a767102411b1ea23846113f69"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "174bacfadcd83164ad166d749f0a147a61271c2dfad4b8b47b911a7796f93e16"
+ "name": "cpython-3.13.15+20260901-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "3ff5259a142d84d6fdfb8ca12289e3bd2247823757d2e8abaa44d48fc15f006e"
},
{
- "name": "cpython-3.13.13+20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "c725dc7c1d7b471ce6c4b6e6844b0c6055feab5d6e1f3649119c4535b4920ee1"
+ "name": "cpython-3.13.15+20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "059a6fe485618b68e770733bc988b7a4a3a94b7955de4da9464e39299f9b45d0"
},
{
- "name": "cpython-3.13.13+20260602-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
- "sha256": "caa81ca4436fe25c61e47a2f8b2e88b39d391c3e67253f61efb84ae7d702a6f2"
+ "name": "cpython-3.13.15+20260901-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
+ "sha256": "f297c277dea76da5b16211974772a372acbc35adc6602f2c63aa7e48e7442a5a"
},
{
- "name": "cpython-3.13.13+20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "sha256": "e006896934faeee5b0dad2a78398b49ffe9be74abffd2df18bfbae22aee04c97"
+ "name": "cpython-3.13.15+20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "sha256": "aa3c60631c3f92056f29151033e4d9181b39ae78c203f7652cc5186ad4178d05"
},
{
- "name": "cpython-3.13.13+20260602-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
- "sha256": "33a059506b80eab20b2210db8e96e7bdc43fc92bd985ac41d3342ee4c6831c3b"
+ "name": "cpython-3.13.15+20260901-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
+ "sha256": "f8afe3736add6478847ccabaeef3e948d97c70621f64a0a609e493dc5e75c42f"
},
{
- "name": "cpython-3.13.13+20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "sha256": "a3d327444aa55fb909ea1cc26e037cf9bf98fc47989a92f954085575c5e2308e"
+ "name": "cpython-3.13.15+20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "sha256": "e073c1271262cd71d64de2c2290a46465d3167eca6b679a1aa91508a16f2d8e9"
},
{
- "name": "cpython-3.13.13+20260602-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "a0451b0a6efca7f476aef37797bffb2c720baeaf2f1601b5a0d465b4af7b9c7c"
+ "name": "cpython-3.13.15+20260901-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "6019fc368e3ea3612b4fa256c6aeab4d31e7919263033d058925e7c4ee2fb870"
},
{
- "name": "cpython-3.13.13+20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "sha256": "bb47068aae26c8e10ad466b3d19f3a1dd33056db3bd0e15eadc78e880fa77fdf"
+ "name": "cpython-3.13.15+20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "62ab9e252bb85f4538972f99eb1824d720c3f98ae1b2f7cd6988a93cba515252"
},
{
- "name": "cpython-3.13.13+20260602-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "aba753c914258dcdfcb546e1b49ad0c3fc0ef10e54bb0590f8d088033451fd20"
+ "name": "cpython-3.13.15+20260901-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "648bf620fe31d2545e834c890718631181da9dbf866d8b5313ebec232146370e"
},
{
- "name": "cpython-3.13.13+20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "d1150b1372660aeb5362b6a761e3f18dfe695dccbf66edabd50baf4fc9bdf922"
+ "name": "cpython-3.13.15+20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "d5ffad41d9b1449ad622647234ba275f01638b750ba63e53543744daf96faa29"
},
{
- "name": "cpython-3.13.13+20260602-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "e2b91ff508443a13d2f81d28b4d9906c93502381ed522bada273565c8a2892ad"
+ "name": "cpython-3.13.15+20260901-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "8b20c09f026a9fc01d64a755015bddd52fb4eefa72da748dda6516d8845ebcb5"
},
{
- "name": "cpython-3.13.13+20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "4171a01b5fde498e0b0bf435d4d6908e911f858eb3a7b8009f447f5a340e3876"
+ "name": "cpython-3.13.15+20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "584a5a197a3d1ce8d8e45496515802872f1c18c4d20ee54f088081f75e7e8b4b"
},
{
- "name": "cpython-3.13.13+20260602-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "943f0b9a6829dfdf540274a1d52e848e061c2abcf66c04552c586781aa4628d3"
+ "name": "cpython-3.13.15+20260901-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "9ff6673c4ada22a621f77c5ae745d98c54d2d6b2275abb2b93cc7ac3f224093a"
},
{
- "name": "cpython-3.13.13+20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "65a8f8bba065ae52ada7611cdc2397daa760d0999b3cbaeae0ed0b66052e47d5"
+ "name": "cpython-3.13.15+20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "b738ddb7271b2591d6e89fcd4ef42b6cbbcac7c489daf807b6b01442ae065a0a"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
- "sha256": "b9847c8ab2d259a1c09ee8939a6106dc0f6928a09a8ee229d17d73d276278cc6"
+ "name": "cpython-3.13.15+20260901-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
+ "sha256": "fc463d12d2cae4423cf43856291a01b0b01d190d50508f857d7eef82fa5bded8"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-apple-darwin-install_only.tar.gz",
- "sha256": "f1b72aec03318c2687a76f204775cf9ba426125d8f43394ad9d1fd34e0afefaa"
+ "name": "cpython-3.13.15+20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "sha256": "49f0d97f506b855eed60b74a8ac138595c5b39799a6aa5e0d7ca8abe1019a4d4"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "d79cc4ad5fd73770c443957c3689c20235e0d34340ded001f57eb97edc8f72bd"
+ "name": "cpython-3.13.15+20260901-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "f6fdbe70e660985a465d743b63701d917f1cc24f6cc190dc59e8d1f2063ab22d"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "6d55af5fc4fa206af6219f02332ecbb956f8b02ad2a0735c3e09b9d23ecd2ace"
+ "name": "cpython-3.13.15+20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "9bcc038a0bf180612ed56dec93d4977d035e80b8d9320ef51a38c287baf134b7"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "c187f0e86f239b2398a229cb969fefeb0f3a615072ad815f151b9130f583d567"
+ "name": "cpython-3.13.15+20260901-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "2b88cc0ae36a34ff264cd2d3531d022a6e318316cc7fd6d5074b0471bdf23221"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "db60826602e4db5e866878d4af8dec638cdf5a6a56a87cd66a18fc7bf879bfed"
+ "name": "cpython-3.13.15+20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "0651dd7157d3debf769e15a52c1de9de7fbcdc36ba72faf79fde3c44f14d9461"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "604c9432fb9a71b532e4473895fb0f71daf28cb8b5be9d0de8a45cc10dc91a80"
+ "name": "cpython-3.13.15+20260901-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "60f47b56dafb1af8f195498435a56e2e746360126ac89e501e3edd61d7f21701"
},
{
- "name": "cpython-3.13.13+20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "0379330c1ebe81a5f938ed2a5c69f584f497fcc4166e3434317ecb947d472b50"
+ "name": "cpython-3.13.15+20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "840460794a4c092ebbc4988e4190012b17cadaee8ef5f2b8467eb3fe3756f806"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "fd2610795399ff43d9cbd57991075cf6d8d8f57fb33382245a67f9ba21b79f68"
+ "name": "cpython-3.13.15+20260901-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "c678f6978a3925ca12dfc432bf6f88ee30d9f6c7af32d44d8cf1b02153283dde"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "aede37f2f3d73fcc4f8c07f6b8e02343e37f194f9e4a45fc84afe5a506bf9c44"
+ "name": "cpython-3.13.15+20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "dc8c0bb0563dc6e7818abf128d7a0d30002f0f56b401ec9440be2ac5462d91c3"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "12d8963706844e840d3b3ef3bea98530d976777fb55044d8eb3f77673a82c13b"
+ "name": "cpython-3.13.15+20260901-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "ce2a9ade6c71c210264a27673930a41891a975961bf351d91042a8491c3a7b38"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "sha256": "ac3042eaeede17630eed2c4522b9763234a09459d6959b53d91f403fcf0ff376"
+ "name": "cpython-3.13.15+20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "d48149bf623bffa0d8cb3eaab2bb96543fefc8fc21ff8d9be7a5b60d41b7c14b"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "d7c5990e25349e93f7037452b9669e75a3e33b1aa4d36dc487b3d0d290af9075"
+ "name": "cpython-3.13.15+20260901-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "9e857fb70b0ef6877b6c45d406d2d4925a424c97646d2712e7f8f98508b30cf3"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "d3c12dc56fa8f572ca1e8ed0cbd1a4b9e25160ca4a1242c20219c1ebcc3d1eab"
+ "name": "cpython-3.13.15+20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "d80ff86776b472d8590717984dba05b40ef0965ab4ddd2db096b8f0eba0814ad"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "9938eeb8d76dbc73f0e89279e461b2a1a4078f7891b3a155da1a73982899a2da"
+ "name": "cpython-3.13.15+20260901-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "6ac3c5f7833eb86c34183e90b28864df581bbb779b300896a0de637725adfd89"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "sha256": "040dbb0cac14680419d4808309aebe10ea6df3212a6735b3543faf90aeb4cba9"
+ "name": "cpython-3.13.15+20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "e54617bb390ef594f3beeb97e75fe3eba2d22a32ce6d39b0227d941fe02c6261"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "35ce18534e6845d7c412fbe7c54052736e8d625a225ff54fea00360826647946"
+ "name": "cpython-3.13.15+20260901-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "09c02d0150707bdf18b0195ca4fc919eb12b14e306b15472bbdb5aab008d413d"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "3d025281305d3a4cdf8f83501bc7b0b46e4a04648ed923a572ee9f7f9ba6702a"
+ "name": "cpython-3.13.15+20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "28c05a71d7aad77534e3dbb010f8a924336af3cf62d1dfa9913cd3140ed8c732"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "9d8e030ee3f7536eb9626686afc058d2b4dea21d1bcdb1341f4cb7eef3232362"
+ "name": "cpython-3.13.15+20260901-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "4cb3676709303ccf3e9999cbdd0874a617e8267926c49d450d1530fb87c963f9"
},
{
- "name": "cpython-3.13.13+20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.13.13%2B20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "sha256": "a8c4960df22ff7f555143df7399f051a4e46b93daeb4f0d70aeeac1954d3903a"
+ "name": "cpython-3.13.15+20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.13.15%2B20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "4b91f441643d3272e0af2e82d28918e2c981e6fd56b36bfdb1c81df8c9c5870d"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
- "sha256": "fa450eb774a8ad87087877425a6cd43b70fac19543ba322a6683fde2fdce2592"
+ "name": "cpython-3.14.7+20260901-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
+ "sha256": "55fa56e8ee036e946e4379185562580aa87a43ea7e68f3e7f0a9b84c42140795"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-apple-darwin-install_only.tar.gz",
- "sha256": "f3219c9b562a9e5d16c0f3f544412341c515079e7544e07aa0432676df319c27"
+ "name": "cpython-3.14.7+20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "sha256": "30daa970c7d223530120f1693cd3c6fa4c0c0d31ef158710b0dd77f286a5b23e"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "11b41bea3d31f574f0be01853a7d17ae2fd18a99ed9eee37b540f4d856e5ac5c"
+ "name": "cpython-3.14.7+20260901-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "0673a4dab23382fa9d356e4f4508b6ddf17ea83199b06c86699215ee39f5c99b"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "cd8daabba0a180c247bed312311571f7ad8a5cc217a3219e49a8842c676ba91c"
+ "name": "cpython-3.14.7+20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "5efa2548bf1248ca07ed6f8afb0cb52b83d4869d533ea5be919a989c8ee1b17c"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "4cf52c0392eec7b57c212b5338b2984d2fd8bdc817b3da37ff3a66eabd789db9"
+ "name": "cpython-3.14.7+20260901-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "e865a0aefb4b061fa53f77465a0d7d541575ef12880a51ad4d5e6460247b52b2"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "c276ccc5100504309c3398e6986d10f1aeb42fb652632907816517329ae6ae5e"
+ "name": "cpython-3.14.7+20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "30f1cc489be654477d895b441e196bb080738bf0456da82080ad4ab66a22d80f"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "2bf233059fd3abba0a2357104c146c9eefd0cc2d41362bd0b4a1860e49d92791"
+ "name": "cpython-3.14.7+20260901-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "5b893c62fdc9bb77b441d6f81b6a6e92f22ac27a641e91752fafd1fce1c3913c"
},
{
- "name": "cpython-3.14.5+20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "7ec270ede892830ecacce6d25bc104c5d336b9a2e2633a3d8eae1727aa2b5a3c"
+ "name": "cpython-3.14.7+20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "6fcb8708ec4cf604bd970068ce45e4b3228bb207fbce043ccb78e750243bb274"
},
{
- "name": "cpython-3.14.5+20260602-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
- "sha256": "e2d120b976d2bf9115de9bb7bfc74b0110b140d103d81bf8e9ff40540874ebb7"
+ "name": "cpython-3.14.7+20260901-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
+ "sha256": "63f3e5a73c226f8f001433a5f342daf0f8acb8c3f7d6d45d44a6b61845f8fc52"
},
{
- "name": "cpython-3.14.5+20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "sha256": "2450571b1b05887f568660887ecb9819f7733e040faa3e0669bf68495982c808"
+ "name": "cpython-3.14.7+20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "sha256": "983d1f03bb927f32a73053381570e2b3e73cc131b9c88807c801ed73274e3ed0"
},
{
- "name": "cpython-3.14.5+20260602-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
- "sha256": "aee5f770aa1c9954869cb496e946b03f0637d2c0afe518c3c399381b665a5c2b"
+ "name": "cpython-3.14.7+20260901-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
+ "sha256": "732bfbcd2ee84ca256aa3e12f42c36255d42da3b86c107677f9a68cd9feb83a3"
},
{
- "name": "cpython-3.14.5+20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "sha256": "4a9fbe387ef93a4d386cb155794d3162882e05e1bd1f2c8d6fb392069d43f64c"
+ "name": "cpython-3.14.7+20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "sha256": "068b41d859508a71d5dd7c9e8e0e2481932691a055a67cf6ff94f2321959114d"
},
{
- "name": "cpython-3.14.5+20260602-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "1701aa712a09532cc89ec6f383250957c8b9396798b70f9cb3153ab17fab1194"
+ "name": "cpython-3.14.7+20260901-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "1be3d2857597ff608956762e4a39f00097579470b8f682415ed5486e08efce04"
},
{
- "name": "cpython-3.14.5+20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "sha256": "125357e9dd801e665a4eaa4ff3905e76cbe50cccf9dae3d8ee5ffca5d607c55f"
+ "name": "cpython-3.14.7+20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "0192371e2eb46e66c3da0047d97397cc5703046cd9a9bccd4adb527bf50930ac"
},
{
- "name": "cpython-3.14.5+20260602-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "d971c55084367c97ce836da7698e281bfd731d9c5b75027eb75d161a1079057b"
+ "name": "cpython-3.14.7+20260901-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "74c6d212de7b7412441967c23f011718db2565245c161380f124a0143986c726"
},
{
- "name": "cpython-3.14.5+20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "2689307ba60183d80685d957b5ce82c1f9e3a557f9f365bf15f894b307bdef08"
+ "name": "cpython-3.14.7+20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "e7c0c1bca93696109993a633651e538a31ba0552764cfa4aaa2800ca87e670e3"
},
{
- "name": "cpython-3.14.5+20260602-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "0a77184c08ccf228c87fda228db0ec0683b7b06d9869668878d4dcb465936604"
+ "name": "cpython-3.14.7+20260901-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "48a3b103a5acbfed26d21359c901f368007e51a6a88a16c8a4d5db3c2065e34c"
},
{
- "name": "cpython-3.14.5+20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "0a42cc5196a897ab5fef80799fdb9e2f24cdb6021083d13afdbe1c5fdc1aaa4f"
+ "name": "cpython-3.14.7+20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "cf71ad2f451ba9af30992391b2a403cddb6965f11ef5255ee2f5d3e504f75add"
},
{
- "name": "cpython-3.14.5+20260602-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "c6b10f9928f88e73a448adcf1a454811117b17c68b6583b422d8b58deff2d544"
+ "name": "cpython-3.14.7+20260901-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "16a7cc04d9e912e35d9a1d1ae92927e8f7b1d865d44d09040e72751be25b8317"
},
{
- "name": "cpython-3.14.5+20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "7ba684d3d200072abbf7475cf6773d9d8266d12844b23e15f0b5692346d090d3"
+ "name": "cpython-3.14.7+20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "dc27e917b88db2560fe213244ffa6a656e8197ca0beb4ddeaaee5286041488ad"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
- "sha256": "aae5b4884cca1b642479b81972aaffbff92aaffe8f0c20bba3610acd07e02f8e"
+ "name": "cpython-3.14.7+20260901-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
+ "sha256": "c4d8b269c9d5a6645d87ba6efdd480bdb7c058ec2c280c3111c2bc7ef289cfc2"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-apple-darwin-install_only.tar.gz",
- "sha256": "ae35887ed6dccc8f8d8620d0260475ac1aa6a23e35379caa5ddc15b4977da9fb"
+ "name": "cpython-3.14.7+20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "sha256": "dd8841a2e8ef94bd1a02b52f92843120942140f112145d4e0199abab56f120b1"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "0530b1d0b7e517a5e3effd595ae80547e8f1133805924c6d9c5ca17f73a62485"
+ "name": "cpython-3.14.7+20260901-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "f35b706cec736a5960489b2569ecb70e52b52bdb9b4855549acfca1c2262fcd1"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "dc33d76cf5363d79c21f8e9ab4538b0a809c508ed8b9b183ca4dfd62d8546387"
+ "name": "cpython-3.14.7+20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "5d9242012dded591d723a3a572dda265173ad58d8a3e6fdbc6dac8f94f36c80a"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "13ca33fe0f7fb67c56c8b1ece8e14492b343b81c8af17045244dc0137b0dc058"
+ "name": "cpython-3.14.7+20260901-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "73cfe170b3e8f774aef6c06a8155daba0b23f4caebcc092a81832e498a8ca293"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "962cc1605e3f82410e5a2dfa3070265693681c56fc1aa1f30967723605c5d38f"
+ "name": "cpython-3.14.7+20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "0ab3305457051cd3e7c031857e005f1bda17c218a1990567dacaaac6dd1d14f0"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "4a15a4bd09c178881320c6f8a39caa98258709e6d6d8a79aef61216b93183ead"
+ "name": "cpython-3.14.7+20260901-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "b585739fc798db3b25190158874f5ab9877f52e65c6e5c767e8ee800b8e19063"
},
{
- "name": "cpython-3.14.5+20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "72346b4ae5969dff3f875d5d81d770488ae2bd6947e91d7eb0e4c166171649e8"
+ "name": "cpython-3.14.7+20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "75fe4a23502144a343c5c1f27df592ebca085b669fe665394e1812e37bcae258"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "fb5f7669b776643dcdcced06a9ba243ecea4552da8a67a4e94191cdbabf0912a"
+ "name": "cpython-3.14.7+20260901-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "2a5b76f1415657212060b326b06440ae9628fe79bbce4e295db5ce79c39eee4b"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "034c08530cbf873973a07e727c0dcb69c0f2fd04235d6e27eab07708b2135c79"
+ "name": "cpython-3.14.7+20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "3cdeae9e3a45adadd3488df4cd94734b0152bda0c945eb2c971639503edabeaf"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "b1ce0488667649d0bec07a96700e392a3b649b1f0632339cc3ab8dbfe534f6f5"
+ "name": "cpython-3.14.7+20260901-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "512551f41a32f7fae31c17cf2bc919be2a057927bd9bc039c5860149512361e6"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "sha256": "97291c96fe40d65f3e0b40fa64b244483b9c262c8fed8269b24a5ed342c572d0"
+ "name": "cpython-3.14.7+20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "1198340ae028febed270e57b9acec927745e4ad2c0e58b8f2f9a8c39e3664309"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "908b289c4bb92ecc5c1f2a6bb83022bbc9cf4588f92ef78c34eb5b711c53076f"
+ "name": "cpython-3.14.7+20260901-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "e39f34aa17e0da1d95ed4ae586e5b3bdc49b2d87fa25b25bcec83e58d735f2a7"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "fba48ff4568317177e6400620afe27e38b4c561300ef46e49ae8852e27d9b2de"
+ "name": "cpython-3.14.7+20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "254063ae6a98ae46447f35ffa670677d5a2ad52c32a5169cadba79203dfec130"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "08faa6fe170b76ff1d20545afd0d75435ad9442931c2832ba9f7b566d7a4d32f"
+ "name": "cpython-3.14.7+20260901-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "e1e717d31d55bd469ee7ba468ae7bbac926b5b2338fcc5e1d5b3a027d977c2f9"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "sha256": "50d6357893cda3431f1f7f635a3b67f221621a24295b5f1665e4ab750d1b17e4"
+ "name": "cpython-3.14.7+20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "76fa5217e8495f8d461a25a76a1702c030db33899f3a1b2310bec3710897d22b"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "8ec93cab940ef9cb99b5a34560c35f30e4c48f99043842173b2e4cf6338f222b"
+ "name": "cpython-3.14.7+20260901-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "39604e236c5773a19e3f6304c8c7e5c9753ceb1520e48b6c2f85728dd5d94c3c"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "2ae7eedbc7c0b6d2c384628ccd372344e925df05d8cc1cea70efaa8e76cd95d6"
+ "name": "cpython-3.14.7+20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "81c4f95d23197f12208beb651d3db5e48da9dafc60137fd50a0ec8df4dd40b49"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "5dfc38d1f2f5108f5883b6cc025a42b9ca08d7bb89897ef74c6922c8ab32b055"
+ "name": "cpython-3.14.7+20260901-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "5b2244705cf5c0bf1fd909cf3948f551b56a1aa26021ced4e2dcae41d1fc1ca7"
},
{
- "name": "cpython-3.14.5+20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.14.5%2B20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "sha256": "e198ea750c6075a7e03a41a1d25d35d6e0b336c5d419847eb6a4c51bb60937ab"
+ "name": "cpython-3.14.7+20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.14.7%2B20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "8cbe814c8bcb47e90019190c5a1a5073d4002e9b36db45c9acecf1ba6bcdafc0"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
- "sha256": "47a75ddaa503b6f4833c88a0a3b83aff371e6e9f340a21edf34a9673f09dc397"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-apple-darwin-freethreaded-install_only.tar.gz",
+ "sha256": "0faf139c3acd5e72374fb6f1b5f79b26009568185125fb622d141b08336ef78b"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-apple-darwin-install_only.tar.gz",
- "sha256": "82ee518b1465db1b28fe3d8fff48601dec729c4a3852358a9b661a24157793a0"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-apple-darwin-install_only.tar.gz",
+ "sha256": "fb56b7e436f49946de3965a70ca7d6a1d1a205832fd1bd9095e4cbb33158458a"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "e0942a61f58ebaa71db7375149fcf6b6a3e3dcba7c82a5b67b1dffdd0dd1c8b4"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "bc655a00d359b98990abd2ae9b369335e91dc47a6053f7e360188d86e3fbb98d"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "41b69e7e33f318fe685e7c4b7b56547e49f8573631362b7314018321eec021ff"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "e0bcab1eabf1452cbe21ad02b2b51433c1c675d3f8725bce2967f20e1f470f52"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "565fb4fd503fd6ec0c28dfff1e2875153b79f8e82d04236143dfba21bba8880f"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "371144a5159dfd1b1a28e201b9a535fd09c93d03e250c51970b502d4666519bb"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "5232e0028db6dbefdefaf7be31e9e0757566b3defae8cc1a4d0ef09a039dee9a"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "3e78cbe62bd2f69a4209e7937932411af25c6430d3ccd9b3d341dd825f73ba69"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "619cf4e3e5b561b96ffd86961dfb97e6de5d4b5fa76d46da00aabadc7611fea2"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "ce84e57cdf847c1c656557c99fc3f7d9504b73b3d6bce7ef9ecc8d735c6676c5"
},
{
- "name": "cpython-3.15.0b2+20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-aarch64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "2d4d86ff87c40e17537b61b1351f1bb04e4a93dba24665f34cb6d46ccc966135"
+ "name": "cpython-3.15.0rc2+20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-aarch64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "80358a986317d8c7d28534cd3102763b56518c772eacc41aca61e54206f7487a"
},
{
- "name": "cpython-3.15.0b2+20260602-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
- "sha256": "4df8a0f62f9a08028a84fbd2e1438f297db6ef6e23d15f5036572dd3b7a831c5"
+ "name": "cpython-3.15.0rc2+20260901-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-armv7-unknown-linux-gnueabi-freethreaded-install_only.tar.gz",
+ "sha256": "6b04453ba5e6f7bfd7d46a8bfdd23c2c1f1bc2cfdc275a8e167d014352cd97c0"
},
{
- "name": "cpython-3.15.0b2+20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-armv7-unknown-linux-gnueabi-install_only.tar.gz",
- "sha256": "42d2c1d4e765dcfa1e599e4699dd70c8d42855d8e7b5526a987e6bb261031d8f"
+ "name": "cpython-3.15.0rc2+20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-armv7-unknown-linux-gnueabi-install_only.tar.gz",
+ "sha256": "c512d9fcb402ecc1fe047b9ac8e92d4b7fbf0bad8cdd8ce46f0bec3c771112ec"
},
{
- "name": "cpython-3.15.0b2+20260602-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
- "sha256": "db6ca3fd931963b60bed537261e02fabac5b2b1244bbe021c1775717496470d1"
+ "name": "cpython-3.15.0rc2+20260901-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-armv7-unknown-linux-gnueabihf-freethreaded-install_only.tar.gz",
+ "sha256": "6d787a425cb5f258e84aa1695f6598c49105a19e1da00c5c31a441ba14cf9b18"
},
{
- "name": "cpython-3.15.0b2+20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
- "sha256": "e44036c74d68d12a90f1dd14549527bdee761b9cc1c152c2fd643cd8b917e133"
+ "name": "cpython-3.15.0rc2+20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
+ "sha256": "ac06274bf1e02d10b2bec71d1d3127235b9edc48396c03497ec311d54e74d434"
},
{
- "name": "cpython-3.15.0b2+20260602-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "be1531c5743612805af6f0e85ec4a35716f658352ae47e1745630c5136d249c0"
+ "name": "cpython-3.15.0rc2+20260901-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-i686-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "85f62b8aafe4554e37f21ac6534516407934eb0934ada7406ffaaaf3ac64b47a"
},
{
- "name": "cpython-3.15.0b2+20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-i686-pc-windows-msvc-install_only.tar.gz",
- "sha256": "eda6a88a76052720e1cbe3eb8256ede215e2fc0125e2dd910dcaa6dfa5ed3975"
+ "name": "cpython-3.15.0rc2+20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-i686-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "a4b49b026532b4d12b1caf0359f269ec21e5c250f57c8aaa592d8ed116278d08"
},
{
- "name": "cpython-3.15.0b2+20260602-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "7e43efaed73719e491295dc83a869dbc0c29e7de841808057344fd22e4123050"
+ "name": "cpython-3.15.0rc2+20260901-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-ppc64le-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "c6936f0bac848159f74ce3f8417b2e9a3b66aea5a7f9759e3c1ae79e32c184f3"
},
{
- "name": "cpython-3.15.0b2+20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-ppc64le-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "8c3b166dcb218f0df473882305920d20ae6b798189c352a885d0bb4c86617b27"
+ "name": "cpython-3.15.0rc2+20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-ppc64le-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "8b2dc8f853e5a5e292a688060f06ff2e7af043a0e3fbd348f3a9a83d9f751a7a"
},
{
- "name": "cpython-3.15.0b2+20260602-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "ab97ba295b6b47b0135b9f20e27c2ab9cdb0cb826ba4ac413c8d14153c209aa0"
+ "name": "cpython-3.15.0rc2+20260901-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-riscv64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "13de987151be1934c315e2376c6d359323712f188b5c10b4e863693a91b7a0d0"
},
{
- "name": "cpython-3.15.0b2+20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-riscv64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "2c2e07a21299a526ac5ee6b88cff55ede9060f1151c7fdc455b2cf2e7e189408"
+ "name": "cpython-3.15.0rc2+20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-riscv64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "511886279ce9dbadd09a25a813c2a44c0aa2816841762aba5e13c3628bf2d1aa"
},
{
- "name": "cpython-3.15.0b2+20260602-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "867d710a85c174201cbbc41a4f0e5057938217d292f083dcf4f87e3d003ac549"
+ "name": "cpython-3.15.0rc2+20260901-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-s390x-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "efcd7b3990d1a777fff19ba83995bdd82220652d01dcec5648ec02de52de045b"
},
{
- "name": "cpython-3.15.0b2+20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-s390x-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "5cebe4f07918d763ea1553b8546729d0ee55c7c5474b5f01b6b64ed99bd446de"
+ "name": "cpython-3.15.0rc2+20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-s390x-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "8f82351bf8b70e69bcae77404601a48327720dc46d6cae0b13e7c6f9f99fabba"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
- "sha256": "c99115b2f05b6a22f46f0336cb683dd90f4a2351f70c231cf4532881ace48498"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-apple-darwin-freethreaded-install_only.tar.gz",
+ "sha256": "8200b9e8c6057ada95fd0ca45fa6eafeacb0a0a5e5d18bff5b306264568100bf"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-apple-darwin-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-apple-darwin-install_only.tar.gz",
- "sha256": "e9662e5cc7bef95b977ed98332264601176c7c6d4f2f29fc7ebc1a92bb9403b8"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-apple-darwin-install_only.tar.gz",
+ "sha256": "1bcade89183d1540790a0e30c0ac9da5767093a6d5003f75b9bb63aff73aaa15"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
- "sha256": "acb5cc6c6600e37d4d1acbde79ce4afa31dd593b87b9476d3b096a238781d061"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-pc-windows-msvc-freethreaded-install_only.tar.gz",
+ "sha256": "455104765e1086e13b9a6ba5c792c20528a4d43e95bf1fd781d7c1e032d59ec7"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-pc-windows-msvc-install_only.tar.gz",
- "sha256": "b5c6c115871d51181a678036d688eddc7d5e72cd9232bed0c18443479887c10f"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-pc-windows-msvc-install_only.tar.gz",
+ "sha256": "23c45c02793f793d20411de6e9e3dc6864836dd570dbb12be143aea4e63322e9"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "1c7f792b553f0decfaed85a66b2a3449b898d6bdea35f63f78d76e57df80d1fd"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "d3e41f043a9856888df7483f291b48f8cd8f160afc7c71b37e51a8445c10ba8f"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "7ebfca3c26f93f971050df2397597bcf99d5d4aae0c6420f086d287c0ebd7be2"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "6615912f874e37043912aa1516fa8b77e8496e226ba14c7b2b27843b1d819904"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "d41bc6e4f80f198d484d66181c67ad82dc45c7907713d72bd04ee04260650ffa"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "dcdf433f0034bb557fe692fb88d4671eac8557823d77d983608ec6a79f5f0dec"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64-unknown-linux-musl-install_only.tar.gz",
- "sha256": "aca517236ca2156347941bed07a681e00034ca440146cf403f82f2f580def347"
+ "name": "cpython-3.15.0rc2+20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "2cf7982da8354374289f3fe2f705ccd52ae3b81c55715f084add729e41a27155"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "ad29bdab205c4f4f5e37795c02a98ef9be054754eb8acb6eebd6d08f8d46d3e5"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v2-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "71a96715570d2400a525f414f2d149b7cf501cb646b17a91d9e6955422872c0c"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "ccb5fb56d46d9f6ac84804fdd5eae4232ac27f6512108cec8b31387d3f4cd967"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "9052aef0a19070f925638dadc272ad15b64b209e7531b86471e05118c95ffc8a"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "5d6353046e4c0056aacdec08ce62afe7871e692ed9092d3a10423ef35259bf74"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v2-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "2089a540a81b794a7ba8607b346ee50a863f55930d84f9619af28f7602fea064"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
- "sha256": "c3a610a53eb7e2cf85ede3be76985a70f577855f5c821f71cdcaeaf428c4aaf4"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "59d82b934beb28018c44ed8b8763711a2aefe10af864657489625039474eb295"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "3b5f5b5290d089953332fc6891ba0b1fb283a15b28d2c845825d750ccd2550a7"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v3-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "b3479465f671006293627cc43398824023392d78fb5977f06a139c2c8c6fab52"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "dd27066fedd592216aa85168a0cf0d4ed3fa47179f312bda1864f0b1414d23b9"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "4d4b9573e7d4acc52dc0f4168e41443ecb9fb7aec668e86550c2a12a6916cadd"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "f3ab2d08ed381550380895c847710de01af14559b60f236e847d637672df1dc8"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v3-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "03371b16aecf6fb05177ac087c32767c40fe031db609cbccaf0af35c9c85c040"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
- "sha256": "09d2c061d74a2e99613348c011418b34c3be16f68c7a188a400c265a28ea4449"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "12190d8e89f08fc4b3cc35390ea665121701a1cc7d1d6f85e1ade3ad1e120d3b"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
- "sha256": "280614f3db4eeec7394ad2aaacd645ef4ffb05c941251ee59c99a61b621a6dc5"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v4-unknown-linux-gnu-freethreaded-install_only.tar.gz",
+ "sha256": "ab59f77e03f3f1938f7f19051d74750bac6c948d59870c7a299fbbae420d1d32"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
- "sha256": "4518f7991551bd5cf84e87f74131765529c6e722a760025d390af43676063ef4"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
+ "sha256": "36e9a369fb417df943b568cc2962478faf274605d828281234512d02b85a886b"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
- "sha256": "1a8e8e6f40a0aa74fadb17d707696d27e5efac7542b965b304b46f47309b5da6"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v4-unknown-linux-musl-freethreaded-install_only.tar.gz",
+ "sha256": "7c8aa981eef52aa44342b33bfeb53150aef402f31ec9887ccfa1a76eca0468fe"
},
{
- "name": "cpython-3.15.0b2+20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260602/cpython-3.15.0b2%2B20260602-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
- "sha256": "68276bd7c604efc955143f9b4aa9b6d144546002e5b49f31edf334744bfe7ec2"
+ "name": "cpython-3.15.0rc2+20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260901/cpython-3.15.0rc2%2B20260901-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
+ "sha256": "800b4cbfae2b9811ab466e59d48b1ed102cf18dfc3b72ae97ad63d14e50555d4"
}
]
}
diff --git a/cibuildwheel/resources/virtualenv.toml b/cibuildwheel/resources/virtualenv.toml
index 009475d0..68522bda 100644
--- a/cibuildwheel/resources/virtualenv.toml
+++ b/cibuildwheel/resources/virtualenv.toml
@@ -1 +1 @@
-default = { version = "21.4.2", url = "https://github.com/pypa/get-virtualenv/releases/download/21.4.2/virtualenv.pyz", sha256 = "b54c48b9c81468403626762747c5ee5939616f18f46c3c4bbebdbe0aa3a8ba1d" }
+default = { version = "21.7.8", url = "https://github.com/pypa/get-virtualenv/releases/download/21.7.8/virtualenv.pyz", sha256 = "72ebae2a254966c2969f1343c018dc583d1ec92ab98c12d9b329ab09b9e3c21d" }
diff --git a/cibuildwheel/selector.py b/cibuildwheel/selector.py
index 9314fa1e..d710de9d 100644
--- a/cibuildwheel/selector.py
+++ b/cibuildwheel/selector.py
@@ -92,7 +92,7 @@ class BuildSelector:
return False
# filter out groups that are not enabled
- if EnableGroup.CPythonPrerelease not in self.enable and fnmatch(build_id, "cp315*"):
+ if EnableGroup.CPythonPrerelease not in self.enable and fnmatch(build_id, "cp316*"):
return False
is_pypy_eol = fnmatch(build_id, "pp3?-*") or fnmatch(build_id, "pp310-*")
is_pypy = fnmatch(build_id, "pp*") and not is_pypy_eol
@@ -104,19 +104,6 @@ class BuildSelector:
return False
if EnableGroup.PyodideEoL not in self.enable and fnmatch(build_id, "cp312-pyodide_*"):
return False
- # NOTE: Re-enable this when we have a new Pyodide prerelease (e.g., 315.0.0a1+)
- # When doing this, also:
- # 1. update Pyodide tests in unit_test/build_selector_test.py and unit_test/options_test.py accordingly.
- # 2. update Python versions for Pyodide identifiers in cibuildwheel/selector.py.
- # 3. update constraints as necessary via bin/generate_pyodide_constraints.py and add/delete
- # Pyodide constraints files in cibuildwheel/resources/constraints/ as necessary.
- # When re-enabling, update the pattern to match the experimental Python version when
- # it is bumped to Python 3.15 (likely cp315-pyodide_*).
- # This depends on the CPython version being used in the Pyodide runtime at the time.
- # if EnableGroup.PyodidePrerelease not in self.enable and fnmatch(
- # build_id, "cp315-pyodide_*"
- # ):
- # return False
should_build = selector_matches(self.build_config, build_id)
should_skip = selector_matches(self.skip_config, build_id)
diff --git a/cibuildwheel/util/file.py b/cibuildwheel/util/file.py
index 32b0a4fc..a21c290f 100644
--- a/cibuildwheel/util/file.py
+++ b/cibuildwheel/util/file.py
@@ -9,6 +9,7 @@ __lazy_modules__ = {
"tarfile",
"typing",
"urllib",
+ "urllib.error",
"urllib.request",
"zipfile",
}
@@ -20,6 +21,7 @@ import shutil
import ssl
import tarfile
import time
+import urllib.error
import urllib.request
from contextlib import contextmanager
from pathlib import Path, PurePath
@@ -51,7 +53,7 @@ def remove_on_error(path: Path) -> Generator[None, None, None]:
shutil.rmtree(path)
elif path.exists() or path.is_symlink():
path.unlink()
- except BaseException as cleanup_exception:
+ except BaseException as cleanup_exception: # noqa: BLE001
msg = f"Failed to remove {path}. Please remove it manually."
raise BaseExceptionGroup(msg, [original_exception, cleanup_exception]) from None
raise
@@ -86,17 +88,24 @@ def download(url: str, dest: Path, *, sha256: str | None = None) -> None:
# so we use certifi (this sounds odd but requests also does this by default)
cafile = os.environ.get("SSL_CERT_FILE", certifi.where())
context = ssl.create_default_context(cafile=cafile)
- repeat_num = 3
+ # exponential backoff, so that a network outage of about a minute is survivable
+ repeat_num = 6
for i in range(repeat_num):
try:
with urllib.request.urlopen(url, context=context) as response:
dest.write_bytes(response.read())
break
+ except urllib.error.HTTPError as error:
+ # a client error, such as a bad URL, will not fix itself
+ if i == repeat_num - 1 or 400 <= error.code < 500:
+ raise
+ time.sleep(3 * 2**i)
+
except OSError:
if i == repeat_num - 1:
raise
- time.sleep(3)
+ time.sleep(3 * 2**i)
if sha256:
with dest.open("rb") as f:
diff --git a/cibuildwheel/util/resources.py b/cibuildwheel/util/resources.py
index 3bbef753..0240d2f8 100644
--- a/cibuildwheel/util/resources.py
+++ b/cibuildwheel/util/resources.py
@@ -3,6 +3,7 @@ from __future__ import annotations
__lazy_modules__ = {"tomllib"}
import functools
+import os
import tomllib
from pathlib import Path
@@ -18,7 +19,9 @@ FREE_THREAD_ENABLE_314: Final[Path] = PATH / "free-threaded-enable-314.xml"
FREE_THREAD_ENABLE_315: Final[Path] = PATH / "free-threaded-enable-315.xml"
NODEJS: Final[Path] = PATH / "nodejs.toml"
DEFAULTS: Final[Path] = PATH / "defaults.toml"
-PINNED_DOCKER_IMAGES: Final[Path] = PATH / "pinned_docker_images.cfg"
+PINNED_DOCKER_IMAGES: Final[Path] = Path(
+ os.environ.get("CIBW_INTERNAL_PINNED_DOCKER_IMAGES", str(PATH / "pinned_docker_images.cfg"))
+)
BUILD_PLATFORMS: Final[Path] = PATH / "build-platforms.toml"
CONSTRAINTS: Final[Path] = PATH / "constraints.txt"
VIRTUALENV: Final[Path] = PATH / "virtualenv.toml"
diff --git a/cibuildwheel/venv.py b/cibuildwheel/venv.py
index 2867edd7..4253f7bc 100644
--- a/cibuildwheel/venv.py
+++ b/cibuildwheel/venv.py
@@ -152,6 +152,10 @@ def virtualenv(
venv. Otherwise, pip is installed.
"""
+ # the unresolved path, so e.g. the python.org framework bin directory is
+ # used rather than the internal location of the real binary
+ base_python_bin_dir = None if _IS_WIN else python.parent
+
# virtualenv may fail if this is a symlink.
python = python.resolve()
@@ -189,7 +193,7 @@ def virtualenv(
python,
venv_path,
)
- venv_env = activate_virtualenv(venv_path, env=env)
+ venv_env = activate_virtualenv(venv_path, env=env, base_python_bin_dir=base_python_bin_dir)
if not use_uv and pip_version == "embed":
call(
"python",
@@ -208,11 +212,19 @@ def virtualenv(
def activate_virtualenv(
venv_path: Path,
env: dict[str, str] | None = None,
+ base_python_bin_dir: Path | None = None,
) -> dict[str, str]:
"""
Return a copy of the environment with the virtualenv at `venv_path` activated.
+
+ If given, `base_python_bin_dir` is placed on PATH right after the venv, so
+ that scripts installed alongside the base interpreter that aren't copied
+ into the venv (such as python3-config, see #2021) resolve to the matching
+ interpreter.
"""
paths = [str(venv_path), str(venv_path / "Scripts")] if _IS_WIN else [str(venv_path / "bin")]
+ if base_python_bin_dir is not None:
+ paths.append(str(base_python_bin_dir))
venv_env = os.environ.copy() if env is None else env.copy()
venv_env["PATH"] = os.pathsep.join([*paths, venv_env["PATH"]])
venv_env["VIRTUAL_ENV"] = str(venv_path)
diff --git a/docs/_internal/pyodide-maintenance.md b/docs/_internal/pyodide-maintenance.md
index ad790048..422da5b5 100644
--- a/docs/_internal/pyodide-maintenance.md
+++ b/docs/_internal/pyodide-maintenance.md
@@ -1,6 +1,6 @@
# Maintaining Pyodide support
-Last updated: May 2026
+Last updated: August 2026
This page describes how to update cibuildwheel's Pyodide platform code when either:
@@ -11,17 +11,26 @@ This page describes how to update cibuildwheel's Pyodide platform code when eith
Pyodide has three types of releases that matter to cibuildwheel:
-- **Stable** β the most recent full Pyodide release (e.g., `0.29.x` / cp313). This is enabled by default with no special `CIBW_ENABLE` flag needed.
-- **Prerelease** β an alpha/beta/rc Pyodide release that uses the _next_ CPython version (e.g., `314.0.0a1` / cp314). Users must opt in with `CIBW_ENABLE: pyodide-prerelease` to build against this version. This may or may not be available at any given time, depending on the Pyodide release cycle.
-- **End-of-life (EoL)** β older Pyodide stable releases that are no longer the current stable. These are kept available behind `CIBW_ENABLE: pyodide-eol` so that users who still need to build for older Pyodide versions can do so.
+- **Stable** β the most recent full Pyodide release.
+ This is enabled by default with no special `CIBW_ENABLE` flag needed.
+- **Prerelease** β an alpha/beta/rc Pyodide release that uses the _next_ CPython
+ version. Users must opt in with `CIBW_ENABLE:
+ cpython-prerelease` to build against this version. This may or may not be
+ available at any given time, depending on the Pyodide release cycle.
+- **End-of-life (EoL)** β older Pyodide stable releases that are no longer the
+ current stable. These are kept available behind `CIBW_ENABLE: pyodide-eol` so
+ that users who still need to build for older Pyodide versions can do so.
-The guards in `cibuildwheel/selector.py` enforce this distinction. The constraints files under `cibuildwheel/resources/` pin the exact tool versions that go with each build.
+The guards in `cibuildwheel/selector.py` enforce this distinction. The
+constraints files under `cibuildwheel/resources/` pin the exact tool versions
+that go with each build.
---
## When a new Pyodide prerelease becomes available
-For example, consider a scenario when Pyodide ships a new `315.0.0a1` with cp315 support.
+For example, consider a scenario when Pyodide ships a new `315.0.0a1` with cp315
+support.
### 1. Add the new Python configuration
@@ -31,61 +40,39 @@ In `cibuildwheel/resources/build-platforms.toml`, add an entry under `[pyodide]`
{ identifier = "cp315-pyodide_wasm32", version = "3.15", default_pyodide_version = "315.0.0a1", node_version = "v24", sha256 = "SHA256" },
```
-`version` is the CPython version string, `default_pyodide_version` is the Pyodide release to use when the user does not pin one explicitly (use the latest available alpha/beta for a prerelease entry), and `node_version` is the minimum Node.js major required by that Pyodide release β check the [pyodide-build FAQ](https://pyodide-build.readthedocs.io/en/latest/faq.html#what-node-js-version-do-i-need) for a rudimentary idea of what the correct value is. `sha256` is the checksum of the Pyodide xbuildenv tarball.
+`version` is the CPython version string, `default_pyodide_version` is the
+Pyodide release to use when the user does not pin one explicitly (use the latest
+available alpha/beta for a prerelease entry), and `node_version` is the minimum
+Node.js major required by that Pyodide release β check the
+[pyodide-build FAQ](https://pyodide-build.readthedocs.io/en/latest/faq.html#what-node-js-version-do-i-need)
+for a rudimentary idea of what the correct value is. `sha256` is the checksum of
+the Pyodide xbuildenv tarball.
-### 2. Update the prerelease guards in the selector
+### 2. Generate and pin a constraints file
-In `cibuildwheel/selector.py`, update the patterns in the `PyodidePrerelease` guards to match the new identifier:
-
-```python
-if EnableGroup.PyodidePrerelease not in self.enable and fnmatch(
- build_id, "cp315-pyodide_*"
-):
- return False
-```
-
-### 3. Generate and pin a constraints file
-
-Run the `update_constraints` `nox` session, which reads `build-platforms.toml` and regenerates all Pyodide constraints files automatically:
+Run the `update_constraints` `nox` session, which reads `build-platforms.toml`
+and regenerates all Pyodide constraints files automatically:
```bash
nox -s update_constraints
```
-### 4. Update tests
+### 3. Update tests
-Update the unit tests so the new identifier is accepted by the selector with `PyodidePrerelease` enabled and rejected without it. Pyodide-specific integration tests may also need their hardcoded expected-wheel lists extended.
-
-## When a Pyodide prerelease becomes stable
-
-Pyodide uses a versioning scheme where the stable release for a given CPython version is named `[PythonMajorMinor].0.0`, so the first stable release shipping cp314 will be **`314.0.0`**. See [pyodide/pyodide#6084](https://github.com/pyodide/pyodide/issues/6084) for a rationale of this versioning scheme.
-
-### 1. Update the stable entries, and remove (or replace) the prerelease entry
-
-In `build-platforms.toml`, update the former prerelease entry's `default_pyodide_version` to the new stable release (e.g. `314.0.0`) and remove the prerelease marker from the identifier if present. Remove previous prerelease entries if they are now obsolete, or update them to the next prerelease if one is available. Move the previous stable version behind `pyodide-eol` rather than dropping it outright (see below).
-
-### 2. Disable or update the prerelease guards
-
-In `selector.py`:
-
-- **If a new prerelease is available**: update the `fnmatch` pattern to the next identifier (e.g. `cp315-pyodide_*`) as described above.
-- **If there is no new prerelease**: comment out the `PyodidePrerelease` logic.
-
-### 3. Update the constraints file
-
-Run `nox -s update_constraints` to regenerate the constraints file for the newly stable version. If the entry was already in `build-platforms.toml` as a prerelease, its constraints file already exists, and this step just refreshes it against the stable Pyodide release and updates the dependencies' versions.
-
-### 4. Update tests
-
-Update the unit tests so the newly stable identifier is accepted by the selector without needing `PyodidePrerelease` in the enable set. Pyodide-specific integration tests may also need their hardcoded expected-wheel lists extended.
+Update the unit tests so the new identifier is accepted by the selector with
+`CPythonPrerelease` enabled and rejected without it. Pyodide-specific
+integration tests may also need their hardcoded expected-wheel lists extended.
## When an old Pyodide version is to be moved to end-of-life
-When a Pyodide version is superseded by a new stable release, move it behind the `pyodide-eol` enable flag. We want to allow users who still build for older Pyodide ABIs time to upgrade.
+When a Pyodide version is superseded by a new stable release, move it behind the
+`pyodide-eol` enable flag. We want to allow users who still build for older
+Pyodide ABIs time to upgrade.
### 1. Add the `pyodide-eol` guard in the selector
-In `cibuildwheel/selector.py`, add (or update) the `PyodideEoL` guard to include the old identifier:
+In `cibuildwheel/selector.py`, add (or update) the `PyodideEoL` guard to include
+the old identifier:
```python
if EnableGroup.PyodideEoL not in self.enable and fnmatch(build_id, "cp312-pyodide_*"):
@@ -94,15 +81,23 @@ if EnableGroup.PyodideEoL not in self.enable and fnmatch(build_id, "cp312-pyodid
### 2. Update tests
-Update the unit tests so the EoL identifier requires `PyodideEoL` to be included in the enable set. The default (no `CIBW_ENABLE`) should exclude it.
+Update the unit tests so the EoL identifier requires `PyodideEoL` to be included
+in the enable set. The default (no `CIBW_ENABLE`) should exclude it.
## When an old Pyodide version is to be fully retired
-Retirement is not expected to happen on a routine basis. It is only warranted when the Pyodide ecosystem itself has evolved to the point where an older ABI version is considered obsolete β for example, if the surrounding toolchain, packaging standards, or runtime infrastructure have moved on so substantially that building for the older version no longer makes practical sense. Any retirement is to be discussed and agreed upon by Pyodide maintainers before proceeding.
+Retirement is not expected to happen on a routine basis. It is only warranted
+when the Pyodide ecosystem itself has evolved to the point where an older ABI
+version is considered obsolete β for example, if the surrounding toolchain,
+packaging standards, or runtime infrastructure have moved on so substantially
+that building for the older version no longer makes practical sense. Any
+retirement is to be discussed and agreed upon by Pyodide maintainers before
+proceeding.
### 1. Remove the Python configuration
-Delete the entry from `build-platforms.toml` and remove the `PyodideEoL` guard for that identifier in `selector.py`.
+Delete the entry from `build-platforms.toml` and remove the `PyodideEoL` guard
+for that identifier in `selector.py`.
### 2. Delete the constraints file
@@ -110,4 +105,5 @@ Remove `cibuildwheel/resources/constraints-pyodideXYZ.txt`.
### 3. Update tests
-Remove references to the old identifier from the unit tests, integration tests, and drop any expected-wheel entries for it from the test helper.
+Remove references to the old identifier from the unit tests, integration tests,
+and drop any expected-wheel entries for it from the test helper.
diff --git a/docs/changelog.md b/docs/changelog.md
index 1191a107..babaac8a 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -5,6 +5,42 @@ ref: changelog
# Changelog
+### v4.2.0
+
+_4 August 2026_
+
+- π CPython 3.15 wheels are now built by default - without the `"cpython-prerelease"` [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable) set. It's time to build and upload these wheels to PyPI! This release includes CPython 3.15.0rc1, which is guaranteed to be ABI compatible with the final release. (#2944)
+- β¨ Adds Pyodide 3.15 support with the `cp315-pyodide_wasm32` build identifier, using Pyodide 315.0.0a2. These are also stable wrt. the final release. (#2958)
+- π Retries a failed download six times with exponential backoff, so short network outages no longer stop a build. A `4xx` response is still reported at once. (#2953)
+- π Accepts `default` as a [`build-frontend`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) value on Pyodide, and accepts `pyodide-build` in the top-level table and in overrides (#2951)
+- π Holds pip back on GraalPy, where newer pip breaks the build (#2955)
+- π Updates Pyodide to 314.0.4 (#2949, #2952)
+- π Updates dependencies and container pins (#2952, #2960)
+- πΌ Updates CI action pins (#2948, #2954)
+- π§ͺ Uses pp311 for the abi3 test, and deletes `test_overridden_pip_constraint`, which is not necessary since #2583 (#2956, #2957)
+
+### v4.1.1
+
+_24 July 2026_
+
+- β¨ Adds `pyodide-build` as a separate [`build-frontend`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend), now the default frontend for Pyodide, with verbosity flags handling. Any other frontend is ignored with a warning on Pyodide. (#2609, #2945)
+- π Uses digests instead of tags for pinned container images, strengthening supply-chain security. The human-readable tags remain as comments in `pinned_docker_images.cfg`. (#2915)
+- π Fixes platform-specific [`test-runtime`](https://cibuildwheel.pypa.io/en/stable/options/#test-runtime) environment variables (e.g. `CIBW_TEST_RUNTIME_ANDROID`) not being honored (#2941)
+- π Fixes quoting of [`test-requires`](https://cibuildwheel.pypa.io/en/stable/options/#test-requires) and [`audit-requires`](https://cibuildwheel.pypa.io/en/stable/options/#audit-requires) so PEP 508 specifiers containing spaces work (#2913)
+- π Makes [`archs`](https://cibuildwheel.pypa.io/en/stable/options/#archs) parsing case-insensitive and platform-aware, so e.g. `arm64` works on Windows (#2920)
+- π Uses an absolute path for the `{project}` placeholder in [`config-settings`](https://cibuildwheel.pypa.io/en/stable/options/#config-settings) (#2934)
+- π Validates the [`pyodide-version`](https://cibuildwheel.pypa.io/en/stable/options/#pyodide-version) option against the build identifier with a clear error (#2925)
+- π Fixes PyPy installs on macOS after PyPy switched its downloads from `.tar.bz2` to `.tar.gz` (#2939)
+- π Makes a matching `python3-config` available in the build and test venvs on macOS (#2922)
+- π Updates dependencies and container pins (#2917, #2935, #2939)
+- π Updates Android tests to current Python versions and the new test repository URL (#2933)
+- π Drops the `orjson` dependency, no longer used by mypy 2+ (#2923)
+- π Builds the docs with properdocs, a MkDocs fork (#2946)
+- π Adds the missing `cp314-pyodide_wasm32` entry to the build identifier table (#2947)
+- π Removes outdated notes about the `pip wheel` build frontend and ClearLinux (#2926)
+- πΌ Adds a "CI: PyPy EoL" PR label to run PyPy EoL tests on PRs (#2930)
+- πΌ Updates CI action pins and pre-commit hooks (#2914, #2932, #2938, #2940, #2942, #2943)
+
### v4.1.0
_12 June 2026_
diff --git a/docs/ci-services.md b/docs/ci-services.md
index 6c2c99df..ac6c6f8f 100644
--- a/docs/ci-services.md
+++ b/docs/ci-services.md
@@ -85,10 +85,7 @@ To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file
Commit this file, enable building of your repo on CircleCI, and push.
-!!! note
- CircleCI doesn't enable free macOS containers for open source by default, but you can ask for access. See [here](https://circleci.com/docs/2.0/oss/#overview) for more information.
-
-CircleCI will store the built wheels for you - you can access them from the project console. Check out the CircleCI [docs](https://circleci.com/docs/2.0/configuration-reference/#section=configuration) for more info on this config file.
+CircleCI will store the built wheels for you - you can access them from the project console. Check out the CircleCI [docs](https://circleci.com/docs/reference/configuration-reference/) for more info on this config file.
### Gitlab CI [linux] {: #gitlab-ci}
diff --git a/docs/faq.md b/docs/faq.md
index 84f3bd7f..c105a6c1 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -158,7 +158,7 @@ There are two suggested methods for keeping cibuildwheel up to date that instead
If you use GitHub Actions for builds, you can use cibuildwheel as an action:
```yaml
-uses: pypa/cibuildwheel@v4.1.0
+uses: pypa/cibuildwheel@v4.2.0
```
This is a composite step that just runs cibuildwheel using pipx. You can set command-line options as `with:` parameters, and use `env:` as normal.
@@ -183,7 +183,7 @@ The second option, and the only one that supports other CI systems, is using a `
```bash
# requirements-cibw.txt
-cibuildwheel==4.1.0
+cibuildwheel==4.2.0
```
Then your install step would have `python -m pip install -r requirements-cibw.txt` in it. Your `.github/dependabot.yml` file could look like this:
@@ -402,7 +402,7 @@ Solutions to this vary, but the simplest is to use pipx:
# most runners have pipx preinstalled, but in case you don't
python3 -m pip install pipx
-pipx run cibuildwheel==4.1.0 --output-dir wheelhouse
+pipx run cibuildwheel==4.2.0 --output-dir wheelhouse
pipx run twine upload wheelhouse/*.whl
```
diff --git a/docs/main.py b/docs/main.py
index ce79df3a..cb0026ba 100644
--- a/docs/main.py
+++ b/docs/main.py
@@ -12,7 +12,7 @@ def define_env(env: Any) -> None: # noqa: ANN401
"Hook function for mkdocs-macros"
@env.macro # type: ignore[untyped-decorator]
- def subprocess_run(*args: str) -> str:
+ def subprocess_run(*args: str) -> str: # type: ignore[misc]
"Run a subprocess and return the stdout"
env = os.environ.copy()
scripts = sysconfig.get_path("scripts")
diff --git a/docs/options.md b/docs/options.md
index 121dd621..eca0e924 100644
--- a/docs/options.md
+++ b/docs/options.md
@@ -64,8 +64,8 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
| Python 3.11 | cp311-macosx_x86_64
cp311-macosx_universal2
cp311-macosx_arm64 | cp311-win_amd64
cp311-win32
cp311-win_arm64 | cp311-manylinux_x86_64
cp311-manylinux_i686
cp311-musllinux_x86_64
cp311-musllinux_i686 | cp311-manylinux_aarch64
cp311-manylinux_ppc64le
cp311-manylinux_s390x
cp311-manylinux_armv7l
cp311-manylinux_riscv64
cp311-musllinux_aarch64
cp311-musllinux_ppc64le
cp311-musllinux_s390x
cp311-musllinux_armv7l
cp311-musllinux_riscv64 | | | |
| Python 3.12 | cp312-macosx_x86_64
cp312-macosx_universal2
cp312-macosx_arm64 | cp312-win_amd64
cp312-win32
cp312-win_arm64 | cp312-manylinux_x86_64
cp312-manylinux_i686
cp312-musllinux_x86_64
cp312-musllinux_i686 | cp312-manylinux_aarch64
cp312-manylinux_ppc64le
cp312-manylinux_s390x
cp312-manylinux_armv7l
cp312-manylinux_riscv64
cp312-musllinux_aarch64
cp312-musllinux_ppc64le
cp312-musllinux_s390x
cp312-musllinux_armv7l
cp312-musllinux_riscv64 | | | cp312-pyodide_wasm32 |
| Python 3.13 | cp313-macosx_x86_64
cp313-macosx_universal2
cp313-macosx_arm64 | cp313-win_amd64
cp313-win32
cp313-win_arm64 | cp313-manylinux_x86_64
cp313-manylinux_i686
cp313-musllinux_x86_64
cp313-musllinux_i686 | cp313-manylinux_aarch64
cp313-manylinux_ppc64le
cp313-manylinux_s390x
cp313-manylinux_armv7l
cp313-manylinux_riscv64
cp313-musllinux_aarch64
cp313-musllinux_ppc64le
cp313-musllinux_s390x
cp313-musllinux_armv7l
cp313-musllinux_riscv64 | cp313-android_arm64_v8a
cp313-android_x86_64 | cp313-ios_arm64_iphoneos
cp313-ios_arm64_iphonesimulator
cp313-ios_x86_64_iphonesimulator | cp313-pyodide_wasm32 |
-| Python 3.14 | cp314-macosx_x86_64
cp314-macosx_universal2
cp314-macosx_arm64
cp314t-macosx_x86_64
cp314t-macosx_universal2
cp314t-macosx_arm64 | cp314-win_amd64
cp314-win32
cp314-win_arm64
cp314t-win_amd64
cp314t-win32
cp314t-win_arm64 | cp314-manylinux_x86_64
cp314-manylinux_i686
cp314-musllinux_x86_64
cp314-musllinux_i686
cp314t-manylinux_x86_64
cp314t-manylinux_i686
cp314t-musllinux_x86_64
cp314t-musllinux_i686 | cp314-manylinux_aarch64
cp314-manylinux_ppc64le
cp314-manylinux_s390x
cp314-manylinux_armv7l
cp314-manylinux_riscv64
cp314-musllinux_aarch64
cp314-musllinux_ppc64le
cp314-musllinux_s390x
cp314-musllinux_armv7l
cp314-musllinux_riscv64
cp314t-manylinux_aarch64
cp314t-manylinux_ppc64le
cp314t-manylinux_s390x
cp314t-manylinux_armv7l
cp314t-manylinux_riscv64
cp314t-musllinux_aarch64
cp314t-musllinux_ppc64le
cp314t-musllinux_s390x
cp314t-musllinux_armv7l
cp314t-musllinux_riscv64 | cp314-android_arm64_v8a
cp314-android_x86_64 | cp314-ios_arm64_iphoneos
cp314-ios_arm64_iphonesimulator
cp314-ios_x86_64_iphonesimulator | |
-| Python 3.15 | cp315-macosx_x86_64
cp315-macosx_universal2
cp315-macosx_arm64
cp315t-macosx_x86_64
cp315t-macosx_universal2
cp315t-macosx_arm64 | cp315-win_amd64
cp315-win32
cp315-win_arm64
cp315t-win_amd64
cp315t-win32
cp315t-win_arm64 | cp315-manylinux_x86_64
cp315-manylinux_i686
cp315-musllinux_x86_64
cp315-musllinux_i686
cp315t-manylinux_x86_64
cp315t-manylinux_i686
cp315t-musllinux_x86_64
cp315t-musllinux_i686 | cp315-manylinux_aarch64
cp315-manylinux_ppc64le
cp315-manylinux_s390x
cp315-manylinux_armv7l
cp315-manylinux_riscv64
cp315-musllinux_aarch64
cp315-musllinux_ppc64le
cp315-musllinux_s390x
cp315-musllinux_armv7l
cp315-musllinux_riscv64
cp315t-manylinux_aarch64
cp315t-manylinux_ppc64le
cp315t-manylinux_s390x
cp315t-manylinux_armv7l
cp315t-manylinux_riscv64
cp315t-musllinux_aarch64
cp315t-musllinux_ppc64le
cp315t-musllinux_s390x
cp315t-musllinux_armv7l
cp315t-musllinux_riscv64 | cp315-android_arm64_v8a
cp315-android_x86_64 | cp315-ios_arm64_iphoneos
cp315-ios_arm64_iphonesimulator
cp315-ios_x86_64_iphonesimulator | |
+| Python 3.14 | cp314-macosx_x86_64
cp314-macosx_universal2
cp314-macosx_arm64
cp314t-macosx_x86_64
cp314t-macosx_universal2
cp314t-macosx_arm64 | cp314-win_amd64
cp314-win32
cp314-win_arm64
cp314t-win_amd64
cp314t-win32
cp314t-win_arm64 | cp314-manylinux_x86_64
cp314-manylinux_i686
cp314-musllinux_x86_64
cp314-musllinux_i686
cp314t-manylinux_x86_64
cp314t-manylinux_i686
cp314t-musllinux_x86_64
cp314t-musllinux_i686 | cp314-manylinux_aarch64
cp314-manylinux_ppc64le
cp314-manylinux_s390x
cp314-manylinux_armv7l
cp314-manylinux_riscv64
cp314-musllinux_aarch64
cp314-musllinux_ppc64le
cp314-musllinux_s390x
cp314-musllinux_armv7l
cp314-musllinux_riscv64
cp314t-manylinux_aarch64
cp314t-manylinux_ppc64le
cp314t-manylinux_s390x
cp314t-manylinux_armv7l
cp314t-manylinux_riscv64
cp314t-musllinux_aarch64
cp314t-musllinux_ppc64le
cp314t-musllinux_s390x
cp314t-musllinux_armv7l
cp314t-musllinux_riscv64 | cp314-android_arm64_v8a
cp314-android_x86_64 | cp314-ios_arm64_iphoneos
cp314-ios_arm64_iphonesimulator
cp314-ios_x86_64_iphonesimulator | cp314-pyodide_wasm32 |
+| Python 3.15 | cp315-macosx_x86_64
cp315-macosx_universal2
cp315-macosx_arm64
cp315t-macosx_x86_64
cp315t-macosx_universal2
cp315t-macosx_arm64 | cp315-win_amd64
cp315-win32
cp315-win_arm64
cp315t-win_amd64
cp315t-win32
cp315t-win_arm64 | cp315-manylinux_x86_64
cp315-manylinux_i686
cp315-musllinux_x86_64
cp315-musllinux_i686
cp315t-manylinux_x86_64
cp315t-manylinux_i686
cp315t-musllinux_x86_64
cp315t-musllinux_i686 | cp315-manylinux_aarch64
cp315-manylinux_ppc64le
cp315-manylinux_s390x
cp315-manylinux_armv7l
cp315-manylinux_riscv64
cp315-musllinux_aarch64
cp315-musllinux_ppc64le
cp315-musllinux_s390x
cp315-musllinux_armv7l
cp315-musllinux_riscv64
cp315t-manylinux_aarch64
cp315t-manylinux_ppc64le
cp315t-manylinux_s390x
cp315t-manylinux_armv7l
cp315t-manylinux_riscv64
cp315t-musllinux_aarch64
cp315t-musllinux_ppc64le
cp315t-musllinux_s390x
cp315t-musllinux_armv7l
cp315t-musllinux_riscv64 | cp315-android_arm64_v8a
cp315-android_x86_64 | cp315-ios_arm64_iphoneos
cp315-ios_arm64_iphonesimulator
cp315-ios_x86_64_iphonesimulator | cp315-pyodide_wasm32 |
| PyPy3.9 v7.3 | pp39-macosx_x86_64
pp39-macosx_arm64 | pp39-win_amd64 | pp39-manylinux_x86_64
pp39-manylinux_i686 | pp39-manylinux_aarch64 | | | |
| PyPy3.10 v7.3 | pp310-macosx_x86_64
pp310-macosx_arm64 | pp310-win_amd64 | pp310-manylinux_x86_64
pp310-manylinux_i686 | pp310-manylinux_aarch64 | | | |
| PyPy3.11 v7.3 | pp311-macosx_x86_64
pp311-macosx_arm64 | pp311-win_amd64 | pp311-manylinux_x86_64
pp311-manylinux_i686 | pp311-manylinux_aarch64 | | | |
@@ -357,13 +357,11 @@ values are:
- `cpython-prerelease`: Enables beta versions of Pythons if any are available
- (May-July, approximately).
+ (May-July, approximately). This also covers Pyodide versions built against a
+ beta CPython, which is the case for the current Pyodide prerelease.
- `pypy`: Enable PyPy.
- `pypy-eol`: Enable PyPy versions that have passed end of life (if still available).
- `graalpy`: Enable GraalPy.
-- `pyodide-prerelease`: Pyodide versions that haven't released yet, if one is
- available. Safe if you are shipping a site with an early build, not for
- general distribution.
- `pyodide-eol`: Enable Pyodide versions that are no longer the current stable
release (if still available).
- `all`: Enable all of the above.
@@ -481,7 +479,11 @@ files (from workspaces) are not supported.
are building GraalPy wheels, use `build` or `pip` as the build frontend
instead of `build[uv]` or `uv`.
-On Android and Pyodide, the "pip" frontend is not supported.
+On Android, the "pip" frontend is not supported.
+
+On Pyodide, `pyodide-build` is the default and only supported frontend; setting
+another frontend produces a warning and uses `pyodide-build` instead. See
+[Pyodide build frontend support](platforms.md#pyodide-build-frontend) for details.
You can specify extra arguments to pass to the build frontend using the
optional `args` option.
@@ -1916,14 +1918,14 @@ will not produce more logging about the build itself. Other levels only affect
the build frontend output, which is usually things like resolving and
downloading dependencies. The settings are:
-| | build | pip | uv | desc |
-|-------------|-------|--------|-------|----------------------------------------|
-| -2 | `-qq` | `-qq` | `-qq` | even more quiet, where supported |
-| -1 | `-q` | `-q` | `-q` | quiet mode, where supported |
-| 0 (default) | | | | default for build tool |
-| 1 | | `-v` | | print backend output |
-| 2 | `-v` | `-vv` | `-v` | print log messages e.g. resolving info |
-| 3 | `-vv` | `-vvv` | `-vv` | print even more debug info |
+| | build | pip | uv | pyodide-build | desc |
+|-------------|-------|--------|-------|---------------|----------------------------------------|
+| -2 | `-qq` | `-qq` | `-qq` | | even more quiet, where supported |
+| -1 | `-q` | `-q` | `-q` | | quiet mode, where supported |
+| 0 (default) | | | | | default for build tool |
+| 1 | | `-v` | | `-v` | print backend output |
+| 2 | `-v` | `-vv` | `-v` | `-vv` | print log messages e.g. resolving info |
+| 3 | `-vv` | `-vvv` | `-vv` | | print even more debug info |
Settings that are not supported for a specific frontend will log a warning.
The default build frontend is `build`, which does show build backend output by
diff --git a/docs/platforms.md b/docs/platforms.md
index cfae13d5..c1fd64eb 100644
--- a/docs/platforms.md
+++ b/docs/platforms.md
@@ -188,6 +188,11 @@ repair-wheel-command = "pyodide auditwheel repair --libdir /path/to/libraries --
The `--libdir` option specifies the directory containing cross-compiled shared libraries for WASM. You should not use the system library directories (e.g. `/usr/lib`), as those libraries are not built for WebAssembly.
+### Build frontend support {: #pyodide-build-frontend}
+
+The pyodide platform builds wheels by shelling out to `pyodide build`, via the `pyodide-build` [`build-frontend`](options.md#build-frontend), which itself is a meta build frontend and passes through commands to pypa/build with specialised handling. This is the only supported frontend for this platform, and is used by default. A global [`build-frontend`](options.md#build-frontend) setting naming another frontend is ignored with a warning on this platform.
+
+[`build-verbosity`](options.md#build-verbosity) is passed through to `pyodide build` as `-v`/`-vv`. It is capped at `-vv`. `pyodide build` has no `-vvv` flag.
## Android {: android}
@@ -236,7 +241,7 @@ machine β for example, if you're building on an ARM64 machine, then you can te
ARM64 wheel. Wheels of other architectures can still be built, but testing will
automatically be skipped.
-Any arguments specified using [`test-runtime`](options.md#test-runtime) will be passed as arguments to the Python script that starts the [testbed project](https://github.com/python/cpython/blob/main/Android/README.md#testing). cibuildwheel will automatically start the testbed project with `--site-packages` and `--cwd` arguments matching your test environment, as well as enabling verbose output with `-v` if [`build-verbosity`](options.md#build-verbosity) is enabled. The most common additional arguments to use will be `--managed minVersion` or `--managed maxVersion`, specifying the use of a managed Android emulator with the minimum or maximum supported Android version; or `--connected `, specifying the use of an existing booted Android emulator or device. By default, the testbed project will run with `--managed maxVersion`.
+Any arguments specified using [`test-runtime`](options.md#test-runtime) will be passed as arguments to the Python script that starts the [testbed project](https://github.com/python/cpython/blob/main/Platforms/Android/README.md#testing). cibuildwheel will automatically start the testbed project with `--site-packages` and `--cwd` arguments matching your test environment, as well as enabling verbose output with `-v` if [`build-verbosity`](options.md#build-verbosity) is enabled. The most common additional arguments to use will be `--managed minVersion` or `--managed maxVersion`, specifying the use of a managed Android emulator with the minimum or maximum supported Android version; or `--connected `, specifying the use of an existing booted Android emulator or device. By default, the testbed project will run with `--managed maxVersion`.
Running an emulator requires the build machine to either be bare-metal or support
nested virtualization. CI platforms known to meet this requirement are:
@@ -325,6 +330,6 @@ If tests have been configured, the test suite will be executed on the simulator
The iOS test environment can't support running shell scripts, so the [`test-command`](options.md#test-command) value must be specified as if it were a command line being passed to `python -m ...`.
-The test process uses the [same testbed used by CPython itself](https://github.com/python/cpython/tree/main/Apple/iOS#testing-python-on-ios) to run the CPython test suite. It is an Xcode project that has been configured to have a single Xcode "XCUnit" test - the result of which reports the success or failure of running `python -m `.
+The test process uses the [same testbed used by CPython itself](https://github.com/python/cpython/blob/main/Platforms/Apple/iOS/README.md#testing-python-on-ios) to run the CPython test suite. It is an Xcode project that has been configured to have a single Xcode "XCUnit" test - the result of which reports the success or failure of running `python -m `.
Any arguments specified using [`test-runtime`](options.md#test-runtime) will be passed as arguments to the Python script that starts the testbed project. The testbed project will be started with `-v` enabling verbose output if [`build-verbosity`](options.md#build-verbosity) is enabled; the most common additional argument to use will be `--simulator`, which allows the specification of a specific device or iOS version for the test simulator. By default, the testbed project will attempt to find an "SE class" simulator (i.e., an iPhone SE, iPhone 16e, or similar), running the newest iOS version available.
diff --git a/docs/working-examples.md b/docs/working-examples.md
index 87b1a340..a9d1404b 100644
--- a/docs/working-examples.md
+++ b/docs/working-examples.md
@@ -11,8 +11,8 @@ ref: working-examples
|-----------------------------------|----|----|:------|
| [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
-| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | The fundamental package for scientific computing with Python. |
+| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
@@ -35,8 +35,8 @@ ref: working-examples
| [cvxpy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A Python-embedded modeling language for convex optimization problems. |
| [pedalboard][] | ![github icon][] | ![windows icon][] ![linux icon][] ![apple icon][] | A Python library for working with audio data and audio plugins by wrapping the [JUCE](https://github.com/juce-framework/JUCE/) C++ framework. Uses cibuildwheel to deploy on as many operating systems and Python versions as possible with only one dependency (any NumPy). |
| [PyOxidizer][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A modern Python application packaging and distribution tool |
-| [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. |
| [River][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | π Online machine learning in Python |
+| [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. |
| [websockets][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Library for building WebSocket servers and clients. Mostly written in Python, with a small C 'speedups' extension module. |
| [OpenSpiel][] | ![github icon][] | ![apple icon][] ![linux icon][] | OpenSpiel is a collection of environments and algorithms for research in general reinforcement learning and search/planning in games. |
| [aiortc][] | ![github icon][] | ![apple icon][] ![linux icon][] | WebRTC and ORTC implementation for Python using asyncio. |
@@ -48,9 +48,9 @@ ref: working-examples
| [Implicit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes GPU support for linux wheels |
| [vispy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Main repository for Vispy |
| [coverage.py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The coverage tool for Python |
-| [Line Profiler][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Line-by-line profiling for Python |
-| [PyCryptodome][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A self-contained cryptographic library for Python |
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
+| [PyCryptodome][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A self-contained cryptographic library for Python |
+| [Line Profiler][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Line-by-line profiling for Python |
| [PyYAML][] | ![github icon][] | ![apple icon][] | Canonical source repository for PyYAML |
| [pikepdf][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by QPDF |
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, Pandas, PyTables and more |
@@ -67,22 +67,22 @@ ref: working-examples
| [google neuroglancer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | WebGL-based viewer for volumetric data |
| [Parselmouth][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. |
| [H3-py][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for H3, a hierarchical hexagonal geospatial indexing system |
-| [AutoPy][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. |
+| [AutoPy][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [DeepForest][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | An Efficient, Scalable and Optimized Python Framework for Deep Forest (2021.2.1) |
| [mosec][] | ![github icon][] | ![linux icon][] ![apple icon][] | A machine learning model serving framework powered by Rust |
| [Picologging][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A high-performance logging library for Python. |
| [markupsafe][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Safely add untrusted strings to HTML/XML markup. |
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS |
| [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | Example pybind11 module built with a CMake-based build system |
-| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python |
| [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub |
-| [tgcalls][] | ![github icon][] | ![apple icon][] ![windows icon][] | Python `pybind11` binding to Telegram's WebRTC library with third party dependencies like `OpenSSL`, `MozJPEG`, `FFmpeg`, etc. |
+| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python |
| [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] ![pyodide icon][] | Quickly search, compare, and analyze genomic and metagenomic data sets. |
+| [tgcalls][] | ![github icon][] | ![apple icon][] ![windows icon][] | Python `pybind11` binding to Telegram's WebRTC library with third party dependencies like `OpenSSL`, `MozJPEG`, `FFmpeg`, etc. |
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | Example pybind11 module built with a Python-based build system |
-| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
+| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
| [abess][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A fast best-subset selection library. It uses cibuildwheel to build a large project with C++ extensions. |
| [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq |
| [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing |
@@ -91,19 +91,19 @@ ref: working-examples
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | Jupyter-friendly Python interface for C++ MINUIT2 |
| [pillow-heif][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Bindings to libheif library with third party dependencies. Fully automated CI for tests and publishing including Apple Silicon builds. |
| [keyvi][] | ![github icon][] | ![linux icon][] ![apple icon][] | FST based key value index highly optimized for size and lookup performance, utilizes ccache action for improved runtime |
+| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
| [PyGLM][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Fast OpenGL Mathematics (GLM) for Python |
| [iDynTree][] | ![github icon][] | ![linux icon][] | Uses manylinux_2_24 |
-| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
-| [streaming-form-data][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Streaming parser for multipart/form-data written in Cython |
| [Imagecodecs (fork)][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] | Over 20 external dependencies in compiled libraries, custom docker image, `libomp`, `openblas` and `install_name_tool` for macOS. |
+| [streaming-form-data][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Streaming parser for multipart/form-data written in Cython |
| [pybase64][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![android icon][] ![ios icon][] ![pyodide icon][] | setuptools backend with custom CMake step for external sources. SBOM embedded via a custom repair step. |
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | Supports full range of wheels, including PyPy and alternate archs. |
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
| [Python-WebRTC][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | a Python extension that provides bindings to WebRTC M92 |
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] ![pyodide icon][] | An example combining scikit-build and pybind11 |
-| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
| [Arbor][] | ![github icon][] | ![apple icon][] ![linux icon][] | Arbor is a multi-compartment neuron simulation library; compatible with next-generation accelerators; best-practices applied to research software; focused on community-driven development. Includes a [small script](https://github.com/arbor-sim/arbor/blob/master/scripts/patchwheel.py) patching `rpath` in bundled libraries. |
+| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
| [clang-format][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Scikit-build wrapper around LLVM's CMake, all platforms, generic wheels. |
| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. |
| [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
@@ -122,8 +122,8 @@ ref: working-examples
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
[duckdb]: https://github.com/duckdb/duckdb
-[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy
+[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib
[Tornado]: https://github.com/tornadoweb/tornado
@@ -146,8 +146,8 @@ ref: working-examples
[cvxpy]: https://github.com/cvxpy/cvxpy
[pedalboard]: https://github.com/spotify/pedalboard
[PyOxidizer]: https://github.com/indygreg/PyOxidizer
-[twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport
[River]: https://github.com/online-ml/river
+[twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport
[websockets]: https://github.com/python-websockets/websockets
[OpenSpiel]: https://github.com/google-deepmind/open_spiel
[aiortc]: https://github.com/aiortc/aiortc
@@ -159,9 +159,9 @@ ref: working-examples
[Implicit]: https://github.com/benfred/implicit
[vispy]: https://github.com/vispy/vispy
[coverage.py]: https://github.com/nedbat/coveragepy
-[Line Profiler]: https://github.com/pyutils/line_profiler
-[PyCryptodome]: https://github.com/Legrandin/pycryptodome
[PyAV]: https://github.com/PyAV-Org/PyAV
+[PyCryptodome]: https://github.com/Legrandin/pycryptodome
+[Line Profiler]: https://github.com/pyutils/line_profiler
[PyYAML]: https://github.com/yaml/pyyaml
[pikepdf]: https://github.com/pikepdf/pikepdf
[numexpr]: https://github.com/pydata/numexpr
@@ -178,22 +178,22 @@ ref: working-examples
[google neuroglancer]: https://github.com/google/neuroglancer
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
[H3-py]: https://github.com/uber/h3-py
-[AutoPy]: https://github.com/autopilot-rs/autopy
[time-machine]: https://github.com/adamchainz/time-machine
+[AutoPy]: https://github.com/autopilot-rs/autopy
[DeepForest]: https://github.com/LAMDA-NJU/Deep-Forest
[mosec]: https://github.com/mosecorg/mosec
[Picologging]: https://github.com/microsoft/picologging
[markupsafe]: https://github.com/pallets/markupsafe
[Rtree]: https://github.com/Toblerity/rtree
[pybind11 cmake_example]: https://github.com/pybind/cmake_example
-[KDEpy]: https://github.com/tommyod/KDEpy
[dd-trace-py]: https://github.com/DataDog/dd-trace-py
-[tgcalls]: https://github.com/MarshalX/tgcalls
+[KDEpy]: https://github.com/tommyod/KDEpy
[sourmash]: https://github.com/sourmash-bio/sourmash
+[tgcalls]: https://github.com/MarshalX/tgcalls
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
[pybind11 python_example]: https://github.com/pybind/python_example
-[python-snappy]: https://github.com/intake/python-snappy
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
+[python-snappy]: https://github.com/intake/python-snappy
[abess]: https://github.com/abess-team/abess
[jq.py]: https://github.com/mwilliamson/jq.py
[cyvcf2]: https://github.com/brentp/cyvcf2
@@ -202,19 +202,19 @@ ref: working-examples
[iminuit]: https://github.com/scikit-hep/iminuit
[pillow-heif]: https://github.com/bigcat88/pillow_heif
[keyvi]: https://github.com/KeyviDev/keyvi
+[power-grid-model]: https://github.com/PowerGridModel/power-grid-model
[PyGLM]: https://github.com/Zuzu-Typ/PyGLM
[iDynTree]: https://github.com/robotology/idyntree
-[power-grid-model]: https://github.com/PowerGridModel/power-grid-model
[TgCrypto]: https://github.com/pyrogram/tgcrypto
-[streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
+[streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data
[pybase64]: https://github.com/mayeut/pybase64
[boost-histogram]: https://github.com/scikit-hep/boost-histogram
[bx-python]: https://github.com/bxlab/bx-python
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
-[fathon]: https://github.com/stfbnc/fathon
[Arbor]: https://github.com/arbor-sim/arbor
+[fathon]: https://github.com/stfbnc/fathon
[clang-format]: https://github.com/ssciwr/clang-format-wheel
[polaroid]: https://github.com/daggy1234/polaroid
[ninja]: https://github.com/scikit-build/ninja-python-distributions
diff --git a/examples/azure-pipelines-minimal.yml b/examples/azure-pipelines-minimal.yml
index 8f9e1377..dab0aaab 100644
--- a/examples/azure-pipelines-minimal.yml
+++ b/examples/azure-pipelines-minimal.yml
@@ -6,7 +6,7 @@ jobs:
- bash: |
set -o errexit
python3 -m pip install --upgrade pip
- pip3 install cibuildwheel==4.1.0
+ pip3 install cibuildwheel==4.2.0
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
@@ -20,7 +20,7 @@ jobs:
- bash: |
set -o errexit
python3 -m pip install --upgrade pip
- python3 -m pip install cibuildwheel==4.1.0
+ python3 -m pip install cibuildwheel==4.2.0
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
@@ -34,7 +34,7 @@ jobs:
- bash: |
set -o errexit
python -m pip install --upgrade pip
- pip install cibuildwheel==4.1.0
+ pip install cibuildwheel==4.2.0
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
diff --git a/examples/circleci-minimal.yml b/examples/circleci-minimal.yml
index 34803e09..6efbe8c6 100644
--- a/examples/circleci-minimal.yml
+++ b/examples/circleci-minimal.yml
@@ -11,7 +11,7 @@ jobs:
- run:
name: Build the Linux wheels.
command: |
- python3 -m pip install --user cibuildwheel==4.1.0
+ python3 -m pip install --user cibuildwheel==4.2.0
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
@@ -28,7 +28,7 @@ jobs:
- run:
name: Build the Linux aarch64 wheels.
command: |
- python3 -m pip install --user cibuildwheel==4.1.0
+ python3 -m pip install --user cibuildwheel==4.2.0
python3 -m cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
@@ -44,7 +44,7 @@ jobs:
name: Build the OS X wheels.
command: |
sudo softwareupdate --install-rosetta --agree-to-license # for x86_64/universal2 tests
- pip3 install cibuildwheel==4.1.0
+ pip3 install cibuildwheel==4.2.0
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
diff --git a/examples/github-deploy.yml b/examples/github-deploy.yml
index f076c5c1..424786d6 100644
--- a/examples/github-deploy.yml
+++ b/examples/github-deploy.yml
@@ -53,7 +53,7 @@ jobs:
persist-credentials: false
- name: Build wheels
- uses: pypa/cibuildwheel@v4.1.0
+ uses: pypa/cibuildwheel@v4.2.0
env:
CIBW_PLATFORM: ${{ matrix.platform || 'auto' }}
CIBW_ARCHS: ${{ matrix.archs || 'auto' }}
diff --git a/examples/github-minimal.yml b/examples/github-minimal.yml
index 2184393b..32db9ea2 100644
--- a/examples/github-minimal.yml
+++ b/examples/github-minimal.yml
@@ -17,7 +17,7 @@ jobs:
persist-credentials: false
- name: Build wheels
- uses: pypa/cibuildwheel@v4.1.0
+ uses: pypa/cibuildwheel@v4.2.0
# env:
# CIBW_SOME_OPTION: value
# ...
diff --git a/examples/github-pipx.yml b/examples/github-pipx.yml
index a9786952..06fc5880 100644
--- a/examples/github-pipx.yml
+++ b/examples/github-pipx.yml
@@ -17,7 +17,7 @@ jobs:
persist-credentials: false
- name: Build wheels
- run: pipx run cibuildwheel==4.1.0
+ run: pipx run cibuildwheel==4.2.0
- uses: actions/upload-artifact@v4
with:
diff --git a/examples/github-with-qemu.yml b/examples/github-with-qemu.yml
index 28d69750..fbf82808 100644
--- a/examples/github-with-qemu.yml
+++ b/examples/github-with-qemu.yml
@@ -23,7 +23,7 @@ jobs:
platforms: all
- name: Build wheels
- uses: pypa/cibuildwheel@v4.1.0
+ uses: pypa/cibuildwheel@v4.2.0
env:
# configure cibuildwheel on Linux to build native archs ('auto'),
# and to split the remaining architectures between the x86_64 and
diff --git a/examples/gitlab-minimal.yml b/examples/gitlab-minimal.yml
index 655f0b4f..367865a5 100644
--- a/examples/gitlab-minimal.yml
+++ b/examples/gitlab-minimal.yml
@@ -12,7 +12,7 @@ linux:
DOCKER_TLS_CERTDIR: ""
script:
- curl -sSL https://get.docker.com/ | sh
- - python -m pip install cibuildwheel==4.1.0
+ - python -m pip install cibuildwheel==4.2.0
- cibuildwheel --output-dir wheelhouse
artifacts:
paths:
@@ -23,7 +23,7 @@ windows:
before_script:
- choco install python -y --allow-downgrade --version 3.12.4
- choco install git.install -y
- - py -m pip install cibuildwheel==4.1.0
+ - py -m pip install cibuildwheel==4.2.0
script:
- py -m cibuildwheel --output-dir wheelhouse --platform windows
artifacts:
@@ -35,7 +35,7 @@ windows:
macos:
image: macos-14-xcode-15
before_script:
- - python3 -m pip install cibuildwheel==4.1.0
+ - python3 -m pip install cibuildwheel==4.2.0
script:
- python3 -m cibuildwheel --output-dir wheelhouse
artifacts:
diff --git a/examples/gitlab-with-qemu.yml b/examples/gitlab-with-qemu.yml
index 65744895..d123aca0 100644
--- a/examples/gitlab-with-qemu.yml
+++ b/examples/gitlab-with-qemu.yml
@@ -14,7 +14,7 @@ linux:
- curl -sSL https://get.docker.com/ | sh
# Warning: This is extremely slow, be careful with how many wheels you build
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- - python -m pip install cibuildwheel==4.1.0
+ - python -m pip install cibuildwheel==4.2.0
# Assuming your CI runner's default architecture is x86_64...
- cibuildwheel --output-dir wheelhouse --platform linux --archs aarch64
artifacts:
diff --git a/noxfile.py b/noxfile.py
index 319f1b91..ecaa4417 100755
--- a/noxfile.py
+++ b/noxfile.py
@@ -16,9 +16,11 @@ See sessions with `nox -l`
"""
import os
+import re
import shutil
import sys
from pathlib import Path
+from typing import Any
import nox
@@ -63,6 +65,59 @@ def tests(session: nox.Session) -> None:
session.run("pytest", "test", "-x", "--durations", "0", "--timeout=2400", "test")
+# Packages held back for GraalPy until upstream fixes land. uv pip compile
+# can't express a per-implementation split, so the compiled pin is patched:
+# GraalPy (matching `graalpy_marker`) gets `held`, everything else
+# (`other_marker`) tracks the freshly compiled version.
+GRAALPY_HELD_BACK = (
+ # Newer pip breaks GraalPy on macOS and Windows.
+ {
+ "package": "pip",
+ "held": ("26.1.2", "26.0.1"),
+ "graalpy_marker": (
+ 'implementation_name == "graalpy" and platform_system != "Windows"',
+ 'implementation_name == "graalpy" and platform_system == "Windows"',
+ ),
+ "other_marker": 'implementation_name != "graalpy"',
+ },
+ # filelock >=3.30 imports errno.ENOTSUP, which GraalPy lacks (fix due ~2026-08).
+ {
+ "package": "filelock",
+ "held": ("3.29.7",),
+ "graalpy_marker": ('implementation_name == "graalpy"',),
+ "other_marker": 'implementation_name != "graalpy"',
+ },
+)
+
+
+def _pin_graalpy_workarounds(output_file: Path) -> None:
+ text = output_file.read_text()
+ for pin in GRAALPY_HELD_BACK:
+ assert isinstance(pin["package"], str)
+ package = re.escape(pin["package"])
+ graalpy_pins = "\n".join(
+ f"{pin['package']}=={pin['held'][i]}; {pin['graalpy_marker'][i]}"
+ for i in range(len(pin["held"]))
+ )
+ text = re.sub(
+ rf"^{package}==(?P[^\s;]+)$",
+ f"{pin['package']}==\\g; {pin['other_marker']}\n{graalpy_pins}",
+ text,
+ flags=re.MULTILINE,
+ )
+ output_file.write_text(text)
+
+
+def _graalpy_python_versions(build_platforms: dict[str, Any]) -> set[str]:
+ """Python minor versions (e.g. "3.12") that ship a GraalPy configuration."""
+ return {
+ ".".join(config["version"].split(".")[:2])
+ for platform in build_platforms.values()
+ for config in platform["python_configurations"]
+ if config["identifier"].startswith("gp")
+ }
+
+
@nox.session(default=False, tags=["update"])
def update_constraints(session: nox.Session) -> None:
"""
@@ -79,6 +134,9 @@ def update_constraints(session: nox.Session) -> None:
env = os.environ.copy()
env["UV_CUSTOM_COMPILE_COMMAND"] = f"nox -s {session.name}"
+ build_platforms = nox.project.load_toml(resources / "build-platforms.toml")
+ graalpy_versions = _graalpy_python_versions(build_platforms)
+
for minor_version in range(9, 16):
python_version = f"3.{minor_version}"
output_file = resources / f"constraints-python{python_version.replace('.', '')}.txt"
@@ -92,13 +150,14 @@ def update_constraints(session: nox.Session) -> None:
f"--output-file={output_file}",
env=env,
)
+ if python_version in graalpy_versions:
+ _pin_graalpy_workarounds(output_file)
shutil.copyfile(
resources / "constraints-python315.txt",
resources / "constraints.txt",
)
- build_platforms = nox.project.load_toml(resources / "build-platforms.toml")
pyodides = build_platforms["pyodide"]["python_configurations"]
for pyodide in pyodides:
python_version = ".".join(pyodide["version"].split(".")[:2])
@@ -176,7 +235,9 @@ def docs(session: nox.Session) -> None:
"""
pyproject = nox.project.load_toml()
session.install("-e.", *nox.project.dependency_groups(pyproject, "docs"))
- session.run("mkdocs", "serve" if session.interactive else "build", "--strict", *session.posargs)
+ session.run(
+ "properdocs", "serve" if session.interactive else "build", "--strict", *session.posargs
+ )
@nox.session(default=False)
diff --git a/mkdocs.yml b/properdocs.yml
similarity index 100%
rename from mkdocs.yml
rename to properdocs.yml
diff --git a/pyproject.toml b/pyproject.toml
index b0c881c3..8aba9f5d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "cibuildwheel"
-version = "4.1.0"
+version = "4.2.0"
description = "Build Python wheels on CI with minimal configuration."
readme = "README.md"
license = "BSD-2-Clause"
@@ -68,7 +68,8 @@ docs = [
"mkdocs-include-markdown-plugin==7.1.8",
"mkdocs-intersphinx>=0.1.1; python_version >= '3.12'",
"mkdocs-macros-plugin>=1.4.1",
- "mkdocs==1.6.1",
+ "properdocs==1.6.7",
+ "properdocs-theme-readthedocs",
"pymdown-extensions",
"rich",
]
@@ -115,10 +116,27 @@ files = [
"bin/*.py",
"noxfile.py",
]
+disallow_any_decorated = true
+disallow_any_unimported = true
+disallow_untyped_globals = true
+disallow_redefinition = true
warn_unused_configs = true
strict = true
-enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
+enable_error_code = [
+ "deprecated",
+ "exhaustive-match",
+ "ignore-without-code",
+ "mutable-override",
+ "possibly-undefined",
+ "redundant-expr",
+ "redundant-self",
+ "truthy-bool",
+ "truthy-iterable",
+ "unimported-reveal",
+ "unused-awaitable",
+]
warn_unreachable = false
+native_parser = true
[[tool.mypy.overrides]]
module = [
@@ -129,6 +147,10 @@ module = [
]
ignore_missing_imports = true
+[[tool.mypy.overrides]]
+module = ["cibuildwheel.bashlex_eval"]
+disable_error_code = ["no-any-unimported"]
+
[tool.pylint]
py-version = "3.11"
@@ -165,6 +187,7 @@ messages_control.disable = [
"wrong-import-position",
"unused-argument", # Handled by Ruff
"import-outside-toplevel", # Handled by Ruff
+ "broad-exception-caught", # Handled by Ruff
"broad-exception-raised", # Could be improved eventually
"consider-using-in", # MyPy can't narrow "in"
]
@@ -216,6 +239,7 @@ ignore = [
"PT007", # Lists of tuples in Pytest
"PYI025", # Set as AbstractSet
"PTH123", # open -> Path.open
+ "TRY002", # Create your own exception
]
flake8-unused-arguments.ignore-variadic-names = true
flake8-tidy-imports.ban-relative-imports = "all"
@@ -233,7 +257,7 @@ future-annotations = true
[tool.ruff.lint.per-file-ignores]
"unit_test/*" = ["PLC1901", "TID252"]
-"test/*" = ["TID252"]
+"test/*" = ["TID252", "N999"]
"bin/*" = ["TID251"]
"cibuildwheel/resources/install_certifi.py" = ["PTH"]
diff --git a/test/conftest.py b/test/conftest.py
index 15d2f57f..3d648c64 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+import dataclasses
import json
import os
import subprocess
@@ -12,14 +13,16 @@ from cibuildwheel.ci import detect_ci_provider
from cibuildwheel.options import CommandLineArguments, Options
from cibuildwheel.selector import EnableGroup
from cibuildwheel.typing import PLATFORMS
+from cibuildwheel.util.resources import PINNED_DOCKER_IMAGES
from cibuildwheel.venv import find_uv
from . import utils
-from .utils import DEFAULT_CIBW_ENABLE, EMULATED_ARCHS, get_platform
+from .utils import DEFAULT_CIBW_ENABLE, EMULATED_ARCHS, get_enable_groups, get_platform
TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Generator
+ from pathlib import Path
def pytest_addoption(parser: pytest.Parser) -> None:
@@ -74,7 +77,19 @@ def pytest_configure(config: pytest.Config) -> None:
os.environ["CIBW_PLATFORM"] = flag_platform
-def docker_warmup(request: pytest.FixtureRequest) -> None:
+@dataclasses.dataclass(frozen=True)
+class DockerWarmUpImage:
+ source_name: str
+ cached_name: str
+
+
+def get_docker_warmup_images(request: pytest.FixtureRequest) -> list[DockerWarmUpImage] | None:
+ enable_groups = get_enable_groups()
+ # Check missing pre-installed interpreters are needed
+ enable_groups &= {EnableGroup.GraalPy, EnableGroup.PyPyEoL}
+ if not enable_groups:
+ return None
+
machine = request.config.getoption("--run-emulation", default=None)
if machine is None:
archs = {arch.value for arch in Architecture.auto_archs("linux")}
@@ -86,7 +101,7 @@ def docker_warmup(request: pytest.FixtureRequest) -> None:
# Only include architectures where there are missing pre-installed interpreters
archs &= {"x86_64", "i686", "aarch64"}
if not archs:
- return
+ return None
options = Options(
platform="linux",
@@ -96,17 +111,28 @@ def docker_warmup(request: pytest.FixtureRequest) -> None:
)
build_options = options.build_options(None)
assert build_options.manylinux_images is not None
- assert build_options.musllinux_images is not None
- images = [build_options.manylinux_images[arch] for arch in archs] + [
- build_options.musllinux_images[arch] for arch in archs
- ]
+ images: list[DockerWarmUpImage] = []
+ for arch in archs:
+ source_name = build_options.manylinux_images[arch]
+ cached_name = source_name
+ if "@sha256:" in source_name:
+ cached_name = source_name.rsplit("@sha256:", 1)[0] + ":cibw_cache_fixture"
+ images.append(DockerWarmUpImage(source_name, cached_name))
+ if images:
+ return images
+ return None
+
+
+def docker_warmup(images: list[DockerWarmUpImage], docker_warmup_config: Path) -> None:
command = (
"manylinux-interpreters ensure-all &&"
"cpython3.13 -m pip download -d /tmp setuptools wheel pytest"
)
+ config_content = PINNED_DOCKER_IMAGES.read_text()
for image in images:
+ config_content = config_content.replace(image.source_name, image.cached_name)
container_id = subprocess.run(
- ["docker", "create", image, "bash", "-c", command],
+ ["docker", "create", image.source_name, "bash", "-c", command],
text=True,
check=True,
stdout=subprocess.PIPE,
@@ -118,37 +144,48 @@ def docker_warmup(request: pytest.FixtureRequest) -> None:
).stdout.strip()
assert exit_code == "0"
subprocess.run(
- ["docker", "commit", container_id, image], check=True, stdout=subprocess.DEVNULL
+ ["docker", "commit", container_id, image.cached_name],
+ check=True,
+ stdout=subprocess.DEVNULL,
)
finally:
subprocess.run(["docker", "rm", container_id], check=True, stdout=subprocess.DEVNULL)
+ docker_warmup_config.write_text(config_content)
@pytest.fixture(scope="session", autouse=True)
def docker_warmup_fixture(
request: pytest.FixtureRequest, tmp_path_factory: pytest.TempPathFactory, worker_id: str
-) -> None:
+) -> Generator[None, None, None]:
# if we're in CI testing linux, let's warm-up docker images
if detect_ci_provider() is None or get_platform() != "linux":
- return None
- if request.config.getoption("--run-emulation", default=None) is not None:
+ images = None
+ elif request.config.getoption("--run-emulation", default=None) is not None:
# emulation tests only run one test in CI, caching the image only slows down the test
- return None
+ images = None
+ else:
+ images = get_docker_warmup_images(request)
+ if images is None:
+ yield None
+ return
if worker_id == "master":
# not executing with multiple workers
# it might be unsafe to write to tmp_path_factory.getbasetemp().parent
- return docker_warmup(request)
+ docker_warmup_config = tmp_path_factory.getbasetemp() / "docker_warmup.cfg"
+ docker_warmup(images, docker_warmup_config)
+ else:
+ # get the temp directory shared by all workers
+ root_tmp_dir = tmp_path_factory.getbasetemp().parent
- # get the temp directory shared by all workers
- root_tmp_dir = tmp_path_factory.getbasetemp().parent
+ docker_warmup_config = root_tmp_dir / "docker_warmup.cfg"
+ with FileLock(str(docker_warmup_config) + ".lock"):
+ if not docker_warmup_config.is_file():
+ docker_warmup(images, docker_warmup_config)
- fn = root_tmp_dir / "warmup.done"
- with FileLock(str(fn) + ".lock"):
- if not fn.is_file():
- docker_warmup(request)
- fn.write_text("done")
- return None
+ with pytest.MonkeyPatch.context() as monkeypatch:
+ monkeypatch.setenv("CIBW_INTERNAL_PINNED_DOCKER_IMAGES", str(docker_warmup_config))
+ yield None
@pytest.fixture(params=["pip", "build"])
@@ -157,8 +194,8 @@ def build_frontend_env_nouv(request: pytest.FixtureRequest) -> dict[str, str]:
marks = {m.name for m in request.node.iter_markers()}
platform = "pyodide" if "pyodide" in marks else get_platform()
- if platform == "pyodide" and frontend == "pip":
- pytest.skip("Can't use pip as build frontend for pyodide platform")
+ if platform == "pyodide":
+ pytest.skip("pyodide only supports the pyodide-build frontend")
return {"CIBW_BUILD_FRONTEND": frontend}
@@ -176,10 +213,10 @@ def build_frontend_env(request: pytest.FixtureRequest) -> Generator[dict[str, st
else:
platform = get_platform()
- if platform in {"pyodide", "ios", "android"} and frontend == "pip":
+ if platform == "pyodide":
+ pytest.skip("pyodide only supports the pyodide-build frontend")
+ if platform in {"ios", "android"} and frontend == "pip":
pytest.skip(f"Can't use pip as build frontend for {platform}")
- if platform == "pyodide" and frontend in {"build[uv]", "uv"}:
- pytest.skip("Can't use uv with pyodide yet")
uv_path = find_uv()
if uv_path is None and frontend in {"build[uv]", "uv"}:
pytest.skip("Can't find uv, so skipping uv tests")
diff --git a/test/test_abi_variants.py b/test/test_abi_variants.py
index 56fa08de..2d11f8fc 100644
--- a/test/test_abi_variants.py
+++ b/test/test_abi_variants.py
@@ -54,7 +54,7 @@ def test_abi3(tmp_path: Path) -> None:
"CIBW_BUILD": (
"cp314-*"
if utils.get_platform() == "pyodide"
- else "cp39-* cp310-* pp310-* gp312_250-* cp312-* cp314t-*"
+ else "cp39-* cp310-* pp311-* gp312_250-* cp312-* cp314t-*"
),
"CIBW_ENABLE": "all",
},
@@ -77,7 +77,7 @@ def test_abi3(tmp_path: Path) -> None:
"cp39-cp39",
"cp310-abi3", # <-- ABI3, works with 3.10 and 3.12
"cp314-cp314t",
- "pp310-pypy310_pp73",
+ "pp311-pypy311_pp73",
"graalpy312-graalpy250_312_native",
],
)
@@ -203,7 +203,7 @@ def test_abi_none(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
"CIBW_TEST_REQUIRES": "pytest",
"CIBW_TEST_COMMAND": f"{utils.invoke_pytest()} {{project}}/test",
# limit the number of builds for test performance reasons
- "CIBW_BUILD": "cp39-* cp{}{}-* cp314t-* pp310-*".format(*utils.SINGLE_PYTHON_VERSION),
+ "CIBW_BUILD": "cp39-* cp{}{}-* cp314t-* pp311-*".format(*utils.SINGLE_PYTHON_VERSION),
"CIBW_ENABLE": "all",
},
)
diff --git a/test/test_android.py b/test/test_android.py
index 59cec2c2..ae4d23e8 100644
--- a/test/test_android.py
+++ b/test/test_android.py
@@ -619,24 +619,54 @@ def test_repair_error(
assert error in capfd.readouterr().err
-# This also tests integration with pkgconf, because Meson uses it to find Python.
+# This also tests integration with pkgconf, which Meson uses to find Python and
+# OpenBLAS.
@needs_emulator
def test_meson(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
- # Alter spam.filter to return the value of a Fortran function.
new_meson_project(
- spam_c_top_level_add="int fortran_func_();",
- spam_c_function_add="sts = fortran_func_();",
project_args_add="'fortran',",
- extension_args_add="'fortran.f90', link_language: 'fortran',",
+ extension_args_add=dedent(
+ """\
+ 'fortran.f90',
+ link_language: 'fortran',
+ dependencies: [dependency('openblas', method: 'pkg-config')],
+ """
+ ),
+ # Alter spam.filter to call an OpenBLAS function, and return the value of a
+ # Fortran function.
+ spam_c_top_level_add=dedent(
+ """\
+ #include
+ int fortran_func_();
+ """
+ ),
+ spam_c_function_add=dedent(
+ """\
+ openblas_get_config();
+ sts = fortran_func_();
+ """
+ ),
).generate(tmp_path)
- # TODO: remove once meson-python has a release with Android support.
- pyproject_path = tmp_path / "pyproject.toml"
- pyproject_path.write_text(
- pyproject_path.read_text().replace(
- "meson-python", "meson-python @ git+https://github.com/mesonbuild/meson-python@main"
+ # Add a before-build script to download OpenBLAS.
+ before_build = tmp_path / "cibw_before_build.sh"
+ before_build.write_text(
+ dedent(
+ """\
+ #!/bin/sh
+ set -eu
+
+ openblas_dir=$(pwd)/openblas
+ rm -rf $openblas_dir
+ mkdir -p $openblas_dir
+ pip install \\
+ --target $openblas_dir \\
+ --index-url https://chaquo.com/pypi-upstream/ \\
+ chaquopy-openblas==0.3.33
+ """
)
)
+ before_build.chmod(0o755)
# Add Fortran code.
(tmp_path / "fortran.f90").write_text(
@@ -652,7 +682,15 @@ def test_meson(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None:
script = 'import spam; print(f"result: {spam.filter("")}")'
cibuildwheel_run(
tmp_path,
- add_env={**cp313_env, "CIBW_TEST_COMMAND": f"python -c '{script}'"},
+ add_env={
+ **cp313_env,
+ "CIBW_BEFORE_BUILD": str(before_build),
+ "CIBW_ENVIRONMENT": (
+ 'PKG_CONFIG_PATH="$(pwd)/openblas/chaquopy/lib/pkgconfig" '
+ 'AUDITWHEEL_LD_LIBRARY_PATH="$(pwd)/openblas/chaquopy/lib"'
+ ),
+ "CIBW_TEST_COMMAND": f"python -c '{script}'",
+ },
)
assert "result: 42" in capfd.readouterr().out
@@ -690,7 +728,7 @@ def test_xbuild_files(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> None
add_env={
**cp313_env,
# TODO: remove this once there are official Android NumPy wheels on PyPI.
- "PIP_EXTRA_INDEX_URL": "https://chaquo.com/pypi-test",
+ "PIP_EXTRA_INDEX_URL": "https://chaquo.com/pypi-upstream",
"CIBW_ARCHS": "all", # Include both native and non-native archs.
"CIBW_TEST_COMMAND": f"python -c '{script}'",
},
diff --git a/test/test_before_build.py b/test/test_before_build.py
index 6986591c..ca120ad4 100644
--- a/test/test_before_build.py
+++ b/test/test_before_build.py
@@ -50,7 +50,7 @@ def test(tmp_path: Path) -> None:
"""python -c "import pathlib, sys; pathlib.Path('{project}/pythonversion_bb.txt').write_text(sys.version)" && """
f'''python -c "import pathlib, sys; pathlib.Path('{{project}}/pythonprefix_bb.txt').write_text({SYS_PREFIX})"'''
)
- frontend = "build"
+ frontend = "pyodide-build" if utils.get_platform() == "pyodide" else "build"
if utils.get_platform() != "pyodide":
before_build = f"python -m pip install setuptools && {before_build}"
frontend = f"{frontend};args: --no-isolation"
diff --git a/test/test_build_frontend_args.py b/test/test_build_frontend_args.py
index 3c1aa6a2..1e3c4988 100644
--- a/test/test_build_frontend_args.py
+++ b/test/test_build_frontend_args.py
@@ -15,7 +15,17 @@ if TYPE_CHECKING:
"frontend_name",
[
pytest.param("pip", marks=utils.skip_if_pyodide("No pip for pyodide")),
- "build",
+ pytest.param(
+ "build",
+ marks=utils.skip_if_pyodide("pyodide only supports the pyodide-build frontend"),
+ ),
+ pytest.param(
+ "pyodide-build",
+ marks=pytest.mark.skipif(
+ utils.get_platform() != "pyodide",
+ reason="pyodide-build frontend is only valid on pyodide",
+ ),
+ ),
],
)
def test_build_frontend_args(
@@ -27,7 +37,7 @@ def test_build_frontend_args(
# the build will fail because the frontend is called with '-h' - it prints the help message
add_env = {"CIBW_BUILD_FRONTEND": f"{frontend_name}; args: -h"}
- if utils.get_platform() == "pyodide":
+ if frontend_name == "pyodide-build":
add_env["TERM"] = "dumb" # disable color / style
add_env["NO_COLOR"] = "1"
with pytest.raises(subprocess.CalledProcessError):
@@ -40,7 +50,7 @@ def test_build_frontend_args(
if frontend_name == "pip":
assert "Usage:" in captured.out
assert "Wheel Options:" in captured.out
- elif utils.get_platform() == "pyodide":
+ elif frontend_name == "pyodide-build":
assert "Usage: pyodide build" in captured.out
else:
assert "usage:" in captured.out
diff --git a/test/test_container_engine.py b/test/test_container_engine.py
index 34f6a151..99816175 100644
--- a/test/test_container_engine.py
+++ b/test/test_container_engine.py
@@ -12,7 +12,10 @@ basic_project = test_projects.new_c_project()
def test_podman(
- tmp_path: Path, capfd: pytest.CaptureFixture[str], request: pytest.FixtureRequest
+ tmp_path: Path,
+ capfd: pytest.CaptureFixture[str],
+ request: pytest.FixtureRequest,
+ monkeypatch: pytest.MonkeyPatch,
) -> None:
if utils.get_platform() != "linux":
pytest.skip("the test is only relevant to the linux build")
@@ -20,6 +23,9 @@ def test_podman(
if not request.config.getoption("--run-podman"):
pytest.skip("needs --run-podman option to run")
+ # we can't use images cached in the docker_warmup_fixture autouse fixture
+ monkeypatch.delenv("CIBW_INTERNAL_PINNED_DOCKER_IMAGES", raising=False)
+
project_dir = tmp_path / "project"
basic_project.generate(project_dir)
diff --git a/test/test_environment.py b/test/test_environment.py
index aa56bb44..1035a0bf 100644
--- a/test/test_environment.py
+++ b/test/test_environment.py
@@ -100,63 +100,3 @@ def test_overridden_path(tmp_path: Path, capfd: pytest.CaptureFixture[str]) -> N
assert "python available on PATH doesn't match our installed instance" in captured.err.replace(
"venv", "installed"
)
-
-
-@pytest.mark.parametrize(
- "build_frontend",
- [
- pytest.param("pip", marks=utils.skip_if_pyodide("No pip for pyodide")),
- pytest.param(
- "build",
- marks=utils.skip_if_pyodide(
- "pyodide doesn't support multiple values for PIP_CONSTRAINT"
- ),
- ),
- ],
-)
-def test_overridden_pip_constraint(tmp_path: Path, build_frontend: str) -> None:
- """
- Verify that users can use PIP_CONSTRAINT to specify a specific version of
- a build-system.requires dependency, by asserting the version of pytz in the
- setup.py.
- """
- project_dir = tmp_path / "project"
-
- project = test_projects.new_c_project(
- setup_py_add=textwrap.dedent(
- """
- import pytz
- assert pytz.__version__ == "2022.4", f"{pytz.__version__!r} != '2022.4'"
- """
- )
- )
- project.files["pyproject.toml"] = textwrap.dedent(
- """
- [build-system]
- requires = ["setuptools", "pytz"]
- build-backend = "setuptools.build_meta"
- """
- )
- project.generate(project_dir)
-
- if utils.get_platform() == "linux":
- # put the constraints file in the project directory, so it's available
- # in the docker container
- constraints_file = project_dir / "constraints.txt"
- else:
- constraints_file = tmp_path / "constraints.txt"
-
- constraints_file.write_text("pytz==2022.4")
-
- actual_wheels = utils.cibuildwheel_run(
- project_dir,
- add_env={
- "CIBW_BUILD_FRONTEND": build_frontend,
- "PIP_CONSTRAINT": str(constraints_file),
- "CIBW_ENVIRONMENT_LINUX": "PIP_CONSTRAINT=./constraints.txt",
- },
- single_python=True,
- )
-
- expected_wheels = utils.expected_wheels("spam", "0.1.0", single_python=True)
- assert set(actual_wheels) == set(expected_wheels)
diff --git a/test/test_pyodide.py b/test/test_pyodide.py
index 709dd21b..da36d180 100644
--- a/test/test_pyodide.py
+++ b/test/test_pyodide.py
@@ -71,7 +71,9 @@ def test_pyodide_build(tmp_path: Path, use_pyproject_toml: bool) -> None:
basic_project.generate(project_dir)
# check for node in 1 case only to reduce CI load
- add_env = {"CIBW_ENABLE": "pyodide-prerelease"}
+ # cp315 is a Pyodide prerelease embedding a prerelease CPython, so it is
+ # gated by `cpython-prerelease`.
+ add_env = {"CIBW_ENABLE": "cpython-prerelease"}
if use_pyproject_toml:
add_env["CIBW_TEST_COMMAND"] = f"python {{project}}/check_node.py {CIBW_CACHE_PATH}"
@@ -86,6 +88,7 @@ def test_pyodide_build(tmp_path: Path, use_pyproject_toml: bool) -> None:
expected_wheels = [
"spam-0.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl",
"spam-0.1.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl",
+ "spam-0.1.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl",
]
print("actual_wheels", actual_wheels)
@@ -144,13 +147,14 @@ def test_pyodide_build_and_test(tmp_path: Path, expect_failure: bool) -> None:
add_env={
"CIBW_TEST_REQUIRES": "pytest",
"CIBW_TEST_COMMAND": "python -m pytest {project}",
- "CIBW_ENABLE": "pyodide-prerelease",
+ "CIBW_ENABLE": "cpython-prerelease",
},
)
# check that the expected wheels are produced
expected_wheels = [
"spam-0.1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl",
"spam-0.1.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl",
+ "spam-0.1.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl",
]
assert set(actual_wheels) == set(expected_wheels)
diff --git a/test/utils.py b/test/utils.py
index 1553bb2c..eeaa212b 100644
--- a/test/utils.py
+++ b/test/utils.py
@@ -278,18 +278,18 @@ def _expected_wheels(
# To be kept in sync with Python versions for Pyodide identifiers in cibuildwheel/selector.py.
if platform == "pyodide" and python_abi_tags is None:
- python_abi_tags = ["cp313-cp313", "cp314-cp314"]
+ python_abi_tags = ["cp313-cp313", "cp314-cp314", "cp315-cp315"]
if EnableGroup.PyodideEoL in enable_groups:
python_abi_tags.insert(0, "cp312-cp312")
- elif (platform == "android" and python_abi_tags is None) or (
- platform == "ios" and python_abi_tags is None
- ):
+ elif platform in {"android", "ios"} and python_abi_tags is None:
python_abi_tags = [
"cp313-cp313",
"cp314-cp314",
+ "cp315-cp315",
]
if EnableGroup.CPythonPrerelease in enable_groups:
- python_abi_tags += ["cp315-cp315"]
+ # python_abi_tags += ["cp316-cp316"]
+ ... # Add cp316 here when available
elif python_abi_tags is None:
python_abi_tags = [
"cp39-cp39",
@@ -299,13 +299,16 @@ def _expected_wheels(
"cp313-cp313",
"cp314-cp314",
"cp314-cp314t",
+ "cp315-cp315",
+ "cp315-cp315t",
]
if EnableGroup.CPythonPrerelease in enable_groups:
- python_abi_tags += [
- "cp315-cp315",
- "cp315-cp315t",
- ]
+ # python_abi_tags += [
+ # "cp316-cp316",
+ # "cp316-cp316t",
+ # ]
+ ... # Add cp316 here when available
if EnableGroup.PyPyEoL in enable_groups:
python_abi_tags += [
@@ -410,6 +413,7 @@ def _expected_wheels(
"cp312-cp312": ["pyodide_2024_0_wasm32"],
"cp313-cp313": ["pyemscripten_2025_0_wasm32"],
"cp314-cp314": ["pyemscripten_2026_0_wasm32"],
+ "cp315-cp315": ["pyemscripten_2026_5_wasm32"],
}.get(python_abi_tag, [])
if not platform_tags:
diff --git a/unit_test/build_ids_test.py b/unit_test/build_ids_test.py
index 76647623..70a8bcdd 100644
--- a/unit_test/build_ids_test.py
+++ b/unit_test/build_ids_test.py
@@ -1,10 +1,14 @@
import tomllib
+from pathlib import Path
+import pytest
from packaging.version import Version
from cibuildwheel.extra import Printable, dump_python_configurations
from cibuildwheel.util import resources
+OPTIONS_MD = Path(__file__).parents[1] / "docs" / "options.md"
+
def test_compare_configs() -> None:
txt = resources.BUILD_PLATFORMS.read_text()
@@ -18,6 +22,20 @@ def test_compare_configs() -> None:
assert new_txt == txt
+@pytest.mark.skipif(not OPTIONS_MD.is_file(), reason="docs/options.md not present")
+def test_all_identifiers_in_docs_table() -> None:
+ # The build-id table in docs/options.md is hand-maintained; this guards
+ # against forgetting an identifier when build-platforms.toml changes.
+ docs = OPTIONS_MD.read_text()
+ identifiers = [
+ config["identifier"]
+ for configs in resources.read_all_configs().values()
+ for config in configs
+ ]
+ missing = [i for i in identifiers if i not in docs]
+ assert not missing, f"Missing from docs/options.md build-id table: {missing}"
+
+
def test_dump_with_Version() -> None:
# MyPy doesn't understand deeply nested dicts correctly
example: dict[str, dict[str, list[dict[str, Printable]]]] = {
diff --git a/unit_test/build_selector_test.py b/unit_test/build_selector_test.py
index 817cfce5..c5431db0 100644
--- a/unit_test/build_selector_test.py
+++ b/unit_test/build_selector_test.py
@@ -16,6 +16,7 @@ def test_build() -> None:
assert build_selector("cp312-manylinux_x86_64")
assert build_selector("cp313-manylinux_x86_64")
assert build_selector("cp314-manylinux_x86_64")
+ assert build_selector("cp315-manylinux_x86_64")
assert build_selector("pp311-manylinux_x86_64")
assert build_selector("cp36-manylinux_i686")
assert build_selector("cp37-manylinux_i686")
@@ -37,6 +38,7 @@ def test_build() -> None:
assert build_selector("cp312-win_amd64")
assert build_selector("cp313-win_amd64")
assert build_selector("cp314-win_amd64")
+ assert build_selector("cp315-win_amd64")
assert not build_selector("pp310-win_amd64")
assert not build_selector("pp311-win_amd64")
@@ -91,17 +93,6 @@ def test_build_filter_pypy_all() -> None:
assert build_selector("pp39-manylinux_x86_64")
-# Re-enable when we have Pyodide 3.15 prerelease builds to test against
-# def test_build_filter_pyodide_prerelease() -> None:
-# build_selector = BuildSelector(
-# build_config="*",
-# skip_config="",
-# enable=frozenset([EnableGroup.PyodidePrerelease]),
-# )
-# assert build_selector("cp314-pyodide_wasm32")
-# assert build_selector("cp315-pyodide_wasm32")
-
-
def test_build_filter_pyodide() -> None:
build_selector = BuildSelector(
build_config="*",
@@ -111,6 +102,7 @@ def test_build_filter_pyodide() -> None:
assert build_selector("cp313-pyodide_wasm32")
assert build_selector("cp314-pyodide_wasm32")
assert not build_selector("cp312-pyodide_wasm32")
+ assert build_selector("cp315-pyodide_wasm32")
def test_build_filter_pyodide_eol() -> None:
@@ -122,6 +114,7 @@ def test_build_filter_pyodide_eol() -> None:
assert build_selector("cp312-pyodide_wasm32")
assert build_selector("cp313-pyodide_wasm32")
assert build_selector("cp314-pyodide_wasm32")
+ assert build_selector("cp315-pyodide_wasm32")
def test_skip() -> None:
diff --git a/unit_test/download_test.py b/unit_test/download_test.py
index 0508b5f2..7a8826ac 100644
--- a/unit_test/download_test.py
+++ b/unit_test/download_test.py
@@ -1,6 +1,10 @@
from __future__ import annotations
+import io
import ssl
+import time
+import urllib.error
+import urllib.request
import certifi
import pytest
@@ -9,9 +13,12 @@ from cibuildwheel.util.file import download
TYPE_CHECKING = False
if TYPE_CHECKING:
+ from collections.abc import Callable, Iterator
from pathlib import Path
+ from typing import Self
DOWNLOAD_URL = "https://cdn.jsdelivr.net/gh/pypa/cibuildwheel@v1.6.3/requirements-dev.txt"
+PAYLOAD = b"payload"
def test_download(monkeypatch: pytest.MonkeyPatch, tmp_path: Path) -> None:
@@ -35,3 +42,131 @@ def test_download_bad_ssl_cert_file(monkeypatch: pytest.MonkeyPatch, tmp_path: P
dest = tmp_path / "file.txt"
with pytest.raises(ssl.SSLError):
download(DOWNLOAD_URL, dest)
+
+
+def _no_sleep(seconds: float) -> None:
+ pass
+
+
+@pytest.fixture
+def http_error() -> Iterator[Callable[[str, int], urllib.error.HTTPError]]:
+ """Build HTTPErrors, and close them, as each one holds a temporary file."""
+ errors = []
+
+ def make(url: str, code: int) -> urllib.error.HTTPError:
+ error = urllib.error.HTTPError(url, code, "error", {}, io.BytesIO(b"")) # type: ignore[arg-type]
+ errors.append(error)
+ return error
+
+ yield make
+
+ for error in errors:
+ error.close()
+
+
+class FakeResponse:
+ def __enter__(self) -> Self:
+ return self
+
+ def __exit__(self, *args: object) -> None:
+ return None
+
+ def read(self) -> bytes:
+ return PAYLOAD
+
+
+@pytest.fixture
+def fake_network(
+ monkeypatch: pytest.MonkeyPatch,
+) -> Callable[[int], tuple[list[str], list[float]]]:
+ """Fail the first ``failures`` downloads, recording attempts and sleeps."""
+
+ def setup(failures: int) -> tuple[list[str], list[float]]:
+ attempts: list[str] = []
+ sleeps: list[float] = []
+
+ def fake_urlopen(url: str, context: object = None) -> FakeResponse: # noqa: ARG001
+ attempts.append(url)
+ if len(attempts) <= failures:
+ msg = "temporary DNS failure"
+ raise OSError(msg)
+ return FakeResponse()
+
+ monkeypatch.setattr(urllib.request, "urlopen", fake_urlopen)
+ monkeypatch.setattr(time, "sleep", sleeps.append)
+ return attempts, sleeps
+
+ return setup
+
+
+def test_download_retries_transient_failures(
+ fake_network: Callable[[int], tuple[list[str], list[float]]], tmp_path: Path
+) -> None:
+ attempts, sleeps = fake_network(3)
+ dest = tmp_path / "file.txt"
+
+ download(DOWNLOAD_URL, dest)
+
+ assert dest.read_bytes() == PAYLOAD
+ assert len(attempts) == 4
+ # the wait must grow, so that a long outage is survivable
+ assert sleeps == sorted(sleeps)
+ assert sleeps[-1] > sleeps[0]
+
+
+def test_download_backoff_covers_a_minute_outage(
+ fake_network: Callable[[int], tuple[list[str], list[float]]], tmp_path: Path
+) -> None:
+ _, sleeps = fake_network(99)
+ dest = tmp_path / "file.txt"
+
+ with pytest.raises(OSError, match="temporary DNS failure"):
+ download(DOWNLOAD_URL, dest)
+
+ assert sum(sleeps) >= 60
+
+
+@pytest.mark.parametrize("code", [400, 404, 410])
+def test_download_does_not_retry_client_errors(
+ monkeypatch: pytest.MonkeyPatch,
+ tmp_path: Path,
+ code: int,
+ http_error: Callable[[str, int], urllib.error.HTTPError],
+) -> None:
+ """A bad URL is not going to fix itself, so report it at once."""
+ attempts: list[str] = []
+
+ def fake_urlopen(url: str, context: object = None) -> FakeResponse: # noqa: ARG001
+ attempts.append(url)
+ raise http_error(url, code)
+
+ monkeypatch.setattr(urllib.request, "urlopen", fake_urlopen)
+ monkeypatch.setattr(time, "sleep", _no_sleep)
+
+ with pytest.raises(urllib.error.HTTPError):
+ download(DOWNLOAD_URL, tmp_path / "file.txt")
+
+ assert len(attempts) == 1
+
+
+@pytest.mark.parametrize("code", [500, 503])
+def test_download_retries_server_errors(
+ monkeypatch: pytest.MonkeyPatch,
+ tmp_path: Path,
+ code: int,
+ http_error: Callable[[str, int], urllib.error.HTTPError],
+) -> None:
+ attempts: list[str] = []
+
+ def fake_urlopen(url: str, context: object = None) -> FakeResponse: # noqa: ARG001
+ attempts.append(url)
+ if len(attempts) == 1:
+ raise http_error(url, code)
+ return FakeResponse()
+
+ monkeypatch.setattr(urllib.request, "urlopen", fake_urlopen)
+ monkeypatch.setattr(time, "sleep", _no_sleep)
+
+ download(DOWNLOAD_URL, tmp_path / "file.txt")
+
+ assert len(attempts) == 2
diff --git a/unit_test/get_platform_test.py b/unit_test/get_platform_test.py
index 22bd9d05..9eeb79ec 100644
--- a/unit_test/get_platform_test.py
+++ b/unit_test/get_platform_test.py
@@ -8,7 +8,11 @@ import setuptools._distutils.util
from cibuildwheel.ci import CIProvider, detect_ci_provider
from cibuildwheel.errors import FatalError
-from cibuildwheel.platforms.windows import PythonConfiguration, setup_setuptools_cross_compile
+from cibuildwheel.platforms.windows import (
+ PythonConfiguration,
+ get_nuget_args,
+ setup_setuptools_cross_compile,
+)
TYPE_CHECKING = False
if TYPE_CHECKING:
@@ -30,6 +34,20 @@ def patched_environment(
yield
+@pytest.mark.parametrize(
+ ("arch", "free_threaded", "package_name"),
+ [("AMD64", False, "python"), ("ARM64", True, "pythonarm64-freethreaded")],
+)
+def test_get_nuget_args(arch: str, free_threaded: bool, package_name: str, tmp_path: Path) -> None:
+ assert get_nuget_args("3.14.1", arch, free_threaded, tmp_path) == [
+ package_name,
+ "-Version",
+ "3.14.1",
+ "-OutputDirectory",
+ str(tmp_path),
+ ]
+
+
def test_x86(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
environment: dict[str, str] = {}
configuration = PythonConfiguration(version="irrelevant", identifier="cp314-win32", url=None)
diff --git a/unit_test/linux_build_steps_test.py b/unit_test/linux_build_steps_test.py
index b93530be..dd6200ab 100644
--- a/unit_test/linux_build_steps_test.py
+++ b/unit_test/linux_build_steps_test.py
@@ -97,9 +97,11 @@ def test_linux_container_split(tmp_path: Path, monkeypatch: pytest.MonkeyPatch)
"cp313-manylinux_x86_64",
"cp314-manylinux_x86_64",
"cp314t-manylinux_x86_64",
+ "cp315-manylinux_x86_64",
+ "cp315t-manylinux_x86_64",
]
- assert before_alls(build_steps[3]) == [""] * 4
- assert container_engines(build_steps[3]) == [default_container_engine] * 4
+ assert before_alls(build_steps[3]) == [""] * 6
+ assert container_engines(build_steps[3]) == [default_container_engine] * 6
def test_package_dir_outside_working_directory_raises_configuration_error(
diff --git a/unit_test/main_tests/main_options_test.py b/unit_test/main_tests/main_options_test.py
index ebdce967..f13416df 100644
--- a/unit_test/main_tests/main_options_test.py
+++ b/unit_test/main_tests/main_options_test.py
@@ -173,19 +173,19 @@ def test_empty_selector(monkeypatch: pytest.MonkeyPatch) -> None:
@pytest.mark.parametrize(
("architecture", "image", "full_image"),
[
- ("x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64:*"),
- ("x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64:*"),
- ("x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64:*"),
- ("x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64:*"),
+ ("x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64@*"),
+ ("x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64@*"),
+ ("x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64@*"),
+ ("x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64@*"),
("x86_64", "custom_image", "custom_image"),
- ("i686", None, "quay.io/pypa/manylinux_2_28_i686:*"),
- ("i686", "manylinux2014", "quay.io/pypa/manylinux2014_i686:*"),
- ("i686", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_i686:*"),
+ ("i686", None, "quay.io/pypa/manylinux_2_28_i686@*"),
+ ("i686", "manylinux2014", "quay.io/pypa/manylinux2014_i686@*"),
+ ("i686", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_i686@*"),
("i686", "custom_image", "custom_image"),
- ("pypy_x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64:*"),
- ("pypy_x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64:*"),
- ("pypy_x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64:*"),
- ("pypy_x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64:*"),
+ ("pypy_x86_64", None, "quay.io/pypa/manylinux_2_28_x86_64@*"),
+ ("pypy_x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64@*"),
+ ("pypy_x86_64", "manylinux_2_28", "quay.io/pypa/manylinux_2_28_x86_64@*"),
+ ("pypy_x86_64", "manylinux_2_34", "quay.io/pypa/manylinux_2_34_x86_64@*"),
("pypy_x86_64", "custom_image", "custom_image"),
],
)
diff --git a/unit_test/oci_container_test.py b/unit_test/oci_container_test.py
index 8b94187c..5e931976 100644
--- a/unit_test/oci_container_test.py
+++ b/unit_test/oci_container_test.py
@@ -29,6 +29,7 @@ from cibuildwheel.oci_container import (
TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Iterator
+ from typing import Any
# Test utilities
@@ -84,6 +85,18 @@ def test_no_lf(container_engine: OCIContainerEngineConfig) -> None:
assert container.call(["printf", "hello"], capture_output=True) == "hello"
+def test_abnormal_exit(container_engine: OCIContainerEngineConfig) -> None:
+ container = OCIContainer(
+ engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
+ )
+ with container:
+ # kill the shell without a newline, so the write below still goes
+ # through the same buffer and the call fails on read, not on write
+ container.bash_stdin.write(b"exit")
+ with pytest.raises(RuntimeError):
+ container.call(["echo", "hello"])
+
+
def test_debug_info(container_engine: OCIContainerEngineConfig) -> None:
container = OCIContainer(
engine=container_engine, image=DEFAULT_IMAGE, oci_platform=DEFAULT_OCI_PLATFORM
@@ -139,6 +152,7 @@ def test_container_removed(container_engine: OCIContainerEngineConfig) -> None:
) as container:
assert container.name is not None
container_name = container.name
+ docker_containers_listing = ""
for _ in range(timeout):
docker_containers_listing = subprocess.run(
f"{container.engine.name} container ls",
@@ -330,7 +344,7 @@ def test_podman_vfs(
# This requires that we write configuration files and point to them
# with environment variables before we run podman
# https://github.com/containers/common/blob/main/docs/containers.conf.5.md
- vfs_containers_conf_data = {
+ vfs_containers_conf_data: dict[str, dict[str, Any]] = {
"containers": {
"default_capabilities": [
"CHOWN",
@@ -348,6 +362,20 @@ def test_podman_vfs(
},
"engine": {"cgroup_manager": "cgroupfs", "events_logger": "file"},
}
+
+ # Setting CONTAINERS_CONF makes podman ignore its usual config files, so
+ # carry over the default OCI runtime; the fallback found on PATH can be
+ # too old for the OCI spec version podman generates (e.g. Ubuntu 24.04's
+ # crun 1.14.1 with podman 5.x).
+ oci_runtime = subprocess.run(
+ ["podman", "info", "--format", "{{.Host.OCIRuntime.Path}}"],
+ check=True,
+ capture_output=True,
+ text=True,
+ ).stdout.strip()
+ runtime_name = Path(oci_runtime).name
+ vfs_containers_conf_data["engine"]["runtime"] = runtime_name
+ vfs_containers_conf_data["engine"]["runtimes"] = {runtime_name: [oci_runtime]}
# https://github.com/containers/storage/blob/main/docs/containers-storage.conf.5.md
storage_root = vfs_path / ".local/share/containers/vfs-storage"
run_root = vfs_path / ".local/share/containers/vfs-runroot"
diff --git a/unit_test/option_prepare_test.py b/unit_test/option_prepare_test.py
index 5bad4d28..b277c8c4 100644
--- a/unit_test/option_prepare_test.py
+++ b/unit_test/option_prepare_test.py
@@ -13,7 +13,7 @@ from cibuildwheel.__main__ import main
from cibuildwheel.oci_container import OCIPlatform
from cibuildwheel.util import file
-DEFAULT_IDS = {"cp39", "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t"}
+DEFAULT_IDS = {"cp39", "cp310", "cp311", "cp312", "cp313", "cp314", "cp314t", "cp315", "cp315t"}
ALL_IDS = DEFAULT_IDS | {"pp39", "pp310", "pp311", "gp312_250"}
@@ -155,6 +155,8 @@ before-all = "true"
"cp313",
"cp314",
"cp314t",
+ "cp315",
+ "cp315t",
"pp39",
"pp310",
"pp311",
@@ -176,6 +178,8 @@ before-all = "true"
"cp313",
"cp314",
"cp314t",
+ "cp315",
+ "cp315t",
"pp39",
"pp310",
"pp311",
diff --git a/unit_test/options_test.py b/unit_test/options_test.py
index 9b5066a3..d8e15b51 100644
--- a/unit_test/options_test.py
+++ b/unit_test/options_test.py
@@ -39,6 +39,8 @@ TYPE_CHECKING = False
if TYPE_CHECKING:
from collections.abc import Callable, Sequence
+ from cibuildwheel.typing import PlatformName
+
PYPROJECT_1 = """
[tool.cibuildwheel]
build = ["cp38-*", "cp313-*"]
@@ -480,6 +482,93 @@ def test_build_frontend_option(
assert parsed_build_frontend.args == ()
+def test_pyodide_build_frontend_default(tmp_path: Path) -> None:
+ args = CommandLineArguments.defaults()
+ args.package_dir = tmp_path
+
+ tmp_path.joinpath("pyproject.toml").write_text("[tool.cibuildwheel]\n")
+
+ options = Options(platform="pyodide", command_line_arguments=args, env={})
+ build_frontend = options.build_options(identifier=None).build_frontend
+
+ assert build_frontend.name == "pyodide-build"
+ assert build_frontend.args == []
+
+
+def test_pyodide_build_frontend_args(tmp_path: Path) -> None:
+ args = CommandLineArguments.defaults()
+ args.package_dir = tmp_path
+
+ tmp_path.joinpath("pyproject.toml").write_text(
+ textwrap.dedent(
+ """\
+ [tool.cibuildwheel.pyodide]
+ build-frontend = {name = "pyodide-build", args = ["--exports=whole_archive"]}
+ """
+ )
+ )
+
+ options = Options(platform="pyodide", command_line_arguments=args, env={})
+ build_frontend = options.build_options(identifier=None).build_frontend
+
+ assert build_frontend.name == "pyodide-build"
+ assert build_frontend.args == ["--exports=whole_archive"]
+
+
+@pytest.mark.parametrize(
+ "build_frontend_str",
+ ["default", "pip", "build", "build[uv]", "uv"],
+)
+def test_pyodide_global_build_frontend_coerced(tmp_path: Path, build_frontend_str: str) -> None:
+ """A global non-pyodide frontend setting is coerced to pyodide-build, not an error."""
+ args = CommandLineArguments.defaults()
+ args.package_dir = tmp_path
+
+ tmp_path.joinpath("pyproject.toml").write_text(
+ textwrap.dedent(
+ f"""\
+ [tool.cibuildwheel]
+ build-frontend = "{build_frontend_str}"
+ """
+ )
+ )
+
+ options = Options(platform="pyodide", command_line_arguments=args, env={})
+ build_frontend = options.build_options(identifier=None).build_frontend
+
+ assert build_frontend.name == "pyodide-build"
+
+
+@pytest.mark.parametrize(
+ ("platform", "build_frontend_str"),
+ [
+ ("linux", "pyodide-build"),
+ ("macos", "pyodide-build"),
+ ("windows", "pyodide-build"),
+ ("android", "pyodide-build"),
+ ("ios", "pyodide-build"),
+ ],
+)
+def test_build_frontend_platform_mismatch(
+ tmp_path: Path, platform: PlatformName, build_frontend_str: str
+) -> None:
+ args = CommandLineArguments.defaults()
+ args.package_dir = tmp_path
+
+ tmp_path.joinpath("pyproject.toml").write_text(
+ textwrap.dedent(
+ f"""\
+ [tool.cibuildwheel]
+ build-frontend = "{build_frontend_str}"
+ """
+ )
+ )
+
+ options = Options(platform=platform, command_line_arguments=args, env={})
+ with pytest.raises(errors.ConfigurationError):
+ options.build_options(identifier=None)
+
+
def test_override_inherit_environment(tmp_path: Path) -> None:
args = CommandLineArguments.defaults()
args.package_dir = tmp_path
@@ -663,10 +752,15 @@ def test_deprecated_image(
("build", 3, ["-Ca", "-Cb", "-1", "-vv"]),
("build[uv]", 3, ["-Ca", "-Cb", "-1", "-vv"]),
("uv", 3, ["-Ca", "-Cb", "-1", "-vv"]),
+ ("pyodide-build", -1, ["-Ca", "-Cb", "-1"]),
+ ("pyodide-build", 0, ["-Ca", "-Cb", "-1"]),
+ ("pyodide-build", 1, ["-Ca", "-Cb", "-1", "-v"]),
+ ("pyodide-build", 2, ["-Ca", "-Cb", "-1", "-vv"]),
+ ("pyodide-build", 3, ["-Ca", "-Cb", "-1", "-vv"]),
],
)
def test_get_build_frontend_extra_flags(
- frontend: Literal["pip", "build", "build[uv]"],
+ frontend: Literal["pip", "build", "build[uv]", "uv", "pyodide-build"],
verbosity: int,
result: list[str],
monkeypatch: pytest.MonkeyPatch,
@@ -758,6 +852,31 @@ def test_test_runtime_handling(
assert local.test_runtime.args == expected_args
+@pytest.mark.parametrize(
+ ("platform", "platform_envvar"),
+ [
+ ("android", "CIBW_TEST_RUNTIME_ANDROID"),
+ ("ios", "CIBW_TEST_RUNTIME_IOS"),
+ ],
+)
+def test_test_runtime_platform_environment(
+ tmp_path: Path, platform: PlatformName, platform_envvar: str
+) -> None:
+ args = CommandLineArguments.defaults()
+ args.package_dir = tmp_path
+
+ options = Options(
+ platform=platform,
+ command_line_arguments=args,
+ env={
+ "CIBW_TEST_RUNTIME": "args: --global",
+ platform_envvar: "args: --platform-specific",
+ },
+ )
+
+ assert options.build_options(None).test_runtime.args == ["--platform-specific"]
+
+
@pytest.mark.parametrize(
("definition", "expected"),
[
diff --git a/unit_test/validate_schema_test.py b/unit_test/validate_schema_test.py
index 2804ed1b..ebe42134 100644
--- a/unit_test/validate_schema_test.py
+++ b/unit_test/validate_schema_test.py
@@ -207,6 +207,65 @@ def test_invalid_inherit_option_for_scope(
validator(tomllib.loads(config))
+def test_pyodide_build_frontend(validator: validate_pyproject.api.Validator) -> None:
+ """
+ pyodide-build is accepted anywhere the frontend can be set, as an override
+ or a global value can apply to pyodide builds only.
+ """
+ example = tomllib.loads(
+ """
+ [tool.cibuildwheel]
+ build-frontend = "pyodide-build"
+
+ [tool.cibuildwheel.pyodide]
+ build-frontend = { name = "pyodide-build", args = ["--some-arg"] }
+
+ [[tool.cibuildwheel.overrides]]
+ select = "*pyodide*"
+ build-frontend = "pyodide-build; args: --some-arg"
+ """
+ )
+
+ assert validator(example) is not None
+
+
+@pytest.mark.parametrize("frontend", ['"uv"', '"build; args: --some-arg"', '{ name = "pip" }'])
+def test_pyodide_bad_build_frontend(
+ validator: validate_pyproject.api.Validator, frontend: str
+) -> None:
+ """
+ The pyodide table only accepts the pyodide-build frontend.
+ """
+ example = tomllib.loads(
+ f"""
+ [tool.cibuildwheel.pyodide]
+ build-frontend = {frontend}
+ """
+ )
+
+ with pytest.raises(validate_pyproject.error_reporting.ValidationError):
+ validator(example)
+
+
+@pytest.mark.parametrize("platform", ["linux", "macos", "windows", "ios", "android"])
+@pytest.mark.parametrize("frontend", ["pyodide-build", "pyodide-build; args: --some-arg"])
+def test_bad_pyodide_build_frontend(
+ validator: validate_pyproject.api.Validator, platform: str, frontend: str
+) -> None:
+ """
+ Only the pyodide table accepts the pyodide-build frontend.
+ """
+ example = tomllib.loads(
+ f"""
+ [tool.cibuildwheel.{platform}]
+ build-frontend = "{frontend}"
+ """
+ )
+
+ with pytest.raises(validate_pyproject.error_reporting.ValidationError):
+ validator(example)
+
+
def test_docs_examples(validator: validate_pyproject.api.Validator) -> None:
"""
Parse out all the configuration examples, build valid TOML out of them, and
diff --git a/unit_test/venv_test.py b/unit_test/venv_test.py
new file mode 100644
index 00000000..8cd905a1
--- /dev/null
+++ b/unit_test/venv_test.py
@@ -0,0 +1,60 @@
+import os
+import sys
+from pathlib import Path
+
+import pytest
+
+import cibuildwheel.venv
+from cibuildwheel.venv import activate_virtualenv, find_uv, virtualenv
+
+
+def test_activate_virtualenv(tmp_path: Path) -> None:
+ venv_path = tmp_path / "venv"
+ env = activate_virtualenv(venv_path, env={"PATH": "/usr/bin"})
+ paths = env["PATH"].split(os.pathsep)
+ if sys.platform == "win32":
+ assert paths[:2] == [str(venv_path), str(venv_path / "Scripts")]
+ else:
+ assert paths[0] == str(venv_path / "bin")
+ assert paths[-1] == "/usr/bin"
+ assert env["VIRTUAL_ENV"] == str(venv_path)
+
+
+def test_activate_virtualenv_base_python_bin_dir(tmp_path: Path) -> None:
+ venv_path = tmp_path / "venv"
+ base_bin = tmp_path / "base" / "bin"
+ env = activate_virtualenv(venv_path, env={"PATH": "/usr/bin"}, base_python_bin_dir=base_bin)
+ paths = env["PATH"].split(os.pathsep)
+ # the base interpreter's bin dir comes right after the venv, so scripts
+ # like python3-config resolve to the matching interpreter (see #2021)
+ if sys.platform == "win32":
+ assert paths[:3] == [str(venv_path), str(venv_path / "Scripts"), str(base_bin)]
+ else:
+ assert paths[:2] == [str(venv_path / "bin"), str(base_bin)]
+ assert paths[-1] == "/usr/bin"
+
+
+@pytest.mark.skipif(sys.platform == "win32", reason="POSIX-only behavior")
+@pytest.mark.skipif(find_uv() is None, reason="requires uv")
+def test_virtualenv_puts_base_python_bin_dir_on_path(tmp_path: Path) -> None:
+ version = "{}.{}".format(*sys.version_info[:2])
+ venv_path = tmp_path / "venv"
+ env = virtualenv(
+ version, Path(sys.executable), venv_path, None, use_uv=True, env={"PATH": "/usr/bin"}
+ )
+ paths = env["PATH"].split(os.pathsep)
+ assert paths == [str(venv_path / "bin"), str(Path(sys.executable).parent), "/usr/bin"]
+
+
+@pytest.mark.skipif(find_uv() is None, reason="requires uv")
+def test_virtualenv_no_base_python_bin_dir_on_windows(
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
+) -> None:
+ monkeypatch.setattr(cibuildwheel.venv, "_IS_WIN", True)
+ version = "{}.{}".format(*sys.version_info[:2])
+ venv_path = tmp_path / "venv"
+ env = virtualenv(
+ version, Path(sys.executable), venv_path, None, use_uv=True, env={"PATH": "/usr/bin"}
+ )
+ paths = env["PATH"].split(os.pathsep)
+ assert str(Path(sys.executable).parent) not in paths