Compare commits

..
Author SHA1 Message Date
Joe Rickerby 355c5a46b2 Fix PATH manipulation in action.yml 2025-12-21 16:05:43 +00:00
Joe Rickerby bc79c16a71 Another approach to the uv installation question
Don't get clever about it at all, instead make uv on PATH a hard
requirement.
2025-12-19 17:20:39 +00:00
81 changed files with 1240 additions and 1653 deletions
-2
View File
@@ -9,5 +9,3 @@ updates:
actions:
patterns:
- "*"
cooldown:
default-days: 7
+2 -6
View File
@@ -7,15 +7,11 @@ on:
types:
- published
permissions: {}
jobs:
dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: hynek/build-and-inspect-python-package@v2
@@ -31,13 +27,13 @@ jobs:
attestations: write
steps:
- uses: actions/download-artifact@v8
- uses: actions/download-artifact@v7
with:
name: Packages
path: dist
- name: Generate artifact attestation for sdist and wheel
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
with:
subject-path: "dist/cibuildwheel-*"
+18 -92
View File
@@ -28,8 +28,6 @@ on:
workflow_dispatch:
# allow manual runs on branches without a PR
permissions: {}
concurrency:
group: test-${{ github.ref }}
cancel-in-progress: true
@@ -40,41 +38,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-python@v6
id: python
with:
python-version: "3.x"
- uses: j178/prek-action@v1
- uses: pre-commit/action@v3.0.1
- name: PyLint checks
run: pipx run --python "${{ steps.python.outputs.python-path }}" nox -s pylint -- --output-format=github
sample:
name: Generate a sample project
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-python@v6
name: Install Python
with:
python-version: "3.x"
- uses: astral-sh/setup-uv@v7
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Generate a sample project
run: uv run --no-sync -m test.test_projects test.test_0_basic.basic_project sample_proj
- uses: actions/upload-artifact@v7
with:
name: sample_proj
path: sample_proj
test:
name: Test on ${{ matrix.os }} (${{ matrix.python_version }}) ${{ matrix.test_select }}
needs: sample
needs: lint
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@@ -118,8 +92,6 @@ jobs:
timeout-minutes: 180
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-python@v6
name: Install Python ${{ matrix.python_version }}
with:
@@ -139,7 +111,7 @@ jobs:
# for oci_container unit tests
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v4
uses: docker/setup-qemu-action@v3
- name: Set up Xcode
if: ${{ startsWith(matrix.os, 'macos-15') }}
@@ -148,7 +120,8 @@ jobs:
sudo xcode-select --switch /Applications/Xcode_16.4.app
- name: Install dependencies
run: uv sync --no-dev --group test
run: |
uv sync --no-dev --group test
- uses: joerick/pr-labels-action@v1.0.9
@@ -171,11 +144,9 @@ jobs:
fi
echo "CIBW_ENABLE=${CIBW_ENABLE}" >> $GITHUB_ENV
- name: Download a sample project
uses: actions/download-artifact@v8
with:
name: sample_proj
path: sample_proj
- name: Generate a sample project
run: |
uv run --no-sync -m test.test_projects test.test_0_basic.basic_project sample_proj
- name: Run a sample build (GitHub Action)
uses: ./
@@ -230,7 +201,7 @@ jobs:
run: |
test $(find wheelhouse_only -name '*.whl' | wc -l) -eq 1
- uses: actions/upload-artifact@v7
- uses: actions/upload-artifact@v6
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: wheelhouse/*.whl
@@ -238,7 +209,8 @@ jobs:
- name: Test cibuildwheel
env:
CIBW_TEST_RUNTIME: ${{ matrix.test_runtime }}
run: uv run --no-sync bin/run_tests.py --test-select=${{ matrix.test_select || 'native' }} ${{ (runner.os == 'Linux' && runner.arch == 'X64') && '--run-podman' || '' }}
run: |
uv run --no-sync bin/run_tests.py --test-select=${{ matrix.test_select || 'native' }} ${{ (runner.os == 'Linux' && runner.arch == 'X64') && '--run-podman' || '' }}
emulated-archs:
name: Get qemu emulated architectures
@@ -248,8 +220,6 @@ jobs:
archs: ${{ steps.archs.outputs.archs }}
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-python@v6
with:
python-version: "3.x"
@@ -273,8 +243,6 @@ jobs:
arch: ${{ fromJSON(needs.emulated-archs.outputs.archs) }}
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-python@v6
with:
python-version: "3.x"
@@ -283,20 +251,18 @@ jobs:
run: uv sync --no-dev --group test
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
uses: docker/setup-qemu-action@v3
- name: Run the emulation tests
run: uv run --no-sync pytest --run-emulation ${{ matrix.arch }} test/test_emulation.py
test-pyodide:
name: Test pyodide
needs: sample
needs: lint
runs-on: ubuntu-24.04
timeout-minutes: 180
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-python@v6
name: Install Python 3.12
with:
@@ -306,11 +272,9 @@ jobs:
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Download a sample project
uses: actions/download-artifact@v8
with:
name: sample_proj
path: sample_proj
- name: Generate a sample project
run: |
uv run --no-sync -m test.test_projects test.test_0_basic.basic_project sample_proj
- name: Run a sample build (GitHub Action)
uses: ./
@@ -321,45 +285,7 @@ jobs:
CIBW_PLATFORM: pyodide
- name: Run tests with 'CIBW_PLATFORM' set to 'pyodide'
run: uv run --no-sync ./bin/run_tests.py
run: |
uv run --no-sync ./bin/run_tests.py
env:
CIBW_PLATFORM: pyodide
test-uv-extras:
name: Test uv extra on ${{ matrix.os }} ${{ matrix.test_select }}
needs: sample
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
test_select: android
- os: windows-latest
- os: windows-11-arm
- os: macos-15-intel
- os: macos-15
- os: macos-15-intel
test_select: android
- os: macos-15
test_select: android
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: Download a sample project
uses: actions/download-artifact@v8
with:
name: sample_proj
path: sample_proj
- name: Run a sample build (GitHub Action)
uses: ./
with:
extras: uv
package-dir: sample_proj
output-dir: wheelhouse
env:
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
CIBW_BUILD: cp314-*
CIBW_BUILD_FRONTEND: 'build[uv]'
CIBW_PLATFORM: ${{ matrix.test_select }}
+1 -7
View File
@@ -14,15 +14,11 @@ on:
schedule:
- cron: '0 6 * * 1' # "At 06:00 on Monday."
permissions: {}
jobs:
update-dependencies:
name: Update dependencies
if: github.repository_owner == 'pypa' || github.event_name != 'schedule'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
# we use this step to grab a Github App auth token, so that PRs generated by this workflow
@@ -35,10 +31,8 @@ jobs:
private-key: ${{ secrets.CIBUILDWHEEL_BOT_APP_PRIVATE_KEY }}
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: wntrblm/nox@2026.02.09
- uses: wntrblm/nox@2025.11.12
- name: "Run update: dependencies"
run: nox --force-color -s update_constraints
@@ -22,8 +22,6 @@ jobs:
contents: write
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-minor-tag
+4 -6
View File
@@ -1,7 +1,5 @@
ci:
autoupdate_schedule: monthly
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
@@ -16,7 +14,7 @@ repos:
- id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.5
rev: v0.14.9
hooks:
- id: ruff-check
args: ["--fix", "--show-fixes"]
@@ -77,7 +75,7 @@ repos:
additional_dependencies: [cogapp>=3.5]
- repo: https://github.com/codespell-project/codespell
rev: v2.4.2
rev: v2.4.1
hooks:
- id: codespell
args: ["-w"]
@@ -85,7 +83,7 @@ repos:
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.37.0
rev: 0.36.0
hooks:
- id: check-dependabot
- id: check-github-actions
+79
View File
@@ -0,0 +1,79 @@
os: linux
dist: jammy
language: python
branches:
only:
- main
# only build the main branch or PR that explicitely want to test with Travis CI
if: (type = "push") OR (commit_message =~ /travis-ci/)
jobs:
include:
- name: Linux | x86_64 + i686 | Python 3.12
python: 3.12
services: docker
env:
- PYTHON=python
# a build using CIBW_ENABLE=all does not fit into Travis' time limit,
# so only the defaults are tested
- name: Linux | arm64 | Python 3.12
python: 3.12
services: docker
arch: arm64
env:
- PYTHON=python
- CIBW_ENABLE=all
- name: Linux | ppc64le | Python 3.12
python: 3.12
services: docker
arch: ppc64le
allow_failure: True
env:
- PYTHON=python
# skip test_manylinuxXXXX_only, it uses too much disk space
# c.f. https://travis-ci.community/t/running-out-of-disk-space-quota-when-using-docker-on-ppc64le/11634
- PYTEST_ADDOPTS='-k "not test_manylinuxXXXX_only"'
- CIBW_ENABLE=all
- name: Windows | x86_64 | Python 3.12
os: windows
language: shell
before_install:
# http://woshub.com/updating-trusted-root-certificates-in-windows-10
- certutil -generateSSTFromWU roots.sst
- powershell -Command 'Get-ChildItem -Path roots.sst | Import-Certificate -CertStoreLocation Cert:\LocalMachine\Root'
- rm -f roots.sst
- choco upgrade python3 -y --version 3.12.8 --limit-output --params "/InstallDir:C:\\Python312"
env:
- PYTHON=C:\\Python312\\python
# a build using CIBW_ENABLE=all does not fit into Travis' time limit,
# so only the defaults are tested
- name: Linux | s390x | Python 3.12
python: 3.12
services: docker
arch: s390x
allow_failure: True
env:
- PYTHON=python
- CIBW_ENABLE=all
install:
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all; fi
- $PYTHON -m pip install -U pip
- $PYTHON -m pip install -e. --group test
script: |
# travis_wait disable the output while waiting
# use the same kind of tricks as in multibuild
(while true; do echo "travis_keep_alive"; sleep 300; done) &
SPINNER_PID=$!
disown
result=0
$PYTHON ./bin/run_tests.py --num-processes 2 || result=1
kill -9 ${SPINNER_PID}
test ${result} -eq 0
+7 -5
View File
@@ -1,9 +1,11 @@
This is a summary of the host Python versions and platforms covered by the different CI platforms:
| | 3.11 | 3.12 | 3.13 | 3.14 |
|---------|----------------------------------|---------------------------------|----------------|----------------|
| Linux | Azure Pipelines / GitHub Actions | CircleCI¹ / Cirrus CI / GitLab¹ | GitHub Actions | GitHub Actions |
| macOS | Azure Pipelines | CircleCI¹ / Cirrus CI / GitLab¹ | GitHub Actions | |
| Windows | Azure Pipelines | Cirrus CI / GitLab¹ | GitHub Actions | |
| | 3.11 | 3.12 | 3.13 |
|---------|----------------------------------|---------------------------------------------|----------------|
| Linux | Azure Pipelines / GitHub Actions | CircleCI¹ / Cirrus CI / GitLab¹ / Travis CI | GitHub Actions |
| macOS | Azure Pipelines | CircleCI¹ / Cirrus CI / GitLab¹ | GitHub Actions |
| Windows | Azure Pipelines | Cirrus CI / GitLab¹ / Travis CI | GitHub Actions |
> ¹ Runs a reduced set of tests to reduce CI load
Non-x86 architectures are covered on Travis CI using Python 3.12.
+20 -5
View File
@@ -1,9 +1,24 @@
Copyright 2017, Joe Rickerby and contributors. All rights reserved.
This project is licensed under the 'BSD 2-clause license'.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Copyright (c) 2017-2025, Joe Rickerby and contributors. All rights reserved.
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+38 -33
View File
@@ -4,6 +4,7 @@ cibuildwheel
[![PyPI](https://img.shields.io/pypi/v/cibuildwheel.svg)](https://pypi.python.org/pypi/cibuildwheel)
[![Documentation Status](https://readthedocs.org/projects/cibuildwheel/badge/?version=stable)](https://cibuildwheel.pypa.io/en/stable/?badge=stable)
[![Actions Status](https://github.com/pypa/cibuildwheel/workflows/Test/badge.svg)](https://github.com/pypa/cibuildwheel/actions)
[![Travis Status](https://img.shields.io/travis/com/pypa/cibuildwheel/main?logo=travis)](https://travis-ci.com/github/pypa/cibuildwheel)
[![CircleCI Status](https://img.shields.io/circleci/build/gh/pypa/cibuildwheel/main?logo=circleci)](https://circleci.com/gh/pypa/cibuildwheel)
[![Azure Status](https://dev.azure.com/joerick0429/cibuildwheel/_apis/build/status/pypa.cibuildwheel?branchName=main)](https://dev.azure.com/joerick0429/cibuildwheel/_build/latest?definitionId=4&branchName=main)
@@ -14,7 +15,7 @@ cibuildwheel
Python wheels are great. Building them across **Mac, Linux, Windows**, on **multiple versions of Python**, is not.
`cibuildwheel` is here to help. `cibuildwheel` runs on your CI server - currently it supports GitHub Actions, Azure Pipelines, CircleCI, and GitLab CI - and it builds and tests your wheels across all of your platforms.
`cibuildwheel` is here to help. `cibuildwheel` runs on your CI server - currently it supports GitHub Actions, Azure Pipelines, Travis CI, CircleCI, and GitLab CI - and it builds and tests your wheels across all of your platforms.
What does it do?
@@ -45,7 +46,7 @@ While cibuildwheel itself requires a recent Python version to run (we support th
<sup>⁵ manylinux armv7l support is experimental. As there are no RHEL based image for this architecture, it's using an Ubuntu based image instead.</sup><br>
- Builds manylinux, musllinux, macOS, and Windows wheels for CPython, PyPy, and GraalPy
- Works on GitHub Actions, Azure Pipelines, CircleCI, GitLab CI, and Cirrus CI
- Works on GitHub Actions, Azure Pipelines, Travis CI, CircleCI, GitLab CI, and Cirrus CI
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
- Runs your library's tests against the wheel-installed version of your library
@@ -60,6 +61,7 @@ Usage
|-----------------|-------|-------|---------|-----------|-----------|-------------|---------|-----|
| GitHub Actions | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅⁴ | ✅³ |
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅ | ✅² | ✅⁴ | ✅³ |
| Travis CI | ✅ | | ✅ | ✅ | | | ✅⁴ | |
| CircleCI | ✅ | ✅ | | ✅ | ✅ | | ✅⁴ | ✅³ |
| Gitlab CI | ✅ | ✅ | ✅ | ✅¹ | ✅ | | ✅⁴ | ✅³ |
| Cirrus CI | ✅ | ✅ | ✅ | ✅ | ✅ | | ✅⁴ | |
@@ -91,15 +93,13 @@ jobs:
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-15-intel, macos-latest]
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/checkout@v5
# Used to host cibuildwheel
- uses: actions/setup-python@v6
- uses: actions/setup-python@v5
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==3.4.0
run: python -m pip install cibuildwheel==3.3.0
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
@@ -108,7 +108,7 @@ jobs:
# CIBW_SOME_OPTION: value
# ...
- uses: actions/upload-artifact@v6
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
@@ -126,11 +126,6 @@ The following diagram summarises the steps that cibuildwheel takes on each platf
<sup>Explore an interactive version of this diagram [in the docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works).</sup>
> [!WARNING]
> Building and testing wheels executes arbitrary code from your project and its dependencies. Although cibuildwheel uses OCI containers and Pyodide for some builds, these provide no security guarantees - the code you're building and testing has full access to the environment that's invoking cibuildwheel.
>
> If you cannot trust all the code that's pulled in, maintain good security hygiene: keep the job that builds distributions separate from the job that uploads them to PyPI, handle secrets and credentials with care and rotate them regularly, and follow the principle of least privilege when granting permissions. Do not store sensitive data on CI runners.
<!--[[[cog from readme_options_table import get_table; print(get_table()) ]]]-->
@@ -190,8 +185,8 @@ Here are some repos that use cibuildwheel.
| [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][] | The fundamental package for scientific computing with 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][] | 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. |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
@@ -201,8 +196,8 @@ Here are some repos that use cibuildwheel.
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy
[NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib
[Tornado]: https://github.com/tornadoweb/tornado
[Matplotlib]: https://github.com/matplotlib/matplotlib
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
[Prophet]: https://github.com/facebook/prophet
[Kivy]: https://github.com/kivy/kivy
@@ -235,23 +230,6 @@ Changelog
<!-- [[[cog from readme_changelog import mini_changelog; print(mini_changelog()) ]]] -->
### 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)
- 🐛 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)
### v3.3.0
_12 November 2025_
@@ -285,7 +263,34 @@ _22 September 2025_
- ⚠️ PyPy 3.10 was moved to `pypy-eol` in the `enable` option, as it is now end-of-life. (#2521)
- 📚 Docs improvements (#2574, #2601, #2598)
<!-- [[[end]]] (sum: aO1wNWSgKa) -->
### v3.1.4
_19 August 2025_
- ✨ Add a `--clean-cache` command to clean up our cache (#2489)
- 🛠 Update Python to 3.14rc2 and other patch version bumps (#2542, #2556)
- 🛠 Update Pyodide to 0.28.2 (#2562, #2558)
- 🐛 Fix resolution with `pyodide-build` when `dependency-versions` is set (#2548)
- 🐛 Set `CMAKE_FIND_ROOT_PATH_MODE_PACKAGE` to `BOTH` on Android (#2547)
- 🐛 Add `patchelf` dependency for platforms that can build Android wheels (#2552)
- 🐛 Ignore empty values for `CIBW_ARCHS` like most other environment variables (#2541)
- 💼 The `color` and `suggest_on_error` argparse options are now default in 3.14rc1+ (#2554)
- 💼 Use the virtualenv release URL instead of blob URL (should be more robust) (#2555)
- 🧪 For iOS, lowering to macos-14 is needed for now due to issues with GitHub's runner images (#2557)
- 🧪 Split out platforms iOS and Android in our tests (#2519)
- 🧪 Fix and enable doctests (#2546)
- 📚 Improve our docs on free-threading (#2549)
### v3.1.3
_1 August 2025_
- 🐛 Fix bug where "latest" dependencies couldn't update to pip 25.2 on Windows (#2537)
- 🧪 Use pytest-rerunfailures to improve some of our iOS/Android tests (#2527, #2539)
- 🧪 Remove some GraalPy Windows workarounds in our tests (#2501)
<!-- [[[end]]] (sum: vS54piNR4b) -->
---
+11 -21
View File
@@ -28,10 +28,10 @@ branding:
runs:
using: composite
steps:
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- uses: actions/setup-python@v6
id: python
with:
python-version: "3.11 - 3.14"
python-version: "3.11 - 3.13"
update-environment: false
- id: cibw
@@ -69,28 +69,13 @@ runs:
venv_path = Path(r"${{ runner.temp }}") / "cibw"
if venv_path.exists():
shutil.rmtree(venv_path)
builder = EnvBuilder()
builder.create(venv_path)
exposed_binaries = {"cibuildwheel"}
if "uv" in EXTRAS:
exposed_binaries.add("uv")
clean_bin_path = builder.bin_path.parent / f"{builder.bin_path.name}.clean"
clean_bin_path.mkdir()
for path in list(builder.bin_path.iterdir()):
if path.stem in exposed_binaries:
try:
os.symlink(path, clean_bin_path / path.name)
except OSError:
shutil.copy2(path, clean_bin_path / path.name)
cibw_bin = [p for p in builder.bin_path.glob("cibuildwheel*") if p.stem == "cibuildwheel"][0]
with open(os.environ["GITHUB_OUTPUT"], "at") as f:
f.write(f"cibw-bin={cibw_bin}\n")
f.write(f"prepend-path={clean_bin_path}\n")
f.write(f"prepend-path={builder.bin_path if 'uv' in EXTRAS else ''}\n")
print("::endgroup::")
EOF
@@ -98,8 +83,10 @@ runs:
# Redirecting stderr to stdout to fix interleaving issue in Actions.
- run: |
export PATH="${{ steps.cibw.outputs.prepend-path }}:$PATH"
prepend_path="${{ steps.cibw.outputs.prepend-path }}"
if [ -n "$prepend_path" ]; then
export PATH="$prepend_path:$PATH"
fi
"${{ steps.cibw.outputs.cibw-bin }}" \
"${{ inputs.package-dir }}" \
${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}} \
@@ -111,7 +98,10 @@ runs:
# Windows needs powershell to interact nicely with Meson
- run: |
$env:PATH = "${{ steps.cibw.outputs.prepend-path }};$env:PATH"
$PrependPath = "${{ steps.cibw.outputs.prepend-path }}"
if ($PrependPath) {
$env:PATH = "$PrependPath;$env:PATH"
}
& "${{ steps.cibw.outputs.cibw-bin }}" `
"${{ inputs.package-dir }}" `
${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}} `
+3 -3
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# /// script
# dependencies = ["click", "packaging", "prek"]
# dependencies = ["click", "packaging"]
# ///
@@ -139,7 +139,7 @@ def bump_version() -> None:
# run pre-commit to update the README changelog
subprocess.run(
[
"prek",
"pre-commit",
"run",
"--files=docs/changelog.md",
],
@@ -149,7 +149,7 @@ def bump_version() -> None:
# run pre-commit to check that no errors occurred on the second run
subprocess.run(
[
"prek",
"pre-commit",
"run",
"--files=docs/changelog.md",
],
+4 -5
View File
@@ -28,6 +28,7 @@ $defs:
description: How to inherit the parent's value.
enable:
enum:
- cpython-experimental-riscv64
- cpython-freethreading
- cpython-prerelease
- graalpy
@@ -57,23 +58,21 @@ properties:
type: string_array
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]", or "pip"
oneOf:
- enum: [pip, build, "build[uv]", uv, default]
- enum: [pip, build, "build[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]
enum: [pip, build, "build[uv]"]
args:
type: array
items:
+14 -44
View File
@@ -16,8 +16,6 @@ import click
DIR = Path(__file__).parent.parent.resolve()
BuildBackend = typing.Literal["setuptools", "meson"]
def shell(cmd: str, *, check: bool, **kwargs: object) -> subprocess.CompletedProcess[str]:
return subprocess.run([cmd], shell=True, check=check, **kwargs) # type: ignore[call-overload, no-any-return]
@@ -29,17 +27,11 @@ def git_repo_has_changes() -> bool:
return unstaged_changes or staged_changes
def generate_project(path: Path, build_backend: BuildBackend) -> None:
def generate_basic_project(path: Path) -> None:
sys.path.insert(0, "")
match build_backend:
case "meson":
from test.test_projects.meson import new_meson_project as new_project # noqa: PLC0415
case "setuptools":
from test.test_projects.setuptools import new_c_project as new_project # noqa: PLC0415
case _:
typing.assert_never(build_backend)
from test.test_projects.c import new_c_project # noqa: PLC0415
project = new_project()
project = new_c_project()
project.generate(path)
@@ -47,10 +39,10 @@ class CIService(typing.NamedTuple):
name: str
dst_config_path: str
badge_md: str
config_file_transform: typing.Callable[[str, str], str] = lambda x, _: x # identity by default
config_file_transform: typing.Callable[[str], str] = lambda x: x # identity by default
def github_config_file_transform(content: str, git_ref: str) -> str:
def github_config_file_transform(content: str) -> str:
# one of the the github configs only builds on main, so we need to remove that restriction
# so our example build will run on the test branch.
#
@@ -69,22 +61,6 @@ def github_config_file_transform(content: str, git_ref: str) -> str:
"push:",
content,
)
# use the version of cibuildwheel from the current commit, not the latest
# release
# replace:
# """
# uses: pypa/cibuildwheel@v3.3.1
# """
# with:
# """
# uses: pypa/cibuildwheel@<latest commit hash>
# """
content = re.sub(
r"uses: pypa/cibuildwheel@v.*",
f"uses: pypa/cibuildwheel@{git_ref}",
content,
)
return content
@@ -134,23 +110,20 @@ def ci_service_for_config_file(config_file: Path) -> CIService:
@click.command()
@click.argument("config_files", nargs=-1, type=click.Path())
@click.option("--build-backend", type=click.Choice(["setuptools", "meson"]), default="setuptools")
def run_example_ci_configs(
config_files: list[str], build_backend: BuildBackend = "setuptools"
) -> None:
def run_example_ci_configs(config_files=None):
"""
Test the example configs. If no files are specified, will test
examples/*-minimal.yml
"""
if len(config_files) == 0:
config_file_paths = list(Path("examples").glob("*-minimal.yml"))
config_files = Path("examples").glob("*-minimal.yml")
else:
config_file_paths = [Path(f) for f in config_files]
config_files = [Path(f) for f in config_files]
# check each CI service has at most 1 config file
configs_by_service = set()
for config_file in config_file_paths:
for config_file in config_files:
service = ci_service_for_config_file(config_file)
if service.name in configs_by_service:
msg = "You cannot specify more than one config per CI service"
@@ -164,9 +137,6 @@ def run_example_ci_configs(
previous_branch = shell(
"git rev-parse --abbrev-ref HEAD", check=True, capture_output=True, encoding="utf8"
).stdout.strip()
git_ref = shell(
"git rev-parse HEAD", check=True, capture_output=True, encoding="utf8"
).stdout.strip()
timestamp = time.strftime("%Y-%m-%dT%H-%M-%S", time.gmtime())
branch_name = f"example-config-test---{previous_branch}-{timestamp}"
@@ -175,16 +145,16 @@ def run_example_ci_configs(
shell(f"git checkout --orphan {branch_name}", check=True)
example_project = Path("example_root")
generate_project(example_project, build_backend=build_backend)
generate_basic_project(example_project)
for config_file in config_file_paths:
for config_file in config_files:
service = ci_service_for_config_file(config_file)
dst_config_file = example_project / service.dst_config_path
dst_config_file.parent.mkdir(parents=True, exist_ok=True)
contents = config_file.read_text(encoding="utf8")
contents = service.config_file_transform(contents, git_ref)
contents = service.config_file_transform(contents)
dst_config_file.write_text(contents, encoding="utf8")
subprocess.run(["git", "add", example_project], check=True)
@@ -208,14 +178,14 @@ def run_example_ci_configs(
print("> ")
print("> | Service | Config | Status |")
print("> |---|---|---|")
for config_file in config_file_paths:
for config_file in config_files:
service = ci_service_for_config_file(config_file)
badge = service.badge_md.format(
branch=branch_name, branch_escaped=quote(branch_name, safe="")
)
print(f"> | {service.name} | `{config_file}` | {badge} |")
print("> ")
print(f"> Generated by `{' '.join(sys.argv)}`")
print("> Generated by `bin/run_example_ci_config.py`")
print()
print("---")
finally:
+21 -23
View File
@@ -117,7 +117,7 @@ class GraalPyVersions:
self.releases = [r for r in releases if "graalpy_version" in r and "python_version" in r]
def update_version(self, identifier: str, spec: Specifier) -> ConfigUrl | None:
def update_version(self, identifier: str, spec: Specifier) -> ConfigUrl:
if "x86_64" in identifier or "amd64" in identifier:
arch = "x86_64"
elif "arm64" in identifier or "aarch64" in identifier:
@@ -126,14 +126,14 @@ class GraalPyVersions:
msg = f"{identifier} not supported yet on GraalPy"
raise RuntimeError(msg)
gpspec_str = identifier.split("-", maxsplit=1)[0].split("_")[1]
gpspec_str = identifier.split("-")[0].split("_")[1]
if "." not in gpspec_str and len(gpspec_str) == 3:
gpspec_str = gpspec_str[:2] + "." + gpspec_str[-1]
gpspec = Specifier(f"=={gpspec_str}.*")
releases_tmp = (r for r in self.releases if spec.contains(r["python_version"]))
releases_tmp = (r for r in releases_tmp if gpspec.contains(r["graalpy_version"]))
releases = sorted(releases_tmp, key=lambda r: r["graalpy_version"])
releases = [r for r in self.releases if spec.contains(r["python_version"])]
releases = [r for r in self.releases if gpspec.contains(r["graalpy_version"])]
releases = sorted(releases, key=lambda r: r["graalpy_version"])
if not releases:
msg = f"GraalPy {arch} not found for {spec}!"
@@ -155,20 +155,18 @@ class GraalPyVersions:
arch = "amd64" if arch == "x86_64" else "aarch64"
ext = "zip" if "win" in identifier else "tar.gz"
urls = [
(url,) = (
rf["browser_download_url"]
for rf in release["assets"]
if rf["name"].endswith(f"{platform}-{arch}.{ext}")
and rf["name"].startswith(f"graalpy-{gpversion.major}")
]
if urls:
(url,) = urls
return ConfigUrl(
identifier=identifier,
version=f"{version.major}.{version.minor}",
url=url,
)
return None
)
return ConfigUrl(
identifier=identifier,
version=f"{version.major}.{version.minor}",
url=url,
)
class PyPyVersions:
@@ -266,11 +264,9 @@ class CPythonVersions:
# Removing the prefix
version = Version(release["name"].removeprefix("Python "))
self.versions_dict[version] = release["resource_uri"]
files_response = requests.get("https://www.python.org/api/v2/downloads/release_file/")
files_response.raise_for_status()
self.files_info = files_response.json()
uri = int(release["resource_uri"].rstrip("/").split("/")[-1])
self.versions_dict[version] = uri
def update_version(self, identifier: str, spec: Specifier, file_ident: str) -> ConfigUrl | None:
# see note above on Specifier.filter
@@ -280,9 +276,13 @@ class CPythonVersions:
for new_version in sorted_versions:
# Find the first patch version that contains the requested file
uri = self.versions_dict[new_version]
files = [rf for rf in self.files_info if rf["release"] == uri]
response = requests.get(
f"https://www.python.org/api/v2/downloads/release_file/?release={uri}"
)
response.raise_for_status()
file_info = response.json()
urls = [rf["url"] for rf in files if file_ident in rf["url"]]
urls = [rf["url"] for rf in file_info if file_ident in rf["url"]]
if urls:
return ConfigUrl(
identifier=identifier,
@@ -449,8 +449,6 @@ class AllVersions:
elif "macosx_arm64" in identifier:
config_update = self.macos_pypy_arm64.update_version_macos(spec)
elif identifier.startswith("gp"):
if "macosx_x86_64" in identifier:
return
config_update = self.graalpy.update_version(identifier, spec)
elif "t-win32" in identifier and identifier.startswith("cp"):
config_update = self.windows_t_32.update_version_windows(spec)
+1 -1
View File
@@ -1 +1 @@
__version__ = "3.4.0"
__version__ = "3.3.0"
+8 -7
View File
@@ -1,7 +1,6 @@
import argparse
import contextlib
import dataclasses
import functools
import os
import shutil
import sys
@@ -79,13 +78,8 @@ def main_inner(global_options: GlobalOptions) -> None:
`main_inner` is the same as `main`, but it raises FatalError exceptions
rather than exiting directly.
"""
# Default in 3.15+, only needed on 3.14
if sys.version_info >= (3, 14):
arg_parser = functools.partial(argparse.ArgumentParser, suggest_on_error=True)
else:
arg_parser = argparse.ArgumentParser
parser = arg_parser(
parser = argparse.ArgumentParser(
description="Build wheels for all the platforms.",
epilog="""
Most options are supplied via environment variables or in
@@ -469,6 +463,13 @@ def detect_warnings(*, options: Options) -> Generator[str, None, None]:
build_selector = options.globals.build_selector
test_selector = options.globals.test_selector
if EnableGroup.CPythonExperimentalRiscV64 in build_selector.enable:
yield (
"'cpython-experimental-riscv64' enable is deprecated and will be removed in a future version. "
"It should be removed from tool.cibuildwheel.enable in pyproject.toml "
"or CIBW_ENABLE environment variable."
)
all_valid_identifiers = [
config.identifier
for module in ALL_PLATFORM_MODULES.values()
+9 -9
View File
@@ -7,7 +7,7 @@ from typing import Literal, Self, get_args
from .logger import log
from .util.helpers import parse_key_value_string
BuildFrontendName = Literal["pip", "build", "build[uv]", "uv"]
BuildFrontendName = Literal["pip", "build", "build[uv]"]
@dataclasses.dataclass(frozen=True)
@@ -36,13 +36,13 @@ class BuildFrontendConfig:
return {"name": self.name, "args": repr(self.args)}
def _get_verbosity_flags(level: int, frontend: BuildFrontendName, *, py38: bool) -> list[str]:
def _get_verbosity_flags(level: int, frontend: BuildFrontendName) -> list[str]:
if level < 0:
if frontend.startswith("build") and py38:
msg = f"build_verbosity {level} is not supported for {frontend} frontend. Ignoring."
log.warning(msg)
return []
return ["-" + -level * "q"]
if frontend == "pip":
return ["-" + -level * "q"]
msg = f"build_verbosity {level} is not supported for {frontend} frontend. Ignoring."
log.warning(msg)
if level > 0:
if frontend == "pip":
@@ -75,10 +75,10 @@ def parse_config_settings(config_settings_str: str) -> dict[str, str | list[str]
def get_build_frontend_extra_flags(
build_frontend: BuildFrontendConfig, verbosity_level: int, config_settings: str, *, py38: bool
build_frontend: BuildFrontendConfig, verbosity_level: int, config_settings: str
) -> list[str]:
return [
*_split_config_settings(config_settings),
*build_frontend.args,
*_get_verbosity_flags(verbosity_level, build_frontend.name, py38=py38),
*_get_verbosity_flags(verbosity_level, build_frontend.name),
]
+30 -89
View File
@@ -7,7 +7,7 @@ import shlex
import shutil
import subprocess
import sysconfig
from collections.abc import Iterable, Iterator, MutableMapping
from collections.abc import Iterable, Iterator
from dataclasses import dataclass
from os.path import relpath
from pathlib import Path
@@ -34,7 +34,7 @@ from ..util.file import CIBW_CACHE_PATH, copy_test_sources, download, move_file
from ..util.helpers import prepare_command
from ..util.packaging import find_compatible_wheel
from ..util.python_build_standalone import create_python_build_standalone_environment
from ..venv import constraint_flags, find_uv, virtualenv
from ..venv import constraint_flags, ensure_uv, virtualenv
ANDROID_TRIPLET = {
"arm64_v8a": "aarch64-linux-android",
@@ -190,12 +190,10 @@ def setup_env(
"""
log.step("Setting up build environment...")
build_frontend = build_options.build_frontend.name
use_uv = build_frontend in {"build[uv]", "uv"}
uv_path = find_uv()
if use_uv and uv_path is None:
msg = "uv not found"
raise AssertionError(msg)
pip = ["pip"] if not use_uv else [str(uv_path), "pip"]
use_uv = build_frontend == "build[uv]"
if use_uv:
ensure_uv()
pip = ["pip"] if not use_uv else ["uv", "pip"]
# Create virtual environment
python_exe = create_python_build_standalone_environment(
@@ -228,8 +226,8 @@ def setup_env(
android_env = setup_android_env(config, python_dir, venv_dir, build_env)
# Install build tools
if build_frontend not in {"build", "build[uv]", "uv"}:
msg = "Android requires the build frontend to be 'build' or 'uv'"
if build_frontend not in {"build", "build[uv]"}:
msg = "Android requires the build frontend to be 'build'"
raise errors.FatalError(msg)
call(*pip, "install", "build", *constraint_flags(dependency_constraint), env=build_env)
@@ -390,9 +388,6 @@ def setup_android_env(
for key in ["CFLAGS", "CXXFLAGS"]:
android_env[key] += " " + opt
# Cargo target linker needs to be specified after CC is set
setup_rust(config, python_dir, android_env)
# Format the environment so it can be pasted into a shell when debugging.
for key, value in sorted(android_env.items()):
if os.environ.get(key) != value:
@@ -401,34 +396,6 @@ def setup_android_env(
return android_env
def setup_rust(
config: PythonConfiguration,
python_dir: Path,
env: MutableMapping[str, str],
) -> None:
cargo_target = android_triplet(config.identifier)
# CARGO_BUILD_TARGET is the variable used by Cargo and setuptools_rust
env["CARGO_BUILD_TARGET"] = cargo_target
# The linker needs to be specified after CC is set by android-env.sh
cargo_target_linker_env_name = f"CARGO_TARGET_{cargo_target.upper().replace('-', '_')}_LINKER"
# CC has already been set by calling android.py (it calls android-env.sh)
env[cargo_target_linker_env_name] = env["CC"]
# All Python extension modules must be explicitly linked against libpython3.x.so when building for Android.
# See: https://peps.python.org/pep-0738/#linkage
# For projects using PyO3, this requires setting PYO3_CROSS_LIB_DIR to the directory containing libpython3.x.so.
# See: https://pyo3.rs/v0.27.1/building-and-distribution.html#cross-compiling
env["PYO3_CROSS_LIB_DIR"] = str(python_dir / "prefix" / "lib")
venv_bin = Path(env["VIRTUAL_ENV"]) / "bin"
for tool in ["cargo", "rustup"]:
shim_path = venv_bin / tool
shutil.copy(resources.PATH / "_rust_shim.py", shim_path)
shim_path.chmod(0o755)
def before_build(state: BuildState) -> None:
if state.options.before_build:
log.step("Running before_build...")
@@ -442,46 +409,22 @@ def before_build(state: BuildState) -> None:
def build_wheel(state: BuildState) -> Path:
log.step("Building wheel...")
built_wheel_dir = state.build_path / "built_wheel"
match state.options.build_frontend.name:
case "build" | "build[uv]":
call(
"python",
"-m",
"build",
state.options.package_dir,
"--wheel",
"--no-isolation",
"--skip-dependency-check",
f"--outdir={built_wheel_dir}",
*get_build_frontend_extra_flags(
state.options.build_frontend,
state.options.build_verbosity,
state.options.config_settings,
py38=False,
),
env=state.android_env,
)
case "uv":
uv_path = find_uv()
assert uv_path is not None
call(
uv_path,
"build",
state.options.package_dir,
"--wheel",
"--no-build-isolation",
f"--out-dir={built_wheel_dir}",
*get_build_frontend_extra_flags(
state.options.build_frontend,
state.options.build_verbosity,
state.options.config_settings,
py38=False,
),
env=state.android_env,
)
case x:
msg = f"Invalid build backend {x!r}"
raise AssertionError(msg)
call(
"python",
"-m",
"build",
state.options.package_dir,
"--wheel",
"--no-isolation",
"--skip-dependency-check",
f"--outdir={built_wheel_dir}",
*get_build_frontend_extra_flags(
state.options.build_frontend,
state.options.build_verbosity,
state.options.config_settings,
),
env=state.android_env,
)
built_wheels = list(built_wheel_dir.glob("*.whl"))
if len(built_wheels) != 1:
@@ -633,11 +576,9 @@ def test_wheel(state: BuildState, wheel: Path, *, build_frontend: str) -> None:
log.step("Testing wheel...")
use_uv = build_frontend == "build[uv]"
uv_path = find_uv()
if use_uv and uv_path is None:
msg = "uv not found"
raise AssertionError(msg)
pip = ["pip"] if not use_uv else [str(uv_path), "pip"]
if use_uv:
ensure_uv()
pip = ["pip"] if not use_uv else ["uv", "pip"]
native_arch = arch_synonym(platform.machine(), platforms.native_platform(), "android")
if state.config.arch != native_arch:
@@ -689,7 +630,7 @@ def test_wheel(state: BuildState, wheel: Path, *, build_frontend: str) -> None:
)
# Android doesn't support placeholders in the test command.
if any(("{" + placeholder + "}") in test_command for placeholder in ("project", "package")):
if any(("{" + placeholder + "}") in test_command for placeholder in ["project", "package"]):
msg = (
f"Test command {test_command!r} with a "
"'{project}' or '{package}' placeholder is not supported on Android, "
@@ -699,12 +640,12 @@ def test_wheel(state: BuildState, wheel: Path, *, build_frontend: str) -> None:
# Parse test-command.
test_args = shlex.split(test_command)
if test_args[0] in {"python", "python3"} and any(arg in test_args for arg in ("-c", "-m")):
if test_args[0] in ["python", "python3"] and any(arg in test_args for arg in ["-c", "-m"]):
# Forward the args to the CPython testbed script. We require '-c' or '-m'
# to be in the command, because without those flags, the testbed script
# will prepend '-m test', which will run Python's own test suite.
del test_args[0]
elif test_args[0] == "pytest":
elif test_args[0] in ["pytest"]:
# We transform some commands into the `python -m` form, but this is deprecated.
msg = (
f"Test command {test_command!r} is not supported on Android. "
+7 -36
View File
@@ -284,7 +284,7 @@ def setup_python(
build_frontend: BuildFrontendName,
xbuild_tools: Sequence[str] | None,
) -> tuple[Path, dict[str, str]]:
if build_frontend == "build[uv]" or build_frontend == "uv":
if build_frontend == "build[uv]":
msg = "uv doesn't support iOS"
raise errors.FatalError(msg)
@@ -441,7 +441,7 @@ def build(options: Options, tmp_path: Path) -> None:
build_options = options.build_options(config.identifier)
build_frontend = build_options.build_frontend
# uv doesn't support iOS
if build_frontend.name == "build[uv]" or build_frontend.name == "uv":
if build_frontend.name == "build[uv]":
msg = "uv doesn't support iOS"
raise errors.FatalError(msg)
@@ -450,7 +450,6 @@ def build(options: Options, tmp_path: Path) -> None:
identifier_tmp_dir = tmp_path / config.identifier
identifier_tmp_dir.mkdir()
built_wheel_dir = identifier_tmp_dir / "built_wheel"
repaired_wheel_dir = identifier_tmp_dir / "repaired_wheel"
constraints_path = build_options.dependency_constraints.get_for_python_version(
version=config.version, tmp_dir=identifier_tmp_dir
@@ -488,10 +487,7 @@ def build(options: Options, tmp_path: Path) -> None:
built_wheel_dir.mkdir()
extra_flags = get_build_frontend_extra_flags(
build_frontend,
build_options.build_verbosity,
build_options.config_settings,
py38=False,
build_frontend, build_options.build_verbosity, build_options.config_settings
)
match build_frontend.name:
@@ -524,36 +520,11 @@ def build(options: Options, tmp_path: Path) -> None:
case _:
assert_never(build_frontend)
built_wheel = next(built_wheel_dir.glob("*.whl"))
test_wheel = built_wheel = next(built_wheel_dir.glob("*.whl"))
if built_wheel.name.endswith("none-any.whl"):
raise errors.NonPlatformWheelError()
repaired_wheel_dir.mkdir()
if build_options.repair_command:
log.step("Repairing wheel...")
repair_command_prepared = prepare_command(
build_options.repair_command,
wheel=built_wheel,
dest_dir=repaired_wheel_dir,
package=build_options.package_dir,
project=".",
)
shell(repair_command_prepared, env=env)
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
try:
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.RepairStepProducedNoWheelError() from None
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
test_wheel = repaired_wheel
log.step_end()
if build_options.test_command and build_options.test_selector(config.identifier):
@@ -721,11 +692,11 @@ def build(options: Options, tmp_path: Path) -> None:
# We're all done here; move it to output (overwrite existing)
output_wheel: Path | None = None
if compatible_wheel is None:
output_wheel = build_options.output_dir.joinpath(repaired_wheel.name)
moved_wheel = move_file(repaired_wheel, output_wheel)
output_wheel = build_options.output_dir.joinpath(built_wheel.name)
moved_wheel = move_file(built_wheel, output_wheel)
if moved_wheel != output_wheel.resolve():
log.warning(
f"{repaired_wheel} was moved to {moved_wheel} instead of {output_wheel}"
f"{built_wheel} was moved to {moved_wheel} instead of {output_wheel}"
)
built_wheels.append(output_wheel)
+2 -19
View File
@@ -207,7 +207,7 @@ def build_in_container(
local_identifier_tmp_dir = local_tmp_dir / config.identifier
build_options = options.build_options(config.identifier)
build_frontend = build_options.build_frontend
use_uv = build_frontend.name in {"build[uv]", "uv"}
use_uv = build_frontend.name == "build[uv]"
pip = ["uv", "pip"] if use_uv else ["pip"]
log.step("Setting up build environment...")
@@ -274,10 +274,7 @@ def build_in_container(
container.call(["mkdir", "-p", built_wheel_dir])
extra_flags = get_build_frontend_extra_flags(
build_frontend,
build_options.build_verbosity,
build_options.config_settings,
py38=config.identifier[1:].startswith("p38"),
build_frontend, build_options.build_verbosity, build_options.config_settings
)
match build_frontend.name:
@@ -310,19 +307,6 @@ def build_in_container(
],
env=env,
)
case "uv":
container.call(
[
"uv",
"build",
f"--python={python_bin / 'python'}",
container_package_dir,
"--wheel",
f"--out-dir={built_wheel_dir}",
*extra_flags,
],
env=env,
)
case _:
assert_never(build_frontend)
@@ -525,7 +509,6 @@ def _matches_prepared_command(error_cmd: Sequence[str], command_template: str) -
def troubleshoot(options: Options, error: Exception) -> None:
if isinstance(error, subprocess.CalledProcessError) and (
error.cmd[0:4] == ["python", "-m", "pip", "wheel"]
or error.cmd[0:2] == ["uv", "build"]
or error.cmd[0:3] == ["python", "-m", "build"]
or _matches_prepared_command(
error.cmd, options.build_options(None).repair_command
+12 -40
View File
@@ -33,7 +33,7 @@ from ..util.file import (
)
from ..util.helpers import prepare_command, unwrap
from ..util.packaging import find_compatible_wheel, get_pip_version
from ..venv import constraint_flags, find_uv, virtualenv
from ..venv import constraint_flags, ensure_uv, virtualenv
@functools.cache
@@ -151,7 +151,7 @@ def install_cpython(_tmp: Path, version: str, url: str, free_threading: bool) ->
"""
)
raise errors.FatalError(msg)
python_filename = url.rsplit("/", maxsplit=1)[-1]
python_filename = url.split("/")[-1]
pkg_path = CIBW_CACHE_PATH / "cpython-installer" / python_filename
if not pkg_path.exists():
download(url, pkg_path)
@@ -217,8 +217,9 @@ def setup_python(
environment: ParsedEnvironment,
build_frontend: BuildFrontendName,
) -> tuple[Path, dict[str, str]]:
uv_path = find_uv()
use_uv = build_frontend in {"build[uv]", "uv"}
use_uv = build_frontend == "build[uv]"
if use_uv:
ensure_uv()
tmp.mkdir()
implementation_id = python_configuration.identifier.split("-")[0]
@@ -370,25 +371,13 @@ def setup_python(
env=env,
)
case "build[uv]":
assert uv_path is not None
call(
uv_path,
"pip",
"install",
"--upgrade",
"delocate",
"build[virtualenv, uv]",
*constraint_flags(dependency_constraint),
env=env,
)
case "uv":
assert uv_path is not None
call(
uv_path,
"uv",
"pip",
"install",
"--upgrade",
"delocate",
"build",
*constraint_flags(dependency_constraint),
env=env,
)
@@ -424,12 +413,10 @@ def build(options: Options, tmp_path: Path) -> None:
for config in python_configurations:
build_options = options.build_options(config.identifier)
build_frontend = build_options.build_frontend
use_uv = build_frontend.name in {"build[uv]", "uv"}
uv_path = find_uv()
if use_uv and uv_path is None:
msg = "uv not found"
raise AssertionError(msg)
pip = ["pip"] if not use_uv else [str(uv_path), "pip"]
use_uv = build_frontend.name == "build[uv]"
if use_uv:
ensure_uv()
pip = ["pip"] if not use_uv else ["uv", "pip"]
log.build_start(config.identifier)
identifier_tmp_dir = tmp_path / config.identifier
@@ -472,10 +459,7 @@ def build(options: Options, tmp_path: Path) -> None:
built_wheel_dir.mkdir()
extra_flags = get_build_frontend_extra_flags(
build_frontend,
build_options.build_verbosity,
build_options.config_settings,
py38=config.identifier[1:].startswith("p38"),
build_frontend, build_options.build_verbosity, build_options.config_settings
)
build_env = env.copy()
@@ -512,18 +496,6 @@ def build(options: Options, tmp_path: Path) -> None:
*extra_flags,
env=build_env,
)
case "uv":
assert uv_path is not None
call(
uv_path,
"build",
f"--python={base_python}",
build_options.package_dir,
"--wheel",
f"--out-dir={built_wheel_dir}",
*extra_flags,
env=build_env,
)
case _:
assert_never(build_frontend)
+1 -4
View File
@@ -416,10 +416,7 @@ def build(options: Options, tmp_path: Path) -> None:
log.step("Building wheel...")
extra_flags = get_build_frontend_extra_flags(
build_frontend,
build_options.build_verbosity,
build_options.config_settings,
py38=False,
build_frontend, build_options.build_verbosity, build_options.config_settings
)
call(
+11 -32
View File
@@ -5,7 +5,7 @@ import platform as platform_module
import shutil
import subprocess
import textwrap
from collections.abc import MutableMapping, Sequence, Set
from collections.abc import MutableMapping, Set
from functools import cache
from pathlib import Path
from typing import assert_never
@@ -24,7 +24,7 @@ from ..util.cmd import call, shell
from ..util.file import CIBW_CACHE_PATH, copy_test_sources, download, extract_zip, move_file
from ..util.helpers import prepare_command, unwrap
from ..util.packaging import find_compatible_wheel, get_pip_version
from ..venv import constraint_flags, find_uv, virtualenv
from ..venv import constraint_flags, ensure_uv, virtualenv
def get_nuget_args(
@@ -271,8 +271,9 @@ def setup_python(
if build_frontend == "build[uv]" and not can_use_uv(python_configuration):
build_frontend = "build"
use_uv = build_frontend in {"build[uv]", "uv"}
uv_path = find_uv()
use_uv = build_frontend == "build[uv]"
if use_uv:
ensure_uv()
log.step("Setting up build environment...")
venv_path = tmp / "venv"
@@ -323,13 +324,12 @@ def setup_python(
env=env,
)
case "build[uv]":
assert uv_path is not None
call(
uv_path,
"uv",
"pip",
"install",
"--upgrade",
"build[virtualenv]",
"build",
*constraint_flags(dependency_constraint),
env=env,
)
@@ -386,8 +386,6 @@ def build(options: Options, tmp_path: Path) -> None:
if not python_configurations:
return
uv_path = find_uv()
try:
before_all_options_identifier = python_configurations[0].identifier
before_all_options = options.build_options(before_all_options_identifier)
@@ -405,7 +403,8 @@ def build(options: Options, tmp_path: Path) -> None:
for config in python_configurations:
build_options = options.build_options(config.identifier)
build_frontend = build_options.build_frontend
use_uv = build_frontend.name in {"build[uv]", "uv"} and can_use_uv(config)
use_uv = build_frontend.name == "build[uv]" and can_use_uv(config)
log.build_start(config.identifier)
identifier_tmp_dir = tmp_path / config.identifier
@@ -450,10 +449,7 @@ def build(options: Options, tmp_path: Path) -> None:
built_wheel_dir.mkdir()
extra_flags = get_build_frontend_extra_flags(
build_frontend,
build_options.build_verbosity,
build_options.config_settings,
py38=config.identifier[1:].startswith("p38"),
build_frontend, build_options.build_verbosity, build_options.config_settings
)
if (
@@ -505,18 +501,6 @@ def build(options: Options, tmp_path: Path) -> None:
*extra_flags,
env=env,
)
case "uv":
assert uv_path is not None
call(
uv_path,
"build",
f"--python={base_python}",
build_options.package_dir,
"--wheel",
f"--out-dir={built_wheel_dir}",
*extra_flags,
env=env,
)
case _:
assert_never(build_frontend)
@@ -591,12 +575,7 @@ def build(options: Options, tmp_path: Path) -> None:
)
shell(before_test_prepared, env=virtualenv_env)
pip: Sequence[Path | str]
if use_uv:
assert uv_path is not None
pip = [uv_path, "pip"]
else:
pip = ["pip"]
pip = ["uv", "pip"] if use_uv else ["pip"]
# install the wheel
call(
-57
View File
@@ -1,57 +0,0 @@
#!/usr/bin/env python3
import os
import shutil
import subprocess
import sys
from pathlib import Path
def main() -> None:
# CIBW_HOST_TRIPLET is set in the android_env to the Android target triplet.
target = os.environ.get("CIBW_HOST_TRIPLET")
cmd_name = Path(sys.argv[0]).name
# Find the real command in PATH, excluding the current script's directory
path_env = os.environ.get("PATH", "")
script_dir = Path(__file__).resolve().parent
paths = path_env.split(os.pathsep)
# Filter out the script directory to avoid recursion
filtered_paths = [p for p in paths if Path(p).resolve() != script_dir]
filtered_path_env = os.pathsep.join(filtered_paths)
real_cmd = shutil.which(cmd_name, path=filtered_path_env)
if not real_cmd:
sys.stderr.write(f"cibuildwheel: Error: Could not find system {cmd_name}\n")
sys.exit(1)
# If we have a target (i.e. we are in the android_env), try to install it.
if target:
# Check if rustup is available to install the target
rustup_path = shutil.which("rustup", path=filtered_path_env)
if rustup_path:
try:
# We call rustup to ensure the target is installed.
subprocess.run(
[rustup_path, "target", "add", target],
check=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.PIPE,
text=True,
)
except subprocess.CalledProcessError as e:
sys.stderr.write(
f"cibuildwheel: Error: Failed to install Rust target {target}: {e.stderr}\n"
)
sys.exit(1)
# Execute the real command
os.execv(real_cmd, [real_cmd, *sys.argv[1:]])
if __name__ == "__main__":
main()
+40 -40
View File
@@ -161,30 +161,30 @@ 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" },
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.10/python-3.12.10-macos11.pkg" },
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.10/python-3.12.10-macos11.pkg" },
{ identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.12/python-3.13.12-macos11.pkg" },
{ identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.12/python-3.13.12-macos11.pkg" },
{ identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.12/python-3.13.12-macos11.pkg" },
{ identifier = "cp313t-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.12/python-3.13.12-macos11.pkg" },
{ identifier = "cp313t-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.12/python-3.13.12-macos11.pkg" },
{ identifier = "cp313t-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.12/python-3.13.12-macos11.pkg" },
{ identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-macos11.pkg" },
{ identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-macos11.pkg" },
{ identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-macos11.pkg" },
{ identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-macos11.pkg" },
{ identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-macos11.pkg" },
{ identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-macos11.pkg" },
{ identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.11/python-3.13.11-macos11.pkg" },
{ identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.11/python-3.13.11-macos11.pkg" },
{ identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.11/python-3.13.11-macos11.pkg" },
{ identifier = "cp313t-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.11/python-3.13.11-macos11.pkg" },
{ identifier = "cp313t-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.11/python-3.13.11-macos11.pkg" },
{ identifier = "cp313t-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.11/python-3.13.11-macos11.pkg" },
{ identifier = "cp314-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-macos11.pkg" },
{ identifier = "cp314-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-macos11.pkg" },
{ identifier = "cp314-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-macos11.pkg" },
{ identifier = "cp314t-macosx_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-macos11.pkg" },
{ identifier = "cp314t-macosx_arm64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-macos11.pkg" },
{ identifier = "cp314t-macosx_universal2", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-macos11.pkg" },
{ identifier = "pp38-macosx_x86_64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_x86_64.tar.bz2" },
{ identifier = "pp38-macosx_arm64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_arm64.tar.bz2" },
{ identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" },
{ identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2" },
{ identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_x86_64.tar.bz2" },
{ identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_arm64.tar.bz2" },
{ identifier = "pp311-macosx_x86_64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.21-macos_x86_64.tar.bz2" },
{ identifier = "pp311-macosx_arm64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.21-macos_arm64.tar.bz2" },
{ identifier = "pp311-macosx_x86_64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.20-macos_x86_64.tar.bz2" },
{ identifier = "pp311-macosx_arm64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.20-macos_arm64.tar.bz2" },
{ identifier = "gp311_242-macosx_x86_64", version = "3.11", url = "https://github.com/oracle/graalpython/releases/download/graal-24.2.2/graalpy-24.2.2-macos-amd64.tar.gz" },
{ identifier = "gp311_242-macosx_arm64", version = "3.11", url = "https://github.com/oracle/graalpython/releases/download/graal-24.2.2/graalpy-24.2.2-macos-aarch64.tar.gz" },
{ 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" },
{ identifier = "gp312_250-macosx_arm64", version = "3.12", url = "https://github.com/oracle/graalpython/releases/download/graal-25.0.2/graalpy-25.0.2-macos-aarch64.tar.gz" },
{ identifier = "gp312_250-macosx_arm64", version = "3.12", url = "https://github.com/oracle/graalpython/releases/download/graal-25.0.1/graalpy-25.0.1-macos-aarch64.tar.gz" },
]
[windows]
@@ -199,50 +199,50 @@ 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.12" },
{ identifier = "cp313t-win32", version = "3.13.12" },
{ identifier = "cp313-win_amd64", version = "3.13.12" },
{ identifier = "cp313t-win_amd64", version = "3.13.12" },
{ identifier = "cp314-win32", version = "3.14.3" },
{ identifier = "cp314t-win32", version = "3.14.3" },
{ identifier = "cp314-win_amd64", version = "3.14.3" },
{ identifier = "cp314t-win_amd64", version = "3.14.3" },
{ identifier = "cp313-win32", version = "3.13.11" },
{ identifier = "cp313t-win32", version = "3.13.11" },
{ identifier = "cp313-win_amd64", version = "3.13.11" },
{ identifier = "cp313t-win_amd64", version = "3.13.11" },
{ identifier = "cp314-win32", version = "3.14.2" },
{ identifier = "cp314t-win32", version = "3.14.2" },
{ identifier = "cp314-win_amd64", version = "3.14.2" },
{ identifier = "cp314t-win_amd64", version = "3.14.2" },
{ 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.12" },
{ identifier = "cp313t-win_arm64", version = "3.13.12" },
{ identifier = "cp314-win_arm64", version = "3.14.3" },
{ identifier = "cp314t-win_arm64", version = "3.14.3" },
{ identifier = "cp313-win_arm64", version = "3.13.11" },
{ identifier = "cp313t-win_arm64", version = "3.13.11" },
{ identifier = "cp314-win_arm64", version = "3.14.2" },
{ identifier = "cp314t-win_arm64", version = "3.14.2" },
{ identifier = "pp38-win_amd64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" },
{ identifier = "pp39-win_amd64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" },
{ identifier = "pp310-win_amd64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-win64.zip" },
{ identifier = "pp311-win_amd64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.21-win64.zip" },
{ identifier = "pp311-win_amd64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.20-win64.zip" },
{ identifier = "gp311_242-win_amd64", version = "3.11", url = "https://github.com/oracle/graalpython/releases/download/graal-24.2.2/graalpy-24.2.2-windows-amd64.zip" },
{ identifier = "gp312_250-win_amd64", version = "3.12", url = "https://github.com/oracle/graalpython/releases/download/graal-25.0.2/graalpy-25.0.2-windows-amd64.zip" },
{ identifier = "gp312_250-win_amd64", version = "3.12", url = "https://github.com/oracle/graalpython/releases/download/graal-25.0.1/graalpy-25.0.1-windows-amd64.zip" },
]
[pyodide]
python_configurations = [
{ identifier = "cp312-pyodide_wasm32", version = "3.12", default_pyodide_version = "0.27.7", node_version = "v22" },
{ identifier = "cp313-pyodide_wasm32", version = "3.13", default_pyodide_version = "0.29.3", node_version = "v22" },
{ identifier = "cp313-pyodide_wasm32", version = "3.13", default_pyodide_version = "0.29.0", node_version = "v22" },
]
[android]
python_configurations = [
{ identifier = "cp313-android_arm64_v8a", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.12/python-3.13.12-aarch64-linux-android.tar.gz" },
{ identifier = "cp313-android_x86_64", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.12/python-3.13.12-x86_64-linux-android.tar.gz" },
{ identifier = "cp314-android_arm64_v8a", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-aarch64-linux-android.tar.gz" },
{ identifier = "cp314-android_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.3/python-3.14.3-x86_64-linux-android.tar.gz" },
{ identifier = "cp313-android_arm64_v8a", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.11/python-3.13.11-aarch64-linux-android.tar.gz" },
{ identifier = "cp313-android_x86_64", version = "3.13", url = "https://repo.maven.apache.org/maven2/com/chaquo/python/python/3.13.11/python-3.13.11-x86_64-linux-android.tar.gz" },
{ identifier = "cp314-android_arm64_v8a", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-aarch64-linux-android.tar.gz" },
{ identifier = "cp314-android_x86_64", version = "3.14", url = "https://www.python.org/ftp/python/3.14.2/python-3.14.2-x86_64-linux-android.tar.gz" },
]
[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" },
{ 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" },
{ 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" },
{ 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" },
{ 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" },
{ 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" },
{ identifier = "cp313-ios_arm64_iphoneos", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b12/Python-3.13-iOS-support.b12.tar.gz" },
{ identifier = "cp313-ios_x86_64_iphonesimulator", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b12/Python-3.13-iOS-support.b12.tar.gz" },
{ identifier = "cp313-ios_arm64_iphonesimulator", version = "3.13", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.13-b12/Python-3.13-iOS-support.b12.tar.gz" },
{ identifier = "cp314-ios_arm64_iphoneos", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b8/Python-3.14-iOS-support.b8.tar.gz" },
{ identifier = "cp314-ios_x86_64_iphonesimulator", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b8/Python-3.14-iOS-support.b8.tar.gz" },
{ identifier = "cp314-ios_arm64_iphonesimulator", version = "3.14", url = "https://github.com/beeware/Python-Apple-support/releases/download/3.14-b8/Python-3.14-iOS-support.b8.tar.gz" },
]
@@ -13,6 +13,7 @@
},
"enable": {
"enum": [
"cpython-experimental-riscv64",
"cpython-freethreading",
"cpython-prerelease",
"graalpy",
@@ -107,14 +108,13 @@
},
"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]\", or \"pip\"",
"oneOf": [
{
"enum": [
"pip",
"build",
"build[uv]",
"uv",
"default"
]
},
@@ -130,10 +130,6 @@
"type": "string",
"pattern": "^build\\[uv\\]; ?args:"
},
{
"type": "string",
"pattern": "^uv; ?args:"
},
{
"type": "object",
"additionalProperties": false,
@@ -145,8 +141,7 @@
"enum": [
"pip",
"build",
"build[uv]",
"uv"
"build[uv]"
]
},
"args": {
@@ -2,47 +2,57 @@
# nox -s update_constraints
annotated-types==0.7.0
# via pydantic
auditwheel-emscripten==0.2.3
anyio==4.12.0
# via httpx
auditwheel-emscripten==0.2.0
# via pyodide-build
build==1.2.2.post1
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
certifi==2026.2.25
# via requests
charset-normalizer==3.4.5
certifi==2025.11.12
# via
# httpcore
# httpx
# requests
charset-normalizer==3.4.4
# via requests
click==8.1.8
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
# pyodide-cli
# typer
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
filelock==3.20.0
# via virtualenv
h11==0.16.0
# via httpcore
httpcore==1.0.9
# via httpx
httpx==0.28.1
# via unearth
idna==3.11
# via requests
leb128==1.0.9
# via
# anyio
# httpx
# requests
leb128==1.0.8
# via auditwheel-emscripten
markdown-it-py==4.0.0
# via rich
mdurl==0.1.2
# via markdown-it-py
packaging==26.0
packaging==25.0
# via
# auditwheel-emscripten
# build
# pyodide-build
# wheel
pip==26.0.1
# unearth
pip==25.3
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
platformdirs==4.9.4
platformdirs==4.5.1
# via
# pyodide-build
# python-discovery
# virtualenv
pydantic==2.12.5
# via
@@ -52,40 +62,54 @@ pydantic-core==2.41.5
# via pydantic
pygments==2.19.2
# via rich
pyodide-build==0.33.0
pyodide-build==0.30.9
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
pyodide-cli==0.5.0
pyodide-cli==0.4.0
# via
# auditwheel-emscripten
# pyodide-build
pyodide-lock==0.1.2
pyodide-lock==0.1.0
# via pyodide-build
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
requests==2.32.5
# via pyodide-build
rich==14.3.3
resolvelib==1.2.1
# via pyodide-build
rich==14.2.0
# via
# pyodide-build
# pyodide-cli
ruamel-yaml==0.19.1
# typer
ruamel-yaml==0.18.16
# via pyodide-build
ruamel-yaml-clib==0.2.15
# via ruamel-yaml
shellingham==1.5.4
# via typer
typer==0.20.0
# via
# auditwheel-emscripten
# pyodide-build
# pyodide-cli
typing-extensions==4.15.0
# via
# anyio
# pydantic
# pydantic-core
# typer
# typing-inspection
typing-inspection==0.4.2
# via pydantic
urllib3==2.6.3
unearth==0.18.1
# via pyodide-build
urllib3==2.6.2
# via requests
virtualenv==21.2.0
virtualenv==20.35.4
# via
# build
# pyodide-build
wheel==0.46.3
wheel==0.45.1
# via
# auditwheel-emscripten
# pyodide-build
@@ -2,47 +2,57 @@
# nox -s update_constraints
annotated-types==0.7.0
# via pydantic
auditwheel-emscripten==0.2.3
anyio==4.12.0
# via httpx
auditwheel-emscripten==0.2.0
# via pyodide-build
build==1.2.2.post1
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
certifi==2026.2.25
# via requests
charset-normalizer==3.4.5
certifi==2025.11.12
# via
# httpcore
# httpx
# requests
charset-normalizer==3.4.4
# via requests
click==8.1.8
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
# pyodide-cli
# typer
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
filelock==3.20.0
# via virtualenv
h11==0.16.0
# via httpcore
httpcore==1.0.9
# via httpx
httpx==0.28.1
# via unearth
idna==3.11
# via requests
leb128==1.0.9
# via
# anyio
# httpx
# requests
leb128==1.0.8
# via auditwheel-emscripten
markdown-it-py==4.0.0
# via rich
mdurl==0.1.2
# via markdown-it-py
packaging==26.0
packaging==25.0
# via
# auditwheel-emscripten
# build
# pyodide-build
# wheel
pip==26.0.1
# unearth
pip==25.3
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
platformdirs==4.9.4
platformdirs==4.5.1
# via
# pyodide-build
# python-discovery
# virtualenv
pydantic==2.12.5
# via
@@ -52,40 +62,53 @@ pydantic-core==2.41.5
# via pydantic
pygments==2.19.2
# via rich
pyodide-build==0.33.0
pyodide-build==0.30.9
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
pyodide-cli==0.5.0
pyodide-cli==0.4.0
# via
# auditwheel-emscripten
# pyodide-build
pyodide-lock==0.1.2
pyodide-lock==0.1.0
# via pyodide-build
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
requests==2.32.5
# via pyodide-build
rich==14.3.3
resolvelib==1.2.1
# via pyodide-build
rich==14.2.0
# via
# pyodide-build
# pyodide-cli
ruamel-yaml==0.19.1
# typer
ruamel-yaml==0.18.16
# via pyodide-build
ruamel-yaml-clib==0.2.15
# via ruamel-yaml
shellingham==1.5.4
# via typer
typer==0.20.0
# via
# auditwheel-emscripten
# pyodide-build
# pyodide-cli
typing-extensions==4.15.0
# via
# pydantic
# pydantic-core
# typer
# typing-inspection
typing-inspection==0.4.2
# via pydantic
urllib3==2.6.3
unearth==0.18.1
# via pyodide-build
urllib3==2.6.2
# via requests
virtualenv==21.2.0
virtualenv==20.35.4
# via
# build
# pyodide-build
wheel==0.46.3
wheel==0.45.1
# via
# auditwheel-emscripten
# pyodide-build
@@ -2,41 +2,35 @@
# nox -s update_constraints
altgraph==0.17.5
# via macholib
build==1.4.0
build==1.3.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
importlib-metadata==8.7.1
filelock==3.20.0
# via virtualenv
importlib-metadata==8.7.0
# via build
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==26.0.1
pip==25.3
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.9.4
# via
# python-discovery
# virtualenv
platformdirs==4.5.1
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
tomli==2.4.0
tomli==2.3.0
# via build
typing-extensions==4.15.0
# via
# delocate
# virtualenv
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
zipp==3.23.0
# via importlib-metadata
@@ -2,33 +2,27 @@
# nox -s update_constraints
altgraph==0.17.5
# via macholib
build==1.4.0
build==1.3.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
filelock==3.20.0
# via virtualenv
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==26.0.1
pip==25.3
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.9.4
# via
# python-discovery
# virtualenv
platformdirs==4.5.1
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
typing-extensions==4.15.0
# via delocate
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
@@ -2,33 +2,27 @@
# nox -s update_constraints
altgraph==0.17.5
# via macholib
build==1.4.0
build==1.3.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
filelock==3.20.0
# via virtualenv
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==26.0.1
pip==25.3
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.9.4
# via
# python-discovery
# virtualenv
platformdirs==4.5.1
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
typing-extensions==4.15.0
# via delocate
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
@@ -2,33 +2,27 @@
# nox -s update_constraints
altgraph==0.17.5
# via macholib
build==1.4.0
build==1.3.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
filelock==3.20.0
# via virtualenv
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==26.0.1
pip==25.3
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.9.4
# via
# python-discovery
# virtualenv
platformdirs==4.5.1
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
typing-extensions==4.15.0
# via delocate
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
@@ -2,33 +2,27 @@
# nox -s update_constraints
altgraph==0.17.5
# via macholib
build==1.4.0
build==1.3.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
filelock==3.20.0
# via virtualenv
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==26.0.1
pip==25.3
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.9.4
# via
# python-discovery
# virtualenv
platformdirs==4.5.1
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
typing-extensions==4.15.0
# via delocate
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
@@ -9,34 +9,28 @@ delocate==0.12.0
distlib==0.4.0
# via virtualenv
filelock==3.16.1
# via
# python-discovery
# virtualenv
# via virtualenv
importlib-metadata==8.5.0
# via build
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.6
# via
# python-discovery
# virtualenv
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
tomli==2.4.0
tomli==2.3.0
# via build
typing-extensions==4.13.2
# via
# delocate
# virtualenv
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
zipp==3.20.2
# via importlib-metadata
@@ -2,41 +2,35 @@
# nox -s update_constraints
altgraph==0.17.5
# via macholib
build==1.4.0
build==1.3.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.4.0
# via virtualenv
filelock==3.19.1
# via
# python-discovery
# virtualenv
importlib-metadata==8.7.1
# via virtualenv
importlib-metadata==8.7.0
# via build
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==26.0.1
pip==25.3
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.4.0
# via
# python-discovery
# virtualenv
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
tomli==2.4.0
tomli==2.3.0
# via build
typing-extensions==4.15.0
# via
# delocate
# virtualenv
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
zipp==3.23.0
# via importlib-metadata
+8 -14
View File
@@ -2,33 +2,27 @@
# nox -s update_constraints
altgraph==0.17.5
# via macholib
build==1.4.0
build==1.3.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.4.0
# via virtualenv
filelock==3.25.2
# via
# python-discovery
# virtualenv
filelock==3.20.0
# via virtualenv
macholib==1.16.4
# via delocate
packaging==26.0
packaging==25.0
# via
# build
# delocate
pip==26.0.1
pip==25.3
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.9.4
# via
# python-discovery
# virtualenv
platformdirs==4.5.1
# via virtualenv
pyproject-hooks==1.2.0
# via build
python-discovery==1.1.3
# via virtualenv
typing-extensions==4.15.0
# via delocate
virtualenv==21.2.0
virtualenv==20.35.4
# via -r cibuildwheel/resources/constraints.in
+3 -3
View File
@@ -1,4 +1,4 @@
url = "https://nodejs.org/dist/"
v24 = "v24.14.0"
v22 = "v22.22.1"
v20 = "v20.20.1"
v24 = "v24.12.0"
v22 = "v22.21.1"
v20 = "v20.19.6"
+34 -34
View File
@@ -1,54 +1,54 @@
[x86_64]
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.03.14-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.12.13-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2025.12.13-1
[i686]
manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.03.14-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2025.12.13-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2025.12.13-1
[aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.03.14-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.12.13-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2025.12.13-1
[ppc64le]
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2026.03.14-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_ppc64le:2025.12.13-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2025.12.13-1
[s390x]
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2026.03.14-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_s390x:2025.12.13-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2025.12.13-1
[pypy_x86_64]
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_x86_64:2025.12.13-1
[pypy_i686]
manylinux2014 = quay.io/pypa/manylinux2014_i686:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_i686:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_i686:2025.12.13-1
[pypy_aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2026.03.14-2
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2026.03.14-2
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2026.03.14-2
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.12.13-1
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.12.13-1
manylinux_2_34 = quay.io/pypa/manylinux_2_34_aarch64:2025.12.13-1
[armv7l]
manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2026.03.14-2
manylinux_2_35 = quay.io/pypa/manylinux_2_35_armv7l:2026.03.14-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2026.03.14-2
manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2025.12.13-1
manylinux_2_35 = quay.io/pypa/manylinux_2_35_armv7l:2025.12.13-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2025.12.13-1
[riscv64]
manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64:2026.03.14-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64:2026.03.14-2
manylinux_2_39 = quay.io/pypa/manylinux_2_39_riscv64:2025.12.13-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_riscv64:2025.12.13-1
@@ -1,483 +1,483 @@
{
"releases": [
{
"tag": "20260310",
"tag": "20251209",
"assets": [
{
"name": "cpython-3.10.20+20260310-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-aarch64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-aarch64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-aarch64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-aarch64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-aarch64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-aarch64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-i686-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-i686-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-riscv64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-riscv64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-s390x-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-s390x-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.10.20+20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.10.20%2B20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.10.19+20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.10.19%2B20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-aarch64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-aarch64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-aarch64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-aarch64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-aarch64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-aarch64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-aarch64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-aarch64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-i686-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-i686-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-riscv64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-riscv64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-s390x-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-s390x-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.11.15+20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.11.15%2B20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.11.14+20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.11.14%2B20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-aarch64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-aarch64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-aarch64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-aarch64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-aarch64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-aarch64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-aarch64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-aarch64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-i686-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-i686-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-riscv64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-riscv64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-s390x-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-s390x-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.12.13+20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.12.13%2B20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.12.12+20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.12.12%2B20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-aarch64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-aarch64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-aarch64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-aarch64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-aarch64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-aarch64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-aarch64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-aarch64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-i686-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-i686-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-riscv64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-riscv64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-s390x-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-s390x-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.13.12+20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.13.12%2B20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.13.11+20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.13.11%2B20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-aarch64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-aarch64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-aarch64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-aarch64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-aarch64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-aarch64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-aarch64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-aarch64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-i686-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-i686-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-riscv64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-riscv64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-s390x-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-s390x-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.14.3+20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.14.3%2B20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.14.2+20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.14.2%2B20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-aarch64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-aarch64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-aarch64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-aarch64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-aarch64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-aarch64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-aarch64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-aarch64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-aarch64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-aarch64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-aarch64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-aarch64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-armv7-unknown-linux-gnueabi-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-armv7-unknown-linux-gnueabi-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-armv7-unknown-linux-gnueabihf-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-i686-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-i686-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-i686-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-ppc64le-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-ppc64le-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-riscv64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-riscv64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-riscv64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-s390x-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-s390x-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-s390x-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64-apple-darwin-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64-apple-darwin-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64-apple-darwin-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64-pc-windows-msvc-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64-pc-windows-msvc-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64-pc-windows-msvc-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64_v2-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64_v2-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64_v3-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64_v3-unknown-linux-musl-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64_v4-unknown-linux-gnu-install_only.tar.gz"
},
{
"name": "cpython-3.15.0a7+20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20260310/cpython-3.15.0a7%2B20260310-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
"name": "cpython-3.15.0a2+20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz",
"url": "https://github.com/astral-sh/python-build-standalone/releases/download/20251209/cpython-3.15.0a2%2B20251209-x86_64_v4-unknown-linux-musl-install_only.tar.gz"
}
]
}
+1 -1
View File
@@ -1 +1 @@
default = { version = "21.2.0", url = "https://github.com/pypa/get-virtualenv/releases/download/21.2.0/virtualenv.pyz" }
default = { version = "20.35.4", url = "https://github.com/pypa/get-virtualenv/releases/download/20.35.4/virtualenv.pyz" }
+3 -2
View File
@@ -29,6 +29,7 @@ class EnableGroup(StrEnum):
Groups of build selectors that are not enabled by default.
"""
CPythonExperimentalRiscV64 = "cpython-experimental-riscv64"
CPythonFreeThreading = "cpython-freethreading"
CPythonPrerelease = "cpython-prerelease"
GraalPy = "graalpy"
@@ -38,7 +39,7 @@ class EnableGroup(StrEnum):
@classmethod
def all_groups(cls) -> frozenset["EnableGroup"]:
return frozenset(cls)
return frozenset(set(cls) - {cls.CPythonExperimentalRiscV64})
@classmethod
def parse_option_value(cls, value: str) -> frozenset["EnableGroup"]:
@@ -75,7 +76,7 @@ class BuildSelector:
def __call__(self, build_id: str) -> bool:
# Filter build selectors by python_requires if set
if self.requires_python is not None:
py_ver_str = build_id.split("-", maxsplit=1)[0].split("_", maxsplit=1)[0]
py_ver_str = build_id.split("-")[0].split("_")[0]
py_ver_str = py_ver_str.removesuffix("t")
major = int(py_ver_str[2])
minor = int(py_ver_str[3:])
+15 -12
View File
@@ -1,4 +1,3 @@
import contextlib
import functools
import os
import shutil
@@ -108,9 +107,8 @@ def virtualenv(
assert python.exists()
if use_uv:
uv_path = find_uv()
assert uv_path is not None
call(uv_path, "venv", venv_path, "--python", python)
ensure_uv()
call("uv", "venv", venv_path, "--python", python)
else:
virtualenv_app, virtualenv_version = _ensure_virtualenv(version)
if pip_version is None:
@@ -158,12 +156,17 @@ def virtualenv(
return venv_env
def find_uv() -> Path | None:
# Prefer uv in our environment
with contextlib.suppress(ImportError, FileNotFoundError):
from uv import find_uv_bin # noqa: PLC0415
def ensure_uv() -> None:
"""
Ensures uv is available on PATH. Raises an error with a helpful message if not found.
return Path(find_uv_bin())
uv_on_path = shutil.which("uv")
return Path(uv_on_path) if uv_on_path else None
When using build-frontend=build[uv], callers must ensure uv is available
on PATH before invoking cibuildwheel.
"""
if shutil.which("uv") is None:
msg = (
"uv not found on PATH. When using build-frontend=build[uv], "
"ensure uv is installed and available on PATH. "
"You can install it with 'pip install uv' or see https://docs.astral.sh/uv/getting-started/installation/"
)
raise FileNotFoundError(msg)
-17
View File
@@ -4,23 +4,6 @@ title: Changelog
# Changelog
### 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)
- 🐛 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)
### v3.3.0
_12 November 2025_
+17 -1
View File
@@ -25,7 +25,7 @@ To build Linux, macOS, and Windows wheels using GitHub Actions, create a `.githu
`package-dir: .`, `output-dir: wheelhouse` and `config-file: ''`
locations (those values are the defaults). You can also pass a
comma-separated list of extras to install additional packages.
For example, `extras: "uv"` to install UV into the virtual environment.
For example, `extras: "uv"` to make uv available for cibuildwheel to use.
!!! tab "pipx"
The GitHub Actions runners have pipx installed, so you can easily build in
@@ -72,6 +72,22 @@ Commit this file, enable building of your repo on Azure Pipelines, and push.
Wheels will be stored for you and available through the Pipelines interface. For more info on this file, check out the [docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema).
### Travis CI [linux/windows] {: #travis-ci}
To build Linux and Windows wheels on Travis CI, create a `.travis.yml` file in your repo.
> .travis.yml
```yaml
{% include "../examples/travis-ci-minimal.yml" %}
```
Commit this file, enable building of your repo on Travis CI, and push.
Then setup a deployment method by following the [Travis CI deployment docs](https://docs.travis-ci.com/user/deployment/), or see [Delivering to PyPI](deliver-to-pypi.md). For more info on `.travis.yml`, check out the [docs](https://docs.travis-ci.com/).
[`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/travis-ci-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
### CircleCI [linux/mac] {: #circleci}
To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo,
+11
View File
@@ -30,6 +30,17 @@ cibuildwheel to run tests, add the following YAML to your CI config file:
CIBW_TEST_COMMAND: "pytest {project}/tests"
```
!!! tab "Travis CI"
> .travis.yml ([docs](https://docs.travis-ci.com/user/environment-variables/))
```yaml
env:
global:
- CIBW_TEST_REQUIRES=pytest
- CIBW_TEST_COMMAND="pytest {project}/tests"
```
!!! tab "CircleCI"
> .circleci/config.yml ([docs](https://circleci.com/docs/2.0/configuration-reference/#environment))
+7 -2
View File
@@ -29,11 +29,10 @@ GitHub actions has pipx in all the runners as a supported package manager, as we
name: Make SDist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
with:
fetch-depth: 0 # Optional, use if you use setuptools_scm
submodules: true # Optional, use if you have submodules
persist-credentials: false # Highly recommended as a good security practice to not store credentials in disk, unless you need this for your specific use case
- name: Build SDist
run: pipx run build --sdist
@@ -72,6 +71,12 @@ for an example configuration that automatically uploads wheels to PyPI. Also see
[scikit-hep.org/developer/gha_wheels](https://scikit-hep.org/developer/gha_wheels)
for a complete guide.
### TravisCI
See
[`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/travis-ci-deploy.yml)
for an example configuration.
## Manual method
On your development machine, install [pipx](https://pipx.pypa.io/) and do the following:
+3 -18
View File
@@ -99,21 +99,6 @@ Second, there might be platforms you want to ship for that NumPy (or some other
(Note the `*_ONLY_BINARY` variable also supports `":all:"`, and you don't need both that and `*_PREFER_BINARY`, you can use either one, depending on if you want a missing wheel to be a failure or an attempt to build in CI.)
### Building with Meson-Python on Windows
Meson generally works well with cibuildwheel, but there are a few things to be aware of:
- On GitHub Actions, the compiler that's chosen by default on Windows is often the MinGW compiler, rather than the MSVC toolchain that Python was compiled with.
The simplest fix for this is to configure cibuildwheel to pass the `--vsenv` flag to meson, like this:
```toml
[tool.cibuildwheel.windows]
config-settings = { "setup-args" = "--vsenv" }
```
- If you need to build 32-bit Windows wheels, you need to activate a 32-bit compiler toolchain before starting cibuildwheel. Many users use [ilammy/msvc-dev-cmd](https://github.com/ilammy/msvc-dev-cmd) for this purpose.
### Automatic updates using Dependabot {: #automatic-updates}
Selecting a moving target (like the latest release) is generally a bad idea in CI. If something breaks, you can't tell whether it was your code or an upstream update that caused the breakage, and in a worst-case scenario, it could occur during a release.
@@ -125,7 +110,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@v3.4.0
uses: pypa/cibuildwheel@v3.3.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.
@@ -147,7 +132,7 @@ The second option, and the only one that supports other CI systems, is using a `
```bash
# requirements-cibw.txt
cibuildwheel==3.4.0
cibuildwheel==3.3.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:
@@ -312,7 +297,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==3.4.0 --output-dir wheelhouse
pipx run cibuildwheel==3.3.0 --output-dir wheelhouse
pipx run twine upload wheelhouse/*.whl
```
-5
View File
@@ -22,8 +22,3 @@ This diagram summarises the steps that cibuildwheel takes on each platform to bu
%}
This isn't exhaustive, for a full list of the things cibuildwheel can do, check the [options](options.md) page.
!!! warning "A note on security"
Building and testing wheels executes arbitrary code from your project and its dependencies. Although cibuildwheel uses OCI containers and Pyodide for some builds, these provide no security guarantees - the code you're building and testing has full access to the environment that's invoking cibuildwheel.
If you cannot trust all the code that's pulled in, maintain good security hygiene: keep the job that builds distributions separate from the job that uploads them to PyPI, handle secrets and credentials with care and rotate them regularly, and follow the principle of least privilege when granting permissions. Do not store sensitive data on CI runners.
+29 -39
View File
@@ -465,27 +465,25 @@ Options:
- `build[;args: ...]`
- `build[uv][;args: ...]`
- `pip[;args: ...]`
- `uv[;args: ...]`
Default: `build`
Choose which build frontend to use.
You can use "build\[uv\]", which will use an external [uv][] everywhere
possible, both through `--installer=uv` passed to build, as well as when making
all build and test environments. This will generally speed up cibuildwheel.
Make sure you have an external uv on Windows and macOS, either by
pre-installing it, or installing cibuildwheel with the `uv` extra, which is
possible by manually passing `cibuildwheel[uv]` to installers or by using the
`extras` option in the [cibuildwheel action](ci-services.md#github-actions).
uv currently does not support iOS or musllinux on s390x, ppc64le and riscv64.
You can also use the `uv` backend directly; though currently multiple output
files (from workspaces) are not supported.
You can use "build\[uv\]", which will use [uv][] everywhere possible, both
through `--installer=uv` passed to build, as well as when making all build and
test environments. This will generally speed up cibuildwheel.
!!! note
There is currently a compatibility issue between GraalPy and uv. If you
are building GraalPy wheels, use `build` or `pip` as the build frontend
instead of `build[uv]` or `uv`.
When using `build[uv]`, ensure uv is available on PATH. You can do this by:
- Pre-installing uv (e.g., via `pip install uv` or using `astral-sh/setup-uv`
in GitHub Actions)
- Installing cibuildwheel with the `uv` extra by manually passing
`cibuildwheel[uv]` to installers
- Using the `extras: "uv"` option in the [cibuildwheel action](ci-services.md#github-actions),
which installs uv in an isolated environment
uv currently does not support iOS or musllinux on s390x, ppc64le and riscv64.
On Android and Pyodide, the "pip" frontend is not supported.
@@ -519,9 +517,6 @@ optional `args` option.
# Use uv and build with an argument
build-frontend = { name = "build[uv]", args = ["--no-isolation"] }
# Use uv directly
build-frontend = "uv"
```
!!! tab examples "Environment variables"
@@ -538,9 +533,6 @@ optional `args` option.
# Use uv and build with an argument
CIBW_BUILD_FRONTEND: "build[uv]; args: --no-isolation"
# Use uv directly
CIBW_BUILD_FRONTEND: "uv"
```
@@ -634,8 +626,6 @@ Platform-specific environment variables are also available:<br/>
In configuration files, you can use a [TOML][] table instead of a raw string as shown above.
[TOML]: https://toml.io/en/
!!! tab examples "Environment variables"
```yaml
@@ -911,10 +901,6 @@ Default:
- on macOS: `'delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}'`
- on Android: There is no default command, but cibuildwheel will add `libc++` to the
wheel if anything links against it. Setting a command will replace this behavior.
- on Pyodide: You can use `pyodide auditwheel repair --libdir /path/to/libraries --output-dir {dest_dir} {wheel}` command to repair the wheel.
Unlike other platforms, this command is not set by default as you need to explicitly
specify the library directory. You might not want to use the libraries in the system
directory, as they are not built for WASM and will not work.
- on other platforms: `''`
A shell command to repair a built wheel by copying external library dependencies into the wheel tree and relinking them.
@@ -942,6 +928,12 @@ Platform-specific environment variables are also available:<br/>
[Delvewheel]: https://github.com/adang1345/delvewheel
!!! tip
When using `--platform pyodide`, `pyodide build` is used to do the build,
which already uses `auditwheel-emscripten` to repair the wheel, so the default
repair command is empty. If there is a way to do this in two steps in the future,
this could change.
#### Examples
!!! tab examples "pyproject.toml"
@@ -1255,7 +1247,7 @@ Platform-specific environment variables are also available:<br/>
[tool.cibuildwheel.pyodide]
# Choose a specific pyodide-build version
dependency-versions = { packages = ["pyodide-build==0.31.2"] }
dependency-versions = { packages = ["pyodide-build==0.29.1"] }
```
!!! tab examples "Environment variables"
@@ -1274,7 +1266,7 @@ Platform-specific environment variables are also available:<br/>
CIBW_DEPENDENCY_VERSIONS: "packages: auditwheel==6.2.0"
# Choose a specific pyodide-build version
CIBW_DEPENDENCY_VERSIONS_PYODIDE: "packages: pyodide-build==0.31.2"
CIBW_DEPENDENCY_VERSIONS_PYODIDE: "packages: pyodide-build==0.29.1"
# Use shell-style quoting around spaces package specifiers
CIBW_DEPENDENCY_VERSIONS: "packages: 'pip >=16.0.0, !=17'"
@@ -1765,16 +1757,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`[^1] | `-qq` | `-qq` | even more quiet, where supported |
| -1 | `-q`[^1] | `-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 |
[^1]: Not supported on Python 3.8, will be ignored with a warning.
| | build | pip | desc |
|-------------|-------|--------|----------------------------------|
| -2 | N/A | `-qq` | even more quiet, where supported |
| -1 | N/A | `-q` | quiet mode, where supported |
| 0 (default) | | | default for build tool |
| 1 | | `-v` | print backend output |
| 2 | `-v` | `-vv` | print log messages e.g. resolving info |
| 3 | `-vv` | `-vvv` | 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
+7 -16
View File
@@ -179,24 +179,13 @@ If there are pre-releases available for a newer Pyodide version, the `pyodide-pr
Currently, it's recommended to run tests using a `python -m` entrypoint, rather than a command line entrypoint, or a shell script. This is because custom entrypoints have some issues in the Pyodide virtual environment. For example, `pytest` may not work as a command line entrypoint, but will work as a `python -m pytest` entrypoint.
### Repairing wheels
Unlike other platforms, cibuildwheel does not set a default [`repair-wheel-command`](options.md#repair-wheel-command) for Pyodide. If your package links shared libraries, you need to explicitly configure the repair command using [`pyodide auditwheel`](https://github.com/pyodide/auditwheel-emscripten):
```toml
[tool.cibuildwheel.pyodide]
repair-wheel-command = "pyodide auditwheel repair --libdir /path/to/libraries --output-dir {dest_dir} {wheel}"
```
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.
## Android {: android}
### Prerequisites
cibuildwheel can build Android wheels on any POSIX platform supported by the Android
development tools, which currently means Linux `x86_64`, macOS `ARM64` or macOS `x86_64`. Any
development tools, which currently means Linux x86_64, macOS ARM64 or macOS x86_64. Any
of these platforms can be used to build wheels for any Android architecture supported by
Python. However, *testing* wheels has additional requirements: see the section below.
@@ -232,8 +221,10 @@ Python 3.13.
### Build frontend support
Android builds do not support the `pip` frontend. The `build`, `build[uv]`, and
`uv` frontends work.
Android builds only support the `build` frontend. In principle, support for the
`build[uv]` frontend should be possible, but `uv` [doesn't currently have support for
cross-platform builds](https://github.com/astral-sh/uv/issues/7957), and [doesn't have
support for iOS or Android wheel tags](https://github.com/astral-sh/uv/issues/8029).
### Tests
@@ -247,7 +238,7 @@ Any arguments specified using [`test-runtime`](options.md#test-runtime) will be
Running an emulator requires the build machine to either be bare-metal or support
nested virtualization. CI platforms known to meet this requirement are:
* GitHub Actions Linux `x86_64`
* GitHub Actions Linux x86_64
On Linux, the emulator needs access to the KVM virtualization interface. This may
require adding your user to a group, or changing your udev rules. On GitHub
@@ -317,7 +308,7 @@ iOS builds are *cross platform builds*, as it not possible to run compilers and
### Build frontend support
iOS builds support both the `pip` and `build` build frontends. In principle, support for `uv` and `build[uv]` frontends should be possible, but `uv` [doesn't support iOS fully yet](https://github.com/astral-sh/uv/issues/16724).
iOS builds support both the `pip` and `build` build frontends. In principle, support for `uv` with the `build[uv]` frontend should be possible, but `uv` [doesn't currently have support for cross-platform builds](https://github.com/astral-sh/uv/issues/7957), and [doesn't have support for iOS (or Android) tags](https://github.com/astral-sh/uv/issues/8029).
### Build environment
+26 -26
View File
@@ -13,8 +13,8 @@ title: Working examples
| [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][] | The fundamental package for scientific computing with 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][] | 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. |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
@@ -25,20 +25,20 @@ title: Working examples
| [Google Benchmark][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A microbenchmark support library |
| [falcon][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Falcon is a no-magic ASGI/WSGI API and microservices framework; it uses cibuildwheel for (optional) Cython extensions. |
| [PyGame][] | ![github icon][] | ![apple icon][] ![linux icon][] | 🐍🎮 pygame (the library) is a Free and Open Source python programming language library for making multimedia applications like games built on top of the excellent SDL library. C, Python, Native, OpenGL. |
| [Apache Beam][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Apache Beam is a unified programming model for Batch and Streaming data processing. |
| [vaex][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Out-of-Core hybrid Apache Arrow/NumPy DataFrame for Python, ML, visualization and exploration of big tabular data at a billion rows per second 🚀 |
| [Apache Beam][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Apache Beam is a unified programming model for Batch and Streaming data processing. |
| [asyncpg][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A fast PostgreSQL Database Client Library for Python/asyncio. |
| [cmake][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
| [pyinstrument][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python profiler with a C extension. No external dependencies. |
| [scikit-image][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Image processing library. Uses cibuildwheel to build and test a project that uses Cython with platform-native code. |
| [cvxpy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A Python-embedded modeling language for convex optimization problems. |
| [PyOxidizer][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A modern Python application packaging and distribution tool |
| [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). |
| [cvxpy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A Python-embedded modeling language for convex optimization problems. |
| [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. |
| [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). |
| [River][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 🌊 Online machine learning in Python |
| [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. |
| [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. |
| [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI |
| [UltraJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Ultra fast JSON decoder and encoder written in C with Python bindings |
| [CTranslate2][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes libraries from the [Intel oneAPI toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit.html) and CUDA kernels compiled for multiple GPU architectures. |
@@ -47,14 +47,14 @@ title: Working examples
| [tinyobjloader][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Tiny but powerful single file wavefront obj loader |
| [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 |
| [Line Profiler][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Line-by-line profiling for Python |
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
| [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 |
| [Psycopg 3][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A modern implementation of a PostgreSQL adapter for Python |
| [Wrapt][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python module for decorators, wrappers and monkey patching. |
| [Psycopg 3][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A modern implementation of a PostgreSQL adapter for Python |
| [h5py][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | HDF5 for Python -- The h5py package is a Pythonic interface to the HDF5 binary data format. |
| [envd][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A machine learning development environment build tool |
| [OpenColorIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A color management framework for visual effects and animation. |
@@ -65,15 +65,15 @@ title: Working examples
| [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data |
| [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. |
| [H3-py][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for H3, a hierarchical hexagonal geospatial indexing system |
| [DeepForest][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | An Efficient, Scalable and Optimized Python Framework for Deep Forest (2021.2.1) |
| [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. |
| [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][] | Example pybind11 module built with a CMake-based build system |
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS |
| [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. |
@@ -82,9 +82,9 @@ title: Working examples
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
| [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. |
| [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` |
| [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 |
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
| [matrixprofile][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python 3 library making time series data mining tasks, utilizing matrix profile algorithms, accessible to everyone. |
| [Tokenizer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast and customizable text tokenization library with BPE and SentencePiece support |
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 |
@@ -95,8 +95,8 @@ title: Working examples
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
| [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. |
| [pybase64][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast Base64 encoding/decoding in Python |
| [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. |
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. |
| [Python-WebRTC][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | a Python extension that provides bindings to WebRTC M92 |
@@ -108,11 +108,11 @@ title: Working examples
| [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
| [etebase-py][] | ![travisci icon][] | ![linux icon][] | Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. |
| [cf-units][] | ![github icon][] | ![apple icon][] ![linux icon][] | Units of measure as required by the Climate and Forecast (CF) Metadata Conventions |
| [SiPM][] | ![github icon][] | ![apple icon][] ![linux icon][] | High performance library for SiPM detectors simulation using C++17, OpenMP and AVX2 intrinsics. |
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy |
| [aalink][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Async Python interface for Ableton Link. |
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
| [SiPM][] | ![github icon][] | ![apple icon][] ![linux icon][] | High performance library for SiPM detectors simulation using C++17, OpenMP and AVX2 intrinsics. |
| [ril][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A python binding to Rust Imaging library using maturin and Pyo3, utilizes Github Action cache to improve speed. Builds abi3 wheels. |
| [aalink][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Async Python interface for Ableton Link. |
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
| [werpy][] | ![github icon][] | ![windows icon][] ![linux icon][] ![apple icon][] | An ultra-fast python package using optimized dynamic programming to compute the Word Error Rate (WER). |
| [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. |
@@ -124,8 +124,8 @@ title: Working examples
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy
[NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib
[Tornado]: https://github.com/tornadoweb/tornado
[Matplotlib]: https://github.com/matplotlib/matplotlib
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
[Prophet]: https://github.com/facebook/prophet
[Kivy]: https://github.com/kivy/kivy
@@ -136,20 +136,20 @@ title: Working examples
[Google Benchmark]: https://github.com/google/benchmark
[falcon]: https://github.com/falconry/falcon
[PyGame]: https://github.com/pygame/pygame
[Apache Beam]: https://github.com/apache/beam
[vaex]: https://github.com/vaexio/vaex
[Apache Beam]: https://github.com/apache/beam
[asyncpg]: https://github.com/MagicStack/asyncpg
[cmake]: https://github.com/scikit-build/cmake-python-distributions
[pyinstrument]: https://github.com/joerick/pyinstrument
[scikit-image]: https://github.com/scikit-image/scikit-image
[cvxpy]: https://github.com/cvxpy/cvxpy
[PyOxidizer]: https://github.com/indygreg/PyOxidizer
[pedalboard]: https://github.com/spotify/pedalboard
[cvxpy]: https://github.com/cvxpy/cvxpy
[twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport
[pedalboard]: https://github.com/spotify/pedalboard
[River]: https://github.com/online-ml/river
[websockets]: https://github.com/python-websockets/websockets
[OpenSpiel]: https://github.com/google-deepmind/open_spiel
[aiortc]: https://github.com/aiortc/aiortc
[OpenSpiel]: https://github.com/google-deepmind/open_spiel
[Dependency Injector]: https://github.com/ets-labs/python-dependency-injector
[UltraJSON]: https://github.com/ultrajson/ultrajson
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
@@ -158,14 +158,14 @@ title: Working examples
[tinyobjloader]: https://github.com/tinyobjloader/tinyobjloader
[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
[Line Profiler]: https://github.com/pyutils/line_profiler
[PyAV]: https://github.com/PyAV-Org/PyAV
[PyYAML]: https://github.com/yaml/pyyaml
[pikepdf]: https://github.com/pikepdf/pikepdf
[numexpr]: https://github.com/pydata/numexpr
[Psycopg 3]: https://github.com/psycopg/psycopg
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
[Psycopg 3]: https://github.com/psycopg/psycopg
[h5py]: https://github.com/h5py/h5py
[envd]: https://github.com/tensorchord/envd
[OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO
@@ -176,15 +176,15 @@ title: Working examples
[PyTables]: https://github.com/PyTables/PyTables
[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
[H3-py]: https://github.com/uber/h3-py
[DeepForest]: https://github.com/LAMDA-NJU/Deep-Forest
[time-machine]: https://github.com/adamchainz/time-machine
[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
[Rtree]: https://github.com/Toblerity/rtree
[KDEpy]: https://github.com/tommyod/KDEpy
[dd-trace-py]: https://github.com/DataDog/dd-trace-py
[tgcalls]: https://github.com/MarshalX/tgcalls
@@ -193,9 +193,9 @@ title: Working examples
[pybind11 python_example]: https://github.com/pybind/python_example
[abess]: https://github.com/abess-team/abess
[python-snappy]: https://github.com/intake/python-snappy
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
[jq.py]: https://github.com/mwilliamson/jq.py
[cyvcf2]: https://github.com/brentp/cyvcf2
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
[Tokenizer]: https://github.com/OpenNMT/Tokenizer
[iminuit]: https://github.com/scikit-hep/iminuit
@@ -206,8 +206,8 @@ title: Working examples
[TgCrypto]: https://github.com/pyrogram/tgcrypto
[power-grid-model]: https://github.com/PowerGridModel/power-grid-model
[streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
[pybase64]: https://github.com/mayeut/pybase64
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
[bx-python]: https://github.com/bxlab/bx-python
[boost-histogram]: https://github.com/scikit-hep/boost-histogram
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
@@ -219,11 +219,11 @@ title: Working examples
[ninja]: https://github.com/scikit-build/ninja-python-distributions
[etebase-py]: https://github.com/etesync/etebase-py
[cf-units]: https://github.com/SciTools/cf-units
[SiPM]: https://github.com/EdoPro98/SimSiPM
[numpythia]: https://github.com/scikit-hep/numpythia
[aalink]: https://github.com/artfwo/aalink
[pyjet]: https://github.com/scikit-hep/pyjet
[SiPM]: https://github.com/EdoPro98/SimSiPM
[ril]: https://github.com/Cryptex-github/ril-py
[aalink]: https://github.com/artfwo/aalink
[GSD]: https://github.com/glotzerlab/gsd
[werpy]: https://github.com/analyticsinmotion/werpy
[CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib
+3 -3
View File
@@ -6,7 +6,7 @@ jobs:
- bash: |
set -o errexit
python3 -m pip install --upgrade pip
pip3 install cibuildwheel==3.4.0
pip3 install cibuildwheel==3.3.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==3.4.0
python3 -m pip install cibuildwheel==3.3.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==3.4.0
pip install cibuildwheel==3.3.0
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
+3 -3
View File
@@ -11,7 +11,7 @@ jobs:
- run:
name: Build the Linux wheels.
command: |
python3 -m pip install --user cibuildwheel==3.4.0
python3 -m pip install --user cibuildwheel==3.3.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==3.4.0
python3 -m pip install --user cibuildwheel==3.3.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 python<=3.8 or x86_64/universal2 tests
pip3 install cibuildwheel==3.4.0
pip3 install cibuildwheel==3.3.0
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
+1 -1
View File
@@ -1,6 +1,6 @@
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
install_cibuildwheel_script:
- python -m pip install cibuildwheel==3.4.0
- python -m pip install cibuildwheel==3.3.0
run_cibuildwheel_script:
- cibuildwheel
wheels_artifacts:
+1 -1
View File
@@ -1,6 +1,6 @@
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
install_cibuildwheel_script:
- python -m pip install cibuildwheel==3.4.0
- python -m pip install cibuildwheel==3.3.0
run_cibuildwheel_script:
- cibuildwheel
wheels_artifacts:
+3 -7
View File
@@ -48,12 +48,10 @@ jobs:
platform: pyodide
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/checkout@v5
- name: Build wheels
uses: pypa/cibuildwheel@v3.4.0
uses: pypa/cibuildwheel@v3.3.0
env:
CIBW_PLATFORM: ${{ matrix.platform || 'auto' }}
CIBW_ARCHS: ${{ matrix.archs || 'auto' }}
@@ -72,9 +70,7 @@ jobs:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/checkout@v5
- name: Build sdist
run: pipx run build --sdist
+2 -4
View File
@@ -12,12 +12,10 @@ jobs:
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-15-intel, macos-14]
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/checkout@v5
- name: Build wheels
uses: pypa/cibuildwheel@v3.4.0
uses: pypa/cibuildwheel@v3.3.0
# env:
# CIBW_SOME_OPTION: value
# ...
+2 -4
View File
@@ -12,12 +12,10 @@ jobs:
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-15-intel, macos-14]
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/checkout@v5
- name: Build wheels
run: pipx run cibuildwheel==3.4.0
run: pipx run cibuildwheel==3.3.0
- uses: actions/upload-artifact@v4
with:
+2 -4
View File
@@ -12,9 +12,7 @@ jobs:
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-15-intel, macos-14]
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/checkout@v5
- name: Set up QEMU
if: runner.os == 'Linux' && runner.arch == 'X64'
@@ -23,7 +21,7 @@ jobs:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v3.4.0
uses: pypa/cibuildwheel@v3.3.0
env:
# configure cibuildwheel on Linux to build native archs ('auto'),
# and to split the remaining architectures between the x86_64 and
+3 -3
View File
@@ -12,7 +12,7 @@ linux:
DOCKER_TLS_CERTDIR: ""
script:
- curl -sSL https://get.docker.com/ | sh
- python -m pip install cibuildwheel==3.4.0
- python -m pip install cibuildwheel==3.3.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==3.4.0
- py -m pip install cibuildwheel==3.3.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==3.4.0
- python3 -m pip install cibuildwheel==3.3.0
script:
- python3 -m cibuildwheel --output-dir wheelhouse
artifacts:
+1 -1
View File
@@ -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==3.4.0
- python -m pip install cibuildwheel==3.3.0
# Assuming your CI runner's default architecture is x86_64...
- cibuildwheel --output-dir wheelhouse --platform linux --archs aarch64
artifacts:
+36
View File
@@ -0,0 +1,36 @@
# As written, this configuration will build your wheels on every
# commit, but will only push to PyPI on tagged commits.
os: linux
dist: jammy
language: python
python: "3.12"
jobs:
include:
# perform a linux build
- services: docker
# and a windows build
- os: windows
language: shell
before_install:
- choco upgrade python -y --version 3.12.4
- export PATH="/c/Python312:/c/Python312/Scripts:$PATH"
# make sure it's on PATH as 'python3'
- ln -s /c/Python312/python.exe /c/Python312/python3.exe
install:
- python3 -m pip install cibuildwheel==3.3.0
script:
# build the wheels, put them into './dist'
- python3 -m cibuildwheel --output-dir dist
deploy:
provider: pypi
username: "__token__"
skip_cleanup: true
on:
tags: true
password:
secure: "" # Set to an encrypted API token. See https://docs.travis-ci.com/user/deployment/pypi/
+33
View File
@@ -0,0 +1,33 @@
os: linux
dist: jammy
language: python
python: "3.12"
jobs:
include:
# perform a linux build
- services: docker
# perform a linux ARMv8 build
- services: docker
arch: arm64
# perform a linux PPC64LE build
- services: docker
arch: ppc64le
# perform a linux S390X build
- services: docker
arch: s390x
# and a windows build
- os: windows
language: shell
before_install:
- choco upgrade python -y --version 3.12.4
- export PATH="/c/Python312:/c/Python312/Scripts:$PATH"
# make sure it's on PATH as 'python3'
- ln -s /c/Python312/python.exe /c/Python312/python3.exe
install:
- python3 -m pip install cibuildwheel==3.3.0
script:
# build the wheels, put them into './wheelhouse'
- python3 -m cibuildwheel --output-dir wheelhouse
+70
View File
@@ -0,0 +1,70 @@
# In this configuration, the package is tested against multiple versions of python
# on Linux and on one version of Python on Windows. If and only if all tests pass
# will the wheels be built and deployed. Further, deployment is only initiated if
# the current branch is "main", the current commit is tagged, and the current
# repo is yours (e.g. it won't run on a Pull Request). For convenience, a source
# distribution is also created.
os: linux
dist: jammy
language: python
python: "3.12"
before_install:
- |
if [[ "$TRAVIS_OS_NAME" = windows ]]; then
choco upgrade python -y --version 3.12.4
export PATH="/c/Python312:/c/Python312/Scripts:$PATH"
# make sure it's on PATH as 'python3'
ln -s /c/Python312/python.exe /c/Python312/python3.exe
fi
install:
- python3 -m pip install pytest
script:
- python3 -m pip install .
- pytest
stages:
- test
# Only execute deployment stage on tagged commits, and from your repository
# (e.g. not PRs). Replace with your repo name.
- name: deploy
if: tag IS PRESENT AND repo = pypa/cibuildwheel
# To only build tags that look like vX.Y.Z:
# if: tag =~ ^v\d+\.\d+\.\d+$ AND repo = pypa/cibuildwheel
jobs:
include:
# Optional: run a test on Windows
- os: windows
language: shell
name: Test on Windows
# Deploy source distribution
- stage: deploy
name: Deploy source distribution
install: python3 -m pip install build twine
script: python3 -m build --sdist --formats=gztar
after_success: python3 -m twine upload --skip-existing dist/*.tar.gz
# Deploy on linux
- stage: deploy
name: Build and deploy Linux wheels
services: docker
install: python3 -m pip install cibuildwheel==3.3.0 twine
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
# Deploy on windows
- stage: deploy
name: Build and deploy Windows wheels
os: windows
language: shell
install: python3 -m pip install cibuildwheel==3.3.0 twine
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
env:
global:
- TWINE_USERNAME=__token__
# Note: TWINE_PASSWORD is set to a PyPI API token in Travis settings
+2 -2
View File
@@ -33,8 +33,8 @@ def lint(session: nox.Session) -> None:
"""
Run the linter.
"""
session.install("prek")
session.run("prek", "run", "--all-files", *session.posargs)
session.install("pre-commit")
session.run("pre-commit", "run", "--all-files", *session.posargs)
@nox.session(tags=["lint"])
+7 -7
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "cibuildwheel"
version = "3.4.0"
version = "3.3.0"
description = "Build Python wheels on CI with minimal configuration."
readme = "README.md"
license = "BSD-2-Clause"
@@ -19,6 +19,7 @@ keywords = [
"macos",
"packaging",
"pypi",
"travis",
"wheel",
"windows",
]
@@ -90,7 +91,7 @@ test = [
"pytest-timeout",
"pytest-xdist",
"pytest-rerunfailures!=16.0",
"pytest>=9",
"pytest>=6",
"setuptools",
"tomli_w",
"validate-pyproject",
@@ -103,11 +104,11 @@ dev = [
]
[tool.pytest]
minversion = "9.0"
addopts = ["-ra", "--showlocals", "--xdoctest", "--ignore-glob=*venv*"]
strict = true
[tool.pytest.ini_options]
minversion = "6.0"
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config", "--xdoctest", "--ignore-glob=*venv*"]
junit_family = "xunit2"
xfail_strict = true
filterwarnings = ["error"]
log_level = "INFO"
markers = [
@@ -116,7 +117,6 @@ markers = [
"android: tests that run on Android",
"pyodide: tests that run on Pyodide",
]
required_plugins = ["pytest-rerunfailures"]
[tool.mypy]
python_version = "3.11"
+8 -19
View File
@@ -1,5 +1,6 @@
import json
import os
import shutil
import subprocess
from collections.abc import Generator
@@ -11,9 +12,7 @@ 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.venv import find_uv
from . import utils
from .utils import DEFAULT_CIBW_ENABLE, EMULATED_ARCHS, get_platform
@@ -164,8 +163,8 @@ def build_frontend_env_nouv(request: pytest.FixtureRequest) -> dict[str, str]:
return {"CIBW_BUILD_FRONTEND": frontend}
@pytest.fixture(params=["pip", "build", "build[uv]", "uv"])
def build_frontend_env(request: pytest.FixtureRequest) -> Generator[dict[str, str], None, None]:
@pytest.fixture(params=["pip", "build", "build[uv]"])
def build_frontend_env(request: pytest.FixtureRequest) -> dict[str, str]:
frontend = request.param
marks = {m.name for m in request.node.iter_markers()}
if "android" in marks:
@@ -179,25 +178,15 @@ def build_frontend_env(request: pytest.FixtureRequest) -> Generator[dict[str, st
if platform in {"pyodide", "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"}:
if platform == "pyodide" and frontend == "build[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"}:
uv_available = shutil.which("uv") is not None
if not uv_available and frontend == "build[uv]":
pytest.skip("Can't find uv, so skipping uv tests")
if uv_path is not None and frontend == "build" and platform not in {"android", "ios"}:
if uv_available and frontend == "build" and platform not in {"android", "ios"}:
pytest.skip("No need to check build when uv is present")
# temporary workaround: uv doesn't work with graalpy yet
uses_uv = "uv" in frontend
env: dict[str, str] = {"CIBW_BUILD_FRONTEND": frontend}
if uses_uv:
utils.include_graalpy_in_expected_wheels = False
env["CIBW_SKIP"] = "gp*" # skip graalpy when using uv, until uv supports it
try:
yield env
finally:
if uses_uv:
utils.include_graalpy_in_expected_wheels = True
return {"CIBW_BUILD_FRONTEND": frontend}
@pytest.fixture
+1 -160
View File
@@ -4,7 +4,7 @@ import re
import sys
from dataclasses import dataclass
from pathlib import Path
from shutil import rmtree, which
from shutil import rmtree
from subprocess import CalledProcessError
from textwrap import dedent
from zipfile import ZipFile
@@ -496,162 +496,3 @@ def test_libcxx(tmp_path, capfd):
assert len(wheels) == 1
for name in ZipFile(output_dir / wheels[0]).namelist():
assert ".libs" not in name
@needs_emulator
def test_setuptools_rust(tmp_path, capfd):
"""
Test Android cross-compilation using the setuptools-rust toolchain.
"""
if not which("rustup") or not which("cargo"):
pytest.skip("rustup and cargo are required for this test")
# Initialize a basic project and override files for setuptools-rust
project = new_c_project()
project.files["pyproject.toml"] = dedent(
"""\
[build-system]
requires = ["setuptools", "wheel", "setuptools-rust"]
"""
)
project.files["setup.py"] = dedent(
"""\
from setuptools import setup
from setuptools_rust import Binding, RustExtension
setup(
name="spam",
version="0.1.0",
rust_extensions=[RustExtension("spam.rust_ext", binding=Binding.PyO3)],
zip_safe=False,
)
"""
)
project.files["Cargo.toml"] = dedent(
"""\
[package]
name = "rust_ext"
version = "0.1.0"
edition = "2021"
[lib]
name = "rust_ext"
crate-type = ["cdylib"]
[dependencies]
pyo3 = { version = "0.23.3", features = ["extension-module"] }
"""
)
# Create the Rust source directory and file
(tmp_path / "src").mkdir()
project.files["src/lib.rs"] = dedent(
"""\
use pyo3::prelude::*;
#[pyfunction]
fn hello() -> PyResult<String> {
Ok("Hello from Rust via setuptools-rust!".to_string())
}
#[pymodule]
fn rust_ext(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(hello, m)?)?;
Ok(())
}
"""
)
project.generate(tmp_path)
# Command to verify the built extension on the Android emulator
test_command = "python -c 'import spam.rust_ext; print(spam.rust_ext.hello())'"
# Run cibuildwheel to build and test the wheel
wheels = cibuildwheel_run(
tmp_path,
add_env={
**cp313_env,
"CIBW_TEST_COMMAND": test_command,
"CIBW_BUILD_VERBOSITY": "1",
},
)
# Verification
assert len(wheels) == 1
stdout = capfd.readouterr().out
assert "Hello from Rust via setuptools-rust!" in stdout
@needs_emulator
def test_maturin(tmp_path, capfd):
"""
Test Android cross-compilation using the maturin backend.
"""
if not which("rustup") or not which("cargo"):
pytest.skip("rustup and cargo are required for this test")
project = new_c_project()
project.files["pyproject.toml"] = dedent(
"""\
[build-system]
# maturin >= 1.11.0 is required for reliable Android cross-compilation support.
requires = ["maturin>=1.11.0,<2.0"]
build-backend = "maturin"
[project]
name = "spam"
version = "0.1.0"
"""
)
project.files["Cargo.toml"] = dedent(
"""\
[package]
name = "spam"
version = "0.1.0"
edition = "2021"
[lib]
name = "spam"
crate-type = ["cdylib"]
[dependencies]
pyo3 = { version = "0.23.3", features = ["extension-module"] }
"""
)
(tmp_path / "src").mkdir()
project.files["src/lib.rs"] = dedent(
"""\
use pyo3::prelude::*;
#[pyfunction]
fn hello() -> PyResult<String> {
Ok("Hello from Rust via maturin!".to_string())
}
#[pymodule]
fn spam(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(hello, m)?)?;
Ok(())
}
"""
)
project.generate(tmp_path)
(tmp_path / "setup.py").unlink()
test_command = "python -c 'import spam; print(spam.hello())'"
wheels = cibuildwheel_run(
tmp_path,
add_env={
**cp313_env,
"CIBW_TEST_COMMAND": test_command,
"CIBW_BUILD_VERBOSITY": "1",
},
)
assert len(wheels) == 1
stdout = capfd.readouterr().out
assert "Hello from Rust via maturin!" in stdout
+3 -2
View File
@@ -2,7 +2,8 @@ import subprocess
import pytest
from . import test_projects, utils
from . import utils
from .test_projects.c import new_c_project
@pytest.mark.parametrize(
@@ -13,7 +14,7 @@ from . import test_projects, utils
],
)
def test_build_frontend_args(tmp_path, capfd, frontend_name):
project = test_projects.new_c_project()
project = new_c_project()
project_dir = tmp_path / "project"
project.generate(project_dir)
-34
View File
@@ -347,37 +347,3 @@ def test_ios_test_command_invalid(tmp_path, capfd):
)
_, err = capfd.readouterr()
assert "iOS tests configured with a test command which doesn't start with 'python -m'" in err
def test_repair_step(tmp_path):
"""Build will succeed & the custom repair step is called."""
skip_if_ios_testing_not_supported()
project_dir = tmp_path / "project"
basic_project = test_projects.new_c_project()
basic_project.files.update(basic_project_files)
basic_project.generate(project_dir)
# Build, but don't test the wheels; we're only checking that the right
# warning was raised.
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env={
"CIBW_PLATFORM": "ios",
"CIBW_BUILD": "cp314-*",
"CIBW_TEST_SKIP": "*",
"CIBW_REPAIR_WHEEL_COMMAND": "touch .ios-repair-step && mv {wheel} {dest_dir}",
},
)
# The expected wheels were produced.
expected_wheels = utils.expected_wheels(
"spam",
"0.1.0",
platform="ios",
python_abi_tags=["cp314-cp314"],
)
assert set(actual_wheels) == set(expected_wheels)
# The custom repair step is called.
assert project_dir.joinpath(".ios-repair-step").is_file()
-29
View File
@@ -1,29 +0,0 @@
import packaging.utils
from . import test_projects, utils
meson_project = test_projects.new_meson_project()
def test_meson_python_basic(tmp_path, build_frontend_env):
"""Test that cibuildwheel can build a project with meson-python backend."""
project_dir = tmp_path / "project"
meson_project.generate(project_dir)
# build the wheels
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env=build_frontend_env,
single_python=True,
)
# check that the expected wheels are produced
# note that the meson test project doesn't support win32.
is_windows = utils.get_platform() == "windows"
expected_wheels = utils.expected_wheels(
"spam", "0.1.0", single_python=True, single_arch=is_windows
)
actual_wheels_normalized = {packaging.utils.parse_wheel_filename(w) for w in actual_wheels}
expected_wheels_normalized = {packaging.utils.parse_wheel_filename(w) for w in expected_wheels}
assert actual_wheels_normalized == expected_wheels_normalized
+2 -3
View File
@@ -1,5 +1,4 @@
from .base import TestProject
from .meson import new_meson_project
from .setuptools import new_c_project
from .c import new_c_project
__all__ = ("TestProject", "new_c_project", "new_meson_project")
__all__ = ("TestProject", "new_c_project")
+71
View File
@@ -1,3 +1,7 @@
import jinja2
from .base import TestProject
SPAM_C_TEMPLATE = r"""
#include <Python.h>
@@ -35,3 +39,70 @@ PyMODINIT_FUNC PyInit_spam(void)
return PyModule_Create(&moduledef);
}
"""
SETUP_PY_TEMPLATE = r"""
import os
import sys
from setuptools import setup, Extension
{{ setup_py_add }}
libraries = []
# Emscripten fails if you pass -lc...
# See: https://github.com/emscripten-core/emscripten/issues/16680
if sys.platform.startswith('linux') and "emscripten" not in os.environ.get("_PYTHON_HOST_PLATFORM", ""):
libraries.extend(['m', 'c'])
setup(
ext_modules=[Extension(
'spam',
sources=['spam.c'],
libraries=libraries,
{{ setup_py_extension_args_add | indent(8) }}
)],
{{ setup_py_setup_args_add | indent(4) }}
)
"""
SETUP_CFG_TEMPLATE = r"""
[metadata]
name = spam
version = 0.1.0
{{ setup_cfg_add }}
"""
def new_c_project(
*,
spam_c_top_level_add: str = "",
spam_c_function_add: str = "",
setup_py_add: str = "",
setup_py_extension_args_add: str = "",
setup_py_setup_args_add: str = "",
setup_cfg_add: str = "",
) -> TestProject:
project = TestProject()
project.files.update(
{
"spam.c": jinja2.Template(SPAM_C_TEMPLATE),
"setup.py": jinja2.Template(SETUP_PY_TEMPLATE),
"setup.cfg": jinja2.Template(SETUP_CFG_TEMPLATE),
}
)
project.template_context.update(
{
"spam_c_top_level_add": spam_c_top_level_add,
"spam_c_function_add": spam_c_function_add,
"setup_py_add": setup_py_add,
"setup_py_extension_args_add": setup_py_extension_args_add,
"setup_py_setup_args_add": setup_py_setup_args_add,
"setup_cfg_add": setup_cfg_add,
}
)
return project
-60
View File
@@ -1,60 +0,0 @@
import jinja2
from .base import TestProject
from .c import SPAM_C_TEMPLATE
PYPROJECT_TOML_TEMPLATE = r"""
[build-system]
requires = ["meson-python"]
build-backend = "mesonpy"
[project]
name = "spam"
version = "0.1.0"
[tool.cibuildwheel.windows]
config-settings = { "setup-args" = "--vsenv" }
# building win32 wheels on a 64-bit CI machine with meson-python
# requires a few extra steps outside cibuildwheel. See
# https://github.com/pypa/cibuildwheel/pull/2718
archs = ["auto64"]
"""
MESON_BUILD_TEMPLATE = r"""
project('spam', 'c',
version: '0.1.0',
default_options: ['warning_level=2'],
)
py = import('python').find_installation(pure: false)
py.extension_module('spam',
'spam.c',
install: true,
)
"""
def new_meson_project(
*,
spam_c_top_level_add: str = "",
spam_c_function_add: str = "",
) -> TestProject:
project = TestProject()
project.files.update(
{
"spam.c": jinja2.Template(SPAM_C_TEMPLATE),
"pyproject.toml": jinja2.Template(PYPROJECT_TOML_TEMPLATE),
"meson.build": jinja2.Template(MESON_BUILD_TEMPLATE),
}
)
project.template_context.update(
{
"spam_c_top_level_add": spam_c_top_level_add,
"spam_c_function_add": spam_c_function_add,
}
)
return project
-71
View File
@@ -1,71 +0,0 @@
import jinja2
from .base import TestProject
from .c import SPAM_C_TEMPLATE
SETUP_PY_TEMPLATE = r"""
import os
import sys
from setuptools import setup, Extension
{{ setup_py_add }}
libraries = []
# Emscripten fails if you pass -lc...
# See: https://github.com/emscripten-core/emscripten/issues/16680
if sys.platform.startswith('linux') and "emscripten" not in os.environ.get("_PYTHON_HOST_PLATFORM", ""):
libraries.extend(['m', 'c'])
setup(
ext_modules=[Extension(
'spam',
sources=['spam.c'],
libraries=libraries,
{{ setup_py_extension_args_add | indent(8) }}
)],
{{ setup_py_setup_args_add | indent(4) }}
)
"""
SETUP_CFG_TEMPLATE = r"""
[metadata]
name = spam
version = 0.1.0
{{ setup_cfg_add }}
"""
def new_c_project(
*,
spam_c_top_level_add: str = "",
spam_c_function_add: str = "",
setup_py_add: str = "",
setup_py_extension_args_add: str = "",
setup_py_setup_args_add: str = "",
setup_cfg_add: str = "",
) -> TestProject:
project = TestProject()
project.files.update(
{
"spam.c": jinja2.Template(SPAM_C_TEMPLATE),
"setup.py": jinja2.Template(SETUP_PY_TEMPLATE),
"setup.cfg": jinja2.Template(SETUP_CFG_TEMPLATE),
}
)
project.template_context.update(
{
"spam_c_top_level_add": spam_c_top_level_add,
"spam_c_function_add": spam_c_function_add,
"setup_py_add": setup_py_add,
"setup_py_extension_args_add": setup_py_extension_args_add,
"setup_py_setup_args_add": setup_py_setup_args_add,
"setup_cfg_add": setup_cfg_add,
}
)
return project
+3 -26
View File
@@ -99,7 +99,7 @@ def test_pyodide_version_incompatible(tmp_path, capfd):
tmp_path,
add_args=["--platform", "pyodide"],
add_env={
"CIBW_DEPENDENCY_VERSIONS": "packages: pyodide-build==0.31.2",
"CIBW_DEPENDENCY_VERSIONS": "packages: pyodide-build==0.29.3",
"CIBW_PYODIDE_VERSION": "0.26.0a6",
},
)
@@ -146,29 +146,6 @@ def test_pyodide_build_and_test(tmp_path, expect_failure):
"spam-0.1.0-cp312-cp312-pyodide_2024_0_wasm32.whl",
"spam-0.1.0-cp313-cp313-pyodide_2025_0_wasm32.whl",
]
print("actual_wheels", actual_wheels)
print("expected_wheels", expected_wheels)
assert set(actual_wheels) == set(expected_wheels)
def test_pyodide_repair_wheel(tmp_path):
if sys.platform == "win32":
pytest.skip("pyodide-build doesn't work correctly on Windows")
project_dir = tmp_path / "project"
basic_project.generate(project_dir)
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_args=["--platform", "pyodide"],
add_env={
"CIBW_REPAIR_WHEEL_COMMAND_PYODIDE": (
"pyodide auditwheel repair --libdir /path/to/libraries --output-dir {dest_dir} {wheel}"
),
},
single_python=True,
)
# check that the expected wheels are produced
expected_wheels = [
"spam-0.1.0-cp312-cp312-pyodide_2024_0_wasm32.whl",
]
assert set(actual_wheels) == set(expected_wheels)
+10 -17
View File
@@ -1,3 +1,4 @@
import socket
import textwrap
import pytest
@@ -7,25 +8,14 @@ from . import test_projects, utils
project_with_ssl_tests = test_projects.new_c_project(
setup_py_add=textwrap.dedent(
r"""
import ssl, time, urllib.request, urllib.error
import ssl
def check_https(context=None):
# google hosts this endpoint that returns a 204 No Content, it's used for
# connectivity checks in Android & Chrome
url = "https://google.com/generate_204"
from urllib.request import urlopen
for i in range(5):
try:
urllib.request.urlopen(url, context=context, timeout=5)
return
except (OSError, urllib.error.URLError) as e:
print(f"Attempt {i+1}: Could not connect to {url}: {e}")
time.sleep(2 ** i) # Backoff: 1s, 2s, 4s, 8s...
raise ConnectionError(f"Could not connect to {url} after retries.")
check_https()
check_https(context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2))
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# badssl.com is a HTTPS test server that can be used to test SSL connections
data = urlopen("https://tls-v1-2.badssl.com", context=context)
data = urlopen("https://tls-v1-2.badssl.com")
"""
)
)
@@ -38,6 +28,9 @@ def test(tmp_path):
project_dir = tmp_path / "project"
project_with_ssl_tests.generate(project_dir)
# warm up connection
socket.getaddrinfo("tls-v1-2.badssl.com", 443)
actual_wheels = utils.cibuildwheel_run(project_dir)
expected_wheels = utils.expected_wheels("spam", "0.1.0")
+1 -5
View File
@@ -28,10 +28,6 @@ GRAALPY_ARCHS = ["x86_64", "AMD64", "aarch64", "arm64"]
SINGLE_PYTHON_VERSION: Final[tuple[int, int]] = (3, 12)
# temporary workaround: set by build_frontend_env fixture to skip graalpy
# when uv is the build frontend (compatibility issue between graalpy and uv)
include_graalpy_in_expected_wheels: bool = True
_AARCH64_CAN_RUN_ARMV7: Final[bool] = Architecture.aarch64.value not in EMULATED_ARCHS and {
None: Architecture.armv7l.value not in EMULATED_ARCHS,
CIProvider.travis_ci: False,
@@ -309,7 +305,7 @@ def _expected_wheels(
"pp311-pypy311_pp73",
]
if EnableGroup.GraalPy in enable_groups and include_graalpy_in_expected_wheels:
if EnableGroup.GraalPy in enable_groups:
python_abi_tags += [
"graalpy311-graalpy242_311_native",
"graalpy312-graalpy250_312_native",
+65
View File
@@ -1,3 +1,4 @@
import os
import sys
import tomllib
from fnmatch import fnmatch
@@ -141,6 +142,70 @@ def test_empty_selector(monkeypatch):
assert e.value.code == 3
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_riscv64_warning1(monkeypatch, capsys):
monkeypatch.setenv("CIBW_ENABLE", "cpython-experimental-riscv64")
main()
_, err = capsys.readouterr()
print(err)
assert "'cpython-experimental-riscv64' enable is deprecated" in err
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_riscv64_warning2(monkeypatch, capsys, tmp_path):
local_path = tmp_path / "tmp_project"
os.mkdir(local_path) # noqa:PTH102 Path.mkdir has been monkeypatched already
local_path.joinpath("setup.py").touch()
monkeypatch.setattr(
sys, "argv", ["cibuildwheel", "--only", "cp313-manylinux_riscv64", str(local_path)]
)
monkeypatch.setenv("CIBW_ENABLE", "cpython-experimental-riscv64")
main()
_, err = capsys.readouterr()
print(err)
assert "'cpython-experimental-riscv64' enable is deprecated" in err
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_riscv64_no_warning(monkeypatch, capsys, tmp_path):
local_path = tmp_path / "tmp_project"
os.mkdir(local_path) # noqa:PTH102 Path.mkdir has been monkeypatched already
local_path.joinpath("setup.py").touch()
monkeypatch.setattr(
sys, "argv", ["cibuildwheel", "--only", "cp313-manylinux_riscv64", str(local_path)]
)
main()
_, err = capsys.readouterr()
print(err)
assert "'cpython-experimental-riscv64' enable is deprecated" not in err
@pytest.mark.usefixtures("platform", "intercepted_build_args")
def test_riscv64_no_warning2(monkeypatch, capsys, tmp_path):
local_path = tmp_path / "tmp_project"
os.mkdir(local_path) # noqa:PTH102 Path.mkdir has been monkeypatched already
local_path.joinpath("setup.py").touch()
monkeypatch.setattr(
sys, "argv", ["cibuildwheel", "--only", "cp313-manylinux_riscv64", str(local_path)]
)
monkeypatch.setenv("CIBW_ENABLE", "all")
main()
_, err = capsys.readouterr()
print(err)
assert "'cpython-experimental-riscv64' enable is deprecated" not in err
@pytest.mark.parametrize(
("architecture", "image", "full_image"),
[
+2 -11
View File
@@ -328,11 +328,6 @@ def test_environment_pass_references():
"build",
[],
),
(
'build-frontend = "uv"',
"uv",
[],
),
(
'build-frontend = {name = "build"}',
"build",
@@ -594,15 +589,11 @@ def test_deprecated_image(
("pip", 3, ["-Ca", "-Cb", "-1", "-vvv"]),
("pip", 2, ["-Ca", "-Cb", "-1", "-vv"]),
("pip", -1, ["-Ca", "-Cb", "-1", "-q"]),
("uv", -1, ["-Ca", "-Cb", "-1", "-q"]),
("build", -1, ["-Ca", "-Cb", "-1", "-q"]),
("build[uv]", -1, ["-Ca", "-Cb", "-1", "-q"]),
("build", 0, ["-Ca", "-Cb", "-1"]),
("build", 1, ["-Ca", "-Cb", "-1"]),
("build", 2, ["-Ca", "-Cb", "-1", "-v"]),
("build", 3, ["-Ca", "-Cb", "-1", "-vv"]),
("build[uv]", 3, ["-Ca", "-Cb", "-1", "-vv"]),
("uv", 3, ["-Ca", "-Cb", "-1", "-vv"]),
],
)
def test_get_build_frontend_extra_flags(
@@ -615,7 +606,7 @@ def test_get_build_frontend_extra_flags(
monkeypatch.setattr(Logger, "warning", mock_warning)
build_frontend = BuildFrontendConfig(frontend, ["-1"])
args = get_build_frontend_extra_flags(
build_frontend=build_frontend, verbosity_level=verbosity, config_settings="a b", py38=False
build_frontend=build_frontend, verbosity_level=verbosity, config_settings="a b"
)
assert args == result
@@ -630,7 +621,7 @@ def test_get_build_frontend_extra_flags_warning(
monkeypatch.setattr(Logger, "warning", mock_warning)
build_frontend = BuildFrontendConfig(frontend, ["-1"])
args = get_build_frontend_extra_flags(
build_frontend=build_frontend, verbosity_level=-1, config_settings="a b", py38=True
build_frontend=build_frontend, verbosity_level=-1, config_settings="a b"
)
assert args == ["-Ca", "-Cb", "-1"]
mock_warning.assert_called_once()