Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd033a4447 | ||
|
|
9d023cf77a | ||
|
|
8a69dbd9d4 | ||
|
|
147de6f4f7 | ||
|
|
e217e44661 | ||
|
|
871ef6b506 | ||
|
|
fac72f024a | ||
|
|
d4c332104d | ||
|
|
5af5df4e4f | ||
|
|
6c5cf87871 | ||
|
|
46f4108f23 | ||
|
|
1da439f8dc | ||
|
|
7af9d039fb | ||
|
|
de84624d70 | ||
|
|
cac121a67d | ||
|
|
604da878cb | ||
|
|
eaf0051162 | ||
|
|
8dcf71e02d | ||
|
|
92f0142a3e | ||
|
|
6c8347f465 | ||
|
|
a4d24056ef | ||
|
|
7e5a838a63 | ||
|
|
19e1b8a4b0 | ||
|
|
73581ae579 | ||
|
|
f21ff5e84c | ||
|
|
973946b172 | ||
|
|
5ea40e6ff3 | ||
|
|
6a36f6494b | ||
|
|
31de15bcd9 | ||
|
|
3179fd215a | ||
|
|
184d4e1280 | ||
|
|
08165ffeed | ||
|
|
9bb03835e5 | ||
|
|
2552303ff3 | ||
|
|
5b74582a72 | ||
|
|
4470eb0dd9 | ||
|
|
8bda260d3a | ||
|
|
5b5a95bdc2 | ||
|
|
561fa32683 | ||
|
|
70913f0a49 | ||
|
|
f49397f151 | ||
|
|
c1b8a12cd5 | ||
|
|
932529cab1 | ||
|
|
70fb1c4a1a | ||
|
|
405a475ac7 | ||
|
|
78da7bafcc | ||
|
|
8d86d3122b | ||
|
|
89a5cfe272 | ||
|
|
8d5d84e0fc | ||
|
|
4ada77dea4 | ||
|
|
829441f4a0 | ||
|
|
a8d190a111 | ||
|
|
bf817c6dc8 | ||
|
|
384c8d5c82 | ||
|
|
c37e5a2d13 | ||
|
|
130fdd2548 | ||
|
|
ed120540d9 | ||
|
|
6c6e0f6ba5 | ||
|
|
877d3bf649 | ||
|
|
21e9ef1800 | ||
|
|
c333b131d3 | ||
|
|
4c2ed1e632 | ||
|
|
9f2a3cb67c | ||
|
|
687406f664 | ||
|
|
2e6b11e10c | ||
|
|
b713086763 | ||
|
|
8f574d107b | ||
|
|
97da90432e | ||
|
|
67ee9dda92 | ||
|
|
ba8be0d988 | ||
|
|
90dd47640f | ||
|
|
b61324914b | ||
|
|
3992d5719c | ||
|
|
345467c6cf | ||
|
|
791e41cfec | ||
|
|
9d5f5e60b8 | ||
|
|
1b354cfa63 | ||
|
|
d1a4c9c074 | ||
|
|
78bca57cb4 | ||
|
|
f8894e67f5 | ||
|
|
666a2c3f1a | ||
|
|
15447bd591 | ||
|
|
678ef21647 | ||
|
|
e82b1bfc44 | ||
|
|
ced16da65f | ||
|
|
63daa02352 | ||
|
|
711a3d017d | ||
|
|
3873a1edf8 | ||
|
|
6dd4f15a0e | ||
|
|
44c4742477 | ||
|
|
c0217440e8 | ||
|
|
cf18014fce | ||
|
|
3ea0a6c2f0 | ||
|
|
30a0decb47 | ||
|
|
988d512fb3 | ||
|
|
98d57d9547 | ||
|
|
8daac05d63 | ||
|
|
950fbd0a60 | ||
|
|
d24ebf4125 | ||
|
|
8a0d1d59c7 | ||
|
|
208ca32050 | ||
|
|
9cf99e78bc | ||
|
|
2fb3205ff1 | ||
|
|
376414dc69 | ||
|
|
070e744d26 | ||
|
|
89e0a90bc5 | ||
|
|
312cf1573e | ||
|
|
6537b8f51f | ||
|
|
3f00a2fded | ||
|
|
a8d1defda9 | ||
|
|
510382886d | ||
|
|
b3c4d37885 | ||
|
|
3eb6dbbdd3 | ||
|
|
90c14a333f | ||
|
|
8d945475ac | ||
|
|
ca06deb26f | ||
|
|
f7e1922225 | ||
|
|
0d8e919dfc | ||
|
|
022de07dc1 | ||
|
|
920f574191 | ||
|
|
5c06f3c289 | ||
|
|
e2a0839555 | ||
|
|
87fff77282 | ||
|
|
8ef9486aab | ||
|
|
2a7fef07db | ||
|
|
f7de18e291 | ||
|
|
80095ac7af | ||
|
|
df2e35a016 | ||
|
|
f654071fe2 | ||
|
|
b71a83d411 | ||
|
|
a6ecded8c4 | ||
|
|
8f58f71c2e | ||
|
|
6940c77cd3 | ||
|
|
ae2451a199 | ||
|
|
1fe6b1aa44 | ||
|
|
554726e3c4 | ||
|
|
8742ff2ef8 | ||
|
|
75627e8ca4 | ||
|
|
3ae9aa1da5 | ||
|
|
f04a522d50 | ||
|
|
edd67e0d26 | ||
|
|
8a8c07d4f9 | ||
|
|
74afe329a1 | ||
|
|
7ada127bfc | ||
|
|
6b3122aff7 | ||
|
|
86ed421c1b | ||
|
|
b4a22b6d5e | ||
|
|
7c02fa721c | ||
|
|
88d60dce89 | ||
|
|
1dea9e4a14 | ||
|
|
53e2c74ab0 | ||
|
|
32343a3cf1 | ||
|
|
2e0ab0176c | ||
|
|
75d6d9d55b | ||
|
|
81b0a578df | ||
|
|
27d0942e1c | ||
|
|
68f1058d7e | ||
|
|
dfca0ce96a | ||
|
|
abd05a65ba | ||
|
|
d65d46ca24 | ||
|
|
88c113402d | ||
|
|
c7a653d6a9 | ||
|
|
6c93c131c4 | ||
|
|
d635c0eee6 | ||
|
|
a78facb861 | ||
|
|
ce3fb78320 | ||
|
|
5b0b4583a8 | ||
|
|
a7ea5fb408 | ||
|
|
bc55e8bf0a | ||
|
|
c753cd282d | ||
|
|
07bd78c4e6 | ||
|
|
d7db575b96 | ||
|
|
7154e181e6 | ||
|
|
0b04ab1040 | ||
|
|
34b049f138 | ||
|
|
3bf1908dcb | ||
|
|
4a79413fe6 | ||
|
|
e250df5d5d | ||
|
|
ddc2c6e845 | ||
|
|
fd0aae31e3 | ||
|
|
2a83588552 | ||
|
|
a1e3efb81c | ||
|
|
c0e4b16ab9 | ||
|
|
40b63b834d | ||
|
|
4db49f5485 | ||
|
|
23a6e88b0c | ||
|
|
4ca5d7cd2a | ||
|
|
9879937c63 | ||
|
|
c18f6cba12 | ||
|
|
93542c397c | ||
|
|
7a5515e3e0 | ||
|
|
a6da0692ce | ||
|
|
c9765e9dc2 | ||
|
|
53a38b70b2 | ||
|
|
fab2a86a3f | ||
|
|
d0a527bfd5 | ||
|
|
f11f1b2ef9 | ||
|
|
056a543dd9 | ||
|
|
bf6eacdf25 | ||
|
|
909d53b9b6 | ||
|
|
2c4974286f | ||
|
|
6e2f4c00ab | ||
|
|
d371852317 | ||
|
|
c7b505db47 | ||
|
|
7ddddff94f | ||
|
|
4136cb5969 | ||
|
|
a3e5b541dc | ||
|
|
9195da8c1a | ||
|
|
606879f2d3 | ||
|
|
f2dc466d03 | ||
|
|
0618babf0c | ||
|
|
886ba0f662 | ||
|
|
8e9a703abc | ||
|
|
4dba644b8d | ||
|
|
4cedf1c603 | ||
|
|
796361d9f9 | ||
|
|
22aff1bc25 | ||
|
|
86ef5eed8a | ||
|
|
a4f8eb3544 | ||
|
|
270c626d6b | ||
|
|
ae0c33b395 | ||
|
|
2a1edad716 | ||
|
|
c2b03ead3e | ||
|
|
d198c90f7a | ||
|
|
6c6c51ef3b | ||
|
|
a6345190fa | ||
|
|
ebf48d4122 | ||
|
|
9213ca194d | ||
|
|
b371ae35d1 | ||
|
|
92ee0fda43 | ||
|
|
5baa3de6df | ||
|
|
a561ae0f9d | ||
|
|
7c99262c00 | ||
|
|
277abc5ffa | ||
|
|
a70a6346c5 | ||
|
|
859ebaf371 | ||
|
|
39d9b00eeb | ||
|
|
e577a9fbdf | ||
|
|
77c57bdfa8 | ||
|
|
81812d05a3 | ||
|
|
cc25f71674 | ||
|
|
6853b08120 | ||
|
|
c38a3d7026 | ||
|
|
2090f0ddce | ||
|
|
cec051f4b8 | ||
|
|
89d5bd58f5 | ||
|
|
4586062efb | ||
|
|
1efccd03b5 | ||
|
|
c4fdf66efc | ||
|
|
75f6b45a75 | ||
|
|
c2e19fb391 | ||
|
|
b29dda3b4d | ||
|
|
0ec6d97029 | ||
|
|
36e40805e8 | ||
|
|
fff9ec32ed | ||
|
|
f4291e7492 | ||
|
|
9da4ede616 | ||
|
|
77d3a5f98e | ||
|
|
9535d168fa | ||
|
|
70fae8d0b7 | ||
|
|
7699db3017 | ||
|
|
6dceb29008 | ||
|
|
035f5a2297 | ||
|
|
951d453a2e | ||
|
|
b05d91ee01 | ||
|
|
cbffaf76d2 | ||
|
|
46a7bf14dc | ||
|
|
1e2942dd68 | ||
|
|
de4fe44dc8 | ||
|
|
96e0efe076 | ||
|
|
84ffe27f78 | ||
|
|
129137d894 | ||
|
|
35a8d6486e | ||
|
|
74c99e0d93 | ||
|
|
86248929ed | ||
|
|
5fee29256d | ||
|
|
d4af0ac229 | ||
|
|
7da7df1efc | ||
|
|
9deb1b6794 | ||
|
|
271c5fe6e4 | ||
|
|
c716cfaeb8 | ||
|
|
28ad6e4b40 | ||
|
|
13599a1a10 | ||
|
|
a1bebe5362 | ||
|
|
687981060f | ||
|
|
29cb13893f | ||
|
|
099d397aee | ||
|
|
d7a6d04353 | ||
|
|
72222654f4 | ||
|
|
7a8b8012ff | ||
|
|
0ccf1dc016 | ||
|
|
ba11212a13 | ||
|
|
6d0890e7e0 | ||
|
|
cf7586ce7e | ||
|
|
137dc1a2cf | ||
|
|
1646b08659 | ||
|
|
391249a1ca | ||
|
|
62a06d28b5 | ||
|
|
647b509c74 |
@@ -1,9 +1,10 @@
|
||||
version: 2
|
||||
|
||||
jobs:
|
||||
osx-python3.9:
|
||||
osx-python3.12:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
xcode: 15.4.0
|
||||
resource_class: macos.m1.medium.gen1
|
||||
environment:
|
||||
PYTHON: python3
|
||||
steps:
|
||||
@@ -17,9 +18,9 @@ jobs:
|
||||
command: venv/bin/python ./bin/run_tests.py
|
||||
no_output_timeout: 30m
|
||||
|
||||
linux-python3.9:
|
||||
linux-python3.12:
|
||||
docker:
|
||||
- image: circleci/python:3.9
|
||||
- image: cimg/python:3.12
|
||||
environment:
|
||||
PYTHON: python3
|
||||
# Temporarily restrict the tests that are run on CircleCI to prevent
|
||||
@@ -39,7 +40,7 @@ jobs:
|
||||
|
||||
linux-aarch64:
|
||||
machine:
|
||||
image: ubuntu-2004:2022.04.1
|
||||
image: default
|
||||
resource_class: arm.medium
|
||||
environment:
|
||||
PYTHON: python3
|
||||
@@ -61,6 +62,6 @@ workflows:
|
||||
version: 2
|
||||
all-tests:
|
||||
jobs:
|
||||
- osx-python3.9
|
||||
- linux-python3.9
|
||||
- osx-python3.12
|
||||
- linux-python3.12
|
||||
- linux-aarch64
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
set -o errexit
|
||||
set -o xtrace
|
||||
|
||||
if [ "$(uname -s)" == "Darwin" ]; then
|
||||
sudo softwareupdate --install-rosetta --agree-to-license
|
||||
fi
|
||||
|
||||
$PYTHON --version
|
||||
$PYTHON -m pip --version
|
||||
$PYTHON -m virtualenv -p "$PYTHON" venv
|
||||
$PYTHON -m venv venv
|
||||
venv/bin/python -m pip install -U pip
|
||||
venv/bin/python -m pip install -e ".[dev]"
|
||||
venv/bin/python -m pip freeze
|
||||
venv/bin/python --version
|
||||
|
||||
+5
-7
@@ -1,4 +1,4 @@
|
||||
skip: changesIncludeOnly('docs/*', '.pre-commit-config.yaml')
|
||||
only_if: changesInclude('.cirrus.yml') || ($CIRRUS_BRANCH == "main" && !changesIncludeOnly('docs/*', '.pre-commit-config.yaml')) || $CIRRUS_BRANCH =~ 'cirrus.*'
|
||||
|
||||
run_tests: &RUN_TESTS
|
||||
install_cibuildwheel_script:
|
||||
@@ -50,25 +50,23 @@ windows_x86_task:
|
||||
|
||||
macos_arm64_task:
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-monterey-xcode
|
||||
image: ghcr.io/cirruslabs/macos-sonoma-xcode
|
||||
|
||||
env:
|
||||
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
|
||||
PATH: /opt/homebrew/opt/python@3.10/libexec/bin:$PATH
|
||||
install_pre_requirements_script:
|
||||
- brew install python@3.10
|
||||
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
|
||||
<<: *RUN_TESTS
|
||||
|
||||
macos_arm64_cp38_task:
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-monterey-xcode
|
||||
image: ghcr.io/cirruslabs/macos-sonoma-xcode
|
||||
|
||||
env:
|
||||
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
|
||||
PATH: /opt/homebrew/opt/python@3.10/libexec/bin:$PATH
|
||||
PYTEST_ADDOPTS: --run-cp38-universal2 -k 'test_cp38_arm64_testing_universal2_installer or test_arch_auto'
|
||||
install_pre_requirements_script:
|
||||
- brew install python@3.10
|
||||
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
|
||||
- curl -fsSLO https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg
|
||||
- sudo installer -pkg python-3.8.10-macos11.pkg -target /
|
||||
- rm python-3.8.10-macos11.pkg
|
||||
|
||||
@@ -5,3 +5,7 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
groups:
|
||||
actions:
|
||||
patterns:
|
||||
- "*"
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"severity": "warning",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^:]+):(\\d+):(\\d+): ([A-DF-Z]\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"code": 4,
|
||||
"message": 5
|
||||
}
|
||||
],
|
||||
"owner": "pylint-warning"
|
||||
},
|
||||
{
|
||||
"severity": "error",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^:]+):(\\d+):(\\d+): (E\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"code": 4,
|
||||
"message": 5
|
||||
}
|
||||
],
|
||||
"owner": "pylint-error"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -16,8 +16,9 @@ jobs:
|
||||
- name: Build SDist and wheel
|
||||
run: pipx run build
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-sdist
|
||||
path: dist/*
|
||||
|
||||
- name: Check metadata
|
||||
@@ -27,14 +28,23 @@ jobs:
|
||||
needs: [dist]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
environment: pypi
|
||||
environment:
|
||||
name: pypi
|
||||
url: https://pypi.org/p/cibuildwheel
|
||||
permissions:
|
||||
id-token: write
|
||||
attestations: write
|
||||
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: artifact
|
||||
pattern: cibw-*
|
||||
path: dist
|
||||
merge-multiple: true
|
||||
|
||||
- name: Generate artifact attestation for sdist and wheel
|
||||
uses: actions/attest-build-provenance@5e9cb68e95676991667494a6a4e59b8a2f13e1d0 # v1.3.3
|
||||
with:
|
||||
subject-path: "dist/cibuildwheel-*"
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
||||
+142
-43
@@ -21,36 +21,37 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
id: python
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- uses: pre-commit/action@v3.0.0
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
- name: Check manifest
|
||||
run: pipx run nox -s check_manifest
|
||||
run: pipx run --python "${{ steps.python.outputs.python-path }}" nox -s check_manifest
|
||||
- name: PyLint checks
|
||||
run: |
|
||||
echo "::add-matcher::$GITHUB_WORKSPACE/.github/matchers/pylint.json"
|
||||
pipx run nox -s pylint
|
||||
run: pipx run --python "${{ steps.python.outputs.python-path }}" nox -s pylint -- --output-format=github
|
||||
|
||||
test:
|
||||
name: Test cibuildwheel on ${{ matrix.os }}
|
||||
name: Test on ${{ matrix.os }} (${{ matrix.python_version }})
|
||||
needs: lint
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-latest, macos-11]
|
||||
python_version: ['3.11']
|
||||
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
|
||||
python_version: ['3.12']
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-latest
|
||||
python_version: '3.8'
|
||||
timeout-minutes: 180
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/setup-python@v5
|
||||
name: Install Python ${{ matrix.python_version }}
|
||||
with:
|
||||
python-version: ${{ matrix.python_version }}
|
||||
|
||||
- uses: yezz123/setup-uv@v4
|
||||
|
||||
# Install podman on this CI instance for podman tests on linux
|
||||
# Snippet from: https://github.com/redhat-actions/podman-login/blob/main/.github/workflows/example.yml
|
||||
- name: Install latest podman
|
||||
@@ -62,6 +63,131 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install podman
|
||||
|
||||
# free some space to prevent reaching GHA disk space limits
|
||||
- name: Clean docker images
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
docker system prune -a -f
|
||||
df -h
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv pip install --system ".[test]"
|
||||
|
||||
- name: Generate a sample project
|
||||
run: |
|
||||
python -m test.test_projects test.test_0_basic.basic_project sample_proj
|
||||
|
||||
- name: Run a sample build (GitHub Action)
|
||||
uses: ./
|
||||
with:
|
||||
package-dir: sample_proj
|
||||
output-dir: wheelhouse
|
||||
env:
|
||||
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
|
||||
CIBW_BUILD_FRONTEND: 'build[uv]'
|
||||
CIBW_FREE_THREADED_SUPPORT: 1
|
||||
CIBW_PRERELEASE_PYTHONS: 1
|
||||
|
||||
- name: Run a sample build (GitHub Action, only)
|
||||
uses: ./
|
||||
with:
|
||||
package-dir: sample_proj
|
||||
output-dir: wheelhouse_only
|
||||
only: cp312-${{ runner.os == 'Linux' && 'manylinux_x86_64' || (runner.os == 'Windows' && 'win_amd64' || 'macosx_x86_64') }}
|
||||
|
||||
- name: Create custom configuration file
|
||||
shell: bash
|
||||
run: |
|
||||
cat > sample_proj/cibw.toml <<EOF
|
||||
[tool.cibuildwheel]
|
||||
# Only build on CPython 3.12 on native arch
|
||||
archs = ["native"]
|
||||
build = "cp312-*"
|
||||
# Skip musllinux
|
||||
skip = "*-musllinux*"
|
||||
EOF
|
||||
|
||||
- name: Run a sample build (GitHub Action, config-file)
|
||||
uses: ./
|
||||
with:
|
||||
package-dir: sample_proj
|
||||
output-dir: wheelhouse_config_file
|
||||
config-file: sample_proj/cibw.toml
|
||||
|
||||
- name: Check Action artefacts
|
||||
shell: bash
|
||||
run: |
|
||||
test $(find wheelhouse -name '*.whl' | wc -l) -ge 1
|
||||
test $(find wheelhouse_only -name '*.whl' | wc -l) -eq 1
|
||||
test $(find wheelhouse_config_file -name '*.whl' | wc -l) -eq 1
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: wheelhouse/*.whl
|
||||
|
||||
- name: Test cibuildwheel
|
||||
run: |
|
||||
python ./bin/run_tests.py --run-podman
|
||||
|
||||
emulated-archs:
|
||||
name: Get qemu emulated architectures
|
||||
needs: lint
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
archs: ${{ steps.archs.outputs.archs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install dependencies
|
||||
run: python -m pip install ".[test]"
|
||||
- name: Get qemu emulated architectures
|
||||
id: archs
|
||||
run: |
|
||||
OUTPUT=$(python -c "from json import dumps; from test.utils import EMULATED_ARCHS; print(dumps(EMULATED_ARCHS))")
|
||||
echo "${OUTPUT}"
|
||||
echo "archs=${OUTPUT}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
test-emulated:
|
||||
name: Test Linux ${{ matrix.arch }} using qemu
|
||||
needs: emulated-archs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
strategy:
|
||||
matrix:
|
||||
arch: ${{ fromJSON(needs.emulated-archs.outputs.archs) }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install dependencies
|
||||
run: python -m pip install ".[test,uv]"
|
||||
|
||||
- name: Set up QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: all
|
||||
|
||||
- name: Run the emulation tests
|
||||
run: pytest --run-emulation ${{ matrix.arch }} test/test_emulation.py
|
||||
|
||||
test-pyodide:
|
||||
name: Test cibuildwheel building pyodide wheels
|
||||
needs: lint
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 180
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
name: Install Python 3.12
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install ".[test]"
|
||||
@@ -76,37 +202,10 @@ jobs:
|
||||
package-dir: sample_proj
|
||||
output-dir: wheelhouse
|
||||
env:
|
||||
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
|
||||
CIBW_PLATFORM: pyodide
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: sample_wheels_action
|
||||
path: wheelhouse
|
||||
|
||||
- name: Test cibuildwheel
|
||||
- name: Run tests with 'CIBW_PLATFORM' set to 'pyodide'
|
||||
run: |
|
||||
python ./bin/run_tests.py --run-podman
|
||||
|
||||
test-emulated:
|
||||
name: Test emulated cibuildwheel using qemu
|
||||
needs: lint
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install ".[test]"
|
||||
|
||||
- name: Set up QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: all
|
||||
|
||||
- name: Run the emulation tests
|
||||
run: |
|
||||
pytest --run-emulation test/test_emulation.py
|
||||
python ./bin/run_tests.py
|
||||
env:
|
||||
CIBW_PLATFORM: pyodide
|
||||
|
||||
@@ -18,13 +18,13 @@ jobs:
|
||||
update-dependencies:
|
||||
name: Update dependencies
|
||||
if: github.repository_owner == 'pypa' || github.event_name != 'schedule'
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: wntrblm/nox@2023.04.22
|
||||
- uses: wntrblm/nox@2024.04.15
|
||||
with:
|
||||
python-versions: "3.7, 3.8, 3.9, 3.10, 3.11, 3.12-dev"
|
||||
python-versions: "3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13"
|
||||
|
||||
- name: "Run update: dependencies"
|
||||
run: nox --force-color -s update_constraints
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
|
||||
- name: Create Pull Request
|
||||
if: github.ref == 'refs/heads/main' && github.repository == 'pypa/cibuildwheel'
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
commit-message: Update dependencies
|
||||
title: '[Bot] Update dependencies'
|
||||
|
||||
+13
-3
@@ -1,5 +1,5 @@
|
||||
linux:
|
||||
image: python:3.8
|
||||
image: python:3.12
|
||||
services:
|
||||
- name: docker:dind
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
@@ -23,9 +23,19 @@ windows:
|
||||
variables:
|
||||
PYTEST_ADDOPTS: -k "unit_test or test_0_basic" --suppress-no-test-exit-code
|
||||
before_script:
|
||||
- choco install python -y --version 3.8.6
|
||||
- choco install python -y --version 3.12.4
|
||||
script:
|
||||
- py -m pip install -e ".[dev]" pytest-custom-exit-code
|
||||
- py bin\run_tests.py
|
||||
tags:
|
||||
- windows
|
||||
- saas-windows-medium-amd64
|
||||
|
||||
macos:
|
||||
image: macos-14-xcode-15
|
||||
variables:
|
||||
PYTEST_ADDOPTS: -k "unit_test or test_0_basic" --suppress-no-test-exit-code
|
||||
script:
|
||||
- python3 -m pip install -e ".[dev]" pytest-custom-exit-code
|
||||
- python3 ./bin/run_tests.py
|
||||
tags:
|
||||
- saas-macos-medium-m1
|
||||
|
||||
+30
-21
@@ -1,7 +1,7 @@
|
||||
repos:
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: check-case-conflict
|
||||
- id: check-merge-conflict
|
||||
@@ -13,31 +13,22 @@ repos:
|
||||
- id: mixed-line-ending
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 23.9.1
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.0.288
|
||||
rev: v0.5.5
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: ["--fix", "--show-fixes"]
|
||||
|
||||
- repo: https://github.com/asottile/setup-cfg-fmt
|
||||
rev: v2.4.0
|
||||
hooks:
|
||||
- id: setup-cfg-fmt
|
||||
args: [--include-version-classifiers, --min-py-version=3.8, --max-py-version=3.11]
|
||||
- id: ruff-format
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.5.1
|
||||
rev: v1.11.0
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy 3.8 on cibuildwheel/
|
||||
exclude: ^cibuildwheel/resources/.*py$
|
||||
exclude: ^cibuildwheel/resources/.*py|bin/generate_schema.py$
|
||||
args: ["--python-version=3.8"]
|
||||
additional_dependencies: &mypy-dependencies
|
||||
- bracex
|
||||
- nox
|
||||
- packaging
|
||||
- pygithub
|
||||
@@ -49,15 +40,16 @@ repos:
|
||||
- types-jinja2
|
||||
- types-pyyaml
|
||||
- types-requests
|
||||
- bracex
|
||||
- uv
|
||||
- validate-pyproject
|
||||
- id: mypy
|
||||
name: mypy 3.11
|
||||
name: mypy 3.12
|
||||
exclude: ^cibuildwheel/resources/.*py$
|
||||
args: ["--python-version=3.11"]
|
||||
args: ["--python-version=3.12"]
|
||||
additional_dependencies: *mypy-dependencies
|
||||
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.9.0.5
|
||||
rev: v0.10.0.1
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
|
||||
@@ -77,8 +69,25 @@ repos:
|
||||
files: ^docs/changelog.md$
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.5
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
args: ["-L", "sur"]
|
||||
args: ["-L", "sur,assertin", "-w"]
|
||||
exclude: ^docs/working-examples\.md$ # Autogenerated
|
||||
|
||||
|
||||
- repo: https://github.com/python-jsonschema/check-jsonschema
|
||||
rev: 0.29.1
|
||||
hooks:
|
||||
- id: check-dependabot
|
||||
- id: check-github-actions
|
||||
- id: check-github-workflows
|
||||
- id: check-gitlab-ci
|
||||
- id: check-readthedocs
|
||||
- id: check-travis
|
||||
- id: check-jsonschema
|
||||
name: Check projects
|
||||
args: [--schemafile, docs/data/projects.schema.json]
|
||||
files: '^docs/data/projects.yml$'
|
||||
- id: check-metaschema
|
||||
files: '^docs/data/projects.schema.json$'
|
||||
|
||||
+8
-11
@@ -5,14 +5,11 @@ version: 2
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
|
||||
python:
|
||||
install:
|
||||
- method: pip
|
||||
path: .
|
||||
extra_requirements:
|
||||
- docs
|
||||
|
||||
mkdocs:
|
||||
configuration: mkdocs.yml
|
||||
python: "3.12"
|
||||
commands:
|
||||
- asdf plugin add uv
|
||||
- asdf install uv latest
|
||||
- asdf global uv latest
|
||||
- uv venv
|
||||
- uv pip install -e.[docs]
|
||||
- NO_COLOR=1 .venv/bin/mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html
|
||||
|
||||
+1
-1
@@ -56,5 +56,5 @@ script: |
|
||||
(while true; do echo "travis_keep_alive"; sleep 300; done) &
|
||||
SPINNER_PID=$!
|
||||
disown
|
||||
$PYTHON ./bin/run_tests.py
|
||||
$PYTHON ./bin/run_tests.py --num-processes 2
|
||||
kill -9 ${SPINNER_PID}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
This is a summary of the Python versions and platforms covered by the different CI platforms:
|
||||
This is a summary of the host Python versions and platforms covered by the different CI platforms:
|
||||
|
||||
| | 3.8 | 3.9 | 3.10 | 3.11 |
|
||||
|---------|--------------------------------------------------------|-----------------------|-----------|----------------|
|
||||
| Linux | AppVeyor¹ / Azure Pipelines / GitLab¹ / GitHub Actions | CircleCI¹ / Travis CI | Cirrus CI | GitHub Actions |
|
||||
| macOS | AppVeyor¹ / Azure Pipelines | CircleCI¹ / Travis CI | Cirrus CI | GitHub Actions |
|
||||
| Windows | AppVeyor¹ / Azure Pipelines / GitLab¹ | Travis CI | Cirrus CI | GitHub Actions |
|
||||
| | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 |
|
||||
|---------|----------------------------------------------|-----------|-----------|---------|--------------------------------------|
|
||||
| Linux | AppVeyor¹ / Azure Pipelines / GitHub Actions | Travis CI | Cirrus CI | | CircleCI¹ / GitHub Actions / GitLab¹ |
|
||||
| macOS | AppVeyor¹ / Azure Pipelines | | Cirrus CI | GitLab¹ | CircleCI¹ / GitHub Actions |
|
||||
| Windows | AppVeyor¹ / Azure Pipelines | Travis CI | Cirrus CI | | GitHub Actions / GitLab¹ |
|
||||
|
||||
> ¹ Runs a reduced set of tests to reduce CI load
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
This project is licensed under the 'BSD 2-clause license'.
|
||||
|
||||
Copyright (c) 2017-2019, Joe Rickerby and contributors. All rights reserved.
|
||||
Copyright (c) 2017-2023, Joe Rickerby and contributors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
recursive-include cibuildwheel *.cfg
|
||||
recursive-include cibuildwheel *.in
|
||||
recursive-include cibuildwheel *.py
|
||||
recursive-include cibuildwheel *.toml
|
||||
recursive-include cibuildwheel *.txt
|
||||
recursive-include cibuildwheel *.typed
|
||||
@@ -2,16 +2,15 @@ cibuildwheel
|
||||
============
|
||||
|
||||
[](https://pypi.python.org/pypi/cibuildwheel)
|
||||
[](https://cibuildwheel.readthedocs.io/en/stable/?badge=stable)
|
||||
[](https://cibuildwheel.pypa.io/en/stable/?badge=stable)
|
||||
[](https://github.com/pypa/cibuildwheel/actions)
|
||||
[](https://travis-ci.com/pypa/cibuildwheel)
|
||||
[](https://ci.appveyor.com/project/joerick/cibuildwheel/branch/main)
|
||||
[](https://circleci.com/gh/pypa/cibuildwheel)
|
||||
[](https://dev.azure.com/joerick0429/cibuildwheel/_build/latest?definitionId=4&branchName=main)
|
||||
[](https://cirrus-ci.com/github/pypa/cibuildwheel)
|
||||
|
||||
|
||||
[Documentation](https://cibuildwheel.readthedocs.org)
|
||||
[Documentation](https://cibuildwheel.pypa.io)
|
||||
|
||||
<!--intro-start-->
|
||||
|
||||
@@ -23,32 +22,32 @@ Python wheels are great. Building them across **Mac, Linux, Windows**, on **mult
|
||||
What does it do?
|
||||
----------------
|
||||
|
||||
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x |
|
||||
|----------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|
|
||||
| CPython 3.6 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| CPython 3.7 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅³ | ✅ | ✅ | ✅ | ✅ |
|
||||
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| CPython 3.12⁵ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| PyPy 3.7 v7.3 | ✅ | N/A | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
|
||||
| PyPy 3.8 v7.3 | ✅ | ✅⁴ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
|
||||
| PyPy 3.9 v7.3 | ✅ | ✅⁴ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
|
||||
| PyPy 3.10 v7.3 | ✅ | ✅⁴ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
|
||||
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x | Pyodide |
|
||||
|----------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|-----|
|
||||
| CPython 3.6 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
|
||||
| CPython 3.7 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
|
||||
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
|
||||
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
|
||||
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
|
||||
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
|
||||
| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁴ |
|
||||
| CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
|
||||
| PyPy 3.7 v7.3 | ✅ | N/A | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A |
|
||||
| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A |
|
||||
| PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A |
|
||||
| PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A |
|
||||
|
||||
<sup>¹ PyPy is only supported for manylinux wheels.</sup><br>
|
||||
<sup>² Windows arm64 support is experimental.</sup><br>
|
||||
<sup>³ Alpine 3.14 and very briefly 3.15's default python3 [was not able to load](https://github.com/pypa/cibuildwheel/issues/934) musllinux wheels. This has been fixed; please upgrade the python package if using Alpine from before the fix.</sup><br>
|
||||
<sup>⁴ Cross-compilation not supported with PyPy - to build these wheels you need to run cibuildwheel on an Apple Silicon machine.</sup><br>
|
||||
<sup>⁵ CPython 3.12 is built by default using Python RCs, starting with cibuildwheel 2.15.</sup><br>
|
||||
<sup>³ CPython 3.13 is built by default using Python RCs, starting with cibuildwheel 2.20. Free-threaded mode will still require opt-in using [`CIBW_FREE_THREADED_SUPPORT`](https://cibuildwheel.pypa.io/en/stable/options/#free-threaded-support).</sup><br>
|
||||
<sup>⁴ Experimental, not yet supported on PyPI, but can be used directly in web deployment. Use `--platform pyodide` to build.</sup><br>
|
||||
|
||||
- Builds manylinux, musllinux, macOS 10.9+, and Windows wheels for CPython and PyPy
|
||||
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, 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
|
||||
|
||||
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) if you need to build unsupported versions of Python, such as Python 2.
|
||||
See the [cibuildwheel 1 documentation](https://cibuildwheel.pypa.io/en/1.x/) if you need to build unsupported versions of Python, such as Python 2.
|
||||
|
||||
Usage
|
||||
-----
|
||||
@@ -57,18 +56,16 @@ Usage
|
||||
|
||||
| | Linux | macOS | Windows | Linux ARM | macOS ARM | Windows ARM |
|
||||
|-----------------|-------|-------|---------|-----------|-----------|-------------|
|
||||
| GitHub Actions | ✅ | ✅ | ✅ | ✅¹ | ✅² | ✅⁴ |
|
||||
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅² | ✅⁴ |
|
||||
| GitHub Actions | ✅ | ✅ | ✅ | ✅¹ | ✅ | ✅² |
|
||||
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅ | ✅² |
|
||||
| Travis CI | ✅ | | ✅ | ✅ | | |
|
||||
| AppVeyor | ✅ | ✅ | ✅ | | ✅² | ✅⁴ |
|
||||
| CircleCI | ✅ | ✅ | | ✅ | ✅² | |
|
||||
| Gitlab CI | ✅ | | ✅ | ✅¹ | | |
|
||||
| Cirrus CI | ✅ | ✅³ | ✅ | ✅ | ✅ | |
|
||||
| AppVeyor | ✅ | ✅ | ✅ | | ✅ | ✅² |
|
||||
| CircleCI | ✅ | ✅ | | ✅ | ✅ | |
|
||||
| Gitlab CI | ✅ | ✅ | ✅ | ✅¹ | ✅ | |
|
||||
| Cirrus CI | ✅ | ✅ | ✅ | ✅ | ✅ | |
|
||||
|
||||
<sup>¹ [Requires emulation](https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation), distributed separately. Other services may also support Linux ARM through emulation or third-party build hosts, but these are not tested in our CI.</sup><br>
|
||||
<sup>² [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). It is not possible to test `arm64` and the `arm64` part of a `universal2` wheel on this CI platform.</sup><br>
|
||||
<sup>³ [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). Thanks to Rosetta 2 emulation, it is possible to test `x86_64` and both parts of a `universal2` wheel on this CI platform.</sup><br>
|
||||
<sup>⁴ [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#windows-arm64). It is not possible to test `arm64` on this CI platform.</sup>
|
||||
<sup>¹ [Requires emulation](https://cibuildwheel.pypa.io/en/stable/faq/#emulation), distributed separately. Other services may also support Linux ARM through emulation or third-party build hosts, but these are not tested in our CI.</sup><br>
|
||||
<sup>² [Uses cross-compilation](https://cibuildwheel.pypa.io/en/stable/faq/#windows-arm64). It is not possible to test `arm64` on this CI platform.</sup>
|
||||
|
||||
<!--intro-end-->
|
||||
|
||||
@@ -88,16 +85,16 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macOS-11]
|
||||
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Used to host cibuildwheel
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: actions/setup-python@v5
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: python -m pip install cibuildwheel==2.16.0
|
||||
run: python -m pip install cibuildwheel==2.20.0
|
||||
|
||||
- name: Build wheels
|
||||
run: python -m cibuildwheel --output-dir wheelhouse
|
||||
@@ -105,12 +102,13 @@ jobs:
|
||||
# env:
|
||||
# CIBW_SOME_OPTION: value
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
```
|
||||
|
||||
For more information, including PyPI deployment, and the use of other CI services or the dedicated GitHub Action, check out the [documentation](https://cibuildwheel.readthedocs.org) and the [examples](https://github.com/pypa/cibuildwheel/tree/main/examples).
|
||||
For more information, including PyPI deployment, and the use of other CI services or the dedicated GitHub Action, check out the [documentation](https://cibuildwheel.pypa.io) and the [examples](https://github.com/pypa/cibuildwheel/tree/main/examples).
|
||||
|
||||
How it works
|
||||
------------
|
||||
@@ -119,35 +117,35 @@ 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.readthedocs.io/en/stable/#how-it-works).</sup>
|
||||
<sup>Explore an interactive version of this diagram [in the docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works).</sup>
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
| | Option | Description |
|
||||
|---|--------|-------------|
|
||||
| **Build selection** | [`CIBW_PLATFORM`](https://cibuildwheel.readthedocs.io/en/stable/options/#platform) | Override the auto-detected target platform |
|
||||
| | [`CIBW_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) <br> [`CIBW_SKIP`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) | Choose the Python versions to build |
|
||||
| | [`CIBW_ARCHS`](https://cibuildwheel.readthedocs.io/en/stable/options/#archs) | Change the architectures built on your machine by default. |
|
||||
| | [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.readthedocs.io/en/stable/options/#requires-python) | Manually set the Python compatibility of your project |
|
||||
| | [`CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons) | Enable building with pre-release versions of Python if available |
|
||||
| **Build customization** | [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-frontend) | Set the tool to use to build, either "pip" (default for now) or "build" |
|
||||
| | [`CIBW_ENVIRONMENT`](https://cibuildwheel.readthedocs.io/en/stable/options/#environment) | Set environment variables needed during the build |
|
||||
| | [`CIBW_ENVIRONMENT_PASS_LINUX`](https://cibuildwheel.readthedocs.io/en/stable/options/#environment-pass) | Set environment variables on the host to pass-through to the container during the build. |
|
||||
| | [`CIBW_BEFORE_ALL`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. |
|
||||
| | [`CIBW_BEFORE_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build |
|
||||
| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each built wheel |
|
||||
| | [`CIBW_MANYLINUX_*_IMAGE`<br/>`CIBW_MUSLLINUX_*_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image) | Specify alternative manylinux / musllinux Docker images |
|
||||
| | [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.readthedocs.io/en/stable/options/#container-engine) | Specify which container engine to use when building Linux wheels |
|
||||
| | [`CIBW_DEPENDENCY_VERSIONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#dependency-versions) | Specify how cibuildwheel controls the versions of the tools it uses |
|
||||
| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel |
|
||||
| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel |
|
||||
| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests |
|
||||
| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require |
|
||||
| | [`CIBW_TEST_SKIP`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-skip) | Skip running tests on some builds |
|
||||
| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel |
|
||||
| **Build selection** | [`CIBW_PLATFORM`](https://cibuildwheel.pypa.io/en/stable/options/#platform) | Override the auto-detected target platform |
|
||||
| | [`CIBW_BUILD`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) <br> [`CIBW_SKIP`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) | Choose the Python versions to build |
|
||||
| | [`CIBW_ARCHS`](https://cibuildwheel.pypa.io/en/stable/options/#archs) | Change the architectures built on your machine by default. |
|
||||
| | [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.pypa.io/en/stable/options/#requires-python) | Manually set the Python compatibility of your project |
|
||||
| | [`CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons) | Enable building with pre-release versions of Python if available |
|
||||
| **Build customization** | [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) | Set the tool to use to build, either "pip" (default for now) or "build" |
|
||||
| | [`CIBW_ENVIRONMENT`](https://cibuildwheel.pypa.io/en/stable/options/#environment) | Set environment variables needed during the build |
|
||||
| | [`CIBW_ENVIRONMENT_PASS_LINUX`](https://cibuildwheel.pypa.io/en/stable/options/#environment-pass) | Set environment variables on the host to pass-through to the container during the build. |
|
||||
| | [`CIBW_BEFORE_ALL`](https://cibuildwheel.pypa.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. |
|
||||
| | [`CIBW_BEFORE_BUILD`](https://cibuildwheel.pypa.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build |
|
||||
| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each built wheel |
|
||||
| | [`CIBW_MANYLINUX_*_IMAGE`<br/>`CIBW_MUSLLINUX_*_IMAGE`](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) | Specify alternative manylinux / musllinux Docker images |
|
||||
| | [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) | Specify which container engine to use when building Linux wheels |
|
||||
| | [`CIBW_DEPENDENCY_VERSIONS`](https://cibuildwheel.pypa.io/en/stable/options/#dependency-versions) | Specify how cibuildwheel controls the versions of the tools it uses |
|
||||
| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.pypa.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel |
|
||||
| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.pypa.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel |
|
||||
| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.pypa.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests |
|
||||
| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.pypa.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require |
|
||||
| | [`CIBW_TEST_SKIP`](https://cibuildwheel.pypa.io/en/stable/options/#test-skip) | Skip running tests on some builds |
|
||||
| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.pypa.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel |
|
||||
|
||||
These options can be specified in a pyproject.toml file, as well; see [configuration](https://cibuildwheel.readthedocs.io/en/stable/options/#configuration).
|
||||
These options can be specified in a pyproject.toml file, as well; see [configuration](https://cibuildwheel.pypa.io/en/stable/options/#configuration).
|
||||
|
||||
Working examples
|
||||
----------------
|
||||
@@ -164,23 +162,23 @@ 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. |
|
||||
| [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 |
|
||||
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
|
||||
| [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 |
|
||||
| [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. |
|
||||
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
|
||||
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
|
||||
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an in-process SQL OLAP Database Management System |
|
||||
|
||||
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
|
||||
[pytorch-fairseq]: https://github.com/pytorch/fairseq
|
||||
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
|
||||
[NumPy]: https://github.com/numpy/numpy
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
[NCNN]: https://github.com/Tencent/ncnn
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
|
||||
[Kivy]: https://github.com/kivy/kivy
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
|
||||
[appveyor icon]: docs/data/readme_icons/appveyor.svg
|
||||
[github icon]: docs/data/readme_icons/github.svg
|
||||
@@ -195,7 +193,7 @@ Here are some repos that use cibuildwheel.
|
||||
|
||||
<!-- END bin/projects.py -->
|
||||
|
||||
> ℹ️ That's just a handful, there are many more! Check out the [Working Examples](https://cibuildwheel.readthedocs.io/en/stable/working-examples) page in the docs.
|
||||
> ℹ️ That's just a handful, there are many more! Check out the [Working Examples](https://cibuildwheel.pypa.io/en/stable/working-examples) page in the docs.
|
||||
|
||||
Legal note
|
||||
----------
|
||||
@@ -213,47 +211,65 @@ Changelog
|
||||
|
||||
<!-- this section was generated by bin/update_readme_changelog.py -- do not edit manually -->
|
||||
|
||||
### v2.16.0
|
||||
### v2.20.0
|
||||
|
||||
_18 September 2023_
|
||||
- 🌟 CPython 3.13 wheels are now built by default - without the `CIBW_PRERELEASE_PYTHONS` flag. It's time to build and upload these wheels to PyPI! This release includes CPython 3.13.0rc1, which is guaranteed to be ABI compatible with the final release. Free-threading is still behind a flag/config option. (#1950)
|
||||
- ✨ Provide a `CIBW_ALLOW_EMPTY` environment variable as an alternative to the command line flag. (#1937)
|
||||
- 🐛 Don't use uv on PyPy3.8 on Windows, it stopped working starting in 0.2.25. Note that PyPy 3.8 is EoL. (#1868)
|
||||
- 🛠 Set the `VSCMD_ARG_TGT_ARCH` variable based on target arch. (#1876)
|
||||
- 🛠 Undo cleaner output on pytest 8-8.2 now that 8.3 is out. (#1943)
|
||||
- 📚 Update examples to use Python 3.12 on host (cibuildwheel will require Python 3.11+ on the host machine starting in October 2024) (#1919)
|
||||
|
||||
- ✨ Add the ability to pass additional flags to a build frontend through the [CIBW_BUILD_FRONTEND](https://cibuildwheel.readthedocs.io/en/stable/options/#build-frontend) option (#1588).
|
||||
- ✨ The environment variable SOURCE_DATE_EPOCH is now automatically passed through to container Linux builds (useful for [reproducible builds](https://reproducible-builds.org/docs/source-date-epoch/)!) (#1589)
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0rc2 (#1604)
|
||||
- 🐛 Fix `requires_python` auto-detection from setup.py when the call to `setup()` is within an `if __name__ == "__main__" block (#1613)
|
||||
- 🐛 Fix a bug that prevented building Linux wheels in Docker on a Windows host (#1573)
|
||||
- 🐛 `--only` can now select prerelease-pythons (#1564)
|
||||
- 📚 Docs & examples updates (#1582, #1593, #1598, #1615)
|
||||
|
||||
### v2.15.0
|
||||
### v2.19.2
|
||||
|
||||
_8 August 2023_
|
||||
- 🐛 Update manylinux2014 pins to versions that support past-EoL CentOS 7 mirrors. (#1917)
|
||||
- 🐛 Support `--no-isolation` with `build[uv]` build-frontend. (#1889)
|
||||
- 🛠 Provide attestations for releases at <https://github.com/pypa/cibuildwheel/attestations>. (#1916)
|
||||
- 🛠 Provide CPython 3.13.0b3. (#1913)
|
||||
- 🛠 Remove some workarounds now that pip 21.1 is available. (#1891, #1892)
|
||||
- 📚 Remove nosetest from our docs. (#1821)
|
||||
- 📚 Document the macOS ARM workaround for 3.8 on GHA. (#1871)
|
||||
- 📚 GitLab CI + macOS is now a supported platform with an example. (#1911)
|
||||
|
||||
- 🌟 CPython 3.12 wheels are now built by default - without the CIBW_PRERELEASE_PYTHONS flag. It's time to build and upload these wheels to PyPI! This release includes CPython 3.12.0rc1, which is guaranteed to be ABI compatible with the final release. (#1565)
|
||||
- ✨ Adds musllinux_1_2 support - this allows packagers to build for musl-based Linux distributions on a more recent Alpine image, and a newer musl libc. (#1561)
|
||||
|
||||
### v2.14.1
|
||||
### v2.19.1
|
||||
|
||||
_15 July 2023_
|
||||
- 🐛 Don't require setup-python on GHA for Pyodide (#1868)
|
||||
- 🐛 Specify full python path for uv (fixes issue in 0.2.10 & 0.2.11) (#1881)
|
||||
- 🛠 Update for pip 24.1b2 on CPython 3.13. (#1879)
|
||||
- 🛠 Fix a warning in our schema generation script. (#1866)
|
||||
- 🛠 Cleaner output on pytest 8-8.2. (#1865)
|
||||
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0b4 (#1550)
|
||||
|
||||
### v2.14.0
|
||||
### v2.19.0
|
||||
|
||||
_10 July 2023_
|
||||
See the [release post](https://iscinumpy.dev/post/cibuildwheel-2-19-0/) for more info on new features!
|
||||
|
||||
- ✨ Adds support for building PyPy 3.10 wheels. (#1525)
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0b3.
|
||||
- ✨ Allow the use of the `{wheel}` placeholder in CIBW_TEST_COMMAND (#1533)
|
||||
- 📚 Docs & examples updates (#1532, #1416)
|
||||
- ⚠️ Removed support for running cibuildwheel in Python 3.7. Python 3.7 is EOL. However, cibuildwheel continues to build Python 3.7 wheels for the moment. (#1175)
|
||||
- 🌟 Add Pyodide platform. Set with `--platform pyodide` or `CIBW_PLATFORM: pyodide` on Linux with a host Python 3.12 to build WebAssembly wheels. Not accepted on PyPI currently, but usable directly in a website using Pyodide, for live docs, etc. (#1456, #1859)
|
||||
- 🌟 Add `build[uv]` backend, which will take a pre-existing uv install (or install `cibuildwheel[uv]`) and use `uv` for all environment setup and installs on Python 3.8+. This is significantly faster in most cases. (#1856)
|
||||
- ✨ Add free-threaded macOS builds and update CPython to 3.13.0b2. (#1854)
|
||||
- 🐛 Issue copying a wheel to a non-existent output dir fixed. (#1851, #1862)
|
||||
- 🐛 Better determinism for the test environment seeding. (#1835)
|
||||
- 🛠 `VIRTUAL_ENV` variable now set. (#1842)
|
||||
- 🛠 Remove a pip<21.3 workaround. (#1842)
|
||||
- 🛠 Error handling was refactored to use exceptions. (#1719)
|
||||
- 🛠 Hardcoded paths in tests avoided. (#1834)
|
||||
- 🛠 Single Python tests made more generic. (#1835)
|
||||
- 🛠 Sped up our ci by splitting up emulation tests. (#1839)
|
||||
|
||||
### v2.13.1
|
||||
|
||||
_10 June 2023_
|
||||
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0b2. (#1516)
|
||||
- 🛠 Adds a moving `v<major>.<minor>` tag for use in GitHub Actions workflow files. If you use this, you'll get the latest patch release within a minor version. Additionally, Dependabot won't send you PRs for patch releases. (#1517)
|
||||
### v2.18.1
|
||||
|
||||
- 🌟 Add free-threaded Linux and Windows builds for 3.13. New identifiers `cp313t-*`, new option `CIBW_FREE_THREADED_SUPPORT`/`tool.cibuildwheel.free-threaded-support` required to opt-in. [See the docs](https://cibuildwheel.pypa.io/en/stable/options/#free-threaded-support) for more information. (#1831)
|
||||
- ✨ The `container-engine` is now a build (non-global) option. (#1792)
|
||||
- 🛠 The build backend for cibuildwheel is now hatchling. (#1297)
|
||||
- 🛠 Significant improvements and modernization to our noxfile. (#1823)
|
||||
- 🛠 Use pylint's new GitHub Actions reporter instead of a custom matcher. (#1823)
|
||||
- 🛠 Unpin virtualenv updates for Python 3.7+ (#1830)
|
||||
- 🐛 Fix running linux tests from Windows or macOS ARM. (#1788)
|
||||
- 📚 Fix our documentation build. (#1821)
|
||||
|
||||
<!-- END bin/update_readme_changelog.py -->
|
||||
|
||||
@@ -261,14 +277,14 @@ _10 June 2023_
|
||||
|
||||
That's the last few versions.
|
||||
|
||||
ℹ️ **Want more changelog? Head over to [the changelog page in the docs](https://cibuildwheel.readthedocs.io/en/stable/changelog/).**
|
||||
ℹ️ **Want more changelog? Head over to [the changelog page in the docs](https://cibuildwheel.pypa.io/en/stable/changelog/).**
|
||||
|
||||
---
|
||||
|
||||
Contributing
|
||||
============
|
||||
|
||||
For more info on how to contribute to cibuildwheel, see the [docs](https://cibuildwheel.readthedocs.io/en/latest/contributing/).
|
||||
For more info on how to contribute to cibuildwheel, see the [docs](https://cibuildwheel.pypa.io/en/latest/contributing/).
|
||||
|
||||
Everyone interacting with the cibuildwheel project via codebase, issue tracker, chat rooms, or otherwise is expected to follow the [PSF Code of Conduct](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
@@ -303,4 +319,4 @@ See also
|
||||
|
||||
Another very similar tool to consider is [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild). `multibuild` is a shell script toolbox for building a wheel on various platforms. It is used as a basis to build some of the big data science tools, like SciPy.
|
||||
|
||||
If you are building Rust wheels, you can get by without some of the tricks required to make GLIBC work via manylinux; this is especially relevant for cross-compiling, which is easy with Rust. See [maturin-action](https://github.com/messense/maturin-action) for a tool that is optimized for building Rust wheels and cross-compiling.
|
||||
If you are building Rust wheels, you can get by without some of the tricks required to make GLIBC work via manylinux; this is especially relevant for cross-compiling, which is easy with Rust. See [maturin-action](https://github.com/PyO3/maturin-action) for a tool that is optimized for building Rust wheels and cross-compiling.
|
||||
|
||||
+50
-17
@@ -24,36 +24,69 @@ branding:
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# Set up a non-EOL, cibuildwheel & pipx supported Python version
|
||||
- uses: actions/setup-python@v4
|
||||
# Set up the version of Python that supports pyodide
|
||||
- uses: actions/setup-python@v5
|
||||
id: python
|
||||
with:
|
||||
python-version: "3.8 - 3.11"
|
||||
python-version: "3.12"
|
||||
update-environment: false
|
||||
|
||||
- id: cibw
|
||||
run: |
|
||||
# Install cibuildwheel
|
||||
"${{ steps.python.outputs.python-path }}" -u << "EOF"
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import venv
|
||||
|
||||
from pathlib import Path
|
||||
from subprocess import run
|
||||
|
||||
|
||||
class EnvBuilder(venv.EnvBuilder):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def setup_scripts(self, context):
|
||||
pass
|
||||
|
||||
def post_setup(self, context):
|
||||
super().post_setup(context)
|
||||
self.bin_path = Path(context.env_exe).parent
|
||||
run([sys.executable, "-m", "pip", "--python", context.env_exe, "install", r"${{ github.action_path }}"], check=True)
|
||||
|
||||
|
||||
print("::group::Install cibuildwheel")
|
||||
venv_path = Path(r"${{ runner.temp }}") / "cibw"
|
||||
if venv_path.exists():
|
||||
shutil.rmtree(venv_path)
|
||||
builder = EnvBuilder()
|
||||
builder.create(venv_path)
|
||||
cibw_path = [path for path in builder.bin_path.glob("cibuildwheel*") if path.stem == "cibuildwheel"][0]
|
||||
with open(os.environ["GITHUB_OUTPUT"], "at") as f:
|
||||
f.write(f"cibw-path={cibw_path}\n")
|
||||
print("::endgroup::")
|
||||
EOF
|
||||
shell: bash
|
||||
|
||||
# Redirecting stderr to stdout to fix interleaving issue in Actions.
|
||||
- run: >
|
||||
pipx run
|
||||
--python '${{ steps.python.outputs.python-path }}'
|
||||
--spec '${{ github.action_path }}'
|
||||
cibuildwheel
|
||||
"${{ steps.cibw.outputs.cibw-path }}"
|
||||
"${{ inputs.package-dir }}"
|
||||
--output-dir "${{ inputs.output-dir }}"
|
||||
--config-file "${{ inputs.config-file }}"
|
||||
--only "${{ inputs.only }}"
|
||||
${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}}
|
||||
${{ inputs.config-file != '' && format('--config-file "{0}"', inputs.config-file) || ''}}
|
||||
${{ inputs.only != '' && format('--only "{0}"', inputs.only) || ''}}
|
||||
2>&1
|
||||
shell: bash
|
||||
if: runner.os != 'Windows'
|
||||
|
||||
# Windows needs powershell to interact nicely with Meson
|
||||
- run: >
|
||||
pipx run
|
||||
--python "${{ steps.python.outputs.python-path }}"
|
||||
--spec "${{ github.action_path }}"
|
||||
cibuildwheel
|
||||
& "${{ steps.cibw.outputs.cibw-path }}"
|
||||
"${{ inputs.package-dir }}"
|
||||
--output-dir '"${{ inputs.output-dir }}"'
|
||||
--config-file '"${{ inputs.config-file }}"'
|
||||
--only '"${{ inputs.only }}"'
|
||||
${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}}
|
||||
${{ inputs.config-file != '' && format('--config-file "{0}"', inputs.config-file) || ''}}
|
||||
${{ inputs.only != '' && format('--only "{0}"', inputs.only) || ''}}
|
||||
shell: pwsh
|
||||
if: runner.os == 'Windows'
|
||||
|
||||
+2
-2
@@ -17,14 +17,14 @@ jobs:
|
||||
python ./bin/run_tests.py
|
||||
|
||||
- job: macos_38
|
||||
pool: {vmImage: 'macOS-11'}
|
||||
pool: {vmImage: 'macOS-12'}
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '3.8'
|
||||
- bash: |
|
||||
python -m pip install -e ".[dev]"
|
||||
python ./bin/run_tests.py
|
||||
python ./bin/run_tests.py --num-processes 2
|
||||
|
||||
- job: windows_38
|
||||
pool: {vmImage: 'windows-2019'}
|
||||
|
||||
+12
-4
@@ -1,5 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# /// script
|
||||
# dependencies = ["click", "packaging", "tomli; python_version<'3.11'"]
|
||||
# ///
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -13,10 +17,14 @@ from pathlib import Path
|
||||
import click
|
||||
from packaging.version import InvalidVersion, Version
|
||||
|
||||
import cibuildwheel
|
||||
if sys.version_info < (3, 11):
|
||||
import tomli as tomllib
|
||||
else:
|
||||
import tomllib
|
||||
|
||||
config = [
|
||||
# file path, version find/replace format
|
||||
("pyproject.toml", 'version = "{}"'),
|
||||
("README.md", "cibuildwheel=={}"),
|
||||
("cibuildwheel/__init__.py", '__version__ = "{}"'),
|
||||
("docs/faq.md", "cibuildwheel=={}"),
|
||||
@@ -24,7 +32,6 @@ config = [
|
||||
("docs/setup.md", "cibuildwheel=={}"),
|
||||
("examples/*", "cibuildwheel=={}"),
|
||||
("examples/*", "cibuildwheel@v{}"),
|
||||
("setup.cfg", "version = {}"),
|
||||
]
|
||||
|
||||
RED = "\u001b[31m"
|
||||
@@ -34,7 +41,8 @@ OFF = "\u001b[0m"
|
||||
|
||||
@click.command()
|
||||
def bump_version() -> None:
|
||||
current_version = cibuildwheel.__version__
|
||||
with open("pyproject.toml", "rb") as f:
|
||||
current_version = tomllib.load(f)["project"]["version"]
|
||||
|
||||
try:
|
||||
commit_date_str = subprocess.run(
|
||||
@@ -181,7 +189,7 @@ def bump_version() -> None:
|
||||
print()
|
||||
|
||||
print("Push the new version to GitHub with:")
|
||||
print(" git push && git push --tags")
|
||||
print(f" git push && git push origin v{new_version}")
|
||||
print()
|
||||
|
||||
release_url = "https://github.com/pypa/cibuildwheel/releases/new?" + urllib.parse.urlencode(
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
CIBW_PLATFORM=linux pytest "$@"
|
||||
Executable
+309
@@ -0,0 +1,309 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# /// script
|
||||
# dependencies = ["pyyaml"]
|
||||
# ///
|
||||
|
||||
import argparse
|
||||
import copy
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
import yaml
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--schemastore", action="store_true", help="Generate schema_store version")
|
||||
args = parser.parse_args()
|
||||
|
||||
starter = """
|
||||
$schema: http://json-schema.org/draft-07/schema
|
||||
$id: https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/resources/cibuildwheel.schema.json
|
||||
$defs:
|
||||
inherit:
|
||||
enum:
|
||||
- none
|
||||
- prepend
|
||||
- append
|
||||
default: none
|
||||
description: How to inherit the parent's value.
|
||||
additionalProperties: false
|
||||
description: cibuildwheel's settings.
|
||||
type: object
|
||||
properties:
|
||||
archs:
|
||||
description: Change the architectures built on your machine by default.
|
||||
type: string_array
|
||||
before-all:
|
||||
description: Execute a shell command on the build system before any wheels are built.
|
||||
type: string_array
|
||||
before-build:
|
||||
description: Execute a shell command preparing each wheel's build.
|
||||
type: string_array
|
||||
before-test:
|
||||
description: Execute a shell command before testing each wheel.
|
||||
type: string_array
|
||||
build:
|
||||
default: ['*']
|
||||
description: Choose the Python versions to build.
|
||||
type: string_array
|
||||
build-frontend:
|
||||
default: default
|
||||
description: Set the tool to use to build, either "pip" (default for now), "build", or "build[uv]"
|
||||
oneOf:
|
||||
- enum: [pip, build, "build[uv]", default]
|
||||
- type: string
|
||||
pattern: '^pip; ?args:'
|
||||
- type: string
|
||||
pattern: '^build; ?args:'
|
||||
- type: string
|
||||
pattern: '^build\\[uv\\]; ?args:'
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
required: [name]
|
||||
properties:
|
||||
name:
|
||||
enum: [pip, build, "build[uv]"]
|
||||
args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
build-verbosity:
|
||||
type: integer
|
||||
minimum: -3
|
||||
maximum: 3
|
||||
default: 0
|
||||
description: Increase/decrease the output of pip wheel.
|
||||
config-settings:
|
||||
description: Specify config-settings for the build backend.
|
||||
type: string_table_array
|
||||
container-engine:
|
||||
oneOf:
|
||||
- enum: [docker, podman]
|
||||
- type: string
|
||||
pattern: '^docker; ?(create_args|disable_host_mount):'
|
||||
- type: string
|
||||
pattern: '^podman; ?(create_args|disable_host_mount):'
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
required: [name]
|
||||
properties:
|
||||
name:
|
||||
enum: [docker, podman]
|
||||
create-args:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
disable-host-mount:
|
||||
type: boolean
|
||||
dependency-versions:
|
||||
default: pinned
|
||||
description: Specify how cibuildwheel controls the versions of the tools it uses
|
||||
type: string
|
||||
environment:
|
||||
description: Set environment variables needed during the build.
|
||||
type: string_table
|
||||
environment-pass:
|
||||
description: Set environment variables on the host to pass-through to the container
|
||||
during the build.
|
||||
type: string_array
|
||||
free-threaded-support:
|
||||
type: boolean
|
||||
default: false
|
||||
description: The project supports free-threaded builds of Python (PEP703)
|
||||
manylinux-aarch64-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
manylinux-i686-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
manylinux-ppc64le-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
manylinux-pypy_aarch64-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
manylinux-pypy_i686-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
manylinux-pypy_x86_64-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
manylinux-s390x-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
manylinux-x86_64-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
musllinux-aarch64-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
musllinux-i686-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
musllinux-ppc64le-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
musllinux-s390x-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
musllinux-x86_64-image:
|
||||
type: string
|
||||
description: Specify alternative manylinux / musllinux container images
|
||||
repair-wheel-command:
|
||||
type: string_array
|
||||
description: Execute a shell command to repair each built wheel.
|
||||
skip:
|
||||
description: Choose the Python versions to skip.
|
||||
type: string_array
|
||||
test-command:
|
||||
description: Execute a shell command to test each built wheel.
|
||||
type: string_array
|
||||
test-extras:
|
||||
description: Install your wheel for testing using `extras_require`
|
||||
type: string_array
|
||||
test-requires:
|
||||
description: Install Python dependencies before running the tests
|
||||
type: string_array
|
||||
test-skip:
|
||||
description: Skip running tests on some builds.
|
||||
type: string_array
|
||||
"""
|
||||
|
||||
schema = yaml.safe_load(starter)
|
||||
|
||||
string_array = yaml.safe_load(
|
||||
"""
|
||||
- type: string
|
||||
- type: array
|
||||
items:
|
||||
type: string
|
||||
"""
|
||||
)
|
||||
|
||||
string_table_array = yaml.safe_load(
|
||||
"""
|
||||
- type: string
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
patternProperties:
|
||||
.+:
|
||||
oneOf:
|
||||
- type: string
|
||||
- type: array
|
||||
items:
|
||||
type: string
|
||||
"""
|
||||
)
|
||||
|
||||
string_table = yaml.safe_load(
|
||||
"""
|
||||
- type: string
|
||||
- type: object
|
||||
additionalProperties: false
|
||||
patternProperties:
|
||||
.+:
|
||||
type: string
|
||||
"""
|
||||
)
|
||||
|
||||
for value in schema["properties"].values():
|
||||
match value:
|
||||
case {"type": "string_array"}:
|
||||
del value["type"]
|
||||
value["oneOf"] = string_array
|
||||
case {"type": "string_table"}:
|
||||
del value["type"]
|
||||
value["oneOf"] = string_table
|
||||
case {"type": "string_table_array"}:
|
||||
del value["type"]
|
||||
value["oneOf"] = string_table_array
|
||||
|
||||
overrides = yaml.safe_load(
|
||||
"""
|
||||
type: array
|
||||
description: An overrides array
|
||||
items:
|
||||
type: object
|
||||
required: ["select"]
|
||||
minProperties: 2
|
||||
additionalProperties: false
|
||||
properties:
|
||||
select: {}
|
||||
inherit:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
before-all: {"$ref": "#/$defs/inherit"}
|
||||
before-build: {"$ref": "#/$defs/inherit"}
|
||||
before-test: {"$ref": "#/$defs/inherit"}
|
||||
config-settings: {"$ref": "#/$defs/inherit"}
|
||||
container-engine: {"$ref": "#/$defs/inherit"}
|
||||
environment: {"$ref": "#/$defs/inherit"}
|
||||
environment-pass: {"$ref": "#/$defs/inherit"}
|
||||
repair-wheel-command: {"$ref": "#/$defs/inherit"}
|
||||
test-command: {"$ref": "#/$defs/inherit"}
|
||||
test-extras: {"$ref": "#/$defs/inherit"}
|
||||
test-requires: {"$ref": "#/$defs/inherit"}
|
||||
"""
|
||||
)
|
||||
|
||||
for key, value in schema["properties"].items():
|
||||
value["title"] = f'CIBW_{key.replace("-", "_").upper()}'
|
||||
|
||||
non_global_options = {k: {"$ref": f"#/properties/{k}"} for k in schema["properties"]}
|
||||
del non_global_options["build"]
|
||||
del non_global_options["skip"]
|
||||
del non_global_options["test-skip"]
|
||||
del non_global_options["free-threaded-support"]
|
||||
|
||||
overrides["items"]["properties"]["select"]["oneOf"] = string_array
|
||||
overrides["items"]["properties"] |= non_global_options.copy()
|
||||
|
||||
del overrides["items"]["properties"]["archs"]
|
||||
|
||||
not_linux = non_global_options.copy()
|
||||
|
||||
del not_linux["environment-pass"]
|
||||
del not_linux["container-engine"]
|
||||
for key in list(not_linux):
|
||||
if "linux-" in key:
|
||||
del not_linux[key]
|
||||
|
||||
|
||||
def as_object(d: dict[str, Any]) -> dict[str, Any]:
|
||||
return {
|
||||
"type": "object",
|
||||
"additionalProperties": False,
|
||||
"properties": copy.deepcopy(d),
|
||||
}
|
||||
|
||||
|
||||
oses = {
|
||||
"linux": as_object(non_global_options),
|
||||
"windows": as_object(not_linux),
|
||||
"macos": as_object(not_linux),
|
||||
"pyodide": as_object(not_linux),
|
||||
}
|
||||
|
||||
oses["linux"]["properties"]["repair-wheel-command"] = {
|
||||
**schema["properties"]["repair-wheel-command"],
|
||||
"default": "auditwheel repair -w {dest_dir} {wheel}",
|
||||
}
|
||||
oses["macos"]["properties"]["repair-wheel-command"] = {
|
||||
**schema["properties"]["repair-wheel-command"],
|
||||
"default": "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
|
||||
}
|
||||
|
||||
del oses["linux"]["properties"]["dependency-versions"]
|
||||
|
||||
schema["properties"]["overrides"] = overrides
|
||||
schema["properties"] |= oses
|
||||
|
||||
if args.schemastore:
|
||||
schema["$id"] = "https://json.schemastore.org/partial-cibuildwheel.json"
|
||||
schema["$schema"] = "http://json-schema.org/draft-07/schema#"
|
||||
schema["description"] = (
|
||||
"cibuildwheel's toml file, generated with ./bin/generate_schema.py --schemastore from cibuildwheel."
|
||||
)
|
||||
|
||||
print(json.dumps(schema, indent=2))
|
||||
@@ -11,7 +11,6 @@ This will cache the results to all_known_setup.yaml; you can reprint
|
||||
the results without the `--online` setting.
|
||||
"""
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# /// script
|
||||
# dependencies = [
|
||||
# "click",
|
||||
# "pyyaml",
|
||||
# "pygithub",
|
||||
# ]
|
||||
# ///
|
||||
|
||||
"""
|
||||
Convert a yaml project list into a nice table.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import shutil
|
||||
import sys
|
||||
import textwrap
|
||||
import time
|
||||
from collections import namedtuple
|
||||
import typing
|
||||
from glob import glob
|
||||
from pathlib import Path
|
||||
from subprocess import run
|
||||
@@ -34,7 +34,12 @@ def generate_basic_project(path):
|
||||
project.generate(path)
|
||||
|
||||
|
||||
CIService = namedtuple("CIService", "name dst_config_path badge_md")
|
||||
class CIService(typing.NamedTuple):
|
||||
name: str
|
||||
dst_config_path: str
|
||||
badge_md: str
|
||||
|
||||
|
||||
services = [
|
||||
CIService(
|
||||
name="appveyor",
|
||||
|
||||
+8
-1
@@ -9,10 +9,17 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
if __name__ == "__main__":
|
||||
default_cpu_count = os.cpu_count() or 2
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--run-podman", action="store_true", default=False, help="run podman tests (linux only)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--num-processes",
|
||||
action="store",
|
||||
default=default_cpu_count,
|
||||
help="number of processes to use for testing",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# move cwd to the project root
|
||||
@@ -35,7 +42,7 @@ if __name__ == "__main__":
|
||||
sys.executable,
|
||||
"-m",
|
||||
"pytest",
|
||||
"--numprocesses=2",
|
||||
f"--numprocesses={args.num_processes}",
|
||||
"-x",
|
||||
"--durations",
|
||||
"0",
|
||||
|
||||
@@ -7,7 +7,7 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from html2image import Html2Image # type: ignore[import]
|
||||
from html2image import Html2Image # type: ignore[import-not-found]
|
||||
except ImportError:
|
||||
sys.exit(
|
||||
"""
|
||||
|
||||
Executable
+148
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import difflib
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
import click
|
||||
import packaging.specifiers
|
||||
import requests
|
||||
import rich
|
||||
from packaging.version import InvalidVersion, Version
|
||||
from rich.logging import RichHandler
|
||||
from rich.syntax import Syntax
|
||||
|
||||
from cibuildwheel._compat import tomllib
|
||||
|
||||
log = logging.getLogger("cibw")
|
||||
|
||||
# Looking up the dir instead of using utils.resources_dir
|
||||
# since we want to write to it.
|
||||
DIR: Final[Path] = Path(__file__).parent.parent.resolve()
|
||||
RESOURCES_DIR: Final[Path] = DIR / "cibuildwheel/resources"
|
||||
|
||||
NODEJS_DIST: Final[str] = "https://nodejs.org/dist/"
|
||||
NODEJS_INDEX: Final[str] = f"{NODEJS_DIST}index.json"
|
||||
|
||||
|
||||
@dataclass(frozen=True, order=True)
|
||||
class VersionTuple:
|
||||
version: Version
|
||||
version_string: str
|
||||
|
||||
|
||||
def parse_nodejs_index() -> list[VersionTuple]:
|
||||
versions: list[VersionTuple] = []
|
||||
response = requests.get(NODEJS_INDEX)
|
||||
response.raise_for_status()
|
||||
versions_info = response.json()
|
||||
for version_info in versions_info:
|
||||
version_string = version_info.get("version", "???")
|
||||
if not version_info.get("lts", False):
|
||||
log.debug("Ignoring non LTS release %r", version_string)
|
||||
continue
|
||||
if "linux-x64" not in version_info.get("files", []):
|
||||
log.warning(
|
||||
"Ignoring release %r which does not include a linux-x64 binary", version_string
|
||||
)
|
||||
continue
|
||||
try:
|
||||
version = Version(version_string)
|
||||
if version.is_devrelease:
|
||||
log.info("Ignoring development release %r", str(version))
|
||||
continue
|
||||
if version.is_prerelease:
|
||||
log.info("Ignoring pre-release %r", str(version))
|
||||
continue
|
||||
versions.append(VersionTuple(version, version_string))
|
||||
except InvalidVersion:
|
||||
log.warning("Ignoring release %r", version_string)
|
||||
versions.sort(reverse=True)
|
||||
return versions
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option("--force", is_flag=True)
|
||||
@click.option(
|
||||
"--level", default="INFO", type=click.Choice(["WARNING", "INFO", "DEBUG"], case_sensitive=False)
|
||||
)
|
||||
def update_nodejs(force: bool, level: str) -> None:
|
||||
logging.basicConfig(
|
||||
level="INFO",
|
||||
format="%(message)s",
|
||||
datefmt="[%X]",
|
||||
handlers=[RichHandler(rich_tracebacks=True, markup=True)],
|
||||
)
|
||||
log.setLevel(level)
|
||||
|
||||
toml_file_path = RESOURCES_DIR / "nodejs.toml"
|
||||
|
||||
original_toml = toml_file_path.read_text()
|
||||
with toml_file_path.open("rb") as f:
|
||||
nodejs_data = tomllib.load(f)
|
||||
|
||||
nodejs_data.pop("url")
|
||||
|
||||
major_versions = [VersionTuple(Version(key), key) for key in nodejs_data]
|
||||
major_versions.sort(reverse=True)
|
||||
|
||||
versions = parse_nodejs_index()
|
||||
|
||||
# update existing versions, 1 per LTS
|
||||
for major_version in major_versions:
|
||||
current = Version(nodejs_data[major_version.version_string])
|
||||
specifier = packaging.specifiers.SpecifierSet(
|
||||
specifiers=f"=={major_version.version.major}.*"
|
||||
)
|
||||
for version in versions:
|
||||
if specifier.contains(version.version) and version.version > current:
|
||||
nodejs_data[major_version.version_string] = version.version_string
|
||||
break
|
||||
|
||||
# check for a new major LTS to insert
|
||||
if versions and versions[0].version.major > major_versions[0].version.major:
|
||||
major_versions.insert(
|
||||
0,
|
||||
VersionTuple(Version(str(versions[0].version.major)), f"v{versions[0].version.major}"),
|
||||
)
|
||||
nodejs_data[major_versions[0].version_string] = versions[0].version_string
|
||||
|
||||
versions_toml = "\n".join(
|
||||
f'{major_version.version_string} = "{nodejs_data[major_version.version_string]}"'
|
||||
for major_version in major_versions
|
||||
)
|
||||
result_toml = f'url = "{NODEJS_DIST}"\n{versions_toml}\n'
|
||||
|
||||
rich.print() # spacer
|
||||
|
||||
if original_toml == result_toml:
|
||||
rich.print("[green]Check complete, nodejs version unchanged.")
|
||||
return
|
||||
|
||||
rich.print("nodejs version updated.")
|
||||
rich.print("Changes:")
|
||||
rich.print()
|
||||
|
||||
toml_relpath = toml_file_path.relative_to(DIR).as_posix()
|
||||
diff_lines = difflib.unified_diff(
|
||||
original_toml.splitlines(keepends=True),
|
||||
result_toml.splitlines(keepends=True),
|
||||
fromfile=toml_relpath,
|
||||
tofile=toml_relpath,
|
||||
)
|
||||
rich.print(Syntax("".join(diff_lines), "diff", theme="ansi_light"))
|
||||
rich.print()
|
||||
|
||||
if force:
|
||||
toml_file_path.write_text(result_toml)
|
||||
rich.print("[green]TOML file updated.")
|
||||
else:
|
||||
rich.print("[yellow]File left unchanged. Use --force flag to update.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
update_nodejs()
|
||||
+23
-12
@@ -58,7 +58,7 @@ AnyConfig = Union[ConfigWinCP, ConfigWinPP, ConfigMacOS]
|
||||
|
||||
|
||||
class WindowsVersions:
|
||||
def __init__(self, arch_str: ArchStr) -> None:
|
||||
def __init__(self, arch_str: ArchStr, free_threaded: bool) -> None:
|
||||
response = requests.get("https://api.nuget.org/v3/index.json")
|
||||
response.raise_for_status()
|
||||
api_info = response.json()
|
||||
@@ -72,7 +72,11 @@ class WindowsVersions:
|
||||
|
||||
self.arch_str = arch_str
|
||||
self.arch = ARCH_DICT[arch_str]
|
||||
self.free_threaded = free_threaded
|
||||
|
||||
package = PACKAGE_DICT[arch_str]
|
||||
if free_threaded:
|
||||
package = f"{package}-freethreaded"
|
||||
|
||||
response = requests.get(f"{endpoint}{package}/index.json")
|
||||
response.raise_for_status()
|
||||
@@ -92,8 +96,9 @@ class WindowsVersions:
|
||||
if not versions:
|
||||
return None
|
||||
|
||||
flags = "t" if self.free_threaded else ""
|
||||
version = versions[0]
|
||||
identifier = f"cp{version.major}{version.minor}-{self.arch}"
|
||||
identifier = f"cp{version.major}{version.minor}{flags}-{self.arch}"
|
||||
return ConfigWinCP(
|
||||
identifier=identifier,
|
||||
version=self.version_dict[version],
|
||||
@@ -204,10 +209,8 @@ class CPythonVersions:
|
||||
unsorted_versions = spec.filter(self.versions_dict)
|
||||
sorted_versions = sorted(unsorted_versions, reverse=True)
|
||||
|
||||
if version <= Version("3.8.9999"):
|
||||
file_ident = "macosx10.9.pkg"
|
||||
else:
|
||||
file_ident = "macos11.pkg"
|
||||
macver = "x10.9" if version <= Version("3.8.9999") else "11"
|
||||
file_ident = f"macos{macver}.pkg"
|
||||
|
||||
for new_version in sorted_versions:
|
||||
# Find the first patch version that contains the requested file
|
||||
@@ -235,9 +238,12 @@ class CPythonVersions:
|
||||
|
||||
class AllVersions:
|
||||
def __init__(self) -> None:
|
||||
self.windows_32 = WindowsVersions("32")
|
||||
self.windows_64 = WindowsVersions("64")
|
||||
self.windows_arm64 = WindowsVersions("ARM64")
|
||||
self.windows_32 = WindowsVersions("32", False)
|
||||
self.windows_t_32 = WindowsVersions("32", True)
|
||||
self.windows_64 = WindowsVersions("64", False)
|
||||
self.windows_t_64 = WindowsVersions("64", True)
|
||||
self.windows_arm64 = WindowsVersions("ARM64", False)
|
||||
self.windows_t_arm64 = WindowsVersions("ARM64", True)
|
||||
self.windows_pypy_64 = PyPyVersions("64")
|
||||
|
||||
self.macos_cpython = CPythonVersions()
|
||||
@@ -261,14 +267,19 @@ class AllVersions:
|
||||
config_update = self.macos_pypy.update_version_macos(spec)
|
||||
elif "macosx_arm64" in identifier:
|
||||
config_update = self.macos_pypy_arm64.update_version_macos(spec)
|
||||
elif "win32" in identifier:
|
||||
if identifier.startswith("cp"):
|
||||
config_update = self.windows_32.update_version_windows(spec)
|
||||
elif "t-win32" in identifier and identifier.startswith("cp"):
|
||||
config_update = self.windows_t_32.update_version_windows(spec)
|
||||
elif "win32" in identifier and identifier.startswith("cp"):
|
||||
config_update = self.windows_32.update_version_windows(spec)
|
||||
elif "t-win_amd64" in identifier and identifier.startswith("cp"):
|
||||
config_update = self.windows_t_64.update_version_windows(spec)
|
||||
elif "win_amd64" in identifier:
|
||||
if identifier.startswith("cp"):
|
||||
config_update = self.windows_64.update_version_windows(spec)
|
||||
elif identifier.startswith("pp"):
|
||||
config_update = self.windows_pypy_64.update_version_windows(spec)
|
||||
elif "t-win_arm64" in identifier and identifier.startswith("cp"):
|
||||
config_update = self.windows_t_arm64.update_version_windows(spec)
|
||||
elif "win_arm64" in identifier and identifier.startswith("cp"):
|
||||
config_update = self.windows_arm64.update_version_windows(spec)
|
||||
|
||||
|
||||
+13
-12
@@ -25,9 +25,9 @@ DIR: Final[Path] = Path(__file__).parent.parent.resolve()
|
||||
RESOURCES_DIR: Final[Path] = DIR / "cibuildwheel/resources"
|
||||
|
||||
GET_VIRTUALENV_GITHUB: Final[str] = "https://github.com/pypa/get-virtualenv"
|
||||
GET_VIRTUALENV_URL_TEMPLATE: Final[
|
||||
str
|
||||
] = f"{GET_VIRTUALENV_GITHUB}/blob/{{version}}/public/virtualenv.pyz?raw=true"
|
||||
GET_VIRTUALENV_URL_TEMPLATE: Final[str] = (
|
||||
f"{GET_VIRTUALENV_GITHUB}/blob/{{version}}/public/virtualenv.pyz?raw=true"
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, order=True)
|
||||
@@ -53,10 +53,6 @@ def git_ls_remote_versions(url) -> list[VersionTuple]:
|
||||
if version.is_prerelease:
|
||||
log.info("Ignoring pre-release %r", str(version))
|
||||
continue
|
||||
# Do not upgrade past 20.22.0 to keep python 3.6 compat
|
||||
if version >= Version("20.22.0"):
|
||||
log.info("Ignoring %r which is not compatible with python 3.6", str(version))
|
||||
continue
|
||||
versions.append(VersionTuple(version, version_string))
|
||||
except InvalidVersion:
|
||||
log.warning("Ignoring ref %r", ref)
|
||||
@@ -82,15 +78,20 @@ def update_virtualenv(force: bool, level: str) -> None:
|
||||
|
||||
original_toml = toml_file_path.read_text()
|
||||
with toml_file_path.open("rb") as f:
|
||||
loaded_file = tomllib.load(f)
|
||||
version = str(loaded_file["version"])
|
||||
configurations = tomllib.load(f)
|
||||
default = configurations.pop("default")
|
||||
version = str(default["version"])
|
||||
versions = git_ls_remote_versions(GET_VIRTUALENV_GITHUB)
|
||||
if versions[0].version > Version(version):
|
||||
version = versions[0].version_string
|
||||
|
||||
result_toml = (
|
||||
f'version = "{version}"\n'
|
||||
f'url = "{GET_VIRTUALENV_URL_TEMPLATE.format(version=version)}"\n'
|
||||
configurations["default"] = {
|
||||
"version": version,
|
||||
"url": GET_VIRTUALENV_URL_TEMPLATE.format(version=version),
|
||||
}
|
||||
result_toml = "".join(
|
||||
f'{key} = {{ version = "{value["version"]}", url = "{value["url"]}" }}\n'
|
||||
for key, value in configurations.items()
|
||||
)
|
||||
|
||||
rich.print() # spacer
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
from __future__ import annotations
|
||||
|
||||
__version__ = "2.16.0"
|
||||
__version__ = "2.20.0"
|
||||
|
||||
+87
-61
@@ -1,11 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import dataclasses
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tarfile
|
||||
import textwrap
|
||||
import traceback
|
||||
import typing
|
||||
from collections.abc import Iterable, Sequence, Set
|
||||
from pathlib import Path
|
||||
@@ -15,8 +17,10 @@ from typing import Protocol
|
||||
import cibuildwheel
|
||||
import cibuildwheel.linux
|
||||
import cibuildwheel.macos
|
||||
import cibuildwheel.pyodide
|
||||
import cibuildwheel.util
|
||||
import cibuildwheel.windows
|
||||
from cibuildwheel import errors
|
||||
from cibuildwheel._compat.typing import assert_never
|
||||
from cibuildwheel.architecture import Architecture, allowed_architectures_check
|
||||
from cibuildwheel.logger import log
|
||||
@@ -30,10 +34,38 @@ from cibuildwheel.util import (
|
||||
chdir,
|
||||
detect_ci_provider,
|
||||
fix_ansi_codes_for_github_actions,
|
||||
strtobool,
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class GlobalOptions:
|
||||
print_traceback_on_error: bool = True # decides what happens when errors are hit.
|
||||
|
||||
|
||||
def main() -> None:
|
||||
global_options = GlobalOptions()
|
||||
try:
|
||||
main_inner(global_options)
|
||||
except errors.FatalError as e:
|
||||
message = e.args[0]
|
||||
if log.step_active:
|
||||
log.step_end_with_error(message)
|
||||
else:
|
||||
print(f"cibuildwheel: {message}", file=sys.stderr)
|
||||
|
||||
if global_options.print_traceback_on_error:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
|
||||
sys.exit(e.return_code)
|
||||
|
||||
|
||||
def main_inner(global_options: GlobalOptions) -> None:
|
||||
"""
|
||||
`main_inner` is the same as `main`, but it raises FatalError exceptions
|
||||
rather than exiting directly.
|
||||
"""
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Build wheels for all the platforms.",
|
||||
epilog="""
|
||||
@@ -45,14 +77,13 @@ def main() -> None:
|
||||
|
||||
parser.add_argument(
|
||||
"--platform",
|
||||
choices=["auto", "linux", "macos", "windows"],
|
||||
choices=["auto", "linux", "macos", "windows", "pyodide"],
|
||||
default=None,
|
||||
help="""
|
||||
Platform to build for. Use this option to override the
|
||||
auto-detected platform or to run cibuildwheel on your development
|
||||
machine. Specifying "macos" or "windows" only works on that
|
||||
operating system, but "linux" works on all three, as long as
|
||||
Docker/Podman is installed. Default: auto.
|
||||
auto-detected platform. Specifying "macos" or "windows" only works
|
||||
on that operating system, but "linux" works on all three, as long
|
||||
as Docker/Podman is installed. Default: auto.
|
||||
""",
|
||||
)
|
||||
|
||||
@@ -132,8 +163,17 @@ def main() -> None:
|
||||
help="Enable pre-release Python versions if available.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--debug-traceback",
|
||||
action="store_true",
|
||||
default=strtobool(os.environ.get("CIBW_DEBUG_TRACEBACK", "0")),
|
||||
help="Print a full traceback for all errors",
|
||||
)
|
||||
|
||||
args = CommandLineArguments(**vars(parser.parse_args()))
|
||||
|
||||
global_options.print_traceback_on_error = args.debug_traceback
|
||||
|
||||
args.package_dir = args.package_dir.resolve()
|
||||
|
||||
# This are always relative to the base directory, even in SDist builds
|
||||
@@ -160,7 +200,7 @@ def main() -> None:
|
||||
# This is now the new package dir
|
||||
args.package_dir = project_dir.resolve()
|
||||
|
||||
with chdir(temp_dir):
|
||||
with chdir(project_dir):
|
||||
build_in_directory(args)
|
||||
finally:
|
||||
# avoid https://github.com/python/cpython/issues/86962 by performing
|
||||
@@ -177,27 +217,13 @@ def _compute_platform_only(only: str) -> PlatformName:
|
||||
return "macos"
|
||||
if "win_" in only or "win32" in only:
|
||||
return "windows"
|
||||
print(
|
||||
f"Invalid --only='{only}', must be a build selector with a known platform",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
if "pyodide_" in only:
|
||||
return "pyodide"
|
||||
msg = f"Invalid --only='{only}', must be a build selector with a known platform"
|
||||
raise errors.ConfigurationError(msg)
|
||||
|
||||
|
||||
def _compute_platform_ci() -> PlatformName:
|
||||
if detect_ci_provider() is None:
|
||||
print(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
cibuildwheel: Unable to detect platform. cibuildwheel should run on your CI server;
|
||||
Travis CI, AppVeyor, Azure Pipelines, GitHub Actions, CircleCI, Gitlab, and Cirrus CI
|
||||
are supported. You can run on your development machine or other CI providers
|
||||
using the --platform argument. Check --help output for more information.
|
||||
"""
|
||||
),
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
def _compute_platform_auto() -> PlatformName:
|
||||
if sys.platform.startswith("linux"):
|
||||
return "linux"
|
||||
elif sys.platform == "darwin":
|
||||
@@ -205,40 +231,34 @@ def _compute_platform_ci() -> PlatformName:
|
||||
elif sys.platform == "win32":
|
||||
return "windows"
|
||||
else:
|
||||
print(
|
||||
'cibuildwheel: Unable to detect platform from "sys.platform" in a CI environment. You can run '
|
||||
"cibuildwheel using the --platform argument. Check --help output for more information.",
|
||||
file=sys.stderr,
|
||||
msg = (
|
||||
'cibuildwheel: Unable to detect platform from "sys.platform". cibuildwheel doesn\'t '
|
||||
"support building wheels for this platform. You might be able to build for a different "
|
||||
"platform using the --platform argument. Check --help output for more information."
|
||||
)
|
||||
sys.exit(2)
|
||||
raise errors.ConfigurationError(msg)
|
||||
|
||||
|
||||
def _compute_platform(args: CommandLineArguments) -> PlatformName:
|
||||
platform_option_value = args.platform or os.environ.get("CIBW_PLATFORM", "auto")
|
||||
|
||||
if args.only and args.platform is not None:
|
||||
print(
|
||||
"--platform cannot be specified with --only, it is computed from --only",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
msg = "--platform cannot be specified with --only, it is computed from --only"
|
||||
raise errors.ConfigurationError(msg)
|
||||
if args.only and args.archs is not None:
|
||||
print(
|
||||
"--arch cannot be specified with --only, it is computed from --only",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
msg = "--arch cannot be specified with --only, it is computed from --only"
|
||||
raise errors.ConfigurationError(msg)
|
||||
|
||||
if platform_option_value not in PLATFORMS | {"auto"}:
|
||||
print(f"cibuildwheel: Unsupported platform: {platform_option_value}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
msg = f"Unsupported platform: {platform_option_value}"
|
||||
raise errors.ConfigurationError(msg)
|
||||
|
||||
if args.only:
|
||||
return _compute_platform_only(args.only)
|
||||
elif platform_option_value != "auto":
|
||||
return typing.cast(PlatformName, platform_option_value)
|
||||
|
||||
return _compute_platform_ci()
|
||||
return _compute_platform_auto()
|
||||
|
||||
|
||||
class PlatformModule(Protocol):
|
||||
@@ -246,11 +266,9 @@ class PlatformModule(Protocol):
|
||||
# is applied to a module
|
||||
def get_python_configurations(
|
||||
self, build_selector: BuildSelector, architectures: Set[Architecture]
|
||||
) -> Sequence[GenericPythonConfiguration]:
|
||||
...
|
||||
) -> Sequence[GenericPythonConfiguration]: ...
|
||||
|
||||
def build(self, options: Options, tmp_path: Path) -> None:
|
||||
...
|
||||
def build(self, options: Options, tmp_path: Path) -> None: ...
|
||||
|
||||
|
||||
# pylint: disable-next=inconsistent-return-statements
|
||||
@@ -261,11 +279,18 @@ def get_platform_module(platform: PlatformName) -> PlatformModule:
|
||||
return cibuildwheel.windows
|
||||
if platform == "macos":
|
||||
return cibuildwheel.macos
|
||||
if platform == "pyodide":
|
||||
return cibuildwheel.pyodide
|
||||
assert_never(platform)
|
||||
|
||||
|
||||
def build_in_directory(args: CommandLineArguments) -> None:
|
||||
platform: PlatformName = _compute_platform(args)
|
||||
if platform == "pyodide" and sys.platform == "win32":
|
||||
msg = "cibuildwheel: Building for pyodide is not supported on Windows"
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
options = compute_options(platform=platform, command_line_arguments=args, env=os.environ)
|
||||
|
||||
package_dir = options.globals.package_dir
|
||||
@@ -273,9 +298,8 @@ def build_in_directory(args: CommandLineArguments) -> None:
|
||||
|
||||
if not any(package_dir.joinpath(name).exists() for name in package_files):
|
||||
names = ", ".join(sorted(package_files, reverse=True))
|
||||
msg = f"cibuildwheel: Could not find any of {{{names}}} at root of package"
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
msg = f"Could not find any of {{{names}}} at root of package"
|
||||
raise errors.ConfigurationError(msg)
|
||||
|
||||
platform_module = get_platform_module(platform)
|
||||
identifiers = get_build_identifiers(
|
||||
@@ -292,8 +316,10 @@ def build_in_directory(args: CommandLineArguments) -> None:
|
||||
# Add CIBUILDWHEEL environment variable
|
||||
os.environ["CIBUILDWHEEL"] = "1"
|
||||
|
||||
# Python is buffering by default when running on the CI platforms, giving problems interleaving subprocess call output with unflushed calls to 'print'
|
||||
sys.stdout = Unbuffered(sys.stdout) # type: ignore[assignment]
|
||||
# Python is buffering by default when running on the CI platforms, giving
|
||||
# problems interleaving subprocess call output with unflushed calls to
|
||||
# 'print'
|
||||
sys.stdout = Unbuffered(sys.stdout)
|
||||
|
||||
# create the cache dir before it gets printed & builds performed
|
||||
CIBW_CACHE_PATH.mkdir(parents=True, exist_ok=True)
|
||||
@@ -304,16 +330,14 @@ def build_in_directory(args: CommandLineArguments) -> None:
|
||||
options.check_for_invalid_configuration(identifiers)
|
||||
allowed_architectures_check(platform, options.globals.architectures)
|
||||
except ValueError as err:
|
||||
print("cibuildwheel:", *err.args, file=sys.stderr)
|
||||
sys.exit(4)
|
||||
raise errors.DeprecationError(*err.args) from err
|
||||
|
||||
if not identifiers:
|
||||
print(
|
||||
f"cibuildwheel: No build identifiers selected: {options.globals.build_selector}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
if not args.allow_empty:
|
||||
sys.exit(3)
|
||||
message = f"No build identifiers selected: {options.globals.build_selector}"
|
||||
if options.globals.allow_empty:
|
||||
print(f"cibuildwheel: {message}", file=sys.stderr)
|
||||
else:
|
||||
raise errors.NothingToDoError(message)
|
||||
|
||||
output_dir = options.globals.output_dir
|
||||
|
||||
@@ -368,7 +392,9 @@ def print_preamble(platform: str, options: Options, identifiers: Sequence[str])
|
||||
|
||||
|
||||
def get_build_identifiers(
|
||||
platform_module: PlatformModule, build_selector: BuildSelector, architectures: Set[Architecture]
|
||||
platform_module: PlatformModule,
|
||||
build_selector: BuildSelector,
|
||||
architectures: Set[Architecture],
|
||||
) -> list[str]:
|
||||
python_configurations = platform_module.get_python_configurations(build_selector, architectures)
|
||||
return [config.identifier for config in python_configurations]
|
||||
|
||||
@@ -3,8 +3,8 @@ from __future__ import annotations
|
||||
import sys
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
from tomllib import load
|
||||
from tomllib import load, loads
|
||||
else:
|
||||
from tomli import load
|
||||
from tomli import load, loads
|
||||
|
||||
__all__ = ("load",)
|
||||
__all__ = ["load", "loads"]
|
||||
|
||||
@@ -3,11 +3,12 @@ from __future__ import annotations
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3, 11):
|
||||
from typing_extensions import NotRequired, assert_never
|
||||
from typing_extensions import NotRequired, Self, assert_never
|
||||
else:
|
||||
from typing import NotRequired, assert_never
|
||||
from typing import NotRequired, Self, assert_never
|
||||
|
||||
__all__ = (
|
||||
"assert_never",
|
||||
"NotRequired",
|
||||
"Self",
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@ PRETTY_NAMES: Final[dict[PlatformName, str]] = {
|
||||
"linux": "Linux",
|
||||
"macos": "macOS",
|
||||
"windows": "Windows",
|
||||
"pyodide": "Pyodide",
|
||||
}
|
||||
|
||||
ARCH_SYNONYMS: Final[list[dict[PlatformName, str | None]]] = [
|
||||
@@ -46,6 +47,9 @@ class Architecture(Enum):
|
||||
AMD64 = "AMD64"
|
||||
ARM64 = "ARM64"
|
||||
|
||||
# WebAssembly
|
||||
wasm32 = "wasm32"
|
||||
|
||||
# Allow this to be sorted
|
||||
def __lt__(self, other: Architecture) -> bool:
|
||||
return self.value < other.value
|
||||
@@ -72,8 +76,9 @@ class Architecture(Enum):
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def auto_archs(platform: PlatformName) -> set[Architecture]:
|
||||
native_machine = platform_module.machine()
|
||||
def native_arch(platform: PlatformName) -> Architecture | None:
|
||||
if platform == "pyodide":
|
||||
return Architecture.wasm32
|
||||
|
||||
# Cross-platform support. Used for --print-build-identifiers or docker builds.
|
||||
host_platform: PlatformName = (
|
||||
@@ -82,6 +87,7 @@ class Architecture(Enum):
|
||||
else ("macos" if sys.platform.startswith("darwin") else "linux")
|
||||
)
|
||||
|
||||
native_machine = platform_module.machine()
|
||||
native_architecture = Architecture(native_machine)
|
||||
|
||||
# we might need to rename the native arch to the machine we're running
|
||||
@@ -93,11 +99,18 @@ class Architecture(Enum):
|
||||
|
||||
if synonym is None:
|
||||
# can't build anything on this platform
|
||||
return set()
|
||||
return None
|
||||
|
||||
native_architecture = Architecture(synonym)
|
||||
|
||||
result = {native_architecture}
|
||||
return native_architecture
|
||||
|
||||
@staticmethod
|
||||
def auto_archs(platform: PlatformName) -> set[Architecture]:
|
||||
native_arch = Architecture.native_arch(platform)
|
||||
if native_arch is None:
|
||||
return set() # can't build anything on this platform
|
||||
result = {native_arch}
|
||||
|
||||
if platform == "linux" and Architecture.x86_64 in result:
|
||||
# x86_64 machines can run i686 containers
|
||||
@@ -120,6 +133,7 @@ class Architecture(Enum):
|
||||
},
|
||||
"macos": {Architecture.x86_64, Architecture.arm64, Architecture.universal2},
|
||||
"windows": {Architecture.x86, Architecture.AMD64, Architecture.ARM64},
|
||||
"pyodide": {Architecture.wasm32},
|
||||
}
|
||||
return all_archs_map[platform]
|
||||
|
||||
|
||||
@@ -124,8 +124,12 @@ class ParsedEnvironment:
|
||||
|
||||
return environment
|
||||
|
||||
def add(self, name: str, value: str) -> None:
|
||||
self.assignments.append(EnvironmentAssignmentRaw(name=name, value=value))
|
||||
def add(self, name: str, value: str, prepend: bool = False) -> None:
|
||||
assignment = EnvironmentAssignmentRaw(name=name, value=value)
|
||||
if prepend:
|
||||
self.assignments.insert(0, assignment)
|
||||
else:
|
||||
self.assignments.append(assignment)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.__class__.__name__}({[repr(a) for a in self.assignments]!r})"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
"""
|
||||
Errors that can cause the build to fail. Each subclass of FatalError has
|
||||
a different return code, by defining them all here, we can ensure that they're
|
||||
semantically clear and unique.
|
||||
"""
|
||||
|
||||
import textwrap
|
||||
|
||||
|
||||
class FatalError(BaseException):
|
||||
"""
|
||||
Raising an error of this type will cause the message to be printed to
|
||||
stderr and the process to be terminated. Within cibuildwheel, raising this
|
||||
exception produces a better error message, and optional traceback.
|
||||
"""
|
||||
|
||||
return_code: int = 1
|
||||
|
||||
|
||||
class ConfigurationError(FatalError):
|
||||
return_code = 2
|
||||
|
||||
|
||||
class NothingToDoError(FatalError):
|
||||
return_code = 3
|
||||
|
||||
|
||||
class DeprecationError(FatalError):
|
||||
return_code = 4
|
||||
|
||||
|
||||
class NonPlatformWheelError(FatalError):
|
||||
def __init__(self) -> None:
|
||||
message = textwrap.dedent(
|
||||
"""
|
||||
Build failed because a pure Python wheel was generated.
|
||||
|
||||
If you intend to build a pure-Python wheel, you don't need cibuildwheel - use
|
||||
`pip wheel -w DEST_DIR .` instead.
|
||||
|
||||
If you expected a platform wheel, check your project configuration, or run
|
||||
cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
|
||||
"""
|
||||
)
|
||||
super().__init__(message)
|
||||
self.return_code = 5
|
||||
|
||||
|
||||
class AlreadyBuiltWheelError(FatalError):
|
||||
def __init__(self, wheel_name: str) -> None:
|
||||
message = textwrap.dedent(
|
||||
f"""
|
||||
Build failed because a wheel named {wheel_name} was already generated in the current run.
|
||||
|
||||
If you expected another wheel to be generated, check your project configuration, or run
|
||||
cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
|
||||
"""
|
||||
)
|
||||
super().__init__(message)
|
||||
self.return_code = 6
|
||||
@@ -12,12 +12,11 @@ __all__ = ("Printable", "dump_python_configurations")
|
||||
|
||||
|
||||
class Printable(Protocol):
|
||||
def __str__(self) -> str:
|
||||
...
|
||||
def __str__(self) -> str: ...
|
||||
|
||||
|
||||
def dump_python_configurations(
|
||||
inp: Mapping[str, Mapping[str, Sequence[Mapping[str, Printable]]]]
|
||||
inp: Mapping[str, Mapping[str, Sequence[Mapping[str, Printable]]]],
|
||||
) -> str:
|
||||
output = StringIO()
|
||||
for header, values in inp.items():
|
||||
|
||||
+87
-64
@@ -8,17 +8,18 @@ from dataclasses import dataclass
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
from typing import OrderedDict, Tuple
|
||||
|
||||
from packaging.version import Version
|
||||
|
||||
from . import errors
|
||||
from ._compat.typing import assert_never
|
||||
from .architecture import Architecture
|
||||
from .logger import log
|
||||
from .oci_container import OCIContainer
|
||||
from .options import Options
|
||||
from .oci_container import OCIContainer, OCIContainerEngineConfig
|
||||
from .options import BuildOptions, Options
|
||||
from .typing import PathOrStr
|
||||
from .util import (
|
||||
AlreadyBuiltWheelError,
|
||||
BuildFrontendConfig,
|
||||
BuildSelector,
|
||||
NonPlatformWheelError,
|
||||
find_compatible_wheel,
|
||||
get_build_verbosity_extra_flags,
|
||||
prepare_command,
|
||||
@@ -44,6 +45,7 @@ class PythonConfiguration:
|
||||
class BuildStep:
|
||||
platform_configs: list[PythonConfiguration]
|
||||
platform_tag: str
|
||||
container_engine: OCIContainerEngineConfig
|
||||
container_image: str
|
||||
|
||||
|
||||
@@ -65,8 +67,9 @@ def get_python_configurations(
|
||||
]
|
||||
|
||||
|
||||
def container_image_for_python_configuration(config: PythonConfiguration, options: Options) -> str:
|
||||
build_options = options.build_options(config.identifier)
|
||||
def container_image_for_python_configuration(
|
||||
config: PythonConfiguration, build_options: BuildOptions
|
||||
) -> str:
|
||||
# e.g
|
||||
# identifier is 'cp310-manylinux_x86_64'
|
||||
# platform_tag is 'manylinux_x86_64'
|
||||
@@ -91,15 +94,18 @@ def get_build_steps(
|
||||
Groups PythonConfigurations into BuildSteps. Each BuildStep represents a
|
||||
separate container instance.
|
||||
"""
|
||||
steps = OrderedDict[Tuple[str, str, str], BuildStep]()
|
||||
steps = OrderedDict[Tuple[str, str, str, OCIContainerEngineConfig], BuildStep]()
|
||||
|
||||
for config in python_configurations:
|
||||
_, platform_tag = config.identifier.split("-", 1)
|
||||
|
||||
before_all = options.build_options(config.identifier).before_all
|
||||
container_image = container_image_for_python_configuration(config, options)
|
||||
build_options = options.build_options(config.identifier)
|
||||
|
||||
step_key = (platform_tag, container_image, before_all)
|
||||
before_all = build_options.before_all
|
||||
container_image = container_image_for_python_configuration(config, build_options)
|
||||
container_engine = build_options.container_engine
|
||||
|
||||
step_key = (platform_tag, container_image, before_all, container_engine)
|
||||
|
||||
if step_key in steps:
|
||||
steps[step_key].platform_configs.append(config)
|
||||
@@ -107,6 +113,7 @@ def get_build_steps(
|
||||
steps[step_key] = BuildStep(
|
||||
platform_configs=[config],
|
||||
platform_tag=platform_tag,
|
||||
container_engine=container_engine,
|
||||
container_image=container_image,
|
||||
)
|
||||
|
||||
@@ -117,10 +124,20 @@ def check_all_python_exist(
|
||||
*, platform_configs: Iterable[PythonConfiguration], container: OCIContainer
|
||||
) -> None:
|
||||
exist = True
|
||||
has_manylinux_interpreters = True
|
||||
messages = []
|
||||
|
||||
try:
|
||||
# use capture_output to keep quiet
|
||||
container.call(["manylinux-interpreters", "--help"], capture_output=True)
|
||||
except subprocess.CalledProcessError:
|
||||
has_manylinux_interpreters = False
|
||||
|
||||
for config in platform_configs:
|
||||
python_path = config.path / "bin" / "python"
|
||||
try:
|
||||
if has_manylinux_interpreters:
|
||||
container.call(["manylinux-interpreters", "ensure", config.path.name])
|
||||
container.call(["test", "-x", python_path])
|
||||
except subprocess.CalledProcessError:
|
||||
messages.append(
|
||||
@@ -129,11 +146,7 @@ def check_all_python_exist(
|
||||
exist = False
|
||||
if not exist:
|
||||
message = "\n".join(messages)
|
||||
print(
|
||||
f"cibuildwheel:\n{message}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
raise errors.FatalError(message)
|
||||
|
||||
|
||||
def build_in_container(
|
||||
@@ -178,6 +191,8 @@ def build_in_container(
|
||||
log.build_start(config.identifier)
|
||||
build_options = options.build_options(config.identifier)
|
||||
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
|
||||
use_uv = build_frontend.name == "build[uv]" and Version(config.version) >= Version("3.8")
|
||||
pip = ["uv", "pip"] if use_uv else ["pip"]
|
||||
|
||||
dependency_constraint_flags: list[PathOrStr] = []
|
||||
|
||||
@@ -205,19 +220,19 @@ def build_in_container(
|
||||
# check config python is still on PATH
|
||||
which_python = container.call(["which", "python"], env=env, capture_output=True).strip()
|
||||
if PurePosixPath(which_python) != python_bin / "python":
|
||||
print(
|
||||
"cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
msg = "python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
which_pip = container.call(["which", "pip"], env=env, capture_output=True).strip()
|
||||
if PurePosixPath(which_pip) != python_bin / "pip":
|
||||
print(
|
||||
"cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
if use_uv:
|
||||
which_uv = container.call(["which", "uv"], env=env, capture_output=True).strip()
|
||||
if not which_uv:
|
||||
msg = "uv not found on PATH. You must use a supported manylinux or musllinux environment with uv."
|
||||
raise errors.FatalError(msg)
|
||||
else:
|
||||
which_pip = container.call(["which", "pip"], env=env, capture_output=True).strip()
|
||||
if PurePosixPath(which_pip) != python_bin / "pip":
|
||||
msg = "pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||
if compatible_wheel:
|
||||
@@ -261,10 +276,12 @@ def build_in_container(
|
||||
],
|
||||
env=env,
|
||||
)
|
||||
elif build_frontend.name == "build":
|
||||
elif build_frontend.name == "build" or build_frontend.name == "build[uv]":
|
||||
if not 0 <= build_options.build_verbosity < 2:
|
||||
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
||||
log.warning(msg)
|
||||
if use_uv and "--no-isolation" not in extra_flags and "-n" not in extra_flags:
|
||||
extra_flags += ["--installer=uv"]
|
||||
container.call(
|
||||
[
|
||||
"python",
|
||||
@@ -287,7 +304,7 @@ def build_in_container(
|
||||
container.call(["mkdir", "-p", repaired_wheel_dir])
|
||||
|
||||
if built_wheel.name.endswith("none-any.whl"):
|
||||
raise NonPlatformWheelError()
|
||||
raise errors.NonPlatformWheelError()
|
||||
|
||||
if build_options.repair_command:
|
||||
log.step("Repairing wheel...")
|
||||
@@ -302,24 +319,36 @@ def build_in_container(
|
||||
|
||||
for repaired_wheel in repaired_wheels:
|
||||
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
|
||||
raise AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
|
||||
if build_options.test_command and build_options.test_selector(config.identifier):
|
||||
log.step("Testing wheel...")
|
||||
|
||||
# set up a virtual environment to install and test from, to make sure
|
||||
# there are no dependencies that were pulled in at build time.
|
||||
container.call(["pip", "install", "virtualenv", *dependency_constraint_flags], env=env)
|
||||
if not use_uv:
|
||||
container.call(
|
||||
["pip", "install", "virtualenv", *dependency_constraint_flags], env=env
|
||||
)
|
||||
|
||||
testing_temp_dir = PurePosixPath(
|
||||
container.call(["mktemp", "-d"], capture_output=True).strip()
|
||||
)
|
||||
venv_dir = testing_temp_dir / "venv"
|
||||
|
||||
container.call(["python", "-m", "virtualenv", "--no-download", venv_dir], env=env)
|
||||
if use_uv:
|
||||
container.call(["uv", "venv", venv_dir], env=env)
|
||||
else:
|
||||
# Use embedded dependencies from virtualenv to ensure determinism
|
||||
venv_args = ["--no-periodic-update", "--pip=embed"]
|
||||
# In Python<3.12, setuptools & wheel are installed as well
|
||||
if Version(config.version) < Version("3.12"):
|
||||
venv_args.extend(("--setuptools=embed", "--wheel=embed"))
|
||||
container.call(["python", "-m", "virtualenv", *venv_args, venv_dir], env=env)
|
||||
|
||||
virtualenv_env = env.copy()
|
||||
virtualenv_env["PATH"] = f"{venv_dir / 'bin'}:{virtualenv_env['PATH']}"
|
||||
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
|
||||
|
||||
if build_options.before_test:
|
||||
before_test_prepared = prepare_command(
|
||||
@@ -337,13 +366,13 @@ def build_in_container(
|
||||
# Let's just pick the first one.
|
||||
wheel_to_test = repaired_wheels[0]
|
||||
container.call(
|
||||
["pip", "install", str(wheel_to_test) + build_options.test_extras],
|
||||
[*pip, "install", str(wheel_to_test) + build_options.test_extras],
|
||||
env=virtualenv_env,
|
||||
)
|
||||
|
||||
# Install any requirements to run the tests
|
||||
if build_options.test_requires:
|
||||
container.call(["pip", "install", *build_options.test_requires], env=virtualenv_env)
|
||||
container.call([*pip, "install", *build_options.test_requires], env=virtualenv_env)
|
||||
|
||||
# Run the tests from a different directory
|
||||
test_command_prepared = prepare_command(
|
||||
@@ -378,29 +407,6 @@ def build_in_container(
|
||||
|
||||
|
||||
def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
||||
try:
|
||||
# check the container engine is installed
|
||||
subprocess.run(
|
||||
[options.globals.container_engine.name, "--version"],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
print(
|
||||
unwrap(
|
||||
f"""
|
||||
cibuildwheel: {options.globals.container_engine} not found. An
|
||||
OCI exe like Docker or Podman is required to run Linux builds.
|
||||
If you're building on Travis CI, add `services: [docker]` to
|
||||
your .travis.yml. If you're building on Circle CI in Linux,
|
||||
add a `setup_remote_docker` step to your .circleci/config.yml.
|
||||
If you're building on Cirrus CI, use `docker_builder` task.
|
||||
"""
|
||||
),
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
|
||||
python_configurations = get_python_configurations(
|
||||
options.globals.build_selector, options.globals.architectures
|
||||
)
|
||||
@@ -415,6 +421,26 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
||||
container_package_dir = container_project_path / abs_package_dir.relative_to(cwd)
|
||||
|
||||
for build_step in get_build_steps(options, python_configurations):
|
||||
try:
|
||||
# check the container engine is installed
|
||||
subprocess.run(
|
||||
[build_step.container_engine.name, "--version"],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
)
|
||||
except subprocess.CalledProcessError as error:
|
||||
msg = unwrap(
|
||||
f"""
|
||||
cibuildwheel: {build_step.container_engine.name} not found. An
|
||||
OCI exe like Docker or Podman is required to run Linux builds.
|
||||
If you're building on Travis CI, add `services: [docker]` to
|
||||
your .travis.yml. If you're building on Circle CI in Linux,
|
||||
add a `setup_remote_docker` step to your .circleci/config.yml.
|
||||
If you're building on Cirrus CI, use `docker_builder` task.
|
||||
"""
|
||||
)
|
||||
raise errors.ConfigurationError(msg) from error
|
||||
|
||||
try:
|
||||
ids_to_build = [x.identifier for x in build_step.platform_configs]
|
||||
log.step(f"Starting container image {build_step.container_image}...")
|
||||
@@ -423,9 +449,9 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
||||
|
||||
with OCIContainer(
|
||||
image=build_step.container_image,
|
||||
simulate_32_bit=build_step.platform_tag.endswith("i686"),
|
||||
enforce_32_bit=build_step.platform_tag.endswith("i686"),
|
||||
cwd=container_project_path,
|
||||
engine=options.globals.container_engine,
|
||||
engine=build_step.container_engine,
|
||||
) as container:
|
||||
build_in_container(
|
||||
options=options,
|
||||
@@ -436,11 +462,9 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
||||
)
|
||||
|
||||
except subprocess.CalledProcessError as error:
|
||||
log.step_end_with_error(
|
||||
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
|
||||
)
|
||||
troubleshoot(options, error)
|
||||
sys.exit(1)
|
||||
msg = f"Command {error.cmd} failed with code {error.returncode}. {error.stdout or ''}"
|
||||
raise errors.FatalError(msg) from error
|
||||
|
||||
|
||||
def _matches_prepared_command(error_cmd: Sequence[str], command_template: str) -> bool:
|
||||
@@ -459,7 +483,6 @@ def troubleshoot(options: Options, error: Exception) -> None:
|
||||
) # TODO allow matching of overrides too?
|
||||
):
|
||||
# the wheel build step or the repair step failed
|
||||
print("Checking for common errors...")
|
||||
so_files = list(options.globals.package_dir.glob("**/*.so"))
|
||||
|
||||
if so_files:
|
||||
|
||||
@@ -34,6 +34,7 @@ PLATFORM_IDENTIFIER_DESCRIPTIONS: Final[dict[str, str]] = {
|
||||
"macosx_x86_64": "macOS x86_64",
|
||||
"macosx_universal2": "macOS Universal 2 - x86_64 and arm64",
|
||||
"macosx_arm64": "macOS arm64 - Apple Silicon",
|
||||
"pyodide_wasm32": "Pyodide",
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +152,10 @@ class Logger:
|
||||
c = self.colors
|
||||
print(f"{c.bright_red}Error{c.end}: {error}\n", file=sys.stderr)
|
||||
|
||||
@property
|
||||
def step_active(self) -> bool:
|
||||
return self.step_start_time is not None
|
||||
|
||||
def _start_fold_group(self, name: str) -> None:
|
||||
self._end_fold_group()
|
||||
self.active_fold_group_name = name
|
||||
|
||||
+214
-92
@@ -1,6 +1,5 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import functools
|
||||
import os
|
||||
import platform
|
||||
@@ -15,7 +14,9 @@ from pathlib import Path
|
||||
from typing import Literal, Tuple
|
||||
|
||||
from filelock import FileLock
|
||||
from packaging.version import Version
|
||||
|
||||
from . import errors
|
||||
from ._compat.typing import assert_never
|
||||
from .architecture import Architecture
|
||||
from .environment import ParsedEnvironment
|
||||
@@ -24,18 +25,20 @@ from .options import Options
|
||||
from .typing import PathOrStr
|
||||
from .util import (
|
||||
CIBW_CACHE_PATH,
|
||||
AlreadyBuiltWheelError,
|
||||
BuildFrontendConfig,
|
||||
BuildFrontendName,
|
||||
BuildSelector,
|
||||
NonPlatformWheelError,
|
||||
call,
|
||||
combine_constraints,
|
||||
detect_ci_provider,
|
||||
download,
|
||||
find_compatible_wheel,
|
||||
find_uv,
|
||||
free_thread_enable_313,
|
||||
get_build_verbosity_extra_flags,
|
||||
get_pip_version,
|
||||
install_certifi_script,
|
||||
move_file,
|
||||
prepare_command,
|
||||
read_python_configs,
|
||||
shell,
|
||||
@@ -46,6 +49,7 @@ from .util import (
|
||||
)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def get_macos_version() -> tuple[int, int]:
|
||||
"""
|
||||
Returns the macOS major/minor version, as a tuple, e.g. (10, 15) or (11, 0)
|
||||
@@ -57,9 +61,29 @@ def get_macos_version() -> tuple[int, int]:
|
||||
"""
|
||||
version_str, _, _ = platform.mac_ver()
|
||||
version = tuple(map(int, version_str.split(".")[:2]))
|
||||
if (10, 15) < version < (11, 0):
|
||||
# When built against an older macOS SDK, Python will report macOS 10.16
|
||||
# instead of the real version.
|
||||
version_str = call(
|
||||
sys.executable,
|
||||
"-sS",
|
||||
"-c",
|
||||
"import platform; print(platform.mac_ver()[0])",
|
||||
env={"SYSTEM_VERSION_COMPAT": "0"},
|
||||
capture_stdout=True,
|
||||
)
|
||||
version = tuple(map(int, version_str.split(".")[:2]))
|
||||
return typing.cast(Tuple[int, int], version)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def get_test_macosx_deployment_target() -> str:
|
||||
version = get_macos_version()
|
||||
if version >= (11, 0):
|
||||
return f"{version[0]}.0"
|
||||
return f"{version[0]}.{version[1]}"
|
||||
|
||||
|
||||
def get_macos_sdks() -> list[str]:
|
||||
output = call("xcodebuild", "-showsdks", capture_stdout=True)
|
||||
return [m.group(1) for m in re.finditer(r"-sdk (macosx\S+)", output)]
|
||||
@@ -114,35 +138,44 @@ def get_python_configurations(
|
||||
return python_configurations
|
||||
|
||||
|
||||
def install_cpython(tmp: Path, version: str, url: str) -> Path:
|
||||
installation_path = Path(f"/Library/Frameworks/Python.framework/Versions/{version}")
|
||||
def install_cpython(tmp: Path, version: str, url: str, free_threading: bool) -> Path:
|
||||
ft = "T" if free_threading else ""
|
||||
installation_path = Path(f"/Library/Frameworks/Python{ft}.framework/Versions/{version}")
|
||||
with FileLock(CIBW_CACHE_PATH / f"cpython{version}.lock"):
|
||||
installed_system_packages = call("pkgutil", "--pkgs", capture_stdout=True).splitlines()
|
||||
# if this version of python isn't installed, get it from python.org and install
|
||||
python_package_identifier = f"org.python.Python.PythonFramework-{version}"
|
||||
python_package_identifier = f"org.python.Python.Python{ft}Framework-{version}"
|
||||
if python_package_identifier not in installed_system_packages:
|
||||
if detect_ci_provider() is None:
|
||||
# if running locally, we don't want to install CPython with sudo
|
||||
# let the user know & provide a link to the installer
|
||||
print(
|
||||
msg = (
|
||||
f"Error: CPython {version} is not installed.\n"
|
||||
"cibuildwheel will not perform system-wide installs when running outside of CI.\n"
|
||||
f"To build locally, install CPython {version} on this machine, or, disable this version of Python using CIBW_SKIP=cp{version.replace('.', '')}-macosx_*\n"
|
||||
f"\nDownload link: {url}",
|
||||
file=sys.stderr,
|
||||
f"\nDownload link: {url}"
|
||||
)
|
||||
raise SystemExit(1)
|
||||
raise errors.FatalError(msg)
|
||||
pkg_path = tmp / "Python.pkg"
|
||||
# download the pkg
|
||||
download(url, pkg_path)
|
||||
# install
|
||||
call("sudo", "installer", "-pkg", pkg_path, "-target", "/")
|
||||
args = []
|
||||
if version.startswith("3.13"):
|
||||
# Python 3.13 is the first version to have a free-threading option
|
||||
args += ["-applyChoiceChangesXML", str(free_thread_enable_313.resolve())]
|
||||
call("sudo", "installer", "-pkg", pkg_path, *args, "-target", "/")
|
||||
pkg_path.unlink()
|
||||
env = os.environ.copy()
|
||||
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
|
||||
call(installation_path / "bin" / "python3", install_certifi_script, env=env)
|
||||
|
||||
return installation_path / "bin" / "python3"
|
||||
if free_threading:
|
||||
call(installation_path / f"bin/python{version}t", "-m", "ensurepip", env=env)
|
||||
call(installation_path / f"bin/python{version}t", install_certifi_script, env=env)
|
||||
else:
|
||||
call(installation_path / "bin/python3", install_certifi_script, env=env)
|
||||
|
||||
return installation_path / "bin" / (f"python{version}t" if free_threading else "python3")
|
||||
|
||||
|
||||
def install_pypy(tmp: Path, url: str) -> Path:
|
||||
@@ -166,22 +199,42 @@ def setup_python(
|
||||
dependency_constraint_flags: Sequence[PathOrStr],
|
||||
environment: ParsedEnvironment,
|
||||
build_frontend: BuildFrontendName,
|
||||
) -> dict[str, str]:
|
||||
) -> tuple[Path, dict[str, str]]:
|
||||
if build_frontend == "build[uv]" and Version(python_configuration.version) < Version("3.8"):
|
||||
build_frontend = "build"
|
||||
|
||||
uv_path = find_uv()
|
||||
use_uv = build_frontend == "build[uv]" and Version(python_configuration.version) >= Version(
|
||||
"3.8"
|
||||
)
|
||||
|
||||
tmp.mkdir()
|
||||
implementation_id = python_configuration.identifier.split("-")[0]
|
||||
log.step(f"Installing Python {implementation_id}...")
|
||||
if implementation_id.startswith("cp"):
|
||||
base_python = install_cpython(tmp, python_configuration.version, python_configuration.url)
|
||||
free_threading = "t-macos" in python_configuration.identifier
|
||||
base_python = install_cpython(
|
||||
tmp, python_configuration.version, python_configuration.url, free_threading
|
||||
)
|
||||
|
||||
elif implementation_id.startswith("pp"):
|
||||
base_python = install_pypy(tmp, python_configuration.url)
|
||||
else:
|
||||
msg = "Unknown Python implementation"
|
||||
raise ValueError(msg)
|
||||
assert base_python.exists()
|
||||
assert (
|
||||
base_python.exists()
|
||||
), f"{base_python.name} not found, has {list(base_python.parent.iterdir())}"
|
||||
|
||||
log.step("Setting up build environment...")
|
||||
venv_path = tmp / "venv"
|
||||
env = virtualenv(base_python, venv_path, dependency_constraint_flags)
|
||||
env = virtualenv(
|
||||
python_configuration.version,
|
||||
base_python,
|
||||
venv_path,
|
||||
dependency_constraint_flags,
|
||||
use_uv=use_uv,
|
||||
)
|
||||
venv_bin_path = venv_path / "bin"
|
||||
assert venv_bin_path.exists()
|
||||
# Fix issue with site.py setting the wrong `sys.prefix`, `sys.exec_prefix`,
|
||||
@@ -197,43 +250,43 @@ def setup_python(
|
||||
|
||||
# upgrade pip to the version matching our constraints
|
||||
# if necessary, reinstall it to ensure that it's available on PATH as 'pip'
|
||||
call(
|
||||
"python",
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"pip",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
cwd=venv_path,
|
||||
)
|
||||
if build_frontend == "build[uv]":
|
||||
assert uv_path is not None
|
||||
pip = [str(uv_path), "pip"]
|
||||
else:
|
||||
pip = ["python", "-m", "pip"]
|
||||
|
||||
if not use_uv:
|
||||
call(
|
||||
*pip,
|
||||
"install",
|
||||
"--upgrade",
|
||||
"pip",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
cwd=venv_path,
|
||||
)
|
||||
|
||||
# Apply our environment after pip is ready
|
||||
env = environment.as_dictionary(prev_environment=env)
|
||||
|
||||
# check what pip version we're on
|
||||
assert (venv_bin_path / "pip").exists()
|
||||
call("which", "pip", env=env)
|
||||
call("pip", "--version", env=env)
|
||||
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
|
||||
if which_pip != str(venv_bin_path / "pip"):
|
||||
print(
|
||||
"cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
if not use_uv:
|
||||
assert (venv_bin_path / "pip").exists()
|
||||
call("which", "pip", env=env)
|
||||
call("pip", "--version", env=env)
|
||||
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
|
||||
if which_pip != str(venv_bin_path / "pip"):
|
||||
msg = "cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
# check what Python version we're on
|
||||
call("which", "python", env=env)
|
||||
call("python", "--version", env=env)
|
||||
which_python = call("which", "python", env=env, capture_stdout=True).strip()
|
||||
if which_python != str(venv_bin_path / "python"):
|
||||
print(
|
||||
"cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
msg = "cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
config_is_arm64 = python_configuration.identifier.endswith("arm64")
|
||||
config_is_universal2 = python_configuration.identifier.endswith("universal2")
|
||||
@@ -241,8 +294,25 @@ def setup_python(
|
||||
# Set MACOSX_DEPLOYMENT_TARGET, if the user didn't set it.
|
||||
# For arm64, the minimal deployment target is 11.0.
|
||||
# On x86_64 (or universal2), use 10.9 as a default.
|
||||
# PyPy defaults to 10.7, causing inconsistencies if it's left unset.
|
||||
env.setdefault("MACOSX_DEPLOYMENT_TARGET", "11.0" if config_is_arm64 else "10.9")
|
||||
# CPython 3.13 needs 10.13.
|
||||
if config_is_arm64:
|
||||
default_target = "11.0"
|
||||
elif Version(python_configuration.version) >= Version("3.13"):
|
||||
default_target = "10.13"
|
||||
elif python_configuration.identifier.startswith("pp") and Version(
|
||||
python_configuration.version
|
||||
) >= Version("3.9"):
|
||||
default_target = "10.15"
|
||||
else:
|
||||
default_target = "10.9"
|
||||
env.setdefault("MACOSX_DEPLOYMENT_TARGET", default_target)
|
||||
|
||||
# This is a floor, it can't be set lower than the default_target.
|
||||
if Version(env["MACOSX_DEPLOYMENT_TARGET"]) < Version(default_target):
|
||||
log.warning(
|
||||
f"Bumping MACOSX_DEPLOYMENT_TARGET ({env['MACOSX_DEPLOYMENT_TARGET']}) to the minimum required ({default_target})."
|
||||
)
|
||||
env["MACOSX_DEPLOYMENT_TARGET"] = default_target
|
||||
|
||||
if python_configuration.version not in {"3.6", "3.7"}:
|
||||
if config_is_arm64:
|
||||
@@ -287,8 +357,6 @@ def setup_python(
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"setuptools",
|
||||
"wheel",
|
||||
"delocate",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
@@ -303,10 +371,22 @@ def setup_python(
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
)
|
||||
elif build_frontend == "build[uv]":
|
||||
assert uv_path is not None
|
||||
call(
|
||||
uv_path,
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"delocate",
|
||||
"build[virtualenv, uv]",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
)
|
||||
else:
|
||||
assert_never(build_frontend)
|
||||
|
||||
return env
|
||||
return base_python, env
|
||||
|
||||
|
||||
def build(options: Options, tmp_path: Path) -> None:
|
||||
@@ -335,6 +415,14 @@ 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 or BuildFrontendConfig("pip")
|
||||
use_uv = build_frontend.name == "build[uv]" and Version(config.version) >= Version(
|
||||
"3.8"
|
||||
)
|
||||
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"]
|
||||
log.build_start(config.identifier)
|
||||
|
||||
identifier_tmp_dir = tmp_path / config.identifier
|
||||
@@ -352,13 +440,15 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
build_options.dependency_constraints.get_for_python_version(config.version),
|
||||
]
|
||||
|
||||
env = setup_python(
|
||||
base_python, env = setup_python(
|
||||
identifier_tmp_dir / "build",
|
||||
config,
|
||||
dependency_constraint_flags,
|
||||
build_options.environment,
|
||||
build_frontend.name,
|
||||
)
|
||||
if not use_uv:
|
||||
pip_version = get_pip_version(env)
|
||||
|
||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||
if compatible_wheel:
|
||||
@@ -383,6 +473,17 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
)
|
||||
extra_flags += build_frontend.args
|
||||
|
||||
build_env = env.copy()
|
||||
if not use_uv:
|
||||
build_env["VIRTUALENV_PIP"] = pip_version
|
||||
if build_options.dependency_constraints:
|
||||
constraint_path = build_options.dependency_constraints.get_for_python_version(
|
||||
config.version
|
||||
)
|
||||
combine_constraints(
|
||||
build_env, constraint_path, identifier_tmp_dir if use_uv else None
|
||||
)
|
||||
|
||||
if build_frontend.name == "pip":
|
||||
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
|
||||
@@ -396,21 +497,14 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
f"--wheel-dir={built_wheel_dir}",
|
||||
"--no-deps",
|
||||
*extra_flags,
|
||||
env=env,
|
||||
env=build_env,
|
||||
)
|
||||
elif build_frontend.name == "build":
|
||||
elif build_frontend.name == "build" or build_frontend.name == "build[uv]":
|
||||
if not 0 <= build_options.build_verbosity < 2:
|
||||
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
||||
log.warning(msg)
|
||||
build_env = env.copy()
|
||||
if build_options.dependency_constraints:
|
||||
constraint_path = (
|
||||
build_options.dependency_constraints.get_for_python_version(
|
||||
config.version
|
||||
)
|
||||
)
|
||||
build_env["PIP_CONSTRAINT"] = constraint_path.as_uri()
|
||||
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
|
||||
if use_uv and "--no-isolation" not in extra_flags and "-n" not in extra_flags:
|
||||
extra_flags.append("--installer=uv")
|
||||
call(
|
||||
"python",
|
||||
"-m",
|
||||
@@ -429,7 +523,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
repaired_wheel_dir.mkdir()
|
||||
|
||||
if built_wheel.name.endswith("none-any.whl"):
|
||||
raise NonPlatformWheelError()
|
||||
raise errors.NonPlatformWheelError()
|
||||
|
||||
if build_options.repair_command:
|
||||
log.step("Repairing wheel...")
|
||||
@@ -454,7 +548,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
|
||||
|
||||
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
|
||||
raise AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
|
||||
log.step_end()
|
||||
|
||||
@@ -488,10 +582,9 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
unwrap(
|
||||
"""
|
||||
While arm64 wheels can be built on x86_64, they cannot be
|
||||
tested. The ability to test the arm64 wheels will be added in a
|
||||
future release of cibuildwheel, once Apple Silicon CI runners
|
||||
are widely available. To silence this warning, set
|
||||
`CIBW_TEST_SKIP: *-macosx_arm64`.
|
||||
tested. Consider building arm64 wheels natively, if your CI
|
||||
provider offers this. To silence this warning, set
|
||||
`CIBW_TEST_SKIP: "*-macosx_arm64"`.
|
||||
"""
|
||||
)
|
||||
)
|
||||
@@ -500,11 +593,11 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
unwrap(
|
||||
"""
|
||||
While universal2 wheels can be built on x86_64, the arm64 part
|
||||
of them cannot currently be tested. The ability to test the
|
||||
arm64 part of a universal2 wheel will be added in a future
|
||||
release of cibuildwheel, once Apple Silicon CI runners are
|
||||
widely available. To silence this warning, set
|
||||
`CIBW_TEST_SKIP: *-macosx_universal2:arm64`.
|
||||
of the wheel cannot be tested on x86_64. Consider building
|
||||
universal2 wheels on an arm64 runner, if your CI provider offers
|
||||
this. Notably, an arm64 runner can also test the x86_64 part of
|
||||
the wheel, through Rosetta emulation. To silence this warning,
|
||||
set `CIBW_TEST_SKIP: "*-macosx_universal2:arm64"`.
|
||||
"""
|
||||
)
|
||||
)
|
||||
@@ -525,7 +618,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
Silicon machine. This is because we use the x86_64 installer of
|
||||
CPython 3.8. See the discussion in
|
||||
https://github.com/pypa/cibuildwheel/pull/1169 for the details. To
|
||||
silence this warning, set `CIBW_TEST_SKIP: cp38-macosx_*:arm64`.
|
||||
silence this warning, set `CIBW_TEST_SKIP: "cp38-macosx_*:arm64"`.
|
||||
"""
|
||||
)
|
||||
)
|
||||
@@ -541,15 +634,18 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
|
||||
# set up a virtual environment to install and test from, to make sure
|
||||
# there are no dependencies that were pulled in at build time.
|
||||
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
|
||||
if not use_uv:
|
||||
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
|
||||
|
||||
venv_dir = identifier_tmp_dir / "venv-test"
|
||||
venv_dir = identifier_tmp_dir / f"venv-test-{testing_arch}"
|
||||
|
||||
arch_prefix = []
|
||||
uv_arch_args = []
|
||||
if testing_arch != machine_arch:
|
||||
if machine_arch == "arm64" and testing_arch == "x86_64":
|
||||
# rosetta2 will provide the emulation with just the arch prefix.
|
||||
arch_prefix = ["arch", "-x86_64"]
|
||||
uv_arch_args = ["--python-platform", "x86_64-apple-darwin"]
|
||||
else:
|
||||
msg = f"don't know how to emulate {testing_arch} on {machine_arch}"
|
||||
raise RuntimeError(msg)
|
||||
@@ -558,17 +654,27 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
call_with_arch = functools.partial(call, *arch_prefix)
|
||||
shell_with_arch = functools.partial(call, *arch_prefix, "/bin/sh", "-c")
|
||||
|
||||
# Use --no-download to ensure determinism by using seed libraries
|
||||
# built into virtualenv
|
||||
call_with_arch("python", "-m", "virtualenv", "--no-download", venv_dir, env=env)
|
||||
if use_uv:
|
||||
pip_install = functools.partial(call, *pip, "install", *uv_arch_args)
|
||||
call("uv", "venv", venv_dir, f"--python={base_python}", env=env)
|
||||
else:
|
||||
pip_install = functools.partial(call_with_arch, *pip, "install")
|
||||
# Use pip version from the initial env to ensure determinism
|
||||
venv_args = ["--no-periodic-update", f"--pip={pip_version}"]
|
||||
# In Python<3.12, setuptools & wheel are installed as well, use virtualenv embedded ones
|
||||
if Version(config.version) < Version("3.12"):
|
||||
venv_args.extend(("--setuptools=embed", "--wheel=embed"))
|
||||
call_with_arch("python", "-m", "virtualenv", *venv_args, venv_dir, env=env)
|
||||
|
||||
virtualenv_env = env.copy()
|
||||
virtualenv_env["MACOSX_DEPLOYMENT_TARGET"] = get_test_macosx_deployment_target()
|
||||
virtualenv_env["PATH"] = os.pathsep.join(
|
||||
[
|
||||
str(venv_dir / "bin"),
|
||||
virtualenv_env["PATH"],
|
||||
]
|
||||
)
|
||||
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
|
||||
|
||||
# check that we are using the Python from the virtual environment
|
||||
call_with_arch("which", "python", env=virtualenv_env)
|
||||
@@ -582,17 +688,33 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
shell_with_arch(before_test_prepared, env=virtualenv_env)
|
||||
|
||||
# install the wheel
|
||||
call_with_arch(
|
||||
"pip",
|
||||
"install",
|
||||
if is_cp38 and python_arch == "x86_64":
|
||||
virtualenv_env_install_wheel = virtualenv_env.copy()
|
||||
virtualenv_env_install_wheel["SYSTEM_VERSION_COMPAT"] = "0"
|
||||
log.notice(
|
||||
unwrap(
|
||||
"""
|
||||
Setting SYSTEM_VERSION_COMPAT=0 to ensure CPython 3.8 can get
|
||||
correct macOS version and allow installation of wheels with
|
||||
MACOSX_DEPLOYMENT_TARGET >= 11.0.
|
||||
See https://github.com/pypa/cibuildwheel/issues/1767 for the
|
||||
details.
|
||||
"""
|
||||
)
|
||||
)
|
||||
else:
|
||||
virtualenv_env_install_wheel = virtualenv_env
|
||||
|
||||
pip_install(
|
||||
f"{repaired_wheel}{build_options.test_extras}",
|
||||
env=virtualenv_env,
|
||||
env=virtualenv_env_install_wheel,
|
||||
)
|
||||
|
||||
# test the wheel
|
||||
if build_options.test_requires:
|
||||
call_with_arch(
|
||||
"pip", "install", *build_options.test_requires, env=virtualenv_env
|
||||
pip_install(
|
||||
*build_options.test_requires,
|
||||
env=virtualenv_env_install_wheel,
|
||||
)
|
||||
|
||||
# run the tests from a temp dir, with an absolute path in the command
|
||||
@@ -613,18 +735,18 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
|
||||
# we're all done here; move it to output (overwrite existing)
|
||||
if compatible_wheel is None:
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
(build_options.output_dir / repaired_wheel.name).unlink()
|
||||
|
||||
shutil.move(str(repaired_wheel), build_options.output_dir)
|
||||
built_wheels.append(build_options.output_dir / repaired_wheel.name)
|
||||
output_wheel = build_options.output_dir.joinpath(repaired_wheel.name)
|
||||
moved_wheel = move_file(repaired_wheel, output_wheel)
|
||||
if moved_wheel != output_wheel.resolve():
|
||||
log.warning(
|
||||
"{repaired_wheel} was moved to {moved_wheel} instead of {output_wheel}"
|
||||
)
|
||||
built_wheels.append(output_wheel)
|
||||
|
||||
# clean up
|
||||
shutil.rmtree(identifier_tmp_dir)
|
||||
|
||||
log.build_end()
|
||||
except subprocess.CalledProcessError as error:
|
||||
log.step_end_with_error(
|
||||
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
|
||||
)
|
||||
sys.exit(1)
|
||||
msg = f"Command {error.cmd} failed with code {error.returncode}. {error.stdout or ''}"
|
||||
raise errors.FatalError(msg) from error
|
||||
|
||||
@@ -11,13 +11,20 @@ import sys
|
||||
import typing
|
||||
import uuid
|
||||
from collections.abc import Mapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
from types import TracebackType
|
||||
from typing import IO, Dict, Literal
|
||||
|
||||
from ._compat.typing import Self
|
||||
from .typing import PathOrStr, PopenBytes
|
||||
from .util import CIProvider, detect_ci_provider, parse_key_value_string
|
||||
from .util import (
|
||||
CIProvider,
|
||||
call,
|
||||
detect_ci_provider,
|
||||
parse_key_value_string,
|
||||
strtobool,
|
||||
)
|
||||
|
||||
ContainerEngineName = Literal["docker", "podman"]
|
||||
|
||||
@@ -25,12 +32,15 @@ ContainerEngineName = Literal["docker", "podman"]
|
||||
@dataclass(frozen=True)
|
||||
class OCIContainerEngineConfig:
|
||||
name: ContainerEngineName
|
||||
create_args: Sequence[str] = ()
|
||||
create_args: tuple[str, ...] = field(default_factory=tuple)
|
||||
disable_host_mount: bool = False
|
||||
|
||||
@staticmethod
|
||||
def from_config_string(config_string: str) -> OCIContainerEngineConfig:
|
||||
config_dict = parse_key_value_string(
|
||||
config_string, ["name"], ["create_args", "create-args"]
|
||||
config_string,
|
||||
["name"],
|
||||
["create_args", "create-args", "disable_host_mount", "disable-host-mount"],
|
||||
)
|
||||
name = " ".join(config_dict["name"])
|
||||
if name not in {"docker", "podman"}:
|
||||
@@ -38,15 +48,28 @@ class OCIContainerEngineConfig:
|
||||
raise ValueError(msg)
|
||||
|
||||
name = typing.cast(ContainerEngineName, name)
|
||||
# some flexibility in the option name to cope with TOML conventions
|
||||
# some flexibility in the option names to cope with TOML conventions
|
||||
create_args = config_dict.get("create_args") or config_dict.get("create-args") or []
|
||||
return OCIContainerEngineConfig(name=name, create_args=create_args)
|
||||
disable_host_mount_options = (
|
||||
config_dict.get("disable_host_mount") or config_dict.get("disable-host-mount") or []
|
||||
)
|
||||
disable_host_mount = (
|
||||
strtobool(disable_host_mount_options[-1]) if disable_host_mount_options else False
|
||||
)
|
||||
|
||||
return OCIContainerEngineConfig(
|
||||
name=name, create_args=tuple(create_args), disable_host_mount=disable_host_mount
|
||||
)
|
||||
|
||||
def options_summary(self) -> str | dict[str, str]:
|
||||
if not self.create_args:
|
||||
return self.name
|
||||
else:
|
||||
return {"name": self.name, "create_args": repr(self.create_args)}
|
||||
return {
|
||||
"name": self.name,
|
||||
"create_args": repr(self.create_args),
|
||||
"disable_host_mount": str(self.disable_host_mount),
|
||||
}
|
||||
|
||||
|
||||
DEFAULT_ENGINE = OCIContainerEngineConfig("docker")
|
||||
@@ -85,7 +108,7 @@ class OCIContainer:
|
||||
self,
|
||||
*,
|
||||
image: str,
|
||||
simulate_32_bit: bool = False,
|
||||
enforce_32_bit: bool = False,
|
||||
cwd: PathOrStr | None = None,
|
||||
engine: OCIContainerEngineConfig = DEFAULT_ENGINE,
|
||||
):
|
||||
@@ -94,12 +117,12 @@ class OCIContainer:
|
||||
raise ValueError(msg)
|
||||
|
||||
self.image = image
|
||||
self.simulate_32_bit = simulate_32_bit
|
||||
self.enforce_32_bit = enforce_32_bit
|
||||
self.cwd = cwd
|
||||
self.name: str | None = None
|
||||
self.engine = engine
|
||||
|
||||
def __enter__(self) -> OCIContainer:
|
||||
def __enter__(self) -> Self:
|
||||
self.name = f"cibuildwheel-{uuid.uuid4()}"
|
||||
|
||||
# work-around for Travis-CI PPC64le Docker runs since 2021:
|
||||
@@ -110,7 +133,17 @@ class OCIContainer:
|
||||
if detect_ci_provider() == CIProvider.travis_ci and platform.machine() == "ppc64le":
|
||||
network_args = ["--network=host"]
|
||||
|
||||
shell_args = ["linux32", "/bin/bash"] if self.simulate_32_bit else ["/bin/bash"]
|
||||
simulate_32_bit = False
|
||||
if self.enforce_32_bit:
|
||||
# If the architecture running the image is already the right one
|
||||
# or the image entrypoint takes care of enforcing this, then we don't need to
|
||||
# simulate this
|
||||
container_machine = call(
|
||||
self.engine.name, "run", "--rm", self.image, "uname", "-m", capture_stdout=True
|
||||
).strip()
|
||||
simulate_32_bit = container_machine != "i686"
|
||||
|
||||
shell_args = ["linux32", "/bin/bash"] if simulate_32_bit else ["/bin/bash"]
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
@@ -120,7 +153,7 @@ class OCIContainer:
|
||||
"--env=SOURCE_DATE_EPOCH",
|
||||
f"--name={self.name}",
|
||||
"--interactive",
|
||||
"--volume=/:/host", # ignored on CircleCI
|
||||
*(["--volume=/:/host"] if not self.engine.disable_host_mount else []),
|
||||
*network_args,
|
||||
*self.engine.create_args,
|
||||
self.image,
|
||||
@@ -178,12 +211,14 @@ class OCIContainer:
|
||||
|
||||
assert isinstance(self.name, str)
|
||||
|
||||
subprocess.run(
|
||||
[self.engine.name, "rm", "--force", "-v", self.name],
|
||||
stdout=subprocess.DEVNULL,
|
||||
check=False,
|
||||
)
|
||||
self.name = None
|
||||
keep_container = strtobool(os.environ.get("CIBW_DEBUG_KEEP_CONTAINER", ""))
|
||||
if not keep_container:
|
||||
subprocess.run(
|
||||
[self.engine.name, "rm", "--force", "-v", self.name],
|
||||
stdout=subprocess.DEVNULL,
|
||||
check=False,
|
||||
)
|
||||
self.name = None
|
||||
|
||||
def copy_into(self, from_path: Path, to_path: PurePath) -> None:
|
||||
# `docker cp` causes 'no space left on device' error when
|
||||
|
||||
+192
-98
@@ -5,19 +5,19 @@ import configparser
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import difflib
|
||||
import enum
|
||||
import functools
|
||||
import shlex
|
||||
import sys
|
||||
import textwrap
|
||||
import traceback
|
||||
from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Set
|
||||
from collections.abc import Callable, Generator, Iterable, Iterator, Set
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Literal, TypedDict, Union
|
||||
from typing import Any, Literal, Mapping, Sequence, TypedDict, Union # noqa: TID251
|
||||
|
||||
from packaging.specifiers import SpecifierSet
|
||||
|
||||
from . import errors
|
||||
from ._compat import tomllib
|
||||
from ._compat.typing import NotRequired
|
||||
from ._compat.typing import NotRequired, assert_never
|
||||
from .architecture import Architecture
|
||||
from .environment import EnvironmentParseError, ParsedEnvironment, parse_environment
|
||||
from .logger import log
|
||||
@@ -31,7 +31,6 @@ from .util import (
|
||||
BuildSelector,
|
||||
DependencyConstraints,
|
||||
TestSelector,
|
||||
cached_property,
|
||||
format_safe,
|
||||
resources_dir,
|
||||
selector_matches,
|
||||
@@ -51,6 +50,7 @@ class CommandLineArguments:
|
||||
print_build_identifiers: bool
|
||||
allow_empty: bool
|
||||
prerelease_pythons: bool
|
||||
debug_traceback: bool
|
||||
|
||||
@staticmethod
|
||||
def defaults() -> CommandLineArguments:
|
||||
@@ -64,6 +64,7 @@ class CommandLineArguments:
|
||||
package_dir=Path("."),
|
||||
prerelease_pythons=False,
|
||||
print_build_identifiers=False,
|
||||
debug_traceback=False,
|
||||
)
|
||||
|
||||
|
||||
@@ -74,7 +75,7 @@ class GlobalOptions:
|
||||
build_selector: BuildSelector
|
||||
test_selector: TestSelector
|
||||
architectures: set[Architecture]
|
||||
container_engine: OCIContainerEngineConfig
|
||||
allow_empty: bool
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
@@ -94,6 +95,7 @@ class BuildOptions:
|
||||
build_verbosity: int
|
||||
build_frontend: BuildFrontendConfig | None
|
||||
config_settings: str
|
||||
container_engine: OCIContainerEngineConfig
|
||||
|
||||
@property
|
||||
def package_dir(self) -> Path:
|
||||
@@ -116,13 +118,14 @@ class BuildOptions:
|
||||
return self.globals.architectures
|
||||
|
||||
|
||||
Setting = Union[Dict[str, str], List[str], str, int]
|
||||
Setting = Union[Mapping[str, str], Sequence[str], str, int, bool]
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class Override:
|
||||
select_pattern: str
|
||||
options: dict[str, Setting]
|
||||
inherit: dict[str, InheritRule]
|
||||
|
||||
|
||||
MANYLINUX_OPTIONS = {f"manylinux-{build_platform}-image" for build_platform in MANYLINUX_ARCHS}
|
||||
@@ -150,28 +153,116 @@ class ConfigOptionError(KeyError):
|
||||
pass
|
||||
|
||||
|
||||
def _dig_first(*pairs: tuple[Mapping[str, Setting], str], ignore_empty: bool = False) -> Setting:
|
||||
"""
|
||||
Return the first dict item that matches from pairs of dicts and keys.
|
||||
Will throw a KeyError if missing.
|
||||
class InheritRule(enum.Enum):
|
||||
NONE = enum.auto()
|
||||
APPEND = enum.auto()
|
||||
PREPEND = enum.auto()
|
||||
|
||||
_dig_first((dict1, "key1"), (dict2, "key2"), ...)
|
||||
|
||||
def _resolve_cascade(
|
||||
*pairs: tuple[Setting | None, InheritRule],
|
||||
ignore_empty: bool = False,
|
||||
list_sep: str | None = None,
|
||||
table_format: TableFmt | None = None,
|
||||
) -> str:
|
||||
"""
|
||||
Given a cascade of values with inherit rules, resolve them into a single
|
||||
value.
|
||||
|
||||
'None' values mean that the option was not set at that level, and are
|
||||
ignored. If `ignore_empty` is True, empty values are ignored too.
|
||||
|
||||
Values start with defaults, followed by more specific rules. If rules are
|
||||
NONE, the last non-null value is returned. If a rule is APPEND or PREPEND,
|
||||
the value is concatenated with the previous value.
|
||||
|
||||
The following idiom can be used to get the first matching value:
|
||||
|
||||
_resolve_cascade(("value1", Inherit.NONE), ("value2", Inherit.NONE), ...)))
|
||||
"""
|
||||
if not pairs:
|
||||
msg = "pairs cannot be empty"
|
||||
raise ValueError(msg)
|
||||
|
||||
for dict_like, key in pairs:
|
||||
if key in dict_like:
|
||||
value = dict_like[key]
|
||||
result: str | None = None
|
||||
|
||||
if ignore_empty and value == "":
|
||||
continue
|
||||
if table_format is not None:
|
||||
merge_sep = table_format["sep"]
|
||||
elif list_sep is not None:
|
||||
merge_sep = list_sep
|
||||
else:
|
||||
merge_sep = None
|
||||
|
||||
return value
|
||||
for value, rule in pairs:
|
||||
if value is None:
|
||||
continue
|
||||
|
||||
last_key = pairs[-1][1]
|
||||
raise KeyError(last_key)
|
||||
if ignore_empty and not value and value is not False:
|
||||
continue
|
||||
|
||||
value_string = _stringify_setting(value, list_sep, table_format)
|
||||
|
||||
result = _merge_values(
|
||||
result,
|
||||
value_string,
|
||||
rule=rule,
|
||||
merge_sep=merge_sep,
|
||||
)
|
||||
|
||||
if result is None:
|
||||
msg = "a setting should at least have a default value"
|
||||
raise ValueError(msg)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# pylint: disable-next=inconsistent-return-statements
|
||||
def _merge_values(before: str | None, after: str, rule: InheritRule, merge_sep: str | None) -> str:
|
||||
if rule == InheritRule.NONE:
|
||||
return after
|
||||
|
||||
if not before:
|
||||
# if before is None, we can just return after
|
||||
# if before is an empty string, we shouldn't add any separator
|
||||
return after
|
||||
|
||||
if not after:
|
||||
# if after is an empty string, we shouldn't add any separator
|
||||
return before
|
||||
|
||||
if not merge_sep:
|
||||
msg = f"Don't know how to merge {before!r} and {after!r} with {rule}"
|
||||
raise ConfigOptionError(msg)
|
||||
|
||||
if rule == InheritRule.APPEND:
|
||||
return f"{before}{merge_sep}{after}"
|
||||
elif rule == InheritRule.PREPEND:
|
||||
return f"{after}{merge_sep}{before}"
|
||||
else:
|
||||
assert_never(rule)
|
||||
|
||||
|
||||
def _stringify_setting(
|
||||
setting: Setting, list_sep: str | None, table_format: TableFmt | None
|
||||
) -> str:
|
||||
if isinstance(setting, Mapping):
|
||||
if table_format is None:
|
||||
msg = f"Error converting {setting!r} to a string: this setting doesn't accept a table"
|
||||
raise ConfigOptionError(msg)
|
||||
return table_format["sep"].join(
|
||||
item for k, v in setting.items() for item in _inner_fmt(k, v, table_format)
|
||||
)
|
||||
|
||||
if not isinstance(setting, str) and isinstance(setting, Sequence):
|
||||
if list_sep is None:
|
||||
msg = f"Error converting {setting!r} to a string: this setting doesn't accept a list"
|
||||
raise ConfigOptionError(msg)
|
||||
return list_sep.join(setting)
|
||||
|
||||
if isinstance(setting, (bool, int)):
|
||||
return str(setting)
|
||||
|
||||
return setting
|
||||
|
||||
|
||||
class OptionsReader:
|
||||
@@ -244,7 +335,16 @@ class OptionsReader:
|
||||
if isinstance(select, list):
|
||||
select = " ".join(select)
|
||||
|
||||
self.overrides.append(Override(select, config_override))
|
||||
inherit = config_override.pop("inherit", {})
|
||||
if not isinstance(inherit, dict) or not all(
|
||||
i in {"none", "append", "prepend"} for i in inherit.values()
|
||||
):
|
||||
msg = "'inherit' must be a dict containing only {'none', 'append', 'prepend'} values"
|
||||
raise ConfigOptionError(msg)
|
||||
|
||||
inherit_enum = {k: InheritRule[v.upper()] for k, v in inherit.items()}
|
||||
|
||||
self.overrides.append(Override(select, config_override, inherit_enum))
|
||||
|
||||
def _validate_global_option(self, name: str) -> None:
|
||||
"""
|
||||
@@ -312,8 +412,8 @@ class OptionsReader:
|
||||
name: str,
|
||||
*,
|
||||
env_plat: bool = True,
|
||||
sep: str | None = None,
|
||||
table: TableFmt | None = None,
|
||||
list_sep: str | None = None,
|
||||
table_format: TableFmt | None = None,
|
||||
ignore_empty: bool = False,
|
||||
) -> str:
|
||||
"""
|
||||
@@ -335,41 +435,24 @@ class OptionsReader:
|
||||
envvar = f"CIBW_{name.upper().replace('-', '_')}"
|
||||
plat_envvar = f"{envvar}_{self.platform.upper()}"
|
||||
|
||||
# later overrides take precedence over earlier ones, so reverse the list
|
||||
active_config_overrides = reversed(self.active_config_overrides)
|
||||
|
||||
# get the option from the environment, then the config file, then finally the default.
|
||||
# get the option from the default, then the config file, then finally the environment.
|
||||
# platform-specific options are preferred, if they're allowed.
|
||||
result = _dig_first(
|
||||
(self.env if env_plat else {}, plat_envvar),
|
||||
(self.env, envvar),
|
||||
*[(o.options, name) for o in active_config_overrides],
|
||||
(self.config_platform_options, name),
|
||||
(self.config_options, name),
|
||||
(self.default_platform_options, name),
|
||||
(self.default_options, name),
|
||||
return _resolve_cascade(
|
||||
(self.default_options.get(name), InheritRule.NONE),
|
||||
(self.default_platform_options.get(name), InheritRule.NONE),
|
||||
(self.config_options.get(name), InheritRule.NONE),
|
||||
(self.config_platform_options.get(name), InheritRule.NONE),
|
||||
*[
|
||||
(o.options.get(name), o.inherit.get(name, InheritRule.NONE))
|
||||
for o in self.active_config_overrides
|
||||
],
|
||||
(self.env.get(envvar), InheritRule.NONE),
|
||||
(self.env.get(plat_envvar) if env_plat else None, InheritRule.NONE),
|
||||
ignore_empty=ignore_empty,
|
||||
list_sep=list_sep,
|
||||
table_format=table_format,
|
||||
)
|
||||
|
||||
if isinstance(result, dict):
|
||||
if table is None:
|
||||
msg = f"{name!r} does not accept a table"
|
||||
raise ConfigOptionError(msg)
|
||||
return table["sep"].join(
|
||||
item for k, v in result.items() for item in _inner_fmt(k, v, table)
|
||||
)
|
||||
|
||||
if isinstance(result, list):
|
||||
if sep is None:
|
||||
msg = f"{name!r} does not accept a list"
|
||||
raise ConfigOptionError(msg)
|
||||
return sep.join(result)
|
||||
|
||||
if isinstance(result, int):
|
||||
return str(result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _inner_fmt(k: str, v: Any, table: TableFmt) -> Iterator[str]:
|
||||
quote_function = table.get("quote", lambda a: a)
|
||||
@@ -378,6 +461,9 @@ def _inner_fmt(k: str, v: Any, table: TableFmt) -> Iterator[str]:
|
||||
for inner_v in v:
|
||||
qv = quote_function(inner_v)
|
||||
yield table["item"].format(k=k, v=qv)
|
||||
elif isinstance(v, bool):
|
||||
qv = quote_function(str(v))
|
||||
yield table["item"].format(k=k, v=qv)
|
||||
else:
|
||||
qv = quote_function(v)
|
||||
yield table["item"].format(k=k, v=qv)
|
||||
@@ -416,7 +502,7 @@ class Options:
|
||||
|
||||
return None
|
||||
|
||||
@cached_property
|
||||
@functools.cached_property
|
||||
def package_requires_python_str(self) -> str | None:
|
||||
args = self.command_line_arguments
|
||||
return get_requires_python_str(Path(args.package_dir))
|
||||
@@ -427,9 +513,15 @@ class Options:
|
||||
package_dir = args.package_dir
|
||||
output_dir = args.output_dir
|
||||
|
||||
build_config = self.reader.get("build", env_plat=False, sep=" ") or "*"
|
||||
skip_config = self.reader.get("skip", env_plat=False, sep=" ")
|
||||
test_skip = self.reader.get("test-skip", env_plat=False, sep=" ")
|
||||
build_config = self.reader.get("build", env_plat=False, list_sep=" ") or "*"
|
||||
skip_config = self.reader.get("skip", env_plat=False, list_sep=" ")
|
||||
test_skip = self.reader.get("test-skip", env_plat=False, list_sep=" ")
|
||||
|
||||
free_threaded_support = strtobool(
|
||||
self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True)
|
||||
)
|
||||
|
||||
allow_empty = args.allow_empty or strtobool(self.env.get("CIBW_ALLOW_EMPTY", "0"))
|
||||
|
||||
prerelease_pythons = args.prerelease_pythons or strtobool(
|
||||
self.env.get("CIBW_PRERELEASE_PYTHONS", "0")
|
||||
@@ -442,7 +534,7 @@ class Options:
|
||||
)
|
||||
requires_python = None if requires_python_str is None else SpecifierSet(requires_python_str)
|
||||
|
||||
archs_config_str = args.archs or self.reader.get("archs", sep=" ")
|
||||
archs_config_str = args.archs or self.reader.get("archs", list_sep=" ")
|
||||
architectures = Architecture.parse_config(archs_config_str, platform=self.platform)
|
||||
|
||||
# Process `--only`
|
||||
@@ -451,33 +543,24 @@ class Options:
|
||||
skip_config = ""
|
||||
architectures = Architecture.all_archs(self.platform)
|
||||
prerelease_pythons = True
|
||||
free_threaded_support = True
|
||||
|
||||
build_selector = BuildSelector(
|
||||
build_config=build_config,
|
||||
skip_config=skip_config,
|
||||
requires_python=requires_python,
|
||||
prerelease_pythons=prerelease_pythons,
|
||||
free_threaded_support=free_threaded_support,
|
||||
)
|
||||
test_selector = TestSelector(skip_config=test_skip)
|
||||
|
||||
container_engine_str = self.reader.get(
|
||||
"container-engine", table={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote}
|
||||
)
|
||||
|
||||
try:
|
||||
container_engine = OCIContainerEngineConfig.from_config_string(container_engine_str)
|
||||
except ValueError as e:
|
||||
msg = f"cibuildwheel: Failed to parse container config. {e}"
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
return GlobalOptions(
|
||||
package_dir=package_dir,
|
||||
output_dir=output_dir,
|
||||
build_selector=build_selector,
|
||||
test_selector=test_selector,
|
||||
architectures=architectures,
|
||||
container_engine=container_engine,
|
||||
allow_empty=allow_empty,
|
||||
)
|
||||
|
||||
def build_options(self, identifier: str | None) -> BuildOptions:
|
||||
@@ -486,29 +569,30 @@ class Options:
|
||||
"""
|
||||
|
||||
with self.reader.identifier(identifier):
|
||||
before_all = self.reader.get("before-all", sep=" && ")
|
||||
before_all = self.reader.get("before-all", list_sep=" && ")
|
||||
|
||||
environment_config = self.reader.get(
|
||||
"environment", table={"item": '{k}="{v}"', "sep": " "}
|
||||
"environment", table_format={"item": '{k}="{v}"', "sep": " "}
|
||||
)
|
||||
environment_pass = self.reader.get("environment-pass", sep=" ").split()
|
||||
before_build = self.reader.get("before-build", sep=" && ")
|
||||
repair_command = self.reader.get("repair-wheel-command", sep=" && ")
|
||||
environment_pass = self.reader.get("environment-pass", list_sep=" ").split()
|
||||
before_build = self.reader.get("before-build", list_sep=" && ")
|
||||
repair_command = self.reader.get("repair-wheel-command", list_sep=" && ")
|
||||
config_settings = self.reader.get(
|
||||
"config-settings", table={"item": "{k}={v}", "sep": " ", "quote": shlex.quote}
|
||||
"config-settings",
|
||||
table_format={"item": "{k}={v}", "sep": " ", "quote": shlex.quote},
|
||||
)
|
||||
|
||||
dependency_versions = self.reader.get("dependency-versions")
|
||||
test_command = self.reader.get("test-command", sep=" && ")
|
||||
before_test = self.reader.get("before-test", sep=" && ")
|
||||
test_requires = self.reader.get("test-requires", sep=" ").split()
|
||||
test_extras = self.reader.get("test-extras", sep=",")
|
||||
test_command = self.reader.get("test-command", list_sep=" && ")
|
||||
before_test = self.reader.get("before-test", list_sep=" && ")
|
||||
test_requires = self.reader.get("test-requires", list_sep=" ").split()
|
||||
test_extras = self.reader.get("test-extras", list_sep=",")
|
||||
build_verbosity_str = self.reader.get("build-verbosity")
|
||||
|
||||
build_frontend_str = self.reader.get(
|
||||
"build-frontend",
|
||||
env_plat=False,
|
||||
table={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
||||
table_format={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
||||
)
|
||||
build_frontend: BuildFrontendConfig | None
|
||||
if not build_frontend_str or build_frontend_str == "default":
|
||||
@@ -517,24 +601,20 @@ class Options:
|
||||
try:
|
||||
build_frontend = BuildFrontendConfig.from_config_string(build_frontend_str)
|
||||
except ValueError as e:
|
||||
print(f"cibuildwheel: {e}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
msg = f"Failed to parse build frontend. {e}"
|
||||
raise errors.ConfigurationError(msg) from e
|
||||
|
||||
try:
|
||||
environment = parse_environment(environment_config)
|
||||
except (EnvironmentParseError, ValueError):
|
||||
print(
|
||||
f"cibuildwheel: Malformed environment option {environment_config!r}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
traceback.print_exc(None, sys.stderr)
|
||||
sys.exit(2)
|
||||
except (EnvironmentParseError, ValueError) as e:
|
||||
msg = f"Malformed environment option {environment_config!r}"
|
||||
raise errors.ConfigurationError(msg) from e
|
||||
|
||||
# Pass through environment variables
|
||||
if self.platform == "linux":
|
||||
for env_var_name in environment_pass:
|
||||
for env_var_name in reversed(environment_pass):
|
||||
with contextlib.suppress(KeyError):
|
||||
environment.add(env_var_name, self.env[env_var_name])
|
||||
environment.add(env_var_name, self.env[env_var_name], prepend=True)
|
||||
|
||||
if dependency_versions == "pinned":
|
||||
dependency_constraints: None | (
|
||||
@@ -556,6 +636,8 @@ class Options:
|
||||
|
||||
manylinux_images: dict[str, str] = {}
|
||||
musllinux_images: dict[str, str] = {}
|
||||
container_engine: OCIContainerEngineConfig | None = None
|
||||
|
||||
if self.platform == "linux":
|
||||
all_pinned_container_images = _get_pinned_container_images()
|
||||
|
||||
@@ -582,7 +664,7 @@ class Options:
|
||||
config_value = self.reader.get(f"musllinux-{build_platform}-image")
|
||||
|
||||
if not config_value:
|
||||
image = pinned_images["musllinux_1_1"]
|
||||
image = pinned_images["musllinux_1_2"]
|
||||
elif config_value in pinned_images:
|
||||
image = pinned_images[config_value]
|
||||
else:
|
||||
@@ -590,6 +672,17 @@ class Options:
|
||||
|
||||
musllinux_images[build_platform] = image
|
||||
|
||||
container_engine_str = self.reader.get(
|
||||
"container-engine",
|
||||
table_format={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
||||
)
|
||||
|
||||
try:
|
||||
container_engine = OCIContainerEngineConfig.from_config_string(container_engine_str)
|
||||
except ValueError as e:
|
||||
msg = f"Failed to parse container config. {e}"
|
||||
raise errors.ConfigurationError(msg) from e
|
||||
|
||||
return BuildOptions(
|
||||
globals=self.globals,
|
||||
test_command=test_command,
|
||||
@@ -606,6 +699,7 @@ class Options:
|
||||
musllinux_images=musllinux_images or None,
|
||||
build_frontend=build_frontend,
|
||||
config_settings=config_settings,
|
||||
container_engine=container_engine,
|
||||
)
|
||||
|
||||
def check_for_invalid_configuration(self, identifiers: Iterable[str]) -> None:
|
||||
@@ -631,7 +725,7 @@ class Options:
|
||||
deprecated_selectors("CIBW_SKIP", build_selector.skip_config)
|
||||
deprecated_selectors("CIBW_TEST_SKIP", test_selector.skip_config)
|
||||
|
||||
@cached_property
|
||||
@functools.cached_property
|
||||
def defaults(self) -> Options:
|
||||
return Options(
|
||||
platform=self.platform,
|
||||
@@ -767,6 +861,6 @@ def _get_pinned_container_images() -> Mapping[str, Mapping[str, str]]:
|
||||
def deprecated_selectors(name: str, selector: str, *, error: bool = False) -> None:
|
||||
if "p2" in selector or "p35" in selector:
|
||||
msg = f"cibuildwheel 2.x no longer supports Python < 3.6. Please use the 1.x series or update {name}"
|
||||
print(msg, file=sys.stderr)
|
||||
if error:
|
||||
sys.exit(4)
|
||||
raise errors.DeprecationError(msg)
|
||||
log.warning(msg)
|
||||
|
||||
@@ -39,10 +39,8 @@ def is_main(parent: ast.AST | None) -> bool:
|
||||
if len(mains) != 1:
|
||||
return False
|
||||
consts = {x for x in values if isinstance(x, ast.Name) and x.id == "__name__"}
|
||||
if len(consts) != 1:
|
||||
return False
|
||||
|
||||
return True
|
||||
return len(consts) == 1
|
||||
|
||||
|
||||
class Analyzer(ast.NodeVisitor):
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
from collections.abc import Sequence, Set
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from filelock import FileLock
|
||||
|
||||
from . import errors
|
||||
from .architecture import Architecture
|
||||
from .environment import ParsedEnvironment
|
||||
from .logger import log
|
||||
from .options import Options
|
||||
from .typing import PathOrStr
|
||||
from .util import (
|
||||
CIBW_CACHE_PATH,
|
||||
BuildFrontendConfig,
|
||||
BuildSelector,
|
||||
call,
|
||||
combine_constraints,
|
||||
download,
|
||||
ensure_node,
|
||||
extract_zip,
|
||||
find_compatible_wheel,
|
||||
get_pip_version,
|
||||
move_file,
|
||||
prepare_command,
|
||||
read_python_configs,
|
||||
shell,
|
||||
split_config_settings,
|
||||
test_fail_cwd_file,
|
||||
virtualenv,
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PythonConfiguration:
|
||||
version: str
|
||||
identifier: str
|
||||
pyodide_version: str
|
||||
emscripten_version: str
|
||||
node_version: str
|
||||
|
||||
|
||||
def install_emscripten(tmp: Path, version: str) -> Path:
|
||||
# We don't need to match the emsdk version to the version we install, but
|
||||
# we do for stability
|
||||
url = f"https://github.com/emscripten-core/emsdk/archive/refs/tags/{version}.zip"
|
||||
installation_path = CIBW_CACHE_PATH / f"emsdk-{version}"
|
||||
emsdk_path = installation_path / f"emsdk-{version}/emsdk"
|
||||
emcc_path = installation_path / f"emsdk-{version}/upstream/emscripten/emcc"
|
||||
with FileLock(f"{installation_path}.lock"):
|
||||
if installation_path.exists():
|
||||
return emcc_path
|
||||
emsdk_zip = tmp / "emsdk.zip"
|
||||
download(url, emsdk_zip)
|
||||
installation_path.mkdir()
|
||||
extract_zip(emsdk_zip, installation_path)
|
||||
call(emsdk_path, "install", version)
|
||||
call(emsdk_path, "activate", version)
|
||||
|
||||
return emcc_path
|
||||
|
||||
|
||||
def install_xbuildenv(env: dict[str, str], pyodide_version: str) -> str:
|
||||
pyodide_root = (
|
||||
CIBW_CACHE_PATH
|
||||
/ f".pyodide-xbuildenv-{pyodide_version}/{pyodide_version}/xbuildenv/pyodide-root"
|
||||
)
|
||||
with FileLock(CIBW_CACHE_PATH / "xbuildenv.lock"):
|
||||
if pyodide_root.exists():
|
||||
return str(pyodide_root)
|
||||
|
||||
# We don't want to mutate env but we need to delete any existing
|
||||
# PYODIDE_ROOT so copy it first.
|
||||
env = dict(env)
|
||||
env.pop("PYODIDE_ROOT", None)
|
||||
call(
|
||||
"pyodide",
|
||||
"xbuildenv",
|
||||
"install",
|
||||
pyodide_version,
|
||||
env=env,
|
||||
cwd=CIBW_CACHE_PATH,
|
||||
)
|
||||
return str(pyodide_root)
|
||||
|
||||
|
||||
def get_base_python(identifier: str) -> Path:
|
||||
implementation_id = identifier.split("-")[0]
|
||||
majorminor = implementation_id[len("cp") :]
|
||||
version_info = (int(majorminor[0]), int(majorminor[1:]))
|
||||
if version_info == sys.version_info[:2]:
|
||||
return Path(sys.executable)
|
||||
|
||||
major_minor = ".".join(str(v) for v in version_info)
|
||||
python_name = f"python{major_minor}"
|
||||
which_python = shutil.which(python_name)
|
||||
if which_python is None:
|
||||
msg = f"CPython {major_minor} is not installed."
|
||||
raise errors.FatalError(msg)
|
||||
return Path(which_python)
|
||||
|
||||
|
||||
def setup_python(
|
||||
tmp: Path,
|
||||
python_configuration: PythonConfiguration,
|
||||
dependency_constraint_flags: Sequence[PathOrStr],
|
||||
environment: ParsedEnvironment,
|
||||
) -> dict[str, str]:
|
||||
base_python = get_base_python(python_configuration.identifier)
|
||||
|
||||
log.step("Setting up build environment...")
|
||||
venv_path = tmp / "venv"
|
||||
env = virtualenv(python_configuration.version, base_python, venv_path, [], use_uv=False)
|
||||
venv_bin_path = venv_path / "bin"
|
||||
assert venv_bin_path.exists()
|
||||
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
|
||||
|
||||
# upgrade pip to the version matching our constraints
|
||||
# if necessary, reinstall it to ensure that it's available on PATH as 'pip'
|
||||
call(
|
||||
"python",
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"pip",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
cwd=venv_path,
|
||||
)
|
||||
|
||||
env = environment.as_dictionary(prev_environment=env)
|
||||
|
||||
# check what pip version we're on
|
||||
assert (venv_bin_path / "pip").exists()
|
||||
call("which", "pip", env=env)
|
||||
call("pip", "--version", env=env)
|
||||
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
|
||||
if which_pip != str(venv_bin_path / "pip"):
|
||||
msg = "pip available on PATH doesn't match our venv instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
# check what Python version we're on
|
||||
call("which", "python", env=env)
|
||||
call("python", "--version", env=env)
|
||||
which_python = call("which", "python", env=env, capture_stdout=True).strip()
|
||||
if which_python != str(venv_bin_path / "python"):
|
||||
msg = "python available on PATH doesn't match our venv instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
log.step("Installing build tools...")
|
||||
call(
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"auditwheel-emscripten",
|
||||
"build[virtualenv]",
|
||||
"pyodide-build",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
)
|
||||
|
||||
log.step("Installing emscripten...")
|
||||
emcc_path = install_emscripten(tmp, python_configuration.emscripten_version)
|
||||
|
||||
env["PATH"] = os.pathsep.join([str(emcc_path.parent), env["PATH"]])
|
||||
|
||||
log.step("Installing Pyodide xbuildenv...")
|
||||
env["PYODIDE_ROOT"] = install_xbuildenv(env, python_configuration.pyodide_version)
|
||||
|
||||
return env
|
||||
|
||||
|
||||
def get_python_configurations(
|
||||
build_selector: BuildSelector,
|
||||
architectures: Set[Architecture], # noqa: ARG001
|
||||
) -> list[PythonConfiguration]:
|
||||
full_python_configs = read_python_configs("pyodide")
|
||||
|
||||
python_configurations = [PythonConfiguration(**item) for item in full_python_configs]
|
||||
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
|
||||
return python_configurations
|
||||
|
||||
|
||||
def build(options: Options, tmp_path: Path) -> None:
|
||||
python_configurations = get_python_configurations(
|
||||
options.globals.build_selector, options.globals.architectures
|
||||
)
|
||||
|
||||
if not python_configurations:
|
||||
return
|
||||
|
||||
try:
|
||||
before_all_options_identifier = python_configurations[0].identifier
|
||||
before_all_options = options.build_options(before_all_options_identifier)
|
||||
|
||||
if before_all_options.before_all:
|
||||
log.step("Running before_all...")
|
||||
env = before_all_options.environment.as_dictionary(prev_environment=os.environ)
|
||||
before_all_prepared = prepare_command(
|
||||
before_all_options.before_all, project=".", package=before_all_options.package_dir
|
||||
)
|
||||
shell(before_all_prepared, env=env)
|
||||
|
||||
built_wheels: list[Path] = []
|
||||
|
||||
for config in python_configurations:
|
||||
build_options = options.build_options(config.identifier)
|
||||
build_frontend = build_options.build_frontend or BuildFrontendConfig("build")
|
||||
|
||||
if build_frontend.name == "pip":
|
||||
msg = "The pyodide platform doesn't support pip frontend"
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
log.build_start(config.identifier)
|
||||
|
||||
identifier_tmp_dir = tmp_path / config.identifier
|
||||
built_wheel_dir = identifier_tmp_dir / "built_wheel"
|
||||
repaired_wheel_dir = identifier_tmp_dir / "repaired_wheel"
|
||||
identifier_tmp_dir.mkdir()
|
||||
built_wheel_dir.mkdir()
|
||||
repaired_wheel_dir.mkdir()
|
||||
|
||||
dependency_constraint_flags: Sequence[PathOrStr] = []
|
||||
if build_options.dependency_constraints:
|
||||
constraints_path = build_options.dependency_constraints.get_for_python_version(
|
||||
config.version, variant="pyodide"
|
||||
)
|
||||
dependency_constraint_flags = ["-c", constraints_path]
|
||||
|
||||
env = setup_python(
|
||||
identifier_tmp_dir / "build",
|
||||
config,
|
||||
dependency_constraint_flags,
|
||||
build_options.environment,
|
||||
)
|
||||
pip_version = get_pip_version(env)
|
||||
# The Pyodide command line runner mounts all directories in the host
|
||||
# filesystem into the Pyodide file system, except for the custom
|
||||
# file systems /dev, /lib, /proc, and /tmp. Mounting the mount
|
||||
# points for alternate file systems causes some mysterious failure
|
||||
# of the process (it just quits without any clear error).
|
||||
#
|
||||
# Because of this, by default Pyodide can't see anything under /tmp.
|
||||
# This environment variable tells it also to mount our temp
|
||||
# directory.
|
||||
oldmounts = ""
|
||||
extra_mounts = [str(identifier_tmp_dir)]
|
||||
if str(Path(".").resolve()).startswith("/tmp"):
|
||||
extra_mounts.append(str(Path(".").resolve()))
|
||||
|
||||
if "_PYODIDE_EXTRA_MOUNTS" in env:
|
||||
oldmounts = env["_PYODIDE_EXTRA_MOUNTS"] + ":"
|
||||
env["_PYODIDE_EXTRA_MOUNTS"] = oldmounts + ":".join(extra_mounts)
|
||||
|
||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||
if compatible_wheel:
|
||||
log.step_end()
|
||||
print(
|
||||
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
|
||||
)
|
||||
built_wheel = compatible_wheel
|
||||
else:
|
||||
if build_options.before_build:
|
||||
log.step("Running before_build...")
|
||||
before_build_prepared = prepare_command(
|
||||
build_options.before_build, project=".", package=build_options.package_dir
|
||||
)
|
||||
shell(before_build_prepared, env=env)
|
||||
|
||||
log.step("Building wheel...")
|
||||
|
||||
extra_flags = split_config_settings(build_options.config_settings, "build")
|
||||
extra_flags += build_frontend.args
|
||||
|
||||
if not 0 <= build_options.build_verbosity < 2:
|
||||
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
||||
log.warning(msg)
|
||||
|
||||
build_env = env.copy()
|
||||
if build_options.dependency_constraints:
|
||||
combine_constraints(build_env, constraints_path, identifier_tmp_dir)
|
||||
build_env["VIRTUALENV_PIP"] = pip_version
|
||||
call(
|
||||
"pyodide",
|
||||
"build",
|
||||
build_options.package_dir,
|
||||
f"--outdir={built_wheel_dir}",
|
||||
*extra_flags,
|
||||
env=build_env,
|
||||
)
|
||||
built_wheel = next(built_wheel_dir.glob("*.whl"))
|
||||
|
||||
if built_wheel.name.endswith("none-any.whl"):
|
||||
raise errors.NonPlatformWheelError()
|
||||
|
||||
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,
|
||||
)
|
||||
shell(repair_command_prepared, env=env)
|
||||
else:
|
||||
shutil.move(str(built_wheel), repaired_wheel_dir)
|
||||
|
||||
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
|
||||
|
||||
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
|
||||
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
|
||||
if build_options.test_command and build_options.test_selector(config.identifier):
|
||||
log.step("Testing wheel...")
|
||||
|
||||
venv_dir = identifier_tmp_dir / "venv-test"
|
||||
# set up a virtual environment to install and test from, to make sure
|
||||
# there are no dependencies that were pulled in at build time.
|
||||
|
||||
virtualenv_env = env.copy()
|
||||
virtualenv_env["PATH"] = os.pathsep.join(
|
||||
[
|
||||
str(ensure_node(config.node_version)),
|
||||
virtualenv_env["PATH"],
|
||||
]
|
||||
)
|
||||
|
||||
# pyodide venv uses virtualenv under the hood
|
||||
# use the pip embedded with virtualenv & disable network updates
|
||||
virtualenv_create_env = virtualenv_env.copy()
|
||||
virtualenv_create_env["VIRTUALENV_PIP"] = pip_version
|
||||
virtualenv_create_env["VIRTUALENV_NO_PERIODIC_UPDATE"] = "1"
|
||||
|
||||
call("pyodide", "venv", venv_dir, env=virtualenv_create_env)
|
||||
|
||||
virtualenv_env["PATH"] = os.pathsep.join(
|
||||
[
|
||||
str(venv_dir / "bin"),
|
||||
virtualenv_env["PATH"],
|
||||
]
|
||||
)
|
||||
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
|
||||
|
||||
# check that we are using the Python from the virtual environment
|
||||
call("which", "python", env=virtualenv_env)
|
||||
|
||||
if build_options.before_test:
|
||||
before_test_prepared = prepare_command(
|
||||
build_options.before_test,
|
||||
project=".",
|
||||
package=build_options.package_dir,
|
||||
)
|
||||
shell(before_test_prepared, env=virtualenv_env)
|
||||
|
||||
# install the wheel
|
||||
call(
|
||||
"pip",
|
||||
"install",
|
||||
f"{repaired_wheel}{build_options.test_extras}",
|
||||
env=virtualenv_env,
|
||||
)
|
||||
|
||||
# test the wheel
|
||||
if build_options.test_requires:
|
||||
call("pip", "install", *build_options.test_requires, env=virtualenv_env)
|
||||
|
||||
# run the tests from a temp dir, with an absolute path in the command
|
||||
# (this ensures that Python runs the tests against the installed wheel
|
||||
# and not the repo code)
|
||||
test_command_prepared = prepare_command(
|
||||
build_options.test_command,
|
||||
project=Path(".").resolve(),
|
||||
package=build_options.package_dir.resolve(),
|
||||
)
|
||||
|
||||
test_cwd = identifier_tmp_dir / "test_cwd"
|
||||
test_cwd.mkdir(exist_ok=True)
|
||||
(test_cwd / "test_fail.py").write_text(test_fail_cwd_file.read_text())
|
||||
|
||||
shell(test_command_prepared, cwd=test_cwd, env=virtualenv_env)
|
||||
|
||||
# we're all done here; move it to output (overwrite existing)
|
||||
if compatible_wheel is None:
|
||||
output_wheel = build_options.output_dir.joinpath(repaired_wheel.name)
|
||||
moved_wheel = move_file(repaired_wheel, output_wheel)
|
||||
if moved_wheel != output_wheel.resolve():
|
||||
log.warning(
|
||||
"{repaired_wheel} was moved to {moved_wheel} instead of {output_wheel}"
|
||||
)
|
||||
built_wheels.append(output_wheel)
|
||||
|
||||
finally:
|
||||
pass
|
||||
@@ -7,6 +7,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-manylinux_x86_64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-manylinux_x86_64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-manylinux_x86_64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-manylinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-manylinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "cp36-manylinux_i686", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-manylinux_i686", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-manylinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
@@ -14,6 +16,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-manylinux_i686", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-manylinux_i686", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-manylinux_i686", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-manylinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-manylinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "pp37-manylinux_x86_64", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
|
||||
{ identifier = "pp38-manylinux_x86_64", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" },
|
||||
{ identifier = "pp39-manylinux_x86_64", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" },
|
||||
@@ -25,6 +29,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-manylinux_aarch64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-manylinux_aarch64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-manylinux_aarch64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-manylinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-manylinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "cp36-manylinux_ppc64le", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-manylinux_ppc64le", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-manylinux_ppc64le", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
@@ -32,6 +38,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-manylinux_ppc64le", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-manylinux_ppc64le", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-manylinux_ppc64le", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-manylinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-manylinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "cp36-manylinux_s390x", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-manylinux_s390x", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-manylinux_s390x", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
@@ -39,6 +47,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-manylinux_s390x", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-manylinux_s390x", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-manylinux_s390x", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-manylinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-manylinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "pp37-manylinux_aarch64", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
|
||||
{ identifier = "pp38-manylinux_aarch64", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" },
|
||||
{ identifier = "pp39-manylinux_aarch64", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" },
|
||||
@@ -54,6 +64,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-musllinux_x86_64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-musllinux_x86_64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-musllinux_x86_64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-musllinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-musllinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "cp36-musllinux_i686", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-musllinux_i686", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-musllinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
@@ -61,6 +73,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-musllinux_i686", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-musllinux_i686", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-musllinux_i686", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-musllinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-musllinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "cp36-musllinux_aarch64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-musllinux_aarch64", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-musllinux_aarch64", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
@@ -68,6 +82,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-musllinux_aarch64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-musllinux_aarch64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-musllinux_aarch64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-musllinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-musllinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "cp36-musllinux_ppc64le", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-musllinux_ppc64le", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-musllinux_ppc64le", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
@@ -75,6 +91,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-musllinux_ppc64le", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-musllinux_ppc64le", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-musllinux_ppc64le", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-musllinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-musllinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
{ identifier = "cp36-musllinux_s390x", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-musllinux_s390x", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-musllinux_s390x", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
@@ -82,6 +100,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-musllinux_s390x", version = "3.10", path_str = "/opt/python/cp310-cp310" },
|
||||
{ identifier = "cp311-musllinux_s390x", version = "3.11", path_str = "/opt/python/cp311-cp311" },
|
||||
{ identifier = "cp312-musllinux_s390x", version = "3.12", path_str = "/opt/python/cp312-cp312" },
|
||||
{ identifier = "cp313-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" },
|
||||
{ identifier = "cp313t-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
|
||||
]
|
||||
|
||||
[macos]
|
||||
@@ -97,19 +117,25 @@ python_configurations = [
|
||||
{ identifier = "cp310-macosx_x86_64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg" },
|
||||
{ identifier = "cp310-macosx_arm64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg" },
|
||||
{ identifier = "cp310-macosx_universal2", version = "3.10", url = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_x86_64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.5/python-3.11.5-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.5/python-3.11.5-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.5/python-3.11.5-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0rc2-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0rc2-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0rc2-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_x86_64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.4/python-3.12.4-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.4/python-3.12.4-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.4/python-3.12.4-macos11.pkg" },
|
||||
{ identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
|
||||
{ identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
|
||||
{ identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
|
||||
{ identifier = "cp313t-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
|
||||
{ identifier = "cp313t-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
|
||||
{ identifier = "cp313t-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
|
||||
{ identifier = "pp37-macosx_x86_64", version = "3.7", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.9-osx64.tar.bz2" },
|
||||
{ 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.12-macos_x86_64.tar.bz2" },
|
||||
{ identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.12-macos_arm64.tar.bz2" },
|
||||
{ identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.12-macos_x86_64.tar.bz2" },
|
||||
{ identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.12-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.16-macos_x86_64.tar.bz2" },
|
||||
{ identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.16-macos_arm64.tar.bz2" },
|
||||
]
|
||||
|
||||
[windows]
|
||||
@@ -124,16 +150,27 @@ python_configurations = [
|
||||
{ identifier = "cp39-win_amd64", version = "3.9.13", arch = "64" },
|
||||
{ identifier = "cp310-win32", version = "3.10.11", arch = "32" },
|
||||
{ identifier = "cp310-win_amd64", version = "3.10.11", arch = "64" },
|
||||
{ identifier = "cp311-win32", version = "3.11.5", arch = "32" },
|
||||
{ identifier = "cp311-win_amd64", version = "3.11.5", arch = "64" },
|
||||
{ identifier = "cp312-win32", version = "3.12.0-rc2", arch = "32" },
|
||||
{ identifier = "cp312-win_amd64", version = "3.12.0-rc2", arch = "64" },
|
||||
{ identifier = "cp311-win32", version = "3.11.9", arch = "32" },
|
||||
{ identifier = "cp311-win_amd64", version = "3.11.9", arch = "64" },
|
||||
{ identifier = "cp312-win32", version = "3.12.4", arch = "32" },
|
||||
{ identifier = "cp312-win_amd64", version = "3.12.4", arch = "64" },
|
||||
{ identifier = "cp313-win32", version = "3.13.0-rc1", arch = "32" },
|
||||
{ identifier = "cp313t-win32", version = "3.13.0-rc1", arch = "32" },
|
||||
{ identifier = "cp313-win_amd64", version = "3.13.0-rc1", arch = "64" },
|
||||
{ identifier = "cp313t-win_amd64", version = "3.13.0-rc1", arch = "64" },
|
||||
{ identifier = "cp39-win_arm64", version = "3.9.10", arch = "ARM64" },
|
||||
{ identifier = "cp310-win_arm64", version = "3.10.11", arch = "ARM64" },
|
||||
{ identifier = "cp311-win_arm64", version = "3.11.5", arch = "ARM64" },
|
||||
{ identifier = "cp312-win_arm64", version = "3.12.0-rc2", arch = "ARM64" },
|
||||
{ identifier = "cp311-win_arm64", version = "3.11.9", arch = "ARM64" },
|
||||
{ identifier = "cp312-win_arm64", version = "3.12.4", arch = "ARM64" },
|
||||
{ identifier = "cp313-win_arm64", version = "3.13.0-rc1", arch = "ARM64" },
|
||||
{ identifier = "cp313t-win_arm64", version = "3.13.0-rc1", arch = "ARM64" },
|
||||
{ identifier = "pp37-win_amd64", version = "3.7", arch = "64", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.9-win64.zip" },
|
||||
{ identifier = "pp38-win_amd64", version = "3.8", arch = "64", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" },
|
||||
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.12-win64.zip" },
|
||||
{ identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.12-win64.zip" },
|
||||
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" },
|
||||
{ identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.16-win64.zip" },
|
||||
]
|
||||
|
||||
[pyodide]
|
||||
python_configurations = [
|
||||
{ identifier = "cp312-pyodide_wasm32", version = "3.12.1", pyodide_version = "0.26.1", emscripten_version = "3.1.58", node_version = "v20" },
|
||||
]
|
||||
|
||||
@@ -0,0 +1,821 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/resources/cibuildwheel.schema.json",
|
||||
"$defs": {
|
||||
"inherit": {
|
||||
"enum": [
|
||||
"none",
|
||||
"prepend",
|
||||
"append"
|
||||
],
|
||||
"default": "none",
|
||||
"description": "How to inherit the parent's value."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"description": "cibuildwheel's settings.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"archs": {
|
||||
"description": "Change the architectures built on your machine by default.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_ARCHS"
|
||||
},
|
||||
"before-all": {
|
||||
"description": "Execute a shell command on the build system before any wheels are built.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_BEFORE_ALL"
|
||||
},
|
||||
"before-build": {
|
||||
"description": "Execute a shell command preparing each wheel's build.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_BEFORE_BUILD"
|
||||
},
|
||||
"before-test": {
|
||||
"description": "Execute a shell command before testing each wheel.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_BEFORE_TEST"
|
||||
},
|
||||
"build": {
|
||||
"default": [
|
||||
"*"
|
||||
],
|
||||
"description": "Choose the Python versions to build.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_BUILD"
|
||||
},
|
||||
"build-frontend": {
|
||||
"default": "default",
|
||||
"description": "Set the tool to use to build, either \"pip\" (default for now), \"build\", or \"build[uv]\"",
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"pip",
|
||||
"build",
|
||||
"build[uv]",
|
||||
"default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^pip; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^build; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^build\\[uv\\]; ?args:"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"enum": [
|
||||
"pip",
|
||||
"build",
|
||||
"build[uv]"
|
||||
]
|
||||
},
|
||||
"args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_BUILD_FRONTEND"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"type": "integer",
|
||||
"minimum": -3,
|
||||
"maximum": 3,
|
||||
"default": 0,
|
||||
"description": "Increase/decrease the output of pip wheel.",
|
||||
"title": "CIBW_BUILD_VERBOSITY"
|
||||
},
|
||||
"config-settings": {
|
||||
"description": "Specify config-settings for the build backend.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
".+": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_CONFIG_SETTINGS"
|
||||
},
|
||||
"container-engine": {
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"docker",
|
||||
"podman"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^docker; ?(create_args|disable_host_mount):"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"pattern": "^podman; ?(create_args|disable_host_mount):"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"enum": [
|
||||
"docker",
|
||||
"podman"
|
||||
]
|
||||
},
|
||||
"create-args": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"disable-host-mount": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_CONTAINER_ENGINE"
|
||||
},
|
||||
"dependency-versions": {
|
||||
"default": "pinned",
|
||||
"description": "Specify how cibuildwheel controls the versions of the tools it uses",
|
||||
"type": "string",
|
||||
"title": "CIBW_DEPENDENCY_VERSIONS"
|
||||
},
|
||||
"environment": {
|
||||
"description": "Set environment variables needed during the build.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
".+": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_ENVIRONMENT"
|
||||
},
|
||||
"environment-pass": {
|
||||
"description": "Set environment variables on the host to pass-through to the container during the build.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_ENVIRONMENT_PASS"
|
||||
},
|
||||
"free-threaded-support": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "The project supports free-threaded builds of Python (PEP703)",
|
||||
"title": "CIBW_FREE_THREADED_SUPPORT"
|
||||
},
|
||||
"manylinux-aarch64-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_AARCH64_IMAGE"
|
||||
},
|
||||
"manylinux-i686-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_I686_IMAGE"
|
||||
},
|
||||
"manylinux-ppc64le-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_PPC64LE_IMAGE"
|
||||
},
|
||||
"manylinux-pypy_aarch64-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_PYPY_AARCH64_IMAGE"
|
||||
},
|
||||
"manylinux-pypy_i686-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_PYPY_I686_IMAGE"
|
||||
},
|
||||
"manylinux-pypy_x86_64-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_PYPY_X86_64_IMAGE"
|
||||
},
|
||||
"manylinux-s390x-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_S390X_IMAGE"
|
||||
},
|
||||
"manylinux-x86_64-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MANYLINUX_X86_64_IMAGE"
|
||||
},
|
||||
"musllinux-aarch64-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MUSLLINUX_AARCH64_IMAGE"
|
||||
},
|
||||
"musllinux-i686-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MUSLLINUX_I686_IMAGE"
|
||||
},
|
||||
"musllinux-ppc64le-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MUSLLINUX_PPC64LE_IMAGE"
|
||||
},
|
||||
"musllinux-s390x-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MUSLLINUX_S390X_IMAGE"
|
||||
},
|
||||
"musllinux-x86_64-image": {
|
||||
"type": "string",
|
||||
"description": "Specify alternative manylinux / musllinux container images",
|
||||
"title": "CIBW_MUSLLINUX_X86_64_IMAGE"
|
||||
},
|
||||
"repair-wheel-command": {
|
||||
"description": "Execute a shell command to repair each built wheel.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_REPAIR_WHEEL_COMMAND"
|
||||
},
|
||||
"skip": {
|
||||
"description": "Choose the Python versions to skip.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_SKIP"
|
||||
},
|
||||
"test-command": {
|
||||
"description": "Execute a shell command to test each built wheel.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_TEST_COMMAND"
|
||||
},
|
||||
"test-extras": {
|
||||
"description": "Install your wheel for testing using `extras_require`",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_TEST_EXTRAS"
|
||||
},
|
||||
"test-requires": {
|
||||
"description": "Install Python dependencies before running the tests",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_TEST_REQUIRES"
|
||||
},
|
||||
"test-skip": {
|
||||
"description": "Skip running tests on some builds.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_TEST_SKIP"
|
||||
},
|
||||
"overrides": {
|
||||
"type": "array",
|
||||
"description": "An overrides array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"select"
|
||||
],
|
||||
"minProperties": 2,
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"select": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"inherit": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"before-all": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"before-build": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"before-test": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"config-settings": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"container-engine": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"environment-pass": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"repair-wheel-command": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"test-command": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"test-extras": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
},
|
||||
"test-requires": {
|
||||
"$ref": "#/$defs/inherit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"before-all": {
|
||||
"$ref": "#/properties/before-all"
|
||||
},
|
||||
"before-build": {
|
||||
"$ref": "#/properties/before-build"
|
||||
},
|
||||
"before-test": {
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
},
|
||||
"config-settings": {
|
||||
"$ref": "#/properties/config-settings"
|
||||
},
|
||||
"container-engine": {
|
||||
"$ref": "#/properties/container-engine"
|
||||
},
|
||||
"dependency-versions": {
|
||||
"$ref": "#/properties/dependency-versions"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "#/properties/environment"
|
||||
},
|
||||
"environment-pass": {
|
||||
"$ref": "#/properties/environment-pass"
|
||||
},
|
||||
"manylinux-aarch64-image": {
|
||||
"$ref": "#/properties/manylinux-aarch64-image"
|
||||
},
|
||||
"manylinux-i686-image": {
|
||||
"$ref": "#/properties/manylinux-i686-image"
|
||||
},
|
||||
"manylinux-ppc64le-image": {
|
||||
"$ref": "#/properties/manylinux-ppc64le-image"
|
||||
},
|
||||
"manylinux-pypy_aarch64-image": {
|
||||
"$ref": "#/properties/manylinux-pypy_aarch64-image"
|
||||
},
|
||||
"manylinux-pypy_i686-image": {
|
||||
"$ref": "#/properties/manylinux-pypy_i686-image"
|
||||
},
|
||||
"manylinux-pypy_x86_64-image": {
|
||||
"$ref": "#/properties/manylinux-pypy_x86_64-image"
|
||||
},
|
||||
"manylinux-s390x-image": {
|
||||
"$ref": "#/properties/manylinux-s390x-image"
|
||||
},
|
||||
"manylinux-x86_64-image": {
|
||||
"$ref": "#/properties/manylinux-x86_64-image"
|
||||
},
|
||||
"musllinux-aarch64-image": {
|
||||
"$ref": "#/properties/musllinux-aarch64-image"
|
||||
},
|
||||
"musllinux-i686-image": {
|
||||
"$ref": "#/properties/musllinux-i686-image"
|
||||
},
|
||||
"musllinux-ppc64le-image": {
|
||||
"$ref": "#/properties/musllinux-ppc64le-image"
|
||||
},
|
||||
"musllinux-s390x-image": {
|
||||
"$ref": "#/properties/musllinux-s390x-image"
|
||||
},
|
||||
"musllinux-x86_64-image": {
|
||||
"$ref": "#/properties/musllinux-x86_64-image"
|
||||
},
|
||||
"repair-wheel-command": {
|
||||
"$ref": "#/properties/repair-wheel-command"
|
||||
},
|
||||
"test-command": {
|
||||
"$ref": "#/properties/test-command"
|
||||
},
|
||||
"test-extras": {
|
||||
"$ref": "#/properties/test-extras"
|
||||
},
|
||||
"test-requires": {
|
||||
"$ref": "#/properties/test-requires"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"linux": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"archs": {
|
||||
"$ref": "#/properties/archs"
|
||||
},
|
||||
"before-all": {
|
||||
"$ref": "#/properties/before-all"
|
||||
},
|
||||
"before-build": {
|
||||
"$ref": "#/properties/before-build"
|
||||
},
|
||||
"before-test": {
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
},
|
||||
"config-settings": {
|
||||
"$ref": "#/properties/config-settings"
|
||||
},
|
||||
"container-engine": {
|
||||
"$ref": "#/properties/container-engine"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "#/properties/environment"
|
||||
},
|
||||
"environment-pass": {
|
||||
"$ref": "#/properties/environment-pass"
|
||||
},
|
||||
"manylinux-aarch64-image": {
|
||||
"$ref": "#/properties/manylinux-aarch64-image"
|
||||
},
|
||||
"manylinux-i686-image": {
|
||||
"$ref": "#/properties/manylinux-i686-image"
|
||||
},
|
||||
"manylinux-ppc64le-image": {
|
||||
"$ref": "#/properties/manylinux-ppc64le-image"
|
||||
},
|
||||
"manylinux-pypy_aarch64-image": {
|
||||
"$ref": "#/properties/manylinux-pypy_aarch64-image"
|
||||
},
|
||||
"manylinux-pypy_i686-image": {
|
||||
"$ref": "#/properties/manylinux-pypy_i686-image"
|
||||
},
|
||||
"manylinux-pypy_x86_64-image": {
|
||||
"$ref": "#/properties/manylinux-pypy_x86_64-image"
|
||||
},
|
||||
"manylinux-s390x-image": {
|
||||
"$ref": "#/properties/manylinux-s390x-image"
|
||||
},
|
||||
"manylinux-x86_64-image": {
|
||||
"$ref": "#/properties/manylinux-x86_64-image"
|
||||
},
|
||||
"musllinux-aarch64-image": {
|
||||
"$ref": "#/properties/musllinux-aarch64-image"
|
||||
},
|
||||
"musllinux-i686-image": {
|
||||
"$ref": "#/properties/musllinux-i686-image"
|
||||
},
|
||||
"musllinux-ppc64le-image": {
|
||||
"$ref": "#/properties/musllinux-ppc64le-image"
|
||||
},
|
||||
"musllinux-s390x-image": {
|
||||
"$ref": "#/properties/musllinux-s390x-image"
|
||||
},
|
||||
"musllinux-x86_64-image": {
|
||||
"$ref": "#/properties/musllinux-x86_64-image"
|
||||
},
|
||||
"repair-wheel-command": {
|
||||
"description": "Execute a shell command to repair each built wheel.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_REPAIR_WHEEL_COMMAND",
|
||||
"default": "auditwheel repair -w {dest_dir} {wheel}"
|
||||
},
|
||||
"test-command": {
|
||||
"$ref": "#/properties/test-command"
|
||||
},
|
||||
"test-extras": {
|
||||
"$ref": "#/properties/test-extras"
|
||||
},
|
||||
"test-requires": {
|
||||
"$ref": "#/properties/test-requires"
|
||||
}
|
||||
}
|
||||
},
|
||||
"windows": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"archs": {
|
||||
"$ref": "#/properties/archs"
|
||||
},
|
||||
"before-all": {
|
||||
"$ref": "#/properties/before-all"
|
||||
},
|
||||
"before-build": {
|
||||
"$ref": "#/properties/before-build"
|
||||
},
|
||||
"before-test": {
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
},
|
||||
"config-settings": {
|
||||
"$ref": "#/properties/config-settings"
|
||||
},
|
||||
"dependency-versions": {
|
||||
"$ref": "#/properties/dependency-versions"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "#/properties/environment"
|
||||
},
|
||||
"repair-wheel-command": {
|
||||
"$ref": "#/properties/repair-wheel-command"
|
||||
},
|
||||
"test-command": {
|
||||
"$ref": "#/properties/test-command"
|
||||
},
|
||||
"test-extras": {
|
||||
"$ref": "#/properties/test-extras"
|
||||
},
|
||||
"test-requires": {
|
||||
"$ref": "#/properties/test-requires"
|
||||
}
|
||||
}
|
||||
},
|
||||
"macos": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"archs": {
|
||||
"$ref": "#/properties/archs"
|
||||
},
|
||||
"before-all": {
|
||||
"$ref": "#/properties/before-all"
|
||||
},
|
||||
"before-build": {
|
||||
"$ref": "#/properties/before-build"
|
||||
},
|
||||
"before-test": {
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
},
|
||||
"config-settings": {
|
||||
"$ref": "#/properties/config-settings"
|
||||
},
|
||||
"dependency-versions": {
|
||||
"$ref": "#/properties/dependency-versions"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "#/properties/environment"
|
||||
},
|
||||
"repair-wheel-command": {
|
||||
"description": "Execute a shell command to repair each built wheel.",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "CIBW_REPAIR_WHEEL_COMMAND",
|
||||
"default": "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
|
||||
},
|
||||
"test-command": {
|
||||
"$ref": "#/properties/test-command"
|
||||
},
|
||||
"test-extras": {
|
||||
"$ref": "#/properties/test-extras"
|
||||
},
|
||||
"test-requires": {
|
||||
"$ref": "#/properties/test-requires"
|
||||
}
|
||||
}
|
||||
},
|
||||
"pyodide": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"archs": {
|
||||
"$ref": "#/properties/archs"
|
||||
},
|
||||
"before-all": {
|
||||
"$ref": "#/properties/before-all"
|
||||
},
|
||||
"before-build": {
|
||||
"$ref": "#/properties/before-build"
|
||||
},
|
||||
"before-test": {
|
||||
"$ref": "#/properties/before-test"
|
||||
},
|
||||
"build-frontend": {
|
||||
"$ref": "#/properties/build-frontend"
|
||||
},
|
||||
"build-verbosity": {
|
||||
"$ref": "#/properties/build-verbosity"
|
||||
},
|
||||
"config-settings": {
|
||||
"$ref": "#/properties/config-settings"
|
||||
},
|
||||
"dependency-versions": {
|
||||
"$ref": "#/properties/dependency-versions"
|
||||
},
|
||||
"environment": {
|
||||
"$ref": "#/properties/environment"
|
||||
},
|
||||
"repair-wheel-command": {
|
||||
"$ref": "#/properties/repair-wheel-command"
|
||||
},
|
||||
"test-command": {
|
||||
"$ref": "#/properties/test-command"
|
||||
},
|
||||
"test-extras": {
|
||||
"$ref": "#/properties/test-extras"
|
||||
},
|
||||
"test-requires": {
|
||||
"$ref": "#/properties/test-requires"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
annotated-types==0.7.0
|
||||
# via pydantic
|
||||
anyio==4.4.0
|
||||
# via httpx
|
||||
auditwheel-emscripten==0.0.16
|
||||
# via pyodide-build
|
||||
build==1.2.1
|
||||
# via
|
||||
# -r .nox/update_constraints/tmp/constraints-pyodide.in
|
||||
# pyodide-build
|
||||
certifi==2024.7.4
|
||||
# via
|
||||
# httpcore
|
||||
# httpx
|
||||
# requests
|
||||
charset-normalizer==3.3.2
|
||||
# via requests
|
||||
click==8.1.7
|
||||
# via typer
|
||||
cloudpickle==3.0.0
|
||||
# via loky
|
||||
cmake==3.30.1
|
||||
# via pyodide-build
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
h11==0.14.0
|
||||
# via httpcore
|
||||
httpcore==1.0.5
|
||||
# via httpx
|
||||
httpx==0.27.0
|
||||
# via unearth
|
||||
idna==3.7
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
# requests
|
||||
leb128==1.0.8
|
||||
# via auditwheel-emscripten
|
||||
loky==3.4.1
|
||||
# via pyodide-build
|
||||
markdown-it-py==3.0.0
|
||||
# via rich
|
||||
mdurl==0.1.2
|
||||
# via markdown-it-py
|
||||
packaging==24.1
|
||||
# via
|
||||
# auditwheel-emscripten
|
||||
# build
|
||||
# pyodide-build
|
||||
# unearth
|
||||
pip==24.2
|
||||
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
pydantic==2.8.2
|
||||
# via
|
||||
# pyodide-build
|
||||
# pyodide-lock
|
||||
pydantic-core==2.20.1
|
||||
# via pydantic
|
||||
pygments==2.18.0
|
||||
# via rich
|
||||
pyodide-build==0.26.1
|
||||
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
|
||||
pyodide-cli==0.2.4
|
||||
# via
|
||||
# auditwheel-emscripten
|
||||
# pyodide-build
|
||||
pyodide-lock==0.1.0a6
|
||||
# via pyodide-build
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
pyyaml==6.0.1
|
||||
# via pyodide-build
|
||||
requests==2.32.3
|
||||
# via pyodide-build
|
||||
resolvelib==1.0.1
|
||||
# via pyodide-build
|
||||
rich==13.7.1
|
||||
# via
|
||||
# pyodide-build
|
||||
# pyodide-cli
|
||||
# typer
|
||||
ruamel-yaml==0.18.6
|
||||
# via pyodide-build
|
||||
ruamel-yaml-clib==0.2.8
|
||||
# via ruamel-yaml
|
||||
shellingham==1.5.4
|
||||
# via typer
|
||||
sniffio==1.3.1
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
typer==0.12.3
|
||||
# via
|
||||
# auditwheel-emscripten
|
||||
# pyodide-build
|
||||
# pyodide-cli
|
||||
types-requests==2.32.0.20240712
|
||||
# via pyodide-build
|
||||
typing-extensions==4.12.2
|
||||
# via
|
||||
# pydantic
|
||||
# pydantic-core
|
||||
# typer
|
||||
unearth==0.16.1
|
||||
# via pyodide-build
|
||||
urllib3==2.2.2
|
||||
# via
|
||||
# requests
|
||||
# types-requests
|
||||
virtualenv==20.26.3
|
||||
# via
|
||||
# build
|
||||
# pyodide-build
|
||||
wheel==0.43.0
|
||||
# via
|
||||
# auditwheel-emscripten
|
||||
# pyodide-build
|
||||
@@ -1,28 +1,34 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.10
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.10
|
||||
#
|
||||
delocate==0.10.4
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.12.4
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
importlib-metadata==8.2.0
|
||||
# via build
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
packaging==24.1
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
tomli==2.0.1
|
||||
# via build
|
||||
typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==68.2.2
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
zipp==3.19.2
|
||||
# via importlib-metadata
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.11
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.11
|
||||
#
|
||||
delocate==0.10.4
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.12.4
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
packaging==24.1
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==68.2.2
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.12
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.12
|
||||
#
|
||||
delocate==0.10.4
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.12.4
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
packaging==24.1
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==68.2.2
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
packaging==24.1
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
@@ -4,18 +4,33 @@
|
||||
#
|
||||
# nox -s update_constraints-3.6
|
||||
#
|
||||
build==0.9.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.10.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.6
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.4.1
|
||||
# via virtualenv
|
||||
importlib-metadata==4.8.3
|
||||
# via virtualenv
|
||||
# via
|
||||
# build
|
||||
# pep517
|
||||
# virtualenv
|
||||
importlib-resources==5.4.0
|
||||
# via virtualenv
|
||||
packaging==21.3
|
||||
# via build
|
||||
pep517==0.13.1
|
||||
# via build
|
||||
platformdirs==2.4.0
|
||||
# via virtualenv
|
||||
pyparsing==3.1.1
|
||||
# via packaging
|
||||
tomli==1.2.3
|
||||
# via
|
||||
# build
|
||||
# pep517
|
||||
typing-extensions==4.1.1
|
||||
# via
|
||||
# delocate
|
||||
@@ -23,13 +38,12 @@ typing-extensions==4.1.1
|
||||
virtualenv==20.17.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
# -r cibuildwheel/resources/constraints.in
|
||||
# delocate
|
||||
# via delocate
|
||||
zipp==3.6.0
|
||||
# via
|
||||
# importlib-metadata
|
||||
# importlib-resources
|
||||
# pep517
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==21.3.1
|
||||
|
||||
@@ -1,35 +1,39 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.7
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.7
|
||||
#
|
||||
delocate==0.10.4
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.1.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.12.2
|
||||
# via virtualenv
|
||||
importlib-metadata==6.7.0
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
# via
|
||||
# build
|
||||
# virtualenv
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
packaging==24.0
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.0.0
|
||||
# via virtualenv
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
tomli==2.0.1
|
||||
# via build
|
||||
typing-extensions==4.7.1
|
||||
# via
|
||||
# delocate
|
||||
# importlib-metadata
|
||||
# platformdirs
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
zipp==3.15.0
|
||||
# via importlib-metadata
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==68.0.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.8
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.8
|
||||
#
|
||||
delocate==0.10.4
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.12.4
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
importlib-metadata==8.2.0
|
||||
# via build
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
packaging==24.1
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
tomli==2.0.1
|
||||
# via build
|
||||
typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==68.2.2
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
zipp==3.19.2
|
||||
# via importlib-metadata
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.9
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.9
|
||||
#
|
||||
delocate==0.10.4
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.12.4
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
importlib-metadata==8.2.0
|
||||
# via build
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
packaging==24.1
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
tomli==2.0.1
|
||||
# via build
|
||||
typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==68.2.2
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
zipp==3.19.2
|
||||
# via importlib-metadata
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
pip
|
||||
setuptools
|
||||
wheel
|
||||
build
|
||||
delocate
|
||||
virtualenv
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.12
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.12
|
||||
#
|
||||
delocate==0.10.4
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# nox -s update_constraints
|
||||
altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
delocate==0.11.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.12.4
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
packaging==24.1
|
||||
# via
|
||||
# build
|
||||
# delocate
|
||||
pip==24.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
platformdirs==4.2.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==68.2.2
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
build = "*"
|
||||
skip = ""
|
||||
test-skip = ""
|
||||
free-threaded-support = false
|
||||
|
||||
archs = ["auto"]
|
||||
build-frontend = "default"
|
||||
@@ -9,7 +10,7 @@ config-settings = {}
|
||||
dependency-versions = "pinned"
|
||||
environment = {}
|
||||
environment-pass = []
|
||||
build-verbosity = ""
|
||||
build-verbosity = 0
|
||||
|
||||
before-all = ""
|
||||
before-build = ""
|
||||
@@ -31,11 +32,11 @@ manylinux-pypy_x86_64-image = "manylinux2014"
|
||||
manylinux-pypy_i686-image = "manylinux2014"
|
||||
manylinux-pypy_aarch64-image = "manylinux2014"
|
||||
|
||||
musllinux-x86_64-image = "musllinux_1_1"
|
||||
musllinux-i686-image = "musllinux_1_1"
|
||||
musllinux-aarch64-image = "musllinux_1_1"
|
||||
musllinux-ppc64le-image = "musllinux_1_1"
|
||||
musllinux-s390x-image = "musllinux_1_1"
|
||||
musllinux-x86_64-image = "musllinux_1_2"
|
||||
musllinux-i686-image = "musllinux_1_2"
|
||||
musllinux-aarch64-image = "musllinux_1_2"
|
||||
musllinux-ppc64le-image = "musllinux_1_2"
|
||||
musllinux-s390x-image = "musllinux_1_2"
|
||||
|
||||
|
||||
[tool.cibuildwheel.linux]
|
||||
@@ -45,3 +46,5 @@ repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}"
|
||||
repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
|
||||
|
||||
[tool.cibuildwheel.windows]
|
||||
|
||||
[tool.cibuildwheel.pyodide]
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<array>
|
||||
<dict>
|
||||
<key>attributeSetting</key>
|
||||
<integer>1</integer>
|
||||
<key>choiceAttribute</key>
|
||||
<string>selected</string>
|
||||
<key>choiceIdentifier</key>
|
||||
<string>org.python.Python.PythonTFramework-3.13</string>
|
||||
</dict>
|
||||
</array>
|
||||
</plist>
|
||||
@@ -0,0 +1,2 @@
|
||||
url = "https://nodejs.org/dist/"
|
||||
v20 = "v20.16.0"
|
||||
@@ -1,54 +1,54 @@
|
||||
[x86_64]
|
||||
manylinux1 = quay.io/pypa/manylinux1_x86_64:2023-09-12-f07b683
|
||||
manylinux1 = quay.io/pypa/manylinux1_x86_64:2024-04-29-76807b8
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-09-17-ae90a16
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2023-09-17-ae90a16
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2023-09-17-ae90a16
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2024.08.03-1
|
||||
|
||||
[i686]
|
||||
manylinux1 = quay.io/pypa/manylinux1_i686:2023-09-12-f07b683
|
||||
manylinux1 = quay.io/pypa/manylinux1_i686:2024-04-29-76807b8
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2023-09-17-ae90a16
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2023-09-17-ae90a16
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2024.08.03-1
|
||||
|
||||
[pypy_x86_64]
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-09-17-ae90a16
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2024.08.03-1
|
||||
|
||||
[pypy_i686]
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
|
||||
|
||||
[aarch64]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-09-17-ae90a16
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2023-09-17-ae90a16
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2023-09-17-ae90a16
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2024.08.03-1
|
||||
|
||||
[ppc64le]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-12-26-0d38463
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2023-09-17-ae90a16
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2023-09-17-ae90a16
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2023-09-17-ae90a16
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2024.08.03-1
|
||||
|
||||
[s390x]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-12-26-0d38463
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2023-09-17-ae90a16
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2023-09-17-ae90a16
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2023-09-17-ae90a16
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2024.08.03-1
|
||||
|
||||
[pypy_aarch64]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-09-17-ae90a16
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2024.08.03-1
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-09-17-ae90a16
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.08.03-1
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
version = "20.21.1"
|
||||
url = "https://github.com/pypa/get-virtualenv/blob/20.21.1/public/virtualenv.pyz?raw=true"
|
||||
py36 = { version = "20.21.1", url = "https://github.com/pypa/get-virtualenv/blob/20.21.1/public/virtualenv.pyz?raw=true" }
|
||||
default = { version = "20.26.3", url = "https://github.com/pypa/get-virtualenv/blob/20.26.3/public/virtualenv.pyz?raw=true" }
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
DIR = Path(__file__).parent.resolve()
|
||||
|
||||
|
||||
def get_schema(tool_name: str = "cibuildwheel") -> dict[str, Any]:
|
||||
"Get the stored complete schema for cibuildwheel settings."
|
||||
assert tool_name == "cibuildwheel", "Only cibuildwheel is supported."
|
||||
|
||||
with DIR.joinpath("resources/cibuildwheel.schema.json").open(encoding="utf-8") as f:
|
||||
return json.load(f) # type: ignore[no-any-return]
|
||||
@@ -22,11 +22,10 @@ else:
|
||||
PathOrStr = Union[str, "os.PathLike[str]"]
|
||||
|
||||
|
||||
PlatformName = Literal["linux", "macos", "windows"]
|
||||
PLATFORMS: Final[set[PlatformName]] = {"linux", "macos", "windows"}
|
||||
PlatformName = Literal["linux", "macos", "windows", "pyodide"]
|
||||
PLATFORMS: Final[set[PlatformName]] = {"linux", "macos", "windows", "pyodide"}
|
||||
|
||||
|
||||
class GenericPythonConfiguration(Protocol):
|
||||
@property
|
||||
def identifier(self) -> str:
|
||||
...
|
||||
def identifier(self) -> str: ...
|
||||
|
||||
+237
-98
@@ -6,21 +6,25 @@ import itertools
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import ssl
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import textwrap
|
||||
import time
|
||||
import typing
|
||||
import urllib.request
|
||||
from collections import defaultdict
|
||||
from collections.abc import Generator, Iterable, Mapping, Sequence
|
||||
from collections.abc import Generator, Iterable, Mapping, MutableMapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from functools import cached_property, lru_cache
|
||||
from functools import lru_cache
|
||||
from pathlib import Path, PurePath
|
||||
from tempfile import TemporaryDirectory
|
||||
from time import sleep
|
||||
from typing import Any, ClassVar, Final, Literal, TextIO, TypeVar
|
||||
from zipfile import ZipFile
|
||||
|
||||
import bracex
|
||||
import certifi
|
||||
@@ -32,29 +36,33 @@ from packaging.version import Version
|
||||
from platformdirs import user_cache_path
|
||||
|
||||
from ._compat import tomllib
|
||||
from .architecture import Architecture
|
||||
from .typing import PathOrStr, PlatformName
|
||||
|
||||
__all__ = [
|
||||
"resources_dir",
|
||||
"MANYLINUX_ARCHS",
|
||||
"call",
|
||||
"shell",
|
||||
"find_compatible_wheel",
|
||||
"format_safe",
|
||||
"prepare_command",
|
||||
"get_build_verbosity_extra_flags",
|
||||
"read_python_configs",
|
||||
"selector_matches",
|
||||
"strtobool",
|
||||
"cached_property",
|
||||
"chdir",
|
||||
"combine_constraints",
|
||||
"find_compatible_wheel",
|
||||
"find_uv",
|
||||
"format_safe",
|
||||
"get_build_verbosity_extra_flags",
|
||||
"prepare_command",
|
||||
"read_python_configs",
|
||||
"resources_dir",
|
||||
"selector_matches",
|
||||
"shell",
|
||||
"split_config_settings",
|
||||
"strtobool",
|
||||
]
|
||||
|
||||
resources_dir: Final[Path] = Path(__file__).parent / "resources"
|
||||
|
||||
install_certifi_script: Final[Path] = resources_dir / "install_certifi.py"
|
||||
|
||||
free_thread_enable_313: Final[Path] = resources_dir / "free-threaded-enable-313.xml"
|
||||
|
||||
test_fail_cwd_file: Final[Path] = resources_dir / "testing_temp_dir_file.py"
|
||||
|
||||
|
||||
@@ -91,8 +99,7 @@ def call(
|
||||
env: Mapping[str, str] | None = None,
|
||||
cwd: PathOrStr | None = None,
|
||||
capture_stdout: Literal[False] = ...,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
|
||||
@typing.overload
|
||||
@@ -101,8 +108,7 @@ def call(
|
||||
env: Mapping[str, str] | None = None,
|
||||
cwd: PathOrStr | None = None,
|
||||
capture_stdout: Literal[True],
|
||||
) -> str:
|
||||
...
|
||||
) -> str: ...
|
||||
|
||||
|
||||
def call(
|
||||
@@ -197,7 +203,9 @@ def get_build_verbosity_extra_flags(level: int) -> list[str]:
|
||||
return []
|
||||
|
||||
|
||||
def split_config_settings(config_settings: str, frontend: Literal["pip", "build"]) -> list[str]:
|
||||
def split_config_settings(
|
||||
config_settings: str, frontend: Literal["pip", "build", "build[uv]"]
|
||||
) -> list[str]:
|
||||
config_settings_list = shlex.split(config_settings)
|
||||
s = "s" if frontend == "pip" else ""
|
||||
return [f"--config-setting{s}={setting}" for setting in config_settings_list]
|
||||
@@ -243,10 +251,14 @@ class BuildSelector:
|
||||
PRERELEASE_SKIP: ClassVar[str] = ""
|
||||
prerelease_pythons: bool = False
|
||||
|
||||
free_threaded_support: bool = False
|
||||
|
||||
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("-")[0]
|
||||
if py_ver_str.endswith("t"):
|
||||
py_ver_str = py_ver_str[:-1]
|
||||
major = int(py_ver_str[2])
|
||||
minor = int(py_ver_str[3:])
|
||||
version = Version(f"{major}.{minor}.99")
|
||||
@@ -257,6 +269,10 @@ class BuildSelector:
|
||||
if not self.prerelease_pythons and selector_matches(self.PRERELEASE_SKIP, build_id):
|
||||
return False
|
||||
|
||||
# filter out free threaded pythons if self.free_threaded_support is False
|
||||
if not self.free_threaded_support and selector_matches("*t-*", build_id):
|
||||
return False
|
||||
|
||||
should_build = selector_matches(self.build_config, build_id)
|
||||
should_skip = selector_matches(self.skip_config, build_id)
|
||||
|
||||
@@ -268,6 +284,7 @@ class BuildSelector:
|
||||
"skip_config": self.skip_config,
|
||||
"requires_python": str(self.requires_python),
|
||||
"prerelease_pythons": self.prerelease_pythons,
|
||||
"free_threaded_support": self.free_threaded_support,
|
||||
}
|
||||
|
||||
|
||||
@@ -327,6 +344,55 @@ def download(url: str, dest: Path) -> None:
|
||||
sleep(3)
|
||||
|
||||
|
||||
def extract_zip(zip_src: Path, dest: Path) -> None:
|
||||
with ZipFile(zip_src) as zip_:
|
||||
for zinfo in zip_.filelist:
|
||||
zip_.extract(zinfo, dest)
|
||||
|
||||
# Set permissions to the same values as they were set in the archive
|
||||
# We have to do this manually due to
|
||||
# https://github.com/python/cpython/issues/59999
|
||||
# But some files in the zipfile seem to have external_attr with 0
|
||||
# permissions. In that case just use the default value???
|
||||
permissions = (zinfo.external_attr >> 16) & 0o777
|
||||
if permissions != 0:
|
||||
dest.joinpath(zinfo.filename).chmod(permissions)
|
||||
|
||||
|
||||
def extract_tar(tar_src: Path, dest: Path) -> None:
|
||||
with tarfile.open(tar_src) as tar_:
|
||||
tar_.extraction_filter = getattr(tarfile, "tar_filter", (lambda member, _: member))
|
||||
tar_.extractall(dest)
|
||||
|
||||
|
||||
def move_file(src_file: Path, dst_file: Path) -> Path:
|
||||
"""Moves a file safely while avoiding potential semantic confusion:
|
||||
|
||||
1. `dst_file` must point to the target filename, not a directory
|
||||
2. `dst_file` will be overwritten if it already exists
|
||||
3. any missing parent directories will be created
|
||||
|
||||
Returns the fully resolved Path of the resulting file.
|
||||
|
||||
Raises:
|
||||
NotADirectoryError: If any part of the intermediate path to `dst_file` is an existing file
|
||||
IsADirectoryError: If `dst_file` points directly to an existing directory
|
||||
"""
|
||||
src_file = src_file.resolve(strict=True)
|
||||
dst_file = dst_file.resolve()
|
||||
|
||||
if dst_file.is_dir():
|
||||
msg = "dst_file must be a valid target filename, not an existing directory."
|
||||
raise IsADirectoryError(msg)
|
||||
dst_file.unlink(missing_ok=True)
|
||||
dst_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# using shutil.move() as Path.rename() is not guaranteed to work across filesystem boundaries
|
||||
# explicit str() needed for Python 3.8
|
||||
resulting_file = shutil.move(str(src_file), str(dst_file))
|
||||
return Path(resulting_file).resolve(strict=True)
|
||||
|
||||
|
||||
class DependencyConstraints:
|
||||
def __init__(self, base_file_path: Path):
|
||||
assert base_file_path.exists()
|
||||
@@ -336,12 +402,14 @@ class DependencyConstraints:
|
||||
def with_defaults() -> DependencyConstraints:
|
||||
return DependencyConstraints(base_file_path=resources_dir / "constraints.txt")
|
||||
|
||||
def get_for_python_version(self, version: str) -> Path:
|
||||
def get_for_python_version(
|
||||
self, version: str, *, variant: Literal["python", "pyodide"] = "python"
|
||||
) -> Path:
|
||||
version_parts = version.split(".")
|
||||
|
||||
# try to find a version-specific dependency file e.g. if
|
||||
# ./constraints.txt is the base, look for ./constraints-python36.txt
|
||||
specific_stem = self.base_file_path.stem + f"-python{version_parts[0]}{version_parts[1]}"
|
||||
specific_stem = self.base_file_path.stem + f"-{variant}{version_parts[0]}{version_parts[1]}"
|
||||
specific_name = specific_stem + self.base_file_path.suffix
|
||||
specific_file_path = self.base_file_path.with_name(specific_name)
|
||||
|
||||
@@ -366,7 +434,7 @@ class DependencyConstraints:
|
||||
return self.base_file_path.name
|
||||
|
||||
|
||||
BuildFrontendName = Literal["pip", "build"]
|
||||
BuildFrontendName = Literal["pip", "build", "build[uv]"]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -378,8 +446,8 @@ class BuildFrontendConfig:
|
||||
def from_config_string(config_string: str) -> BuildFrontendConfig:
|
||||
config_dict = parse_key_value_string(config_string, ["name"], ["args"])
|
||||
name = " ".join(config_dict["name"])
|
||||
if name not in {"pip", "build"}:
|
||||
msg = f"Unrecognised build frontend {name}, only 'pip' and 'build' are supported"
|
||||
if name not in {"pip", "build", "build[uv]"}:
|
||||
msg = f"Unrecognised build frontend {name!r}, only 'pip', 'build', and 'build[uv]' are supported"
|
||||
raise ValueError(msg)
|
||||
|
||||
name = typing.cast(BuildFrontendName, name)
|
||||
@@ -394,37 +462,6 @@ class BuildFrontendConfig:
|
||||
return {"name": self.name, "args": repr(self.args)}
|
||||
|
||||
|
||||
class NonPlatformWheelError(Exception):
|
||||
def __init__(self) -> None:
|
||||
message = textwrap.dedent(
|
||||
"""
|
||||
cibuildwheel: Build failed because a pure Python wheel was generated.
|
||||
|
||||
If you intend to build a pure-Python wheel, you don't need cibuildwheel - use
|
||||
`pip wheel -w DEST_DIR .` instead.
|
||||
|
||||
If you expected a platform wheel, check your project configuration, or run
|
||||
cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
|
||||
"""
|
||||
)
|
||||
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
class AlreadyBuiltWheelError(Exception):
|
||||
def __init__(self, wheel_name: str) -> None:
|
||||
message = textwrap.dedent(
|
||||
f"""
|
||||
cibuildwheel: Build failed because a wheel named {wheel_name} was already generated in the current run.
|
||||
|
||||
If you expected another wheel to be generated, check your project configuration, or run
|
||||
cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
|
||||
"""
|
||||
)
|
||||
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
def strtobool(val: str) -> bool:
|
||||
return val.lower() in {"y", "yes", "t", "true", "on", "1"}
|
||||
|
||||
@@ -528,12 +565,47 @@ def get_pip_version(env: Mapping[str, str]) -> str:
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _ensure_virtualenv() -> Path:
|
||||
def ensure_node(major_version: str) -> Path:
|
||||
input_file = resources_dir / "nodejs.toml"
|
||||
with input_file.open("rb") as f:
|
||||
loaded_file = tomllib.load(f)
|
||||
version = str(loaded_file[major_version])
|
||||
base_url = str(loaded_file["url"])
|
||||
ext = "zip" if IS_WIN else "tar.xz"
|
||||
platform = "win" if IS_WIN else ("darwin" if sys.platform.startswith("darwin") else "linux")
|
||||
linux_arch = Architecture.native_arch("linux")
|
||||
assert linux_arch is not None
|
||||
arch = {"x86_64": "x64", "i686": "x86", "aarch64": "arm64"}.get(
|
||||
linux_arch.value, linux_arch.value
|
||||
)
|
||||
name = f"node-{version}-{platform}-{arch}"
|
||||
path = CIBW_CACHE_PATH / name
|
||||
with FileLock(str(path) + ".lock"):
|
||||
if not path.exists():
|
||||
url = f"{base_url}{version}/{name}.{ext}"
|
||||
with TemporaryDirectory() as tmp_path:
|
||||
archive = Path(tmp_path) / f"{name}.{ext}"
|
||||
download(url, archive)
|
||||
if ext == "zip":
|
||||
extract_zip(archive, path.parent)
|
||||
else:
|
||||
extract_tar(archive, path.parent)
|
||||
assert path.exists()
|
||||
if not IS_WIN:
|
||||
return path / "bin"
|
||||
return path
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _ensure_virtualenv(version: str) -> Path:
|
||||
version_parts = version.split(".")
|
||||
key = f"py{version_parts[0]}{version_parts[1]}"
|
||||
input_file = resources_dir / "virtualenv.toml"
|
||||
with input_file.open("rb") as f:
|
||||
loaded_file = tomllib.load(f)
|
||||
version = str(loaded_file["version"])
|
||||
url = str(loaded_file["url"])
|
||||
configuration = loaded_file.get(key, loaded_file["default"])
|
||||
version = str(configuration["version"])
|
||||
url = str(configuration["url"])
|
||||
path = CIBW_CACHE_PATH / f"virtualenv-{version}.pyz"
|
||||
with FileLock(str(path) + ".lock"):
|
||||
if not path.exists():
|
||||
@@ -542,6 +614,7 @@ def _ensure_virtualenv() -> Path:
|
||||
|
||||
|
||||
def _parse_constraints_for_virtualenv(
|
||||
seed_packages: list[str],
|
||||
dependency_constraint_flags: Sequence[PathOrStr],
|
||||
) -> dict[str, str]:
|
||||
"""
|
||||
@@ -554,8 +627,8 @@ def _parse_constraints_for_virtualenv(
|
||||
{macos|windows}.setup_python function.
|
||||
"""
|
||||
assert len(dependency_constraint_flags) in {0, 2}
|
||||
packages = ["pip", "setuptools", "wheel"]
|
||||
constraints_dict = {package: "embed" for package in packages}
|
||||
# only seed pip if other seed packages do not appear in a constraint file
|
||||
constraints_dict = {"pip": "embed"}
|
||||
if len(dependency_constraint_flags) == 2:
|
||||
assert dependency_constraint_flags[0] == "-c"
|
||||
constraint_path = Path(dependency_constraint_flags[1])
|
||||
@@ -571,7 +644,7 @@ def _parse_constraints_for_virtualenv(
|
||||
requirement = Requirement(line)
|
||||
package = requirement.name
|
||||
if (
|
||||
package not in packages
|
||||
package not in seed_packages
|
||||
or requirement.url is not None
|
||||
or requirement.marker is not None
|
||||
or len(requirement.extras) != 0
|
||||
@@ -588,43 +661,64 @@ def _parse_constraints_for_virtualenv(
|
||||
|
||||
|
||||
def virtualenv(
|
||||
python: Path, venv_path: Path, dependency_constraint_flags: Sequence[PathOrStr]
|
||||
version: str,
|
||||
python: Path,
|
||||
venv_path: Path,
|
||||
dependency_constraint_flags: Sequence[PathOrStr],
|
||||
*,
|
||||
use_uv: bool,
|
||||
) -> dict[str, str]:
|
||||
"""
|
||||
Create a virtual environment. If `use_uv` is True,
|
||||
dependency_constraint_flags are ignored since nothing is installed in the
|
||||
venv. Otherwise, pip is installed, and setuptools + wheel if Python < 3.12.
|
||||
"""
|
||||
assert python.exists()
|
||||
virtualenv_app = _ensure_virtualenv()
|
||||
constraints = _parse_constraints_for_virtualenv(dependency_constraint_flags)
|
||||
additional_flags = [f"--{package}={version}" for package, version in constraints.items()]
|
||||
|
||||
# Using symlinks to pre-installed seed packages is really the fastest way to get a virtual
|
||||
# environment. The initial cost is a bit higher but reusing is much faster.
|
||||
# Windows does not always allow symlinks so just disabling for now.
|
||||
# Requires pip>=19.3 so disabling for "embed" because this means we don't know what's the
|
||||
# version of pip that will end-up installed.
|
||||
# c.f. https://virtualenv.pypa.io/en/latest/cli_interface.html#section-seeder
|
||||
if (
|
||||
not IS_WIN
|
||||
and constraints["pip"] != "embed"
|
||||
and Version(constraints["pip"]) >= Version("19.3")
|
||||
):
|
||||
additional_flags.append("--symlink-app-data")
|
||||
|
||||
call(
|
||||
sys.executable,
|
||||
"-sS", # just the stdlib, https://github.com/pypa/virtualenv/issues/2133#issuecomment-1003710125
|
||||
virtualenv_app,
|
||||
"--activators=",
|
||||
"--no-periodic-update",
|
||||
*additional_flags,
|
||||
"--python",
|
||||
python,
|
||||
venv_path,
|
||||
)
|
||||
if IS_WIN:
|
||||
paths = [str(venv_path), str(venv_path / "Scripts")]
|
||||
if use_uv:
|
||||
call("uv", "venv", venv_path, "--python", python)
|
||||
else:
|
||||
paths = [str(venv_path / "bin")]
|
||||
virtualenv_app = _ensure_virtualenv(version)
|
||||
allowed_seed_packages = ["pip", "setuptools", "wheel"]
|
||||
constraints = _parse_constraints_for_virtualenv(
|
||||
allowed_seed_packages, dependency_constraint_flags
|
||||
)
|
||||
additional_flags: list[str] = []
|
||||
for package in allowed_seed_packages:
|
||||
if package in constraints:
|
||||
additional_flags.append(f"--{package}={constraints[package]}")
|
||||
else:
|
||||
additional_flags.append(f"--no-{package}")
|
||||
|
||||
# Using symlinks to pre-installed seed packages is really the fastest way to get a virtual
|
||||
# environment. The initial cost is a bit higher but reusing is much faster.
|
||||
# Windows does not always allow symlinks so just disabling for now.
|
||||
# Requires pip>=19.3 so disabling for "embed" because this means we don't know what's the
|
||||
# version of pip that will end-up installed.
|
||||
# c.f. https://virtualenv.pypa.io/en/latest/cli_interface.html#section-seeder
|
||||
if (
|
||||
not IS_WIN
|
||||
and constraints["pip"] != "embed"
|
||||
and Version(constraints["pip"]) >= Version("19.3")
|
||||
):
|
||||
additional_flags.append("--symlink-app-data")
|
||||
|
||||
call(
|
||||
sys.executable,
|
||||
"-sS", # just the stdlib, https://github.com/pypa/virtualenv/issues/2133#issuecomment-1003710125
|
||||
virtualenv_app,
|
||||
"--activators=",
|
||||
"--no-periodic-update",
|
||||
*additional_flags,
|
||||
"--python",
|
||||
python,
|
||||
venv_path,
|
||||
)
|
||||
|
||||
paths = [str(venv_path), str(venv_path / "Scripts")] if IS_WIN else [str(venv_path / "bin")]
|
||||
env = os.environ.copy()
|
||||
env["PATH"] = os.pathsep.join([*paths, env["PATH"]])
|
||||
env["VIRTUAL_ENV"] = str(venv_path)
|
||||
return env
|
||||
|
||||
|
||||
@@ -638,10 +732,13 @@ def find_compatible_wheel(wheels: Sequence[T], identifier: str) -> T | None:
|
||||
"""
|
||||
|
||||
interpreter, platform = identifier.split("-")
|
||||
free_threaded = interpreter.endswith("t")
|
||||
if free_threaded:
|
||||
interpreter = interpreter[:-1]
|
||||
for wheel in wheels:
|
||||
_, _, _, tags = parse_wheel_filename(wheel.name)
|
||||
for tag in tags:
|
||||
if tag.abi == "abi3":
|
||||
if tag.abi == "abi3" and not free_threaded:
|
||||
# ABI3 wheels must start with cp3 for impl and tag
|
||||
if not (interpreter.startswith("cp3") and tag.interpreter.startswith("cp3")):
|
||||
continue
|
||||
@@ -731,23 +828,26 @@ def parse_key_value_string(
|
||||
|
||||
all_field_names = [*positional_arg_names, *kw_arg_names]
|
||||
|
||||
shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";:")
|
||||
shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";")
|
||||
shlexer.commenters = ""
|
||||
shlexer.whitespace_split = True
|
||||
parts = list(shlexer)
|
||||
# parts now looks like
|
||||
# ['docker', ';', 'create_args',':', '--some-option=value', 'another-option']
|
||||
# ['docker', ';', 'create_args:', '--some-option=value', 'another-option']
|
||||
|
||||
# split by semicolon
|
||||
fields = [list(group) for k, group in itertools.groupby(parts, lambda x: x == ";") if not k]
|
||||
|
||||
result: dict[str, list[str]] = defaultdict(list)
|
||||
result: defaultdict[str, list[str]] = defaultdict(list)
|
||||
for field_i, field in enumerate(fields):
|
||||
if len(field) > 1 and field[1] == ":":
|
||||
field_name = field[0]
|
||||
values = field[2:]
|
||||
# check to see if the option name is specified
|
||||
field_name, sep, first_value = field[0].partition(":")
|
||||
if sep:
|
||||
if field_name not in all_field_names:
|
||||
msg = f"Failed to parse {key_value_string!r}. Unknown field name {field_name!r}"
|
||||
raise ValueError(msg)
|
||||
|
||||
values = ([first_value] if first_value else []) + field[1:]
|
||||
else:
|
||||
try:
|
||||
field_name = positional_arg_names[field_i]
|
||||
@@ -759,4 +859,43 @@ def parse_key_value_string(
|
||||
|
||||
result[field_name] += values
|
||||
|
||||
return result
|
||||
return dict(result)
|
||||
|
||||
|
||||
def find_uv() -> Path | None:
|
||||
# Prefer uv in our environment
|
||||
with contextlib.suppress(ImportError, FileNotFoundError):
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from uv import find_uv_bin
|
||||
|
||||
return Path(find_uv_bin())
|
||||
|
||||
uv_on_path = shutil.which("uv")
|
||||
return Path(uv_on_path) if uv_on_path else None
|
||||
|
||||
|
||||
def combine_constraints(
|
||||
env: MutableMapping[str, str], /, constraints_path: Path, tmp_dir: Path | None
|
||||
) -> None:
|
||||
"""
|
||||
This will workaround a bug in pip<=21.1.1 or uv<=0.2.0 if a tmp_dir is given.
|
||||
If set to None, this will use the modern URI method.
|
||||
"""
|
||||
|
||||
if tmp_dir:
|
||||
if " " in str(constraints_path):
|
||||
assert " " not in str(tmp_dir)
|
||||
tmp_file = tmp_dir / "constraints.txt"
|
||||
tmp_file.write_bytes(constraints_path.read_bytes())
|
||||
constraints_path = tmp_file
|
||||
our_constraints = str(constraints_path)
|
||||
else:
|
||||
our_constraints = (
|
||||
constraints_path.as_uri() if " " in str(constraints_path) else str(constraints_path)
|
||||
)
|
||||
|
||||
user_constraints = env.get("PIP_CONSTRAINT")
|
||||
|
||||
env["UV_CONSTRAINT"] = env["PIP_CONSTRAINT"] = " ".join(
|
||||
c for c in [our_constraints, user_constraints] if c
|
||||
)
|
||||
|
||||
+132
-123
@@ -4,18 +4,16 @@ import os
|
||||
import platform as platform_module
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from collections.abc import MutableMapping, Sequence, Set
|
||||
from contextlib import suppress
|
||||
from dataclasses import dataclass
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
from zipfile import ZipFile
|
||||
|
||||
from filelock import FileLock
|
||||
from packaging.version import Version
|
||||
|
||||
from . import errors
|
||||
from ._compat.typing import assert_never
|
||||
from .architecture import Architecture
|
||||
from .environment import ParsedEnvironment
|
||||
@@ -24,16 +22,18 @@ from .options import Options
|
||||
from .typing import PathOrStr
|
||||
from .util import (
|
||||
CIBW_CACHE_PATH,
|
||||
AlreadyBuiltWheelError,
|
||||
BuildFrontendConfig,
|
||||
BuildFrontendName,
|
||||
BuildSelector,
|
||||
NonPlatformWheelError,
|
||||
call,
|
||||
combine_constraints,
|
||||
download,
|
||||
extract_zip,
|
||||
find_compatible_wheel,
|
||||
find_uv,
|
||||
get_build_verbosity_extra_flags,
|
||||
get_pip_version,
|
||||
move_file,
|
||||
prepare_command,
|
||||
read_python_configs,
|
||||
shell,
|
||||
@@ -44,7 +44,9 @@ from .util import (
|
||||
)
|
||||
|
||||
|
||||
def get_nuget_args(version: str, arch: str, output_directory: Path) -> list[str]:
|
||||
def get_nuget_args(
|
||||
version: str, arch: str, free_threaded: bool, output_directory: Path
|
||||
) -> list[str]:
|
||||
package_name = {
|
||||
"32": "pythonx86",
|
||||
"64": "python",
|
||||
@@ -53,6 +55,8 @@ def get_nuget_args(version: str, arch: str, output_directory: Path) -> list[str]
|
||||
"x86": "pythonx86",
|
||||
"AMD64": "python",
|
||||
}[arch]
|
||||
if free_threaded:
|
||||
package_name = f"{package_name}-freethreaded"
|
||||
return [
|
||||
package_name,
|
||||
"-Version",
|
||||
@@ -92,11 +96,6 @@ def get_python_configurations(
|
||||
return python_configurations
|
||||
|
||||
|
||||
def extract_zip(zip_src: Path, dest: Path) -> None:
|
||||
with ZipFile(zip_src) as zip_:
|
||||
zip_.extractall(dest)
|
||||
|
||||
|
||||
@lru_cache(maxsize=None)
|
||||
def _ensure_nuget() -> Path:
|
||||
nuget = CIBW_CACHE_PATH / "nuget.exe"
|
||||
@@ -106,11 +105,16 @@ def _ensure_nuget() -> Path:
|
||||
return nuget
|
||||
|
||||
|
||||
def install_cpython(version: str, arch: str) -> Path:
|
||||
def install_cpython(configuration: PythonConfiguration, arch: str | None = None) -> Path:
|
||||
version = configuration.version
|
||||
free_threaded = "t-" in configuration.identifier
|
||||
if arch is None:
|
||||
arch = configuration.arch
|
||||
base_output_dir = CIBW_CACHE_PATH / "nuget-cpython"
|
||||
nuget_args = get_nuget_args(version, arch, base_output_dir)
|
||||
nuget_args = get_nuget_args(version, arch, free_threaded, base_output_dir)
|
||||
installation_path = base_output_dir / (nuget_args[0] + "." + version) / "tools"
|
||||
with FileLock(str(base_output_dir) + f"-{version}-{arch}.lock"):
|
||||
free_threaded_str = "-freethreaded" if free_threaded else ""
|
||||
with FileLock(str(base_output_dir) + f"-{version}{free_threaded_str}-{arch}.lock"):
|
||||
if not installation_path.exists():
|
||||
nuget = _ensure_nuget()
|
||||
call(nuget, "install", *nuget_args)
|
||||
@@ -148,6 +152,16 @@ def setup_setuptools_cross_compile(
|
||||
# set the platform name
|
||||
map_plat = {"32": "win32", "64": "win-amd64", "ARM64": "win-arm64"}
|
||||
plat_name = map_plat[python_configuration.arch]
|
||||
|
||||
# Set environment variable so that setuptools._distutils.get_platform()
|
||||
# identifies the target, not the host
|
||||
vscmd_arg_tgt_arch = {"32": "x86", "64": "x64", "ARM64": "arm64"}
|
||||
current_tgt_arch = vscmd_arg_tgt_arch[python_configuration.arch]
|
||||
if (env.get("VSCMD_ARG_TGT_ARCH") or current_tgt_arch) != current_tgt_arch:
|
||||
msg = f"VSCMD_ARG_TGT_ARCH must be set to {current_tgt_arch!r}, got {env['VSCMD_ARG_TGT_ARCH']!r}. If you're setting up MSVC yourself (e.g. using vcvarsall.bat or msvc-dev-cmd), make sure to target the right architecture. Alternatively, run cibuildwheel without configuring MSVC, and let the build backend handle it."
|
||||
raise errors.FatalError(msg)
|
||||
env["VSCMD_ARG_TGT_ARCH"] = current_tgt_arch
|
||||
|
||||
# (This file must be default/locale encoding, so we can't pass 'encoding')
|
||||
distutils_cfg.write_text(
|
||||
textwrap.dedent(
|
||||
@@ -217,25 +231,21 @@ def setup_python(
|
||||
dependency_constraint_flags: Sequence[PathOrStr],
|
||||
environment: ParsedEnvironment,
|
||||
build_frontend: BuildFrontendName,
|
||||
) -> dict[str, str]:
|
||||
) -> tuple[Path, dict[str, str]]:
|
||||
tmp.mkdir()
|
||||
implementation_id = python_configuration.identifier.split("-")[0]
|
||||
python_libs_base = None
|
||||
log.step(f"Installing Python {implementation_id}...")
|
||||
if implementation_id.startswith("cp"):
|
||||
native_arch = platform_module.machine()
|
||||
base_python = install_cpython(python_configuration)
|
||||
if python_configuration.arch == "ARM64" != native_arch:
|
||||
# To cross-compile for ARM64, we need a native CPython to run the
|
||||
# build, and a copy of the ARM64 import libraries ('.\libs\*.lib')
|
||||
# for any extension modules.
|
||||
python_libs_base = install_cpython(
|
||||
python_configuration.version, python_configuration.arch
|
||||
)
|
||||
python_libs_base = python_libs_base.parent / "libs"
|
||||
python_libs_base = base_python.parent / "libs"
|
||||
log.step(f"Installing native Python {native_arch} for cross-compilation...")
|
||||
base_python = install_cpython(python_configuration.version, native_arch)
|
||||
else:
|
||||
base_python = install_cpython(python_configuration.version, python_configuration.arch)
|
||||
base_python = install_cpython(python_configuration, arch=native_arch)
|
||||
elif implementation_id.startswith("pp"):
|
||||
assert python_configuration.url is not None
|
||||
base_python = install_pypy(tmp, python_configuration.arch, python_configuration.url)
|
||||
@@ -244,28 +254,36 @@ def setup_python(
|
||||
raise ValueError(msg)
|
||||
assert base_python.exists()
|
||||
|
||||
use_uv = (
|
||||
build_frontend == "build[uv]"
|
||||
and Version(python_configuration.version) >= Version("3.8")
|
||||
and not python_configuration.identifier.startswith("pp38-")
|
||||
)
|
||||
uv_path = find_uv()
|
||||
|
||||
log.step("Setting up build environment...")
|
||||
venv_path = tmp / "venv"
|
||||
env = virtualenv(base_python, venv_path, dependency_constraint_flags)
|
||||
env = virtualenv(
|
||||
python_configuration.version,
|
||||
base_python,
|
||||
venv_path,
|
||||
dependency_constraint_flags,
|
||||
use_uv=use_uv,
|
||||
)
|
||||
|
||||
# set up environment variables for run_with_env
|
||||
env["PYTHON_VERSION"] = python_configuration.version
|
||||
env["PYTHON_ARCH"] = python_configuration.arch
|
||||
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
|
||||
|
||||
# pip older than 21.3 builds executables such as pip.exe for x64 platform.
|
||||
# The first re-install of pip updates pip module but builds pip.exe using
|
||||
# the old pip which still generates x64 executable. But the second
|
||||
# re-install uses updated pip and correctly builds pip.exe for the target.
|
||||
# This can be removed once ARM64 Pythons (currently 3.9 and 3.10) bundle
|
||||
# pip versions newer than 21.3.
|
||||
if python_configuration.arch == "ARM64" and Version(get_pip_version(env)) < Version("21.3"):
|
||||
# upgrade pip to the version matching our constraints
|
||||
# if necessary, reinstall it to ensure that it's available on PATH as 'pip.exe'
|
||||
if not use_uv:
|
||||
call(
|
||||
"python",
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"--force-reinstall",
|
||||
"--upgrade",
|
||||
"pip",
|
||||
*dependency_constraint_flags,
|
||||
@@ -273,20 +291,6 @@ def setup_python(
|
||||
cwd=venv_path,
|
||||
)
|
||||
|
||||
# upgrade pip to the version matching our constraints
|
||||
# if necessary, reinstall it to ensure that it's available on PATH as 'pip.exe'
|
||||
call(
|
||||
"python",
|
||||
"-m",
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"pip",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
cwd=venv_path,
|
||||
)
|
||||
|
||||
# update env with results from CIBW_ENVIRONMENT
|
||||
env = environment.as_dictionary(prev_environment=env)
|
||||
|
||||
@@ -296,36 +300,21 @@ def setup_python(
|
||||
call("python", "-c", "\"import struct; print(struct.calcsize('P') * 8)\"", env=env)
|
||||
where_python = call("where", "python", env=env, capture_stdout=True).splitlines()[0].strip()
|
||||
if where_python != str(venv_path / "Scripts" / "python.exe"):
|
||||
print(
|
||||
"cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
msg = "python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
# check what pip version we're on
|
||||
assert (venv_path / "Scripts" / "pip.exe").exists()
|
||||
where_pip = call("where", "pip", env=env, capture_stdout=True).splitlines()[0].strip()
|
||||
if where_pip.strip() != str(venv_path / "Scripts" / "pip.exe"):
|
||||
print(
|
||||
"cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
if not use_uv:
|
||||
assert (venv_path / "Scripts" / "pip.exe").exists()
|
||||
where_pip = call("where", "pip", env=env, capture_stdout=True).splitlines()[0].strip()
|
||||
if where_pip.strip() != str(venv_path / "Scripts" / "pip.exe"):
|
||||
msg = "pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
|
||||
raise errors.FatalError(msg)
|
||||
|
||||
call("pip", "--version", env=env)
|
||||
call("pip", "--version", env=env)
|
||||
|
||||
log.step("Installing build tools...")
|
||||
if build_frontend == "pip":
|
||||
call(
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"setuptools",
|
||||
"wheel",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
)
|
||||
elif build_frontend == "build":
|
||||
if build_frontend == "build":
|
||||
call(
|
||||
"pip",
|
||||
"install",
|
||||
@@ -334,15 +323,24 @@ def setup_python(
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
)
|
||||
else:
|
||||
assert_never(build_frontend)
|
||||
elif build_frontend == "build[uv]":
|
||||
assert uv_path is not None
|
||||
call(
|
||||
uv_path,
|
||||
"pip",
|
||||
"install",
|
||||
"--upgrade",
|
||||
"build[virtualenv]",
|
||||
*dependency_constraint_flags,
|
||||
env=env,
|
||||
)
|
||||
|
||||
if python_libs_base:
|
||||
# Set up the environment for various backends to enable cross-compilation
|
||||
setup_setuptools_cross_compile(tmp, python_configuration, python_libs_base, env)
|
||||
setup_rust_cross_compile(tmp, python_configuration, python_libs_base, env)
|
||||
|
||||
return env
|
||||
return base_python, env
|
||||
|
||||
|
||||
def build(options: Options, tmp_path: Path) -> None:
|
||||
@@ -370,6 +368,11 @@ 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 or BuildFrontendConfig("pip")
|
||||
use_uv = (
|
||||
build_frontend.name == "build[uv]"
|
||||
and Version(config.version) >= Version("3.8")
|
||||
and not config.identifier.startswith("pp38-")
|
||||
)
|
||||
log.build_start(config.identifier)
|
||||
|
||||
identifier_tmp_dir = tmp_path / config.identifier
|
||||
@@ -385,13 +388,15 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
]
|
||||
|
||||
# install Python
|
||||
env = setup_python(
|
||||
base_python, env = setup_python(
|
||||
identifier_tmp_dir / "build",
|
||||
config,
|
||||
dependency_constraint_flags,
|
||||
build_options.environment,
|
||||
build_frontend.name,
|
||||
)
|
||||
if not use_uv:
|
||||
pip_version = get_pip_version(env)
|
||||
|
||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||
if compatible_wheel:
|
||||
@@ -419,6 +424,16 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
)
|
||||
extra_flags += build_frontend.args
|
||||
|
||||
build_env = env.copy()
|
||||
if not use_uv:
|
||||
build_env["VIRTUALENV_PIP"] = pip_version
|
||||
|
||||
if build_options.dependency_constraints:
|
||||
constraints_path = build_options.dependency_constraints.get_for_python_version(
|
||||
config.version
|
||||
)
|
||||
combine_constraints(build_env, constraints_path, identifier_tmp_dir)
|
||||
|
||||
if build_frontend.name == "pip":
|
||||
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
|
||||
@@ -432,41 +447,24 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
f"--wheel-dir={built_wheel_dir}",
|
||||
"--no-deps",
|
||||
*extra_flags,
|
||||
env=env,
|
||||
env=build_env,
|
||||
)
|
||||
elif build_frontend.name == "build":
|
||||
elif build_frontend.name == "build" or build_frontend.name == "build[uv]":
|
||||
if not 0 <= build_options.build_verbosity < 2:
|
||||
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
|
||||
log.warning(msg)
|
||||
build_env = env.copy()
|
||||
if build_options.dependency_constraints:
|
||||
constraints_path = (
|
||||
build_options.dependency_constraints.get_for_python_version(
|
||||
config.version
|
||||
)
|
||||
)
|
||||
# Bug in pip <= 21.1.3 - we can't have a space in the
|
||||
# constraints file, and pip doesn't support drive letters
|
||||
# in uhi. After probably pip 21.2, we can use uri. For
|
||||
# now, use a temporary file.
|
||||
if " " in str(constraints_path):
|
||||
assert " " not in str(identifier_tmp_dir)
|
||||
tmp_file = identifier_tmp_dir / "constraints.txt"
|
||||
tmp_file.write_bytes(constraints_path.read_bytes())
|
||||
constraints_path = tmp_file
|
||||
|
||||
build_env["PIP_CONSTRAINT"] = str(constraints_path)
|
||||
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
|
||||
call(
|
||||
"python",
|
||||
"-m",
|
||||
"build",
|
||||
build_options.package_dir,
|
||||
"--wheel",
|
||||
f"--outdir={built_wheel_dir}",
|
||||
*extra_flags,
|
||||
env=build_env,
|
||||
)
|
||||
if use_uv and "--no-isolation" not in extra_flags and "-n" not in extra_flags:
|
||||
extra_flags.append("--installer=uv")
|
||||
call(
|
||||
"python",
|
||||
"-m",
|
||||
"build",
|
||||
build_options.package_dir,
|
||||
"--wheel",
|
||||
f"--outdir={built_wheel_dir}",
|
||||
*extra_flags,
|
||||
env=build_env,
|
||||
)
|
||||
else:
|
||||
assert_never(build_frontend)
|
||||
|
||||
@@ -476,7 +474,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
repaired_wheel_dir.mkdir()
|
||||
|
||||
if built_wheel.name.endswith("none-any.whl"):
|
||||
raise NonPlatformWheelError()
|
||||
raise errors.NonPlatformWheelError()
|
||||
|
||||
if build_options.repair_command:
|
||||
log.step("Repairing wheel...")
|
||||
@@ -492,7 +490,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
|
||||
|
||||
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
|
||||
raise AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
|
||||
test_selected = options.globals.test_selector(config.identifier)
|
||||
if test_selected and config.arch == "ARM64" != platform_module.machine():
|
||||
@@ -501,7 +499,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
"""
|
||||
While arm64 wheels can be built on other platforms, they cannot
|
||||
be tested. An arm64 runner is required. To silence this warning,
|
||||
set `CIBW_TEST_SKIP: *-win_arm64`.
|
||||
set `CIBW_TEST_SKIP: "*-win_arm64"`.
|
||||
"""
|
||||
)
|
||||
)
|
||||
@@ -510,12 +508,20 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
log.step("Testing wheel...")
|
||||
# set up a virtual environment to install and test from, to make sure
|
||||
# there are no dependencies that were pulled in at build time.
|
||||
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
|
||||
if not use_uv:
|
||||
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
|
||||
|
||||
venv_dir = identifier_tmp_dir / "venv-test"
|
||||
|
||||
# Use --no-download to ensure determinism by using seed libraries
|
||||
# built into virtualenv
|
||||
call("python", "-m", "virtualenv", "--no-download", venv_dir, env=env)
|
||||
if use_uv:
|
||||
call("uv", "venv", venv_dir, f"--python={base_python}", env=env)
|
||||
else:
|
||||
# Use pip version from the initial env to ensure determinism
|
||||
venv_args = ["--no-periodic-update", f"--pip={pip_version}"]
|
||||
# In Python<3.12, setuptools & wheel are installed as well, use virtualenv embedded ones
|
||||
if Version(config.version) < Version("3.12"):
|
||||
venv_args.extend(("--setuptools=embed", "--wheel=embed"))
|
||||
call("python", "-m", "virtualenv", *venv_args, venv_dir, env=env)
|
||||
|
||||
virtualenv_env = env.copy()
|
||||
virtualenv_env["PATH"] = os.pathsep.join(
|
||||
@@ -524,6 +530,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
virtualenv_env["PATH"],
|
||||
]
|
||||
)
|
||||
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
|
||||
|
||||
# check that we are using the Python from the virtual environment
|
||||
call("where", "python", env=virtualenv_env)
|
||||
@@ -536,9 +543,11 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
)
|
||||
shell(before_test_prepared, env=virtualenv_env)
|
||||
|
||||
pip = ["uv", "pip"] if use_uv else ["pip"]
|
||||
|
||||
# install the wheel
|
||||
call(
|
||||
"pip",
|
||||
*pip,
|
||||
"install",
|
||||
str(repaired_wheel) + build_options.test_extras,
|
||||
env=virtualenv_env,
|
||||
@@ -546,7 +555,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
|
||||
# test the wheel
|
||||
if build_options.test_requires:
|
||||
call("pip", "install", *build_options.test_requires, env=virtualenv_env)
|
||||
call(*pip, "install", *build_options.test_requires, env=virtualenv_env)
|
||||
|
||||
# run the tests from a temp dir, with an absolute path in the command
|
||||
# (this ensures that Python runs the tests against the installed wheel
|
||||
@@ -565,11 +574,13 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
|
||||
# we're all done here; move it to output (remove if already exists)
|
||||
if compatible_wheel is None:
|
||||
with suppress(FileNotFoundError):
|
||||
(build_options.output_dir / repaired_wheel.name).unlink()
|
||||
|
||||
shutil.move(str(repaired_wheel), build_options.output_dir)
|
||||
built_wheels.append(build_options.output_dir / repaired_wheel.name)
|
||||
output_wheel = build_options.output_dir.joinpath(repaired_wheel.name)
|
||||
moved_wheel = move_file(repaired_wheel, output_wheel)
|
||||
if moved_wheel != output_wheel.resolve():
|
||||
log.warning(
|
||||
"{repaired_wheel} was moved to {moved_wheel} instead of {output_wheel}"
|
||||
)
|
||||
built_wheels.append(output_wheel)
|
||||
|
||||
# clean up
|
||||
# (we ignore errors because occasionally Windows fails to unlink a file and we
|
||||
@@ -578,7 +589,5 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
|
||||
log.build_end()
|
||||
except subprocess.CalledProcessError as error:
|
||||
log.step_end_with_error(
|
||||
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
|
||||
)
|
||||
sys.exit(1)
|
||||
msg = f"Command {error.cmd} failed with code {error.returncode}. {error.stdout or ''}"
|
||||
raise errors.FatalError(msg) from error
|
||||
|
||||
+178
-43
@@ -4,14 +4,149 @@ title: Changelog
|
||||
|
||||
# Changelog
|
||||
|
||||
### v2.20.0
|
||||
|
||||
- 🌟 CPython 3.13 wheels are now built by default - without the `CIBW_PRERELEASE_PYTHONS` flag. It's time to build and upload these wheels to PyPI! This release includes CPython 3.13.0rc1, which is guaranteed to be ABI compatible with the final release. Free-threading is still behind a flag/config option. (#1950)
|
||||
- ✨ Provide a `CIBW_ALLOW_EMPTY` environment variable as an alternative to the command line flag. (#1937)
|
||||
- 🐛 Don't use uv on PyPy3.8 on Windows, it stopped working starting in 0.2.25. Note that PyPy 3.8 is EoL. (#1868)
|
||||
- 🛠 Set the `VSCMD_ARG_TGT_ARCH` variable based on target arch. (#1876)
|
||||
- 🛠 Undo cleaner output on pytest 8-8.2 now that 8.3 is out. (#1943)
|
||||
- 📚 Update examples to use Python 3.12 on host (cibuildwheel will require Python 3.11+ on the host machine starting in October 2024) (#1919)
|
||||
|
||||
|
||||
### v2.19.2
|
||||
|
||||
- 🐛 Update manylinux2014 pins to versions that support past-EoL CentOS 7 mirrors. (#1917)
|
||||
- 🐛 Support `--no-isolation` with `build[uv]` build-frontend. (#1889)
|
||||
- 🛠 Provide attestations for releases at <https://github.com/pypa/cibuildwheel/attestations>. (#1916)
|
||||
- 🛠 Provide CPython 3.13.0b3. (#1913)
|
||||
- 🛠 Remove some workarounds now that pip 21.1 is available. (#1891, #1892)
|
||||
- 📚 Remove nosetest from our docs. (#1821)
|
||||
- 📚 Document the macOS ARM workaround for 3.8 on GHA. (#1871)
|
||||
- 📚 GitLab CI + macOS is now a supported platform with an example. (#1911)
|
||||
|
||||
|
||||
### v2.19.1
|
||||
|
||||
- 🐛 Don't require setup-python on GHA for Pyodide (#1868)
|
||||
- 🐛 Specify full python path for uv (fixes issue in 0.2.10 & 0.2.11) (#1881)
|
||||
- 🛠 Update for pip 24.1b2 on CPython 3.13. (#1879)
|
||||
- 🛠 Fix a warning in our schema generation script. (#1866)
|
||||
- 🛠 Cleaner output on pytest 8-8.2. (#1865)
|
||||
|
||||
|
||||
### v2.19.0
|
||||
|
||||
See the [release post](https://iscinumpy.dev/post/cibuildwheel-2-19-0/) for more info on new features!
|
||||
|
||||
- 🌟 Add Pyodide platform. Set with `--platform pyodide` or `CIBW_PLATFORM: pyodide` on Linux with a host Python 3.12 to build WebAssembly wheels. Not accepted on PyPI currently, but usable directly in a website using Pyodide, for live docs, etc. (#1456, #1859)
|
||||
- 🌟 Add `build[uv]` backend, which will take a pre-existing uv install (or install `cibuildwheel[uv]`) and use `uv` for all environment setup and installs on Python 3.8+. This is significantly faster in most cases. (#1856)
|
||||
- ✨ Add free-threaded macOS builds and update CPython to 3.13.0b2. (#1854)
|
||||
- 🐛 Issue copying a wheel to a non-existent output dir fixed. (#1851, #1862)
|
||||
- 🐛 Better determinism for the test environment seeding. (#1835)
|
||||
- 🛠 `VIRTUAL_ENV` variable now set. (#1842)
|
||||
- 🛠 Remove a pip<21.3 workaround. (#1842)
|
||||
- 🛠 Error handling was refactored to use exceptions. (#1719)
|
||||
- 🛠 Hardcoded paths in tests avoided. (#1834)
|
||||
- 🛠 Single Python tests made more generic. (#1835)
|
||||
- 🛠 Sped up our ci by splitting up emulation tests. (#1839)
|
||||
|
||||
|
||||
|
||||
### v2.18.1
|
||||
|
||||
- 🌟 Add free-threaded Linux and Windows builds for 3.13. New identifiers `cp313t-*`, new option `CIBW_FREE_THREADED_SUPPORT`/`tool.cibuildwheel.free-threaded-support` required to opt-in. [See the docs](https://cibuildwheel.pypa.io/en/stable/options/#free-threaded-support) for more information. (#1831)
|
||||
- ✨ The `container-engine` is now a build (non-global) option. (#1792)
|
||||
- 🛠 The build backend for cibuildwheel is now hatchling. (#1297)
|
||||
- 🛠 Significant improvements and modernization to our noxfile. (#1823)
|
||||
- 🛠 Use pylint's new GitHub Actions reporter instead of a custom matcher. (#1823)
|
||||
- 🛠 Unpin virtualenv updates for Python 3.7+ (#1830)
|
||||
- 🐛 Fix running linux tests from Windows or macOS ARM. (#1788)
|
||||
- 📚 Fix our documentation build. (#1821)
|
||||
|
||||
|
||||
### v2.18.0
|
||||
|
||||
_12 May 2024_
|
||||
|
||||
- ✨ Adds CPython 3.13 support, under the prerelease flag [CIBW_PRERELEASE_PYTHONS](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons). This version of cibuildwheel uses 3.13.0b1. Free-threading mode is not available yet (#1657), waiting on official binaries (planned for beta 2) and pip support.
|
||||
|
||||
_While CPython is in beta, the ABI can change, so your wheels might not be compatible with the final release. For this reason, we don't recommend distributing wheels until RC1, at which point 3.13 will be available in cibuildwheel without the flag._ (#1815)
|
||||
|
||||
- ✨ Musllinux now defaults to `musllinux_1_2`. You can set the older `musllinux_1_1` via config if needed. (#1817)
|
||||
- 🛠 No longer pre-seed setuptools/wheel in virtual environments (#1819)
|
||||
- 🛠 Respect the constraints file when building with pip, matching build (#1818)
|
||||
- 🛠 Use uv to compile our pinned dependencies, 10x faster and doesn't require special setup (#1778)
|
||||
- 🐛 Fix an issue with the schema (#1788)
|
||||
- 📚 Document the new delocate error checking macOS versions (#1766)
|
||||
- 📚 Document Rust builds (#1816)
|
||||
- 📚 Speed up our readthedocs builds with uv, 26 seconds -> 6 seconds to install dependencies (#1816)
|
||||
|
||||
|
||||
### v2.17.0
|
||||
|
||||
_11 March 2024_
|
||||
|
||||
- 🌟 Adds the ability to inherit configuration in TOML overrides. This makes certain configurations much simpler. If you're overriding an option like `before-build` or `environment`, and you just want to add an extra command or environment variable, you can just append (or prepend) to the previous config. See [the docs](https://cibuildwheel.pypa.io/en/stable/options/#inherit) for more information. (#1730)
|
||||
- 🌟 Adds official support for native `arm64` macOS GitHub runners. To use them, just specify `macos-14` as an `os` of your job in your workflow file. You can also keep `macos-13` in your build matrix to build `x86_64`. Check out the new [GitHub Actions example config](https://cibuildwheel.pypa.io/en/stable/setup/#github-actions).
|
||||
- ✨ You no longer need to specify `--platform` to run cibuildwheel locally! Instead it will detect your platform automatically. This was a safety feature, no longer necessary. (#1727)
|
||||
- 🛠 Removed setuptools and wheel pinned versions. This only affects old-style projects without a `pyproject.toml`, projects with `pyproject.toml` are already getting fresh versions of their `build-system.requires` installed into an isolated environment. (#1725)
|
||||
- 🛠 Improve how the GitHub Action passes arguments (#1757)
|
||||
- 🛠 Remove a system-wide install of pipx in the GitHub Action (#1745)
|
||||
- 🐛 No longer will cibuildwheel override the `PIP_CONSTRAINT` environment variable when using the `build` frontend. Instead it will be extended. (#1675)
|
||||
- 🐛 Fix a bug where building and testing both `x86_86` and `arm64` wheels on the same runner caused the wrong architectures in the test environment (#1750)
|
||||
- 🐛 Fix a bug that prevented testing a CPython 3.8 wheel targeting macOS 11+ on `x86_64` (#1768)
|
||||
- 📚 Moved the docs onto the official PyPA domain - they're now available at https://cibuildwheel.pypa.io . (#1775)
|
||||
- 📚 Docs and examples improvements (#1762, #1734)
|
||||
|
||||
|
||||
### v2.16.5
|
||||
|
||||
_30 January 2024_
|
||||
|
||||
- 🐛 Fix an incompatibility with the GitHub Action and new GitHub Runner images for Windows that bundle Powershell 7.3+ (#1741)
|
||||
- 🛠 Preliminary support for new `macos-14` arm64 runners (#1743)
|
||||
|
||||
### v2.16.4
|
||||
|
||||
_28 January 2024_
|
||||
|
||||
- 🛠 Update manylinux pins to upgrade from a problematic PyPy version. (#1737)
|
||||
|
||||
### v2.16.3
|
||||
|
||||
_26 January 2024_
|
||||
|
||||
- 🐛 Fix a bug when building from sdist, where relative paths to files in the package didn't work because the working directory was wrong (#1687)
|
||||
- 🛠 Adds the ability to disable mounting the host filesystem in containers to `/host`, through the `disable_host_mount` suboption on [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine).
|
||||
- 📚 A lot of docs improvements! (#1708, #1705, #1686, #1679, #1667, #1665)
|
||||
|
||||
### v2.16.2
|
||||
|
||||
_3 October 2023_
|
||||
|
||||
- 🛠 Updates CPython 3.12 version to 3.12.0, final release (#1635)
|
||||
- ✨ Adds a debug option [`CIBW_DEBUG_KEEP_CONTAINER`](https://cibuildwheel.pypa.io/en/stable/options/#cibw_debug_keep_container) to stop cibuildwheel deleting build containers after the build finishes. (#1620)
|
||||
- 📚 Adds support for `[tool.cibuildwheel]` checking by adding a schema compatible with the [validate-pyproject](https://github.com/abravalheri/validate-pyproject/) tool (#1622, #1628, #1629)
|
||||
- 🐛 Fix parsing of `CIBW_CONTAINER_ENGINE` and `CIBW_BUILD_FRONTEND` options to not break arguments on `:` characters (#1621)
|
||||
- 🐛 Fix the evaluation order of `CIBW_ENVIRONMENT` and `CIBW_ENVIRONMENT_PASS` so that `CIBW_ENVIRONMENT` assignments can reference environment variables passed through from the host machine. (#1617)
|
||||
- 🛠 Supports manylinux images' deferred installation of interpreters through the `manylinux-interpreters` tool (#1630)
|
||||
|
||||
### v2.16.1
|
||||
|
||||
_26 September 2023_
|
||||
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0rc3 (#1625)
|
||||
- 🛠 Only calls `linux32` in containers when necessary (#1599)
|
||||
|
||||
### v2.16.0
|
||||
|
||||
_18 September 2023_
|
||||
|
||||
- ✨ Add the ability to pass additional flags to a build frontend through the [CIBW_BUILD_FRONTEND](https://cibuildwheel.readthedocs.io/en/stable/options/#build-frontend) option (#1588).
|
||||
- ✨ Add the ability to pass additional flags to a build frontend through the [CIBW_BUILD_FRONTEND](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) option (#1588).
|
||||
- ✨ The environment variable SOURCE_DATE_EPOCH is now automatically passed through to container Linux builds (useful for [reproducible builds](https://reproducible-builds.org/docs/source-date-epoch/)!) (#1589)
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0rc2 (#1604)
|
||||
- 🐛 Fix `requires_python` auto-detection from setup.py when the call to `setup()` is within an `if __name__ == "__main__" block (#1613)
|
||||
- 🐛 Fix `requires_python` auto-detection from setup.py when the call to `setup()` is within an `if __name__ == "__main__"` block (#1613)
|
||||
- 🐛 Fix a bug that prevented building Linux wheels in Docker on a Windows host (#1573)
|
||||
- 🐛 `--only` can now select prerelease-pythons (#1564)
|
||||
- 📚 Docs & examples updates (#1582, #1593, #1598, #1615)
|
||||
@@ -37,7 +172,7 @@ _10 July 2023_
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0b3.
|
||||
- ✨ Allow the use of the `{wheel}` placeholder in CIBW_TEST_COMMAND (#1533)
|
||||
- 📚 Docs & examples updates (#1532, #1416)
|
||||
- ⚠️ Removed support for running cibuildwheel in Python 3.7. Python 3.7 is EOL. However, cibuildwheel continues to build Python 3.7 wheels for the moment. (#1175)
|
||||
- ⚠️ Removed support for running cibuildwheel in Python 3.7. Python 3.7 is EOL. However, cibuildwheel continues to build Python 3.7 wheels for the moment. (#1175)
|
||||
|
||||
### v2.13.1
|
||||
|
||||
@@ -50,11 +185,11 @@ _10 June 2023_
|
||||
|
||||
_28 May 2023_
|
||||
|
||||
- ✨ Adds CPython 3.12 support, under the prerelease flag [CIBW_PRERELEASE_PYTHONS](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons). This version of cibuildwheel uses 3.12.0b1.
|
||||
- ✨ Adds CPython 3.12 support, under the prerelease flag [CIBW_PRERELEASE_PYTHONS](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons). This version of cibuildwheel uses 3.12.0b1.
|
||||
|
||||
While CPython is in beta, the ABI can change, so your wheels might not be compatible with the final release. For this reason, we don't recommend distributing wheels until RC1, at which point 3.12 will be available in cibuildwheel without the flag. (#1507)
|
||||
|
||||
- ✨ Adds the ability to pass arguments to the container engine when the container is created, using the [CIBW_CONTAINER_ENGINE](https://cibuildwheel.readthedocs.io/en/stable/options/#container-engine) option. (#1499)
|
||||
- ✨ Adds the ability to pass arguments to the container engine when the container is created, using the [CIBW_CONTAINER_ENGINE](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) option. (#1499)
|
||||
|
||||
### v2.12.3
|
||||
|
||||
@@ -109,7 +244,7 @@ _26 October 2022_
|
||||
- 🛠 Fix the default `MACOSX_DEPLOYMENT_TARGET` on arm64 (#1312)
|
||||
- 🛠 Hide irrelevant pip warnings on linux (#1311)
|
||||
- 🐛 Fix a bug that caused the stdout and stderr of commands in containers to be in the wrong order Previously, stdout could appear after stderr. (#1324)
|
||||
- 📚 Added [a FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64) describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
|
||||
- 📚 Added [a FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64) describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
|
||||
- 📚 Other docs improvements
|
||||
|
||||
### v2.11.1
|
||||
@@ -122,7 +257,7 @@ _13 October 2022_
|
||||
|
||||
_13 October 2022_
|
||||
|
||||
- 🌟 Adds support for cross-compiling Windows ARM64 wheels. To use this feature, add `ARM64` to the [CIBW_ARCHS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs) option on a Windows Intel runner. (#1144)
|
||||
- 🌟 Adds support for cross-compiling Windows ARM64 wheels. To use this feature, add `ARM64` to the [CIBW_ARCHS](https://cibuildwheel.pypa.io/en/stable/options/#archs) option on a Windows Intel runner. (#1144)
|
||||
- ✨ Adds support for building Linux aarch64 wheels on Circle CI. (#1307)
|
||||
- ✨ Adds support for building Windows wheels on Gitlab CI. (#1295)
|
||||
- ✨ Adds support for building Linux aarch64 wheels under emulation on Gitlab CI. (#1295)
|
||||
@@ -149,10 +284,10 @@ _18 September 2022_
|
||||
|
||||
_13 September 2022_
|
||||
|
||||
- 🌟 Adds support for [building wheels on Cirrus CI](https://cibuildwheel.readthedocs.io/en/stable/setup/#cirrus-ci). This is exciting for us, as it's the first public CI platform that natively supports macOS Apple Silicon (aka. M1, `arm64`) runners. As such, it's the first platform that you can natively build _and test_ macOS `arm64` wheels. It also has native Linux ARM (aarch64) runners, for fast, native builds there. (#1191)
|
||||
- 🌟 Adds support for [building wheels on Cirrus CI](https://cibuildwheel.pypa.io/en/stable/setup/#cirrus-ci). This is exciting for us, as it's the first public CI platform that natively supports macOS Apple Silicon (aka. M1, `arm64`) runners. As such, it's the first platform that you can natively build _and test_ macOS `arm64` wheels. It also has native Linux ARM (aarch64) runners, for fast, native builds there. (#1191)
|
||||
- 🌟 Adds support for running cibuildwheel on Apple Silicon machines. For a while, we've supported cross-compilation of Apple Silicon wheels on `x86_64`, but now that we have Cirrus CI we can run our test suite and officially support running cibuildwheel on `arm64`. (#1191)
|
||||
- ✨ Adds the `--only` [command line option](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line), to specify a single build to run. Previously, it could be cumbersome to set all the build selection options to target a specific build - for example, you might have to run something like `CIBW_BUILD=cp39-manylinux_x86_64 cibuildwheel --platform linux --archs x86_64`. The new `--only` option overrides all the build selection options to simplify running a single build, which now looks like `cibuildwheel --only cp39-manylinux_x86_64`. (#1098)
|
||||
- ✨ Adds the [`CIBW_CONFIG_SETTINGS`](https://cibuildwheel.readthedocs.io/en/stable/options/#config-settings) option, so you can pass arguments to your package's build backend (#1244)
|
||||
- ✨ Adds the `--only` [command line option](https://cibuildwheel.pypa.io/en/stable/options/#command-line), to specify a single build to run. Previously, it could be cumbersome to set all the build selection options to target a specific build - for example, you might have to run something like `CIBW_BUILD=cp39-manylinux_x86_64 cibuildwheel --platform linux --archs x86_64`. The new `--only` option overrides all the build selection options to simplify running a single build, which now looks like `cibuildwheel --only cp39-manylinux_x86_64`. (#1098)
|
||||
- ✨ Adds the [`CIBW_CONFIG_SETTINGS`](https://cibuildwheel.pypa.io/en/stable/options/#config-settings) option, so you can pass arguments to your package's build backend (#1244)
|
||||
- 🛠 Updates the CPython 3.11 version to the latest release candidate - v3.11.0rc2. (#1265)
|
||||
- 🐛 Fix a bug that can cause a RecursionError on Windows when building from an sdist. (#1253)
|
||||
- 🛠 Add support for the s390x architecture on manylinux_2_28 (#1255)
|
||||
@@ -179,7 +314,7 @@ _18 July 2022_
|
||||
|
||||
_5 July 2022_
|
||||
|
||||
- ✨ You can now run cibuildwheel on Podman, as an alternate container engine to Docker (which remains the default). This is useful in environments where a Docker daemon isn't available, for example, it can be run inside a Docker container, or without root access. To use Podman, set the [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.readthedocs.io/en/stable/options/#container-engine) option. (#966)
|
||||
- ✨ You can now run cibuildwheel on Podman, as an alternate container engine to Docker (which remains the default). This is useful in environments where a Docker daemon isn't available, for example, it can be run inside a Docker container, or without root access. To use Podman, set the [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) option. (#966)
|
||||
- ✨ Adds support for building `py3-none-{platform}` wheels. This works the same as ABI3 - wheels won't be rebuilt, but tests will still be run across all selected versions of Python.
|
||||
|
||||
These wheels contain native extension code, but don't use the Python APIs. Typically, they're bridged to Python using a FFI module like [ctypes](https://docs.python.org/3/library/ctypes.html) or [cffi](https://cffi.readthedocs.io/en/latest/). Because they don't use Python ABI, the wheels are more compatible - they work across many Python versions.
|
||||
@@ -193,7 +328,7 @@ _5 July 2022_
|
||||
|
||||
_17 June 2022_
|
||||
|
||||
- 🌟 Added support for the new `manylinux_2_28` images. These new images are based on AlmaLinux, the community-driven successor to CentOS, unlike manylinux_2_24, which was based on Debian. To build on these images, set your [`CIBW_MANYLINUX_*_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image) option to `manylinux_2_28`. (#1026)
|
||||
- 🌟 Added support for the new `manylinux_2_28` images. These new images are based on AlmaLinux, the community-driven successor to CentOS, unlike manylinux_2_24, which was based on Debian. To build on these images, set your [`CIBW_MANYLINUX_*_IMAGE`](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) option to `manylinux_2_28`. (#1026)
|
||||
- 🐛 Fix a bug where tests were not being run on CPython 3.11 (when CIBW_PRERELEASE_PYTHONS was set) (#1138)
|
||||
- ✨ You can now build Linux wheels on Windows, as long as you have Docker installed and set to 'Linux containers' (#1117)
|
||||
- 🐛 Fix a bug on macOS that caused cibuildwheel to crash trying to overwrite a previously-built wheel of the same name. (#1129)
|
||||
@@ -208,15 +343,15 @@ _7 June 2022_
|
||||
|
||||
_25 May 2022_
|
||||
|
||||
- 🌟 Added the ability to test building wheels on CPython 3.11! Because CPython 3.11 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons) to test. This version of cibuildwheel includes CPython 3.11.0b1. (#1109)
|
||||
- 📚 Added an interactive diagram showing how cibuildwheel works to the [docs](https://cibuildwheel.readthedocs.io/en/stable/#how-it-works) (#1100)
|
||||
- 🌟 Added the ability to test building wheels on CPython 3.11! Because CPython 3.11 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons) to test. This version of cibuildwheel includes CPython 3.11.0b1. (#1109)
|
||||
- 📚 Added an interactive diagram showing how cibuildwheel works to the [docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works) (#1100)
|
||||
|
||||
### v2.5.0
|
||||
|
||||
_29 April 2022_
|
||||
|
||||
- ✨ Added support for building ABI3 wheels. cibuildwheel will now recognise when an ABI3 wheel was produced, and skip subsequent build steps where the previously built wheel is compatible. Tests still will run on all selected versions of Python, using the ABI3 wheel. Check [this entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#abi3) in the docs for more info. (#1091)
|
||||
- ✨ You can now build wheels directly from sdist archives, in addition to source directories. Just call cibuildwheel with an sdist argument on the command line, like `cibuildwheel mypackage-1.0.0.tar.gz`. For more details, check the [`--help` output](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line) (#1096)
|
||||
- ✨ Added support for building ABI3 wheels. cibuildwheel will now recognise when an ABI3 wheel was produced, and skip subsequent build steps where the previously built wheel is compatible. Tests still will run on all selected versions of Python, using the ABI3 wheel. Check [this entry](https://cibuildwheel.pypa.io/en/stable/faq/#abi3) in the docs for more info. (#1091)
|
||||
- ✨ You can now build wheels directly from sdist archives, in addition to source directories. Just call cibuildwheel with an sdist argument on the command line, like `cibuildwheel mypackage-1.0.0.tar.gz`. For more details, check the [`--help` output](https://cibuildwheel.pypa.io/en/stable/options/#command-line) (#1096)
|
||||
- 🐛 Fix a bug where cibuildwheel would crash when no builds are selected and `--allow-empty` is passed (#1086)
|
||||
- 🐛 Workaround a permissions issue on Linux relating to newer versions of git and setuptools_scm (#1095)
|
||||
- 📚 Minor docs improvements
|
||||
@@ -225,7 +360,7 @@ _29 April 2022_
|
||||
|
||||
_2 April 2022_
|
||||
|
||||
- ✨ cibuildwheel now supports running locally on Windows and macOS (as well as Linux). On macOS, you'll have to install the versions of Pythons that you want to use from Python.org, and cibuildwheel will use them. On Windows, cibuildwheel will install it's own versions of Python. Check out [the documentation](https://cibuildwheel.readthedocs.io/en/stable/setup/#local) for instructions. (#974)
|
||||
- ✨ cibuildwheel now supports running locally on Windows and macOS (as well as Linux). On macOS, you'll have to install the versions of Pythons that you want to use from Python.org, and cibuildwheel will use them. On Windows, cibuildwheel will install it's own versions of Python. Check out [the documentation](https://cibuildwheel.pypa.io/en/stable/setup/#local) for instructions. (#974)
|
||||
- ✨ Added support for building PyPy 3.9 wheels. (#1031)
|
||||
- ✨ Listing at the end of the build now displays the size of each wheel (#975)
|
||||
- 🐛 Workaround a connection timeout bug on Travis CI ppc64le runners (#906)
|
||||
@@ -245,12 +380,12 @@ _14 December 2021_
|
||||
|
||||
_26 November 2021_
|
||||
|
||||
- 📈 cibuildwheel now defaults to manylinux2014 image for linux builds, rather than manylinux2010. If you want to stick with manylinux2010, it's simple to set this using [the image options](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image). (#926)
|
||||
- ✨ You can now pass environment variables from the host machine into the Docker container during a Linux build. Check out [the docs for `CIBW_ENVIRONMENT_PASS_LINUX `](https://cibuildwheel.readthedocs.io/en/latest/options/#environment-pass) for the details. (#914)
|
||||
- 📈 cibuildwheel now defaults to manylinux2014 image for linux builds, rather than manylinux2010. If you want to stick with manylinux2010, it's simple to set this using [the image options](https://cibuildwheel.pypa.io/en/stable/options/#linux-image). (#926)
|
||||
- ✨ You can now pass environment variables from the host machine into the Docker container during a Linux build. Check out [the docs for `CIBW_ENVIRONMENT_PASS_LINUX `](https://cibuildwheel.pypa.io/en/latest/options/#environment-pass) for the details. (#914)
|
||||
- ✨ Added support for building PyPy 3.8 wheels. (#881)
|
||||
- ✨ Added support for building Windows arm64 CPython wheels on a Windows arm64 runner. We can't test this in CI yet, so for now, this is experimental. (#920)
|
||||
- 📚 Improved the deployment documentation (#911)
|
||||
- 🛠 Changed the escaping behaviour inside cibuildwheel's option placeholders e.g. `{project}` in `before_build` or `{dest_dir}` in `repair_wheel_command`. This allows bash syntax like `${SOME_VAR}` to passthrough without being interpreted as a placeholder by cibuildwheel. See [this section](https://cibuildwheel.readthedocs.io/en/stable/options/#placeholders) in the docs for more info. (#889)
|
||||
- 🛠 Changed the escaping behaviour inside cibuildwheel's option placeholders e.g. `{project}` in `before_build` or `{dest_dir}` in `repair_wheel_command`. This allows bash syntax like `${SOME_VAR}` to passthrough without being interpreted as a placeholder by cibuildwheel. See [this section](https://cibuildwheel.pypa.io/en/stable/options/#placeholders) in the docs for more info. (#889)
|
||||
- 🛠 Pip updated to 21.3, meaning it now defaults to in-tree builds again. If this causes an issue with your project, setting environment variable `PIP_USE_DEPRECATED=out-of-tree-build` is available as a temporary flag to restore the old behaviour. However, be aware that this flag will probably be removed soon. (#881)
|
||||
- 🐛 You can now access the current Python interpreter using `python3` within a build on Windows (#917)
|
||||
|
||||
@@ -273,15 +408,15 @@ _22 October 2021_
|
||||
|
||||
- 🌟 Added support for [musllinux](https://www.python.org/dev/peps/pep-0656/). Support for this new wheel format lets projects build wheels for Linux distributions that use [musl libc](https://musl.libc.org/), notably, [Alpine](https://alpinelinux.org/) Docker containers. (#768)
|
||||
|
||||
Musllinux builds are enabled by default. If you're not ready to build musllinux, add `*-musllinux_*` to your [`CIBW_SKIP`/`skip`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) option. Or, you might have to make some changes to your options - to simplify that process, you can use...
|
||||
Musllinux builds are enabled by default. If you're not ready to build musllinux, add `*-musllinux_*` to your [`CIBW_SKIP`/`skip`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) option. Or, you might have to make some changes to your options - to simplify that process, you can use...
|
||||
|
||||
- 🌟 TOML option overrides! This provides much greater flexibility in configuration via pyproject.toml. (#854)
|
||||
|
||||
You can now set build options for any subset of your builds using a match pattern. So, for example, you can customise CPython 3.8 builds with an override on `cp38-*` or musllinux builds by selecting `*musllinux*`. Check out [the docs](https://cibuildwheel.readthedocs.io/en/latest/options/#overrides) for more info on the specifics.
|
||||
You can now set build options for any subset of your builds using a match pattern. So, for example, you can customise CPython 3.8 builds with an override on `cp38-*` or musllinux builds by selecting `*musllinux*`. Check out [the docs](https://cibuildwheel.pypa.io/en/latest/options/#overrides) for more info on the specifics.
|
||||
|
||||
- 🛠 Added support for building PyPy wheels on macOS 11 CI runners. (#875)
|
||||
|
||||
- 🛠 Setting an empty string for the [`CIBW_*_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) option will now fallthrough to the config file or cibuildwheel's default, rather than causing an error. This makes the option easier to use in CI build matricies. (#829)
|
||||
- 🛠 Setting an empty string for the [`CIBW_*_IMAGE`](https://cibuildwheel.pypa.io/en/stable/options/#manylinux-image) option will now fallthrough to the config file or cibuildwheel's default, rather than causing an error. This makes the option easier to use in CI build matrices. (#829)
|
||||
|
||||
- 🛠 Support for TOML 1.0 when reading config files, via the `tomli` package. (#876)
|
||||
|
||||
@@ -320,9 +455,9 @@ _25 July 2021_
|
||||
|
||||
_16 July 2021_
|
||||
|
||||
- 🌟 You can now configure cibuildwheel options inside your project's `pyproject.toml`! Environment variables still work of course. Check out the [documentation](https://cibuildwheel.readthedocs.io/en/stable/options/#setting-options) for more info.
|
||||
- 🌟 Added support for building wheels with [build](https://github.com/pypa/build), as well as pip. This feature is controlled with the [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-frontend) option.
|
||||
- 🌟 Added the ability to test building wheels on CPython 3.10! Because CPython 3.10 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons) to test. (#675) This version of cibuildwheel includes CPython 3.10.0b4.
|
||||
- 🌟 You can now configure cibuildwheel options inside your project's `pyproject.toml`! Environment variables still work of course. Check out the [documentation](https://cibuildwheel.pypa.io/en/stable/options/#setting-options) for more info.
|
||||
- 🌟 Added support for building wheels with [build](https://github.com/pypa/build), as well as pip. This feature is controlled with the [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) option.
|
||||
- 🌟 Added the ability to test building wheels on CPython 3.10! Because CPython 3.10 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons) to test. (#675) This version of cibuildwheel includes CPython 3.10.0b4.
|
||||
- ⚠️ **Removed support for building Python 2.7 and Python 3.5 wheels**, for both CPython and PyPy. If you still need to build on these versions, please use the latest v1.x version. (#596)
|
||||
- ✨ Added the ability to build CPython 3.8 wheels for Apple Silicon. (#704)
|
||||
- 🛠 Update to the latest build dependencies, including Auditwheel 4. (#633)
|
||||
@@ -349,7 +484,7 @@ _1 May 2021_
|
||||
|
||||
- 📚 Lots of docs improvements! (#650, #623, #616, #609, #606)
|
||||
- 🐛 Fix nuget "Package is not found" error on Windows. (#653)
|
||||
- ⚠️ cibuildwheel will no longer build Windows 2.7 wheels, unless you specify a custom toolchain using `DISTUTILS_USE_SDK=1` and `MSSdk=1`. This is because Microsoft have stopped distributing Visual C++ Compiler for Python 2.7. See [this FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#windows-and-python-27) for more details. (#649)
|
||||
- ⚠️ cibuildwheel will no longer build Windows 2.7 wheels, unless you specify a custom toolchain using `DISTUTILS_USE_SDK=1` and `MSSdk=1`. This is because Microsoft have stopped distributing Visual C++ Compiler for Python 2.7. See [this FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#windows-and-python-27) for more details. (#649)
|
||||
- 🐛 Fix crash on Windows due to missing `which` command (#641).
|
||||
|
||||
### v1.10.0
|
||||
@@ -357,7 +492,7 @@ _1 May 2021_
|
||||
_22 Feb 2021_
|
||||
|
||||
- ✨ Added `manylinux_2_24` support. To use these new Debian-based manylinux
|
||||
images, set your [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image)
|
||||
images, set your [manylinux image](https://cibuildwheel.pypa.io/en/stable/options/#linux-image)
|
||||
options to `manylinux_2_24`.
|
||||
- 🛠 On macOS, we now set `MACOSX_DEPLOYMENT_TARGET` in before running
|
||||
`CIBW_BEFORE_ALL`. This is useful when using `CIBW_BEFORE_ALL` to build a
|
||||
@@ -374,10 +509,10 @@ _5 February 2021_
|
||||
- 🌟 Added support for Apple Silicon wheels on macOS! You can now
|
||||
cross-compile `universal2` and `arm64` wheels on your existing macOS Intel
|
||||
runners, by setting
|
||||
[CIBW_ARCHS_MACOS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs).
|
||||
[CIBW_ARCHS_MACOS](https://cibuildwheel.pypa.io/en/stable/options/#archs).
|
||||
Xcode 12.2 or later is required, but you don't need macOS 11.0 - you can
|
||||
still build on macOS 10.15. See
|
||||
[this FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#apple-silicon)
|
||||
[this FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#apple-silicon)
|
||||
for more information. (#484)
|
||||
- 🌟 Added auto-detection of your package's Python compatibility, via declared
|
||||
[`requires-python`](https://www.python.org/dev/peps/pep-0621/#requires-python)
|
||||
@@ -387,7 +522,7 @@ _5 February 2021_
|
||||
will automatically skip builds on versions of Python that your package
|
||||
doesn't support. Hopefully this makes the first-run experience of
|
||||
cibuildwheel a bit easier. If you need to override this for any reason,
|
||||
look at [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.readthedocs.io/en/stable/options/#requires-python).
|
||||
look at [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.pypa.io/en/stable/options/#requires-python).
|
||||
(#536)
|
||||
- 🌟 cibuildwheel can now be invoked as a native GitHub Action! You can now
|
||||
invoke cibuildwheel in a GHA build step like:
|
||||
@@ -402,10 +537,10 @@ _5 February 2021_
|
||||
```
|
||||
|
||||
This saves a bit of boilerplate, and you can [use Dependabot to keep the
|
||||
pinned version up-to-date](https://cibuildwheel.readthedocs.io/en/stable/faq/#automatic-updates).
|
||||
pinned version up-to-date](https://cibuildwheel.pypa.io/en/stable/faq/#automatic-updates).
|
||||
|
||||
- ✨ Added `auto64` and `auto32` shortcuts to the
|
||||
[CIBW_ARCHS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs)
|
||||
[CIBW_ARCHS](https://cibuildwheel.pypa.io/en/stable/options/#archs)
|
||||
option. (#553)
|
||||
- ✨ cibuildwheel now prints a list of the wheels built at the end of each
|
||||
run. (#570)
|
||||
@@ -418,9 +553,9 @@ _22 January 2021_
|
||||
- 🌟 Added support for emulated builds! You can now build manylinux wheels on
|
||||
ARM64`aarch64`, as well as `ppc64le` and 's390x'. To build under emulation,
|
||||
register QEMU via binfmt_misc and set the
|
||||
[`CIBW_ARCHS_LINUX`](https://cibuildwheel.readthedocs.io/en/stable/options/#archs)
|
||||
[`CIBW_ARCHS_LINUX`](https://cibuildwheel.pypa.io/en/stable/options/#archs)
|
||||
option to the architectures you want to run. See
|
||||
[this FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation)
|
||||
[this FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#emulation)
|
||||
for more information. (#482)
|
||||
- ✨ Added `CIBW_TEST_SKIP` option. This allows you to choose certain builds
|
||||
whose tests you'd like to skip. This might be useful when running a slow
|
||||
@@ -446,7 +581,7 @@ _1 January 2021_
|
||||
in a virtualenv. (#502)
|
||||
- 🛠 Some preparatory work towards using cibuildwheel as a GitHub Action.
|
||||
Check out
|
||||
[the FAQ](https://cibuildwheel.readthedocs.io/en/stable/faq/#option-1-github-action)
|
||||
[the FAQ](https://cibuildwheel.pypa.io/en/stable/faq/#option-1-github-action)
|
||||
for information on how to use it. We'll be fully updating the docs to this
|
||||
approach in a subsequent release (#494)
|
||||
|
||||
@@ -568,7 +703,7 @@ _25 June 2020_
|
||||
|
||||
_24 June 2020_
|
||||
|
||||
- 🌟 Add [`CIBW_BEFORE_ALL`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-all)
|
||||
- 🌟 Add [`CIBW_BEFORE_ALL`](https://cibuildwheel.pypa.io/en/stable/options/#before-all)
|
||||
option, which lets you run a command on the build machine before any wheels
|
||||
are built. This is especially useful when building on Linux, to `make`
|
||||
something external to Python, or to `yum install` a dependency. (#342)
|
||||
@@ -611,15 +746,15 @@ _2 May 2020_
|
||||
environment on macOS and Windows, where the version of Xcode and Visual
|
||||
Studio can still effect things.
|
||||
|
||||
This can be controlled using the [CIBW_DEPENDENCY_VERSIONS](https://cibuildwheel.readthedocs.io/en/stable/options/#dependency-versions)
|
||||
and [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image)
|
||||
This can be controlled using the [CIBW_DEPENDENCY_VERSIONS](https://cibuildwheel.pypa.io/en/stable/options/#dependency-versions)
|
||||
and [manylinux image](https://cibuildwheel.pypa.io/en/stable/options/#linux-image)
|
||||
options - if you always want to use the latest toolchain, you can still do
|
||||
that, or you can specify your own pip constraints file and manylinux image.
|
||||
(#256)
|
||||
|
||||
- ✨ Added `package_dir` command line option, meaning we now support building
|
||||
a package that lives in a subdirectory and pulls in files from the wider
|
||||
project. See [the `package_dir` option help](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line-options)
|
||||
project. See [the `package_dir` option help](https://cibuildwheel.pypa.io/en/stable/options/#command-line-options)
|
||||
for more information.
|
||||
|
||||
Note that this change makes the working directory (where you call
|
||||
@@ -637,7 +772,7 @@ _2 May 2020_
|
||||
_12 March 2020_
|
||||
|
||||
- 🌟 Add support for building on GitHub Actions! Check out the
|
||||
[docs](https://cibuildwheel.readthedocs.io/en/stable/setup/#github-actions)
|
||||
[docs](https://cibuildwheel.pypa.io/en/stable/setup/#github-actions)
|
||||
for information on how to set it up. (#194)
|
||||
- ✨ Add the `CIBW_BEFORE_TEST` option, which lets you run a command to
|
||||
prepare the environment before your tests are run. (#242)
|
||||
@@ -687,9 +822,9 @@ _10 November 2019_
|
||||
build using the manylinux2010 images by default. If your project is still
|
||||
manylinux1 compatible, you should get both manylinux1 and manylinux2010
|
||||
wheels - you can upload both to PyPI. If you always require manylinux1 wheels, you can
|
||||
build using the old manylinux1 image using the [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image) option.
|
||||
build using the old manylinux1 image using the [manylinux image](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) option.
|
||||
(#155)
|
||||
- 📚 Documentation is now on its [own mini-site](https://cibuildwheel.readthedocs.io),
|
||||
- 📚 Documentation is now on its [own mini-site](https://cibuildwheel.pypa.io),
|
||||
rather than on the README (#169)
|
||||
- ✨ Add support for building Windows wheels on Travis CI. (#160)
|
||||
- 🛠 If you set `CIBW_TEST_COMMAND`, your tests now run in a virtualenv. (#164)
|
||||
|
||||
+77
-23
@@ -12,8 +12,7 @@ If you have an idea for a modification or feature, it's probably best to raise a
|
||||
|
||||
Everyone contributing to the cibuildwheel project is expected to follow the [PSF Code of Conduct](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
Design Goals
|
||||
------------
|
||||
## Design Goals
|
||||
|
||||
- `cibuildwheel` should wrap the complexity of wheel building.
|
||||
- The user interface to `cibuildwheel` is the build script (e.g. `.travis.yml`). Feature additions should not increase the complexity of this script.
|
||||
@@ -33,22 +32,85 @@ We're not responsible for errors in those tools, for fixing errors/crashes there
|
||||
|
||||
So, if we can, I'd like to improve the experience on errors as well. In [this](https://github.com/pypa/cibuildwheel/issues/139) case, it takes a bit of knowledge to understand that the Linux builds are happening in a different OS via Docker, that the linked symbols won't match, that auditwheel will fail because of this. A problem with how the tools fit together, instead of the tools themselves.
|
||||
|
||||
Maintainer notes
|
||||
----------------
|
||||
## Development
|
||||
|
||||
### Nox support
|
||||
### Running the tests
|
||||
|
||||
When making a change to the codebase, you can run tests locally for quicker feedback than the CI runs on a PR. You can [run them directly](#making-a-venv), but the easiest way to run tests is using [nox](https://nox.thea.codes/).
|
||||
|
||||
You can run all the tests locally by doing:
|
||||
|
||||
```bash
|
||||
nox -s tests
|
||||
```
|
||||
|
||||
However, because this takes a while, you might prefer to be more specific.
|
||||
|
||||
#### Unit tests
|
||||
|
||||
To run the project's unit tests, do:
|
||||
|
||||
```bash
|
||||
nox -s tests -- unit_test
|
||||
```
|
||||
|
||||
There are a few custom options to enable different parts of the test suite - check `nox -s tests -- unit_test --help` for details.
|
||||
|
||||
If you're calling this a lot, you might consider using the `-r` or `-R` arguments to nox to make it a bit faster. This calls pytest under the hood, so to target a specific test, use pytest's `-k` option after the `--` above to select a specific test.
|
||||
|
||||
#### Integration tests
|
||||
|
||||
To run the project's integration tests, do:
|
||||
|
||||
```bash
|
||||
nox -s tests -- test
|
||||
```
|
||||
|
||||
The integration test suite is big - it can take more than 30 minutes to run the whole thing.
|
||||
|
||||
Because it takes such a long time, normally you'd choose specific tests to run locally, and rely on the project's CI for the rest. Use pytest's `-k` option to choose specific tests. You can pass a test name or a filename, it'll run everything that matches.
|
||||
|
||||
```bash
|
||||
nox -s tests -- test -k <test_name_or_filename>
|
||||
# e.g.
|
||||
nox -s tests -- test -k before_build
|
||||
```
|
||||
|
||||
A few notes-
|
||||
|
||||
- Because they run inside a container, Linux tests can run on all platforms where Docker is installed, so they're convenient for running integration tests locally. Set CIBW_PLATFORM to do this: `CIBW_PLATFORM=linux nox -s tests -- test`.
|
||||
|
||||
- Running the macOS integration tests requires _system installs_ of Python from python.org for all the versions that are tested. We won't attempt to install these when running locally, but you can do so manually using the URL in the error message that is printed when the install is not found.
|
||||
|
||||
#### Making a venv
|
||||
|
||||
More advanced users might prefer to invoke pytest directly-
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -e .[dev]
|
||||
# run the unit tests
|
||||
pytest unit_test
|
||||
# run the whole integration test suite
|
||||
pytest test
|
||||
# run a specific integration test
|
||||
pytest test -k test_build_frontend_args
|
||||
# run a specific integration test on a different platform
|
||||
CIBW_PLATFORM=linux pytest test -k test_build_frontend_args
|
||||
```
|
||||
|
||||
### Linting, docs
|
||||
|
||||
Most developer tasks have a nox interface. This allows you to very simply run tasks without worrying about setting up a development environment (as shown below). This is a slower than setting up a development environment and reusing it, but has the (important) benefit of being highly reproducible; an earlier run does not affect a current run, or anything else on your machine.
|
||||
|
||||
Install [nox](https://nox.thea.codes); homebrew is recommend on macOS, otherwise, pipx is a great choice - in fact, you can use `pipx run nox` and avoid installing completely.
|
||||
|
||||
You can see a list of sessions by typing `nox -l`; here are a few common ones:
|
||||
|
||||
```console
|
||||
nox -s lint # Run the linters (default)
|
||||
nox -s tests # Run the tests (default)
|
||||
nox -s docs -- serve # Build and serve the documentation
|
||||
nox -s build # Make SDist and wheel
|
||||
nox -s lint # Run the linters (default)
|
||||
nox -s tests [-- PYTEST-ARGS] # Run the tests (default)
|
||||
nox -s docs # Build and serve the documentation
|
||||
nox -s build # Make SDist and wheel
|
||||
```
|
||||
|
||||
More advanced users can run the update scripts. `update_pins` should work directly, but `update_constraints` needs all versions of Python installed. If you don't want to do that locally, a fast way to run it to use docker to run nox:
|
||||
@@ -57,17 +119,7 @@ More advanced users can run the update scripts. `update_pins` should work direct
|
||||
docker run --rm -itv $PWD:/src -w /src quay.io/pypa/manylinux_2_24_x86_64:latest pipx run nox -s update_constraints
|
||||
```
|
||||
|
||||
### Local testing
|
||||
|
||||
You should run:
|
||||
|
||||
```console
|
||||
python3 -m venv venv
|
||||
. venv/bin/activate
|
||||
pip install -e .[dev]
|
||||
```
|
||||
|
||||
To prepare a development environment.
|
||||
## Maintainer notes
|
||||
|
||||
### Testing sample configs
|
||||
|
||||
@@ -125,7 +177,7 @@ Then, increment the project version number using:
|
||||
bin/bump_version.py
|
||||
```
|
||||
|
||||
You'll be prompted to enter the new version number. Update the changelog when prompted. The script will create a 'bump version' commit and version tag.
|
||||
(or `nox -s bump_version`) You'll be prompted to enter the new version number. Update the changelog when prompted. The script will create a 'bump version' commit and version tag.
|
||||
|
||||
Finally, cut the release and push to GitHub.
|
||||
|
||||
@@ -134,3 +186,5 @@ git push && git push --tags
|
||||
```
|
||||
|
||||
Then head to https://github.com/pypa/cibuildwheel/releases and create a GitHub release from the new tag, pasting in the changelog entry. Once the release is created inside GitHub, a CI job will create the assets and upload them to PyPI.
|
||||
|
||||
If there were any schema updates, run `pipx run ./bin/generate_schema.py --schemastore > partial-cibuildwheel.json` and contribute the changes to SchemaStore.
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/docs/data/projects.schema.json",
|
||||
"type": "array",
|
||||
"description": "The projects file for cibuildwheel",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"gh": { "type": "string", "pattern": "[^/]*/[^/]*" },
|
||||
"stars": { "$ref": "#/items/properties/gh" },
|
||||
"pypi": { "type": "string" },
|
||||
"notes": { "type": "string" },
|
||||
"ci": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": [
|
||||
"github",
|
||||
"travisci",
|
||||
"appveyor",
|
||||
"circleci",
|
||||
"gitlab",
|
||||
"cirrusci",
|
||||
"azurepipelines"
|
||||
]
|
||||
}
|
||||
},
|
||||
"ci_config": { "type": "string" },
|
||||
"os": {
|
||||
"type": "array",
|
||||
"items": { "enum": ["windows", "apple", "linux"] }
|
||||
}
|
||||
},
|
||||
"required": ["name", "gh", "ci", "os"]
|
||||
}
|
||||
}
|
||||
+42
-9
@@ -26,7 +26,7 @@
|
||||
notes: A simple C extension, without external dependencies
|
||||
|
||||
- name: websockets
|
||||
gh: aaugustin/websockets
|
||||
gh: python-websockets/websockets
|
||||
ci: [travisci]
|
||||
ci_config: .travis.yml
|
||||
os: [apple, linux]
|
||||
@@ -325,12 +325,12 @@
|
||||
notes: Full range of wheels for setuptools rust, with auto release and PyPI deploy.
|
||||
|
||||
- name: python-snappy
|
||||
gh: andrix/python-snappy
|
||||
gh: intake/python-snappy
|
||||
ci: [github]
|
||||
os: [apple, linux, windows]
|
||||
|
||||
- name: sourmash
|
||||
gh: dib-lab/sourmash
|
||||
gh: sourmash-bio/sourmash
|
||||
ci: [github]
|
||||
os: [apple, linux, windows]
|
||||
|
||||
@@ -418,7 +418,7 @@
|
||||
notes: Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension.
|
||||
|
||||
- name: pytorch-fairseq
|
||||
gh: pytorch/fairseq
|
||||
gh: facebookresearch/fairseq
|
||||
ci: [github]
|
||||
os: [apple, linux]
|
||||
|
||||
@@ -475,7 +475,7 @@
|
||||
os: [apple, linux, windows]
|
||||
|
||||
- name: OpenSpiel
|
||||
gh: deepmind/open_spiel
|
||||
gh: google-deepmind/open_spiel
|
||||
ci: [github]
|
||||
os: [apple, linux]
|
||||
|
||||
@@ -505,7 +505,7 @@
|
||||
os: [apple, linux, windows]
|
||||
|
||||
- name: OpenTimelineIO
|
||||
gh: PixarAnimationStudios/OpenTimelineIO
|
||||
gh: AcademySoftwareFoundation/OpenTimelineIO
|
||||
ci: [github]
|
||||
os: [apple, linux, windows]
|
||||
|
||||
@@ -584,7 +584,7 @@
|
||||
notes: Includes GPU support for linux wheels
|
||||
|
||||
- name: power-grid-model
|
||||
gh: alliander-opensource/power-grid-model
|
||||
gh: PowerGridModel/power-grid-model
|
||||
ci: [github]
|
||||
os: [windows, apple, linux]
|
||||
notes: Python/C++ library for distribution power system analysis
|
||||
@@ -603,13 +603,13 @@
|
||||
gh: tensorchord/envd
|
||||
ci: [github]
|
||||
os: [apple, linux, windows]
|
||||
note: A machine learning development environment build tool
|
||||
notes: A machine learning development environment build tool
|
||||
|
||||
- name: mosec
|
||||
gh: mosecorg/mosec
|
||||
ci: [github]
|
||||
os: [linux, apple]
|
||||
note: A machine learning model serving framework powered by Rust
|
||||
notes: A machine learning model serving framework powered by Rust
|
||||
|
||||
- name: ril
|
||||
gh: Cryptex-github/ril-py
|
||||
@@ -631,3 +631,36 @@
|
||||
os: [windows, apple, linux]
|
||||
pypi: aalink
|
||||
notes: Async Python interface for Ableton Link.
|
||||
|
||||
- name: werpy
|
||||
gh: analyticsinmotion/werpy
|
||||
ci: [github]
|
||||
os: [windows, linux, apple]
|
||||
pypi: werpy
|
||||
notes: An ultra-fast python package using optimized dynamic programming to compute the Word Error Rate (WER).
|
||||
|
||||
- name: keyvi
|
||||
gh: KeyviDev/keyvi
|
||||
ci: [github]
|
||||
os: [linux, apple]
|
||||
pypi: keyvi
|
||||
notes: FST based key value index highly optimized for size and lookup performance, utilizes ccache action for improved runtime
|
||||
|
||||
- name: pedalboard
|
||||
gh: spotify/pedalboard
|
||||
ci: [github]
|
||||
os: [windows, linux, apple]
|
||||
pypi: pedalboard
|
||||
notes: >
|
||||
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).
|
||||
|
||||
- name: streaming-form-data
|
||||
gh: siddhantgoel/streaming-form-data
|
||||
ci: [github]
|
||||
os: [apple, linux, windows]
|
||||
pypi: streaming-form-data
|
||||
notes: Streaming parser for multipart/form-data written in Cython
|
||||
|
||||
@@ -56,8 +56,9 @@ well as several useful actions. Alongside your existing job(s) that runs cibuild
|
||||
- name: Build SDist
|
||||
run: pipx run build --sdist
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-sdist
|
||||
path: dist/*.tar.gz
|
||||
```
|
||||
|
||||
@@ -74,10 +75,11 @@ This requires setting this GitHub workflow in your project's PyPI settings (for
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: artifact
|
||||
pattern: cibw-*
|
||||
path: dist
|
||||
merge-multiple: true
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@release/v1
|
||||
```
|
||||
|
||||
+7
-1
@@ -255,7 +255,7 @@ h1, h2, h3, h4, h5, h6 {
|
||||
border: none;
|
||||
color: inherit;
|
||||
background-color: #f0f1f1;
|
||||
font-size: 100%;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
|
||||
@@ -315,3 +315,9 @@ h1, h2, h3, h4, h5, h6 {
|
||||
.wy-menu-vertical li.current a {
|
||||
|
||||
}
|
||||
|
||||
/* word wrap in table cells */
|
||||
.wy-table-responsive table td, .wy-table-responsive table th {
|
||||
white-space: normal;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
+64
-45
@@ -10,21 +10,21 @@ title: Tips and tricks
|
||||
|
||||
Linux wheels are built in [`manylinux`/`musllinux` containers](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 600](https://www.python.org/dev/peps/pep-0600/) / [PEP 656](https://www.python.org/dev/peps/pep-0656/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
|
||||
|
||||
- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2010` or `manylinux2014`, `apt-get` for `manylinux_2_24` and `apk` for `musllinux_1_1`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.
|
||||
- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2010` or `manylinux2014`, `apt-get` for `manylinux_2_24`, `dnf` for `manylinux_2_28` and `apk` for `musllinux_1_1` or `musllinux_1_2`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.
|
||||
|
||||
`cibuildwheel` supports this by providing the [`CIBW_ENVIRONMENT`](options.md#environment) and [`CIBW_BEFORE_ALL`](options.md#before-all) options to setup the build environment inside the running container.
|
||||
|
||||
- The project directory is copied into the container as `/project`, the output directory for the wheels to be copied out is `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that `/host` is not available on CircleCI due to their Docker policies.
|
||||
- The project directory is copied into the container as `/project`, the output directory for the wheels to be copied out is `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that `/host` is not available on CircleCI and GitLab CI due to their Docker policies.
|
||||
|
||||
- Alternative Docker images can be specified with the `CIBW_MANYLINUX_*_IMAGE`/`CIBW_MUSLLINUX_*_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [options](options.md#linux-image) for more details.
|
||||
|
||||
### Building macOS wheels for Apple Silicon {: #apple-silicon}
|
||||
|
||||
`cibuildwheel` supports cross-compiling `universal2` and `arm64` wheels on `x86_64` runners.
|
||||
`cibuildwheel` supports both native builds and cross-compiling between `arm64` (Apple Silicon) and `x86_64` (Intel) architectures, including the cross-compatible `universal2` format.
|
||||
|
||||
#### Overview of Mac architectures
|
||||
|
||||
With the introduction of Apple Silicon, you now have several choices for wheels for Python 3.8+:
|
||||
You have several choices for wheels for Python 3.8+:
|
||||
|
||||
##### `x86_64`
|
||||
|
||||
@@ -68,43 +68,26 @@ Opinions vary on which of arch-specific or `universal2` wheels are best - some p
|
||||
|
||||
See [GitHub issue 1333](https://github.com/pypa/cibuildwheel/issues/1333) for more discussion.
|
||||
|
||||
#### How to cross-compile
|
||||
#### How?
|
||||
|
||||
With the exception of Cirrus CI, macOS CI runners are still Intel-based, and Apple Silicon wheels are not built by default on Intel runners. However, cross-compilation can be enabled by adding extra archs to the [`CIBW_ARCHS_MACOS` option](options.md#archs) - e.g. `x86_64 arm64`. Cross-compilation is provided by the Xcode toolchain.
|
||||
It's easiest to build `x86_64` wheels on `x86_64` runners, and `arm64` wheels on `arm64` runners.
|
||||
|
||||
!!! important
|
||||
When cross-compiling on Intel, it is not possible to test `arm64` and the `arm64` part of a `universal2` wheel.
|
||||
On GitHub Actions, `macos-14` runners are `arm64`, and `macos-13` runners are `x86_64`. So all you need to do is ensure both are in your build matrix.
|
||||
|
||||
`cibuildwheel` will raise a warning to notify you of this - these warnings be be silenced by skipping testing on these platforms: `CIBW_TEST_SKIP: *_arm64 *_universal2:arm64`.
|
||||
#### Cross-compiling
|
||||
|
||||
!!! note
|
||||
Your runner needs Xcode Command Line Tools 12.2 or later to build `universal2` or `arm64`.
|
||||
If your CI provider doesn't offer arm64 runners yet, or you want to create `universal2`, you'll have to cross-compile. Cross-compilation can be enabled by adding extra archs to the [`CIBW_ARCHS_MACOS` option](options.md#archs) - e.g. `CIBW_ARCHS_MACOS="x86_64 universal2"`. Cross-compilation is provided by Xcode toolchain v12.2+.
|
||||
|
||||
Only CPython 3.8 and newer support `universal2` and `arm64` wheels.
|
||||
Regarding testing,
|
||||
|
||||
- On an arm64 runner, it is possible to test x86_64 wheels and both parts of a universal2 wheel using Rosetta 2 emulation.
|
||||
- On an x86_64 runner, arm64 code can be compiled but it can't be tested. `cibuildwheel` will raise a warning to notify you of this - these warnings can be silenced by skipping testing on these platforms: `CIBW_TEST_SKIP: "*_arm64 *_universal2:arm64"`.
|
||||
|
||||
!!! note
|
||||
If your project uses **Poetry** as a build backend, cross-compiling on macOS [does not currently work](https://github.com/python-poetry/poetry/issues/7107). In some cases arm64 wheels can be built but their tags will be incorrect, with the platform tag showing `x86_64` instead of `arm64`.
|
||||
|
||||
As a workaround, the tag can be fixed before running delocate to repair the wheel. The [`wheel tags`](https://wheel.readthedocs.io/en/stable/reference/wheel_tags.html) command is ideal for this. See [this workflow](https://gist.github.com/anderssonjohan/49f07e33fc5cb2420515a8ac76dc0c95#file-build-pendulum-wheels-yml-L39-L53) for an example usage of `wheel tags`.
|
||||
|
||||
Hopefully, cross-compilation is a temporary situation. Once we have widely available Apple Silicon CI runners, we can build `arm64` wheels natively. Until then, cross-compiling `arm64` or `universal2` wheels requires opt-in by setting `CIBW_ARCHS_MACOS` on Intel runners.
|
||||
|
||||
Here's an example GitHub Actions workflow with a job that builds for Apple Silicon:
|
||||
|
||||
> .github/workflows/build_macos.yml
|
||||
|
||||
```yml
|
||||
{% include "../examples/github-apple-silicon.yml" %}
|
||||
```
|
||||
|
||||
Here's an example Cirrus CI workflow with a job that builds for macOS Intel through Rosetta 2 emulation and for Apple Silicon natively:
|
||||
|
||||
> .cirrus.yml
|
||||
|
||||
```yml
|
||||
{% include "../examples/cirrus-ci-intel-mac.yml" %}
|
||||
```
|
||||
|
||||
### Building Linux wheels for non-native archs using emulation {: #emulation}
|
||||
|
||||
cibuildwheel supports building non-native architectures on Linux, via
|
||||
@@ -159,7 +142,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@v2.16.0
|
||||
uses: pypa/cibuildwheel@v2.20.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.
|
||||
@@ -181,7 +164,7 @@ The second option, and the only one that supports other CI systems, is using a `
|
||||
|
||||
```bash
|
||||
# requirements-cibw.txt
|
||||
cibuildwheel==2.16.0
|
||||
cibuildwheel==2.20.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:
|
||||
@@ -216,7 +199,6 @@ to build, your pyproject.toml might include a section like this:
|
||||
[build-system]
|
||||
requires = [
|
||||
"setuptools>=42",
|
||||
"wheel",
|
||||
"Cython",
|
||||
]
|
||||
|
||||
@@ -267,7 +249,7 @@ Consider incorporating these into your package, for example, in `setup.py` using
|
||||
|
||||
### Python 2.7 / PyPy2 wheels
|
||||
|
||||
See the [cibuildwheel version 1 docs](https://cibuildwheel.readthedocs.io/en/1.x/) for information about building Python 2.7 or PyPy2 wheels. There are lots of tricks and workaround there that are no longer required for Python 3 in cibuildwheel 2.
|
||||
See the [cibuildwheel version 1 docs](https://cibuildwheel.pypa.io/en/1.x/) for information about building Python 2.7 or PyPy2 wheels. There are lots of tricks and workaround there that are no longer required for Python 3 in cibuildwheel 2.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -300,6 +282,27 @@ For these reasons, it's strongly recommended to not use brew for native library
|
||||
[Homebrew]: https://brew.sh/
|
||||
[delocate]: https://github.com/matthew-brett/delocate
|
||||
|
||||
### Building Rust wheels
|
||||
|
||||
If you build Rust wheels, you need to download the Rust compilers in manylinux.
|
||||
If you support 32-bit Windows, you need to add this as a potential target. You
|
||||
can do this on GitHub Actions, for example, with:
|
||||
|
||||
```yaml
|
||||
CIBW_BEFORE_ALL_LINUX: curl -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
CIBW_BEFORE_ALL_WINDOWS: rustup target add i686-pc-windows-msvc
|
||||
CIBW_ENVIRONMENT_LINUX: "PATH=$HOME/.cargo/bin:$PATH"
|
||||
```
|
||||
|
||||
Rust does not provide Cargo for musllinux 32-bit, so that needs to be skipped:
|
||||
|
||||
```toml
|
||||
[tool.cibuildwheel]
|
||||
skip = ["*-musllinux_i686"]
|
||||
```
|
||||
|
||||
Also see [maturin-action](https://github.com/PyO3/maturin-action) which is optimized for Rust wheels, builds the non-Python Rust modules once, and can cross-compile (and can build 32-bit musl, for example).
|
||||
|
||||
### macOS: ModuleNotFoundError
|
||||
|
||||
Calling cibuildwheel from a python3 script and getting a `ModuleNotFoundError`? Due to a (fixed) [bug](https://bugs.python.org/issue22490) in CPython, you'll need to [unset the `__PYVENV_LAUNCHER__` variable](https://github.com/pypa/cibuildwheel/issues/133#issuecomment-478288597) before activating a venv.
|
||||
@@ -325,7 +328,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==2.16.0 --output-dir wheelhouse
|
||||
pipx run cibuildwheel==2.20.0 --output-dir wheelhouse
|
||||
pipx run twine upload wheelhouse/*.whl
|
||||
```
|
||||
|
||||
@@ -333,7 +336,7 @@ pipx run twine upload wheelhouse/*.whl
|
||||
|
||||
macOS has built-in [System Integrity protections](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html) which limits the use of `DYLD_LIBRARY_PATH` and `LD_LIBRARY_PATH` so that it does not automatically pass to children processes. This means if you set `DYLD_LIBRARY_PATH` before running cibuildwheel, or even set it in `CIBW_ENVIRONMENT`, it will be stripped out of the environment before delocate is called.
|
||||
|
||||
To work around this, use a different environment variable such as `REPAIR_LIBRARY_PATH` to store the library path, and set `DYLD_LIBRARY_PATH` in [`CIBW_REPAIR_WHEEL_COMMAND_MACOS`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command), like this:
|
||||
To work around this, use a different environment variable such as `REPAIR_LIBRARY_PATH` to store the library path, and set `DYLD_LIBRARY_PATH` in [`CIBW_REPAIR_WHEEL_COMMAND_MACOS`](https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command), like this:
|
||||
|
||||
!!! tab examples "Environment variables"
|
||||
|
||||
@@ -360,19 +363,35 @@ If you're building on an arm64 runner, you might notice something strange about
|
||||
|
||||
This is fine for simple C extensions, but for more complicated builds on arm64 it becomes an issue.
|
||||
|
||||
So, if the cross-compilation is an issue for you, there is an 'experimental' installer available that's built natively for arm64.
|
||||
|
||||
To use this installer and perform native CPython 3.8 building, before invoking cibuildwheel, install the universal2 version of Python on your arm64 runner, something like:
|
||||
So, if you want to build macOS arm64 wheels on an arm64 runner (e.g., `macos-14`) on Python 3.8, before invoking cibuildwheel, you should install a native arm64 Python 3.8 interpreter on the runner:
|
||||
|
||||
|
||||
```bash
|
||||
curl -o /tmp/Python38.pkg https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg
|
||||
sudo installer -pkg /tmp/Python38.pkg -target /
|
||||
sh "/Applications/Python 3.8/Install Certificates.command"
|
||||
```
|
||||
!!! tab "GitHub Actions"
|
||||
|
||||
```yaml
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.8
|
||||
if: runner.os == 'macOS' && runner.arch == 'ARM64'
|
||||
```
|
||||
|
||||
!!! tab "Generic"
|
||||
|
||||
```bash
|
||||
curl -o /tmp/Python38.pkg https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg
|
||||
sudo installer -pkg /tmp/Python38.pkg -target /
|
||||
sh "/Applications/Python 3.8/Install Certificates.command"
|
||||
```
|
||||
|
||||
Then cibuildwheel will detect that it's installed and use it instead. However, you probably don't want to build x86_64 wheels on this Python, unless you're happy with them only supporting macOS 11+.
|
||||
|
||||
### macOS: Library dependencies do not satisfy target MacOS
|
||||
|
||||
Since delocate 0.11.0 there is added verification that the library binary dependencies match the target macOS version. This is to prevent the situation where a wheel platform tag is lower than the actual minimum macOS version required by the library. To resolve this error you need to build the library to the same macOS version as the target wheel (for example using `MACOSX_DEPLOYMENT_TARGET` environment variable).
|
||||
Alternatively, you could set `MACOSX_DEPLOYMENT_TARGET` in `CIBW_ENVIRONMENT` to correctly label the wheel as incompatible with older macOS versions.
|
||||
|
||||
This error may happen when you install a library using a package manager like Homebrew, which compiles the library for the macOS version of the build machine. This is not suitable for wheels, as the library will only work on the same macOS version as the build machine. You should compile the library yourself, or use a precompiled binary that matches the target macOS version.
|
||||
|
||||
### Windows: 'ImportError: DLL load failed: The specific module could not be found'
|
||||
|
||||
Visual Studio and MSVC link the compiled binary wheels to the Microsoft Visual C++ Runtime. Normally, the C parts of the runtime are included with Python, but the C++ components are not. When compiling modules using C++, it is possible users will run into problems on systems that do not have the full set of runtime libraries installed. The solution is to ask users to download the corresponding Visual C++ Redistributable from the [Microsoft website](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) and install it.
|
||||
@@ -395,7 +414,7 @@ To investigate the dependencies of a C extension (i.e., the `.pyd` file, a DLL i
|
||||
|
||||
### Windows ARM64 builds {: #windows-arm64}
|
||||
|
||||
`cibuildwheel` supports cross-compiling `ARM64` wheels on all Windows runners, but a native ARM64 runner is required for testing. On non-native runners, tests for ARM64 wheels will be automatically skipped with a warning. Add `*-win_arm64` to your `CIBW_TEST_SKIP` setting to suppress the warning.
|
||||
`cibuildwheel` supports cross-compiling `ARM64` wheels on all Windows runners, but a native ARM64 runner is required for testing. On non-native runners, tests for ARM64 wheels will be automatically skipped with a warning. Add `"*-win_arm64"` to your `CIBW_TEST_SKIP` setting to suppress the warning.
|
||||
|
||||
Cross-compilation on Windows relies on a supported build backend. Supported backends use an environment variable to specify their target platform (the one they are compiling native modules for, as opposed to the one they are running on), which is set in [cibuildwheels/windows.py](https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/windows.py) before building. Currently, `setuptools>=65.4.1` and `setuptools_rust` are the only supported backends.
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ How it works
|
||||
This diagram summarises the steps that cibuildwheel takes on each platform to build your package's wheels.
|
||||
|
||||
{%
|
||||
include-markdown "diagram.md"
|
||||
include "diagram.html"
|
||||
%}
|
||||
|
||||
This isn't exhaustive, for a full list of the things cibuildwheel can do, check the [options](options.md) page.
|
||||
|
||||
+6
-3
@@ -1,10 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sysconfig
|
||||
from typing import Any
|
||||
|
||||
# Requires Python 3.7+
|
||||
|
||||
|
||||
def define_env(env: Any) -> None:
|
||||
"Hook function for mkdocs-macros"
|
||||
@@ -12,4 +12,7 @@ def define_env(env: Any) -> None:
|
||||
@env.macro
|
||||
def subprocess_run(*args: str) -> str:
|
||||
"Run a subprocess and return the stdout"
|
||||
return subprocess.run(args, check=True, capture_output=True, text=True).stdout
|
||||
env = os.environ.copy()
|
||||
scripts = sysconfig.get_path("scripts")
|
||||
env["PATH"] = f"{scripts}{os.pathsep}{env.get('PATH', '')}"
|
||||
return subprocess.run(args, check=True, capture_output=True, text=True, env=env).stdout
|
||||
|
||||
+291
-58
@@ -91,9 +91,9 @@ You can configure cibuildwheel with a config file, such as `pyproject.toml`.
|
||||
Options have the same names as the environment variable overrides, but are
|
||||
placed in `[tool.cibuildwheel]` and are lower case, with dashes, following
|
||||
common [TOML][] practice. Anything placed in subsections `linux`, `windows`,
|
||||
or `macos` will only affect those platforms. Lists can be used instead of
|
||||
strings for items that are naturally a list. Multiline strings also work just
|
||||
like in the environment variables. Environment variables will take
|
||||
`macos`, or `pyodide` will only affect those platforms. Lists can be used
|
||||
instead of strings for items that are naturally a list. Multiline strings also
|
||||
work just like in the environment variables. Environment variables will take
|
||||
precedence if defined.
|
||||
|
||||
The example above using environment variables could have been written like this:
|
||||
@@ -135,6 +135,10 @@ trigger new containers, one per image. Some commands are not supported;
|
||||
`output-dir`, build/skip/test_skip selectors, and architectures cannot be
|
||||
overridden.
|
||||
|
||||
You can specify a table of overrides in `inherit={}`, any list or table in this
|
||||
list will inherit from previous overrides or the main configuration. The valid
|
||||
options are `"none"` (the default), `"append"`, and `"prepend"`.
|
||||
|
||||
##### Examples:
|
||||
|
||||
```toml
|
||||
@@ -169,6 +173,69 @@ This example will build CPython 3.6 wheels on manylinux1, CPython 3.7-3.9
|
||||
wheels on manylinux2010, and manylinux2014 wheels for any newer Python
|
||||
(like 3.10).
|
||||
|
||||
```toml
|
||||
[tool.cibuildwheel]
|
||||
environment = {FOO="BAR", "HAM"="EGGS"}
|
||||
test-command = ["pyproject"]
|
||||
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "cp311*"
|
||||
|
||||
inherit.test-command = "prepend"
|
||||
test-command = ["pyproject-before"]
|
||||
|
||||
inherit.environment="append"
|
||||
environment = {FOO="BAZ", "PYTHON"="MONTY"}
|
||||
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "cp311*"
|
||||
inherit.test-command = "append"
|
||||
test-command = ["pyproject-after"]
|
||||
```
|
||||
|
||||
This example will provide the command `"pyproject-before && pyproject && pyproject-after"`
|
||||
on Python 3.11, and will have `environment = {FOO="BAZ", "PYTHON"="MONTY", "HAM"="EGGS"}`.
|
||||
|
||||
|
||||
### Extending existing options {: #inherit }
|
||||
|
||||
In the TOML configuration, you can choose how tables and lists are inherited.
|
||||
By default, all values are overridden completely (`"none"`) but sometimes you'd
|
||||
rather `"append"` or `"prepend"` to an existing list or table. You can do this
|
||||
with the `inherit` table in overrides. For example, if you want to add an environment
|
||||
variable for CPython 3.11, without `inherit` you'd have to repeat all the
|
||||
original environment variables in the override. With `inherit`, it's just:
|
||||
|
||||
```toml
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "cp311*"
|
||||
inherit.environment = "append"
|
||||
environment.NEWVAR = "Added!"
|
||||
```
|
||||
|
||||
For a table, `"append"` will replace a key if it exists, while `"prepend"` will
|
||||
only add a new key, older keys take precedence.
|
||||
|
||||
Lists are also supported (and keep in mind that commands are lists). For
|
||||
example, you can print a message before and after a wheel is repaired:
|
||||
|
||||
```toml
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "*"
|
||||
inherit.repair-wheel-command = "prepend"
|
||||
repair-wheel-command = "echo 'Before repair'"
|
||||
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "*"
|
||||
inherit.repair-wheel-command = "append"
|
||||
repair-wheel-command = "echo 'After repair'"
|
||||
```
|
||||
|
||||
As seen in this example, you can have multiple overrides match - they match top
|
||||
to bottom, with the config being accumulated. If you need platform-specific
|
||||
inheritance, you can use `select = "*-????linux_*"` for Linux, `select =
|
||||
"*-win_*"` for Windows, and `select = "*-macosx_*"` for macOS. As always,
|
||||
environment variables will completely override any TOML configuration.
|
||||
|
||||
## Options summary
|
||||
|
||||
@@ -180,19 +247,20 @@ wheels on manylinux2010, and manylinux2014 wheels for any newer Python
|
||||
|
||||
> Override the auto-detected target platform
|
||||
|
||||
Options: `auto` `linux` `macos` `windows`
|
||||
Options: `auto` `linux` `macos` `windows` `pyodide`
|
||||
|
||||
Default: `auto`
|
||||
|
||||
`auto` will auto-detect platform using environment variables, such as `TRAVIS_OS_NAME`/`APPVEYOR`/`CIRCLECI`.
|
||||
`auto` will build wheels for the current platform.
|
||||
|
||||
- For `linux`, you need [Docker or Podman](#container-engine) running, on Linux, macOS, or Windows.
|
||||
- For `macos` and `windows`, you need to be running on the respective system, with a working compiler toolchain installed - Xcode Command Line tools for macOS, and MSVC for Windows.
|
||||
- For `pyodide` you need to be on an x86-64 linux runner and `python3.12` must be available in `PATH`.
|
||||
|
||||
This option can also be set using the [command-line option](#command-line) `--platform`. This option is not available in the `pyproject.toml` config.
|
||||
|
||||
!!! tip
|
||||
You can use this option to locally debug your cibuildwheel config, instead of pushing to CI to test every change. For example:
|
||||
You can use this option to locally debug your cibuildwheel config on Linux, instead of pushing to CI to test every change. For example:
|
||||
|
||||
```bash
|
||||
export CIBW_BUILD='cp37-*'
|
||||
@@ -200,6 +268,8 @@ This option can also be set using the [command-line option](#command-line) `--pl
|
||||
cibuildwheel --platform linux .
|
||||
```
|
||||
|
||||
Linux builds are the easiest to test locally, because all the build tools are supplied in the container, and they run exactly the same locally as in CI.
|
||||
|
||||
This is even more convenient if you store your cibuildwheel config in [`pyproject.toml`](#configuration-file).
|
||||
|
||||
You can also run a single identifier with `--only <identifier>`. This will
|
||||
@@ -227,6 +297,7 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
|
||||
| Python 3.10 | cp310-macosx_x86_64<br/>cp310-macosx_universal2<br/>cp310-macosx_arm64 | cp310-win_amd64<br/>cp310-win32<br/>cp310-win_arm64 | cp310-manylinux_x86_64<br/>cp310-manylinux_i686<br/>cp310-musllinux_x86_64<br/>cp310-musllinux_i686 | cp310-manylinux_aarch64<br/>cp310-manylinux_ppc64le<br/>cp310-manylinux_s390x<br/>cp310-musllinux_aarch64<br/>cp310-musllinux_ppc64le<br/>cp310-musllinux_s390x |
|
||||
| Python 3.11 | cp311-macosx_x86_64<br/>cp311-macosx_universal2<br/>cp311-macosx_arm64 | cp311-win_amd64<br/>cp311-win32<br/>cp311-win_arm64 | cp311-manylinux_x86_64<br/>cp311-manylinux_i686<br/>cp311-musllinux_x86_64<br/>cp311-musllinux_i686 | cp311-manylinux_aarch64<br/>cp311-manylinux_ppc64le<br/>cp311-manylinux_s390x<br/>cp311-musllinux_aarch64<br/>cp311-musllinux_ppc64le<br/>cp311-musllinux_s390x |
|
||||
| Python 3.12 | cp312-macosx_x86_64<br/>cp312-macosx_universal2<br/>cp312-macosx_arm64 | cp312-win_amd64<br/>cp312-win32<br/>cp312-win_arm64 | cp312-manylinux_x86_64<br/>cp312-manylinux_i686<br/>cp312-musllinux_x86_64<br/>cp312-musllinux_i686 | cp312-manylinux_aarch64<br/>cp312-manylinux_ppc64le<br/>cp312-manylinux_s390x<br/>cp312-musllinux_aarch64<br/>cp312-musllinux_ppc64le<br/>cp312-musllinux_s390x |
|
||||
| Python 3.13 | cp313-macosx_x86_64<br/>cp313-macosx_universal2<br/>cp313-macosx_arm64 | cp313-win_amd64<br/>cp313-win32<br/>cp313-win_arm64 | cp313-manylinux_x86_64<br/>cp313-manylinux_i686<br/>cp313-musllinux_x86_64<br/>cp313-musllinux_i686 | cp313-manylinux_aarch64<br/>cp313-manylinux_ppc64le<br/>cp313-manylinux_s390x<br/>cp313-musllinux_aarch64<br/>cp313-musllinux_ppc64le<br/>cp313-musllinux_s390x |
|
||||
| PyPy3.7 v7.3 | pp37-macosx_x86_64 | pp37-win_amd64 | pp37-manylinux_x86_64<br/>pp37-manylinux_i686 | pp37-manylinux_aarch64 |
|
||||
| PyPy3.8 v7.3 | pp38-macosx_x86_64<br/>pp38-macosx_arm64 | pp38-win_amd64 | pp38-manylinux_x86_64<br/>pp38-manylinux_i686 | pp38-manylinux_aarch64 |
|
||||
| PyPy3.9 v7.3 | pp39-macosx_x86_64<br/>pp39-macosx_arm64 | pp39-win_amd64 | pp39-manylinux_x86_64<br/>pp39-manylinux_i686 | pp39-manylinux_aarch64 |
|
||||
@@ -239,7 +310,10 @@ For CPython, the minimally supported macOS version is 10.9; for PyPy 3.7, macOS
|
||||
|
||||
Windows arm64 platform support is experimental.
|
||||
|
||||
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) for past end-of-life versions of Python, and PyPy2.7.
|
||||
For an experimental WebAssembly build with `--platform pyodide`,
|
||||
`cp312-pyodide_wasm32` is the only platform identifier.
|
||||
|
||||
See the [cibuildwheel 1 documentation](https://cibuildwheel.pypa.io/en/1.x/) for past end-of-life versions of Python, and PyPy2.7.
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -338,13 +412,60 @@ See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.
|
||||
}
|
||||
</style>
|
||||
|
||||
### `CIBW_FREE_THREADED_SUPPORT` {: #free-threaded-support}
|
||||
|
||||
> Choose whether free-threaded variants should be built
|
||||
|
||||
[PEP 703](https://www.python.org/dev/peps/pep-0703) introduced variants of CPython that can be built without the Global Interpreter Lock (GIL).
|
||||
Those variants are also known as free-threaded / no-gil.
|
||||
|
||||
Building for free-threaded variants is disabled by default.
|
||||
|
||||
Building can be enabled by setting this option to `true`. The free-threaded compatible wheels will be built in addition to the standard wheels.
|
||||
|
||||
This option doesn't support overrides.
|
||||
If you need to enable/disable it per platform or python version, set this option to `true` and use [`CIBW_BUILD`](#build-skip)/[`CIBW_SKIP`](#build-skip) options to filter the builds.
|
||||
|
||||
The build identifiers for those variants have a `t` suffix in their `python_tag` (e.g. `cp313t-manylinux_x86_64`)
|
||||
|
||||
!!! note
|
||||
This feature is experimental: [What’s New In Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython)
|
||||
|
||||
#### Examples
|
||||
|
||||
!!! tab examples "Environment variables"
|
||||
|
||||
```yaml
|
||||
# Enable free-threaded support
|
||||
CIBW_FREE_THREADED_SUPPORT: 1
|
||||
|
||||
# Skip building free-threaded compatible wheels on Windows
|
||||
CIBW_FREE_THREADED_SUPPORT: 1
|
||||
CIBW_SKIP: *t-win*
|
||||
```
|
||||
|
||||
It is generally recommended to use `free-threaded-support` in a config file as you can statically declare that you
|
||||
support free-threaded builds.
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.cibuildwheel]
|
||||
# Enable free-threaded support
|
||||
free-threaded-support = true
|
||||
|
||||
# Skip building free-threaded compatible wheels on Windows
|
||||
free-threaded-support = true
|
||||
skip = "*t-win*"
|
||||
```
|
||||
|
||||
### `CIBW_ARCHS` {: #archs}
|
||||
> Change the architectures built on your machine by default.
|
||||
|
||||
A list of architectures to build.
|
||||
|
||||
On macOS, this option can be used to cross-compile between `x86_64`,
|
||||
`universal2` and `arm64` for Apple Silicon support.
|
||||
On macOS, this option can be used to [cross-compile](faq.md#cross-compiling)
|
||||
between `x86_64`, `universal2` and `arm64`.
|
||||
|
||||
On Linux, this option can be used to build non-native architectures under
|
||||
emulation. See [this guide](faq.md#emulation) for more information.
|
||||
@@ -357,6 +478,7 @@ Options:
|
||||
- Linux: `x86_64` `i686` `aarch64` `ppc64le` `s390x`
|
||||
- macOS: `x86_64` `arm64` `universal2`
|
||||
- Windows: `AMD64` `x86` `ARM64`
|
||||
- Pyodide: `wasm32`
|
||||
- `auto`: The default archs for your machine - see the table below.
|
||||
- `auto64`: Just the 64-bit auto archs
|
||||
- `auto32`: Just the 32-bit auto archs
|
||||
@@ -499,10 +621,32 @@ This option can also be set using the [command-line option](#command-line) `--pr
|
||||
CIBW_PRERELEASE_PYTHONS: True
|
||||
```
|
||||
|
||||
### `CIBW_ALLOW_EMPTY` {: #allow-empty}
|
||||
> Suppress the error code if no wheels match the specified build identifiers
|
||||
|
||||
When none of the specified build identifiers match any available versions,
|
||||
cibuildwheel will typically return error code 3, indicating that there are
|
||||
no wheels to build. Enabling this option will suppress this error, allowing
|
||||
the build process to complete without signaling an error.
|
||||
|
||||
Default: Off (0). Error code 3 is returned when no builds are selected.
|
||||
|
||||
This option can also be set using the [command-line option](#command-line)
|
||||
`--allow-empty`. This option is not available in the `pyproject.toml` config.
|
||||
|
||||
#### Examples
|
||||
|
||||
!!! tab examples "Environment variables"
|
||||
|
||||
```yaml
|
||||
# Prevent an error code if the build does not match any wheels
|
||||
CIBW_ALLOW_EMPTY: True
|
||||
```
|
||||
|
||||
## Build customization
|
||||
|
||||
### `CIBW_BUILD_FRONTEND` {: #build-frontend}
|
||||
> Set the tool to use to build, either "pip" (default for now) or "build"
|
||||
> Set the tool to use to build, either "pip" (default for now), "build", or "build\[uv\]"
|
||||
|
||||
Options:
|
||||
|
||||
@@ -514,17 +658,36 @@ Default: `pip`
|
||||
Choose which build frontend to use. Can either be "pip", which will run
|
||||
`python -m pip wheel`, or "build", which will run `python -m build --wheel`.
|
||||
|
||||
You can also 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,
|
||||
`cibuildwheel[uv]`. `uv` will not be used for Python 3.6 or Python 3.7. You
|
||||
cannot use uv currently on Windows for ARM or for musllinux on s390x as
|
||||
binaries are not provided by uv. Legacy dependencies like setuptools on Python
|
||||
< 3.12 and pip are not installed if using uv.
|
||||
|
||||
Pyodide ignores this setting, as only "build" is supported.
|
||||
|
||||
You can specify extra arguments to pass to `pip wheel` or `build` using the
|
||||
optional `args` option.
|
||||
|
||||
!!! tip
|
||||
Until v2.0.0, [pip] was the only way to build wheels, and is still the
|
||||
Until v2.0.0, [pip][] was the only way to build wheels, and is still the
|
||||
default. However, we expect that at some point in the future, cibuildwheel
|
||||
will change the default to [build], in line with the PyPA's recommendation.
|
||||
will change the default to [build][], in line with the PyPA's recommendation.
|
||||
If you want to try `build` before this, you can use this option.
|
||||
|
||||
!!! warning
|
||||
If you are using `build[uv]` and are passing `--no-isolation` or `-n`, we
|
||||
will detect this and avoid passing `--installer=uv` to build, but still
|
||||
install all packages with uv. We do not currently detect combined short
|
||||
options, like `-xn`!
|
||||
|
||||
[pip]: https://pip.pypa.io/en/stable/cli/pip_wheel/
|
||||
[build]: https://github.com/pypa/build/
|
||||
[uv]: https://github.com/astral-sh/uv
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -539,6 +702,12 @@ optional `args` option.
|
||||
|
||||
# supply an extra argument to 'pip wheel'
|
||||
CIBW_BUILD_FRONTEND: "pip; args: --no-build-isolation"
|
||||
|
||||
# Use uv and build
|
||||
CIBW_BUILD_FRONTEND: "build[uv]"
|
||||
|
||||
# Use uv and build with an argument
|
||||
CIBW_BUILD_FRONTEND: "build[uv]; args: --no-isolation"
|
||||
```
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
@@ -553,6 +722,12 @@ optional `args` option.
|
||||
|
||||
# supply an extra argument to 'pip wheel'
|
||||
build-frontend = { name = "pip", args = ["--no-build-isolation"] }
|
||||
|
||||
# Use uv and build
|
||||
build-frontend = "build[uv]"
|
||||
|
||||
# Use uv and build with an argument
|
||||
build-frontend = { name = "build[uv]", args = ["--no-isolation"] }
|
||||
```
|
||||
|
||||
### `CIBW_CONFIG_SETTINGS` {: #config-settings}
|
||||
@@ -567,7 +742,7 @@ a table of items, including arrays.
|
||||
single values.
|
||||
|
||||
Platform-specific environment variables also available:<br/>
|
||||
`CIBW_CONFIG_SETTINGS_MACOS` | `CIBW_CONFIG_SETTINGS_WINDOWS` | `CIBW_CONFIG_SETTINGS_LINUX`
|
||||
`CIBW_CONFIG_SETTINGS_MACOS` | `CIBW_CONFIG_SETTINGS_WINDOWS` | `CIBW_CONFIG_SETTINGS_LINUX` | `CIBW_CONFIG_SETTINGS_PYODIDE`
|
||||
|
||||
|
||||
#### Examples
|
||||
@@ -587,18 +762,18 @@ Platform-specific environment variables also available:<br/>
|
||||
|
||||
|
||||
### `CIBW_ENVIRONMENT` {: #environment}
|
||||
> Set environment variables needed during the build
|
||||
> Set environment variables
|
||||
|
||||
A list of environment variables to set during the build. Bash syntax should be used, even on Windows.
|
||||
A list of environment variables to set during the build and test phases. Bash syntax should be used, even on Windows.
|
||||
|
||||
You must set this variable to pass variables to Linux builds (since they execute in a container). It also works for the other platforms.
|
||||
You must use this variable to pass variables to Linux builds, since they execute in a container. It also works for the other platforms.
|
||||
|
||||
You can use `$PATH` syntax to insert other variables, or the `$(pwd)` syntax to insert the output of other shell commands.
|
||||
|
||||
To specify more than one environment variable, separate the assignments by spaces.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX`
|
||||
`CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX` | `CIBW_ENVIRONMENT_PYODIDE`
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -671,12 +846,15 @@ Platform-specific environment variables are also available:<br/>
|
||||
In configuration mode, you can use a [TOML][] table instead of a raw string as shown above.
|
||||
|
||||
!!! note
|
||||
cibuildwheel always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#building-packages-with-optional-c-extensions).
|
||||
cibuildwheel always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#optional-extensions).
|
||||
|
||||
!!! note
|
||||
To do its work, cibuildwheel sets the variables `VIRTUALENV_PIP`, `DIST_EXTRA_CONFIG`, `SETUPTOOLS_EXT_SUFFIX`, `PIP_DISABLE_PIP_VERSION_CHECK`, `PIP_ROOT_USER_ACTION`, and it extends the variables `PATH` and `PIP_CONSTRAINT`. Your assignments to these options might be replaced or extended.
|
||||
|
||||
### `CIBW_ENVIRONMENT_PASS_LINUX` {: #environment-pass}
|
||||
> Set environment variables on the host to pass-through to the container during the build.
|
||||
> Set environment variables on the host to pass-through to the container.
|
||||
|
||||
A list of environment variables to pass into the linux container during the build. It has no effect on the other platforms, which can already access all environment variables directly.
|
||||
A list of environment variables to pass into the linux container during each build and test. It has no effect on the other platforms, which can already access all environment variables directly.
|
||||
|
||||
To specify more than one environment variable, separate the variable names by spaces.
|
||||
|
||||
@@ -727,7 +905,7 @@ On linux, overriding it triggers a new container launch. It cannot be overridden
|
||||
on macOS and Windows.
|
||||
|
||||
Platform-specific environment variables also available:<br/>
|
||||
`CIBW_BEFORE_ALL_MACOS` | `CIBW_BEFORE_ALL_WINDOWS` | `CIBW_BEFORE_ALL_LINUX`
|
||||
`CIBW_BEFORE_ALL_MACOS` | `CIBW_BEFORE_ALL_WINDOWS` | `CIBW_BEFORE_ALL_LINUX` | `CIBW_BEFORE_ALL_PYODIDE`
|
||||
|
||||
!!! note
|
||||
|
||||
@@ -792,7 +970,7 @@ The active Python binary can be accessed using `python`, and pip with `pip`; cib
|
||||
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`
|
||||
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX` | `CIBW_BEFORE_BUILD_PYODIDE`
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -846,7 +1024,6 @@ Platform-specific environment variables are also available:<br/>
|
||||
[build-system]
|
||||
requires = [
|
||||
"setuptools>=42",
|
||||
"wheel",
|
||||
"Cython",
|
||||
"numpy==1.13.3; python_version<'3.5'",
|
||||
"oldest-supported-numpy; python_version>='3.5'",
|
||||
@@ -874,6 +1051,7 @@ Default:
|
||||
- on Linux: `'auditwheel repair -w {dest_dir} {wheel}'`
|
||||
- on macOS: `'delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}'`
|
||||
- on Windows: `''`
|
||||
- on Pyodide: `''`
|
||||
|
||||
A shell command to repair a built wheel by copying external library dependencies into the wheel tree and relinking them.
|
||||
The command is run on each built wheel (except for pure Python ones) before testing it.
|
||||
@@ -887,7 +1065,7 @@ The following placeholders must be used inside the command and will be replaced
|
||||
The command is run in a shell, so you can run multiple commands like `cmd1 && cmd2`.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX`
|
||||
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX` | `CIBW_REPAIR_WHEEL_COMMAND_PYODIDE`
|
||||
|
||||
!!! tip
|
||||
cibuildwheel doesn't yet ship a default repair command for Windows.
|
||||
@@ -898,6 +1076,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 "Environment variables"
|
||||
@@ -917,9 +1101,7 @@ Platform-specific environment variables are also available:<br/>
|
||||
CIBW_REPAIR_WHEEL_COMMAND: >
|
||||
python scripts/repair_wheel.py -w {dest_dir} {wheel} &&
|
||||
python scripts/check_repaired_wheel.py -w {dest_dir} {wheel}
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Use abi3audit to catch issues with Limited API wheels
|
||||
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >
|
||||
auditwheel repair -w {dest_dir} {wheel} &&
|
||||
@@ -953,9 +1135,7 @@ Platform-specific environment variables are also available:<br/>
|
||||
'python scripts/repair_wheel.py -w {dest_dir} {wheel}',
|
||||
'python scripts/check_repaired_wheel.py -w {dest_dir} {wheel}',
|
||||
]
|
||||
```
|
||||
|
||||
```toml
|
||||
# Use abi3audit to catch issues with Limited API wheels
|
||||
[tool.cibuildwheel.linux]
|
||||
repair-wheel-command = [
|
||||
@@ -989,11 +1169,11 @@ The available options are (default value):
|
||||
- `CIBW_MANYLINUX_S390X_IMAGE` ([`quay.io/pypa/manylinux2014_s390x`](https://quay.io/pypa/manylinux2014_s390x))
|
||||
- `CIBW_MANYLINUX_PYPY_AARCH64_IMAGE` ([`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64))
|
||||
- `CIBW_MANYLINUX_PYPY_I686_IMAGE` ([`quay.io/pypa/manylinux2014_i686`](https://quay.io/pypa/manylinux2014_i686))
|
||||
- `CIBW_MUSLLINUX_X86_64_IMAGE` ([`quay.io/pypa/musllinux_1_1_x86_64`](https://quay.io/pypa/musllinux_1_1_x86_64))
|
||||
- `CIBW_MUSLLINUX_I686_IMAGE` ([`quay.io/pypa/musllinux_1_1_i686`](https://quay.io/pypa/musllinux_1_1_i686))
|
||||
- `CIBW_MUSLLINUX_AARCH64_IMAGE` ([`quay.io/pypa/musllinux_1_1_aarch64`](https://quay.io/pypa/musllinux_1_1_aarch64))
|
||||
- `CIBW_MUSLLINUX_PPC64LE_IMAGE` ([`quay.io/pypa/musllinux_1_1_ppc64le`](https://quay.io/pypa/musllinux_1_1_ppc64le))
|
||||
- `CIBW_MUSLLINUX_S390X_IMAGE` ([`quay.io/pypa/musllinux_1_1_s390x`](https://quay.io/pypa/musllinux_1_1_s390x))
|
||||
- `CIBW_MUSLLINUX_X86_64_IMAGE` ([`quay.io/pypa/musllinux_1_2_x86_64`](https://quay.io/pypa/musllinux_1_2_x86_64))
|
||||
- `CIBW_MUSLLINUX_I686_IMAGE` ([`quay.io/pypa/musllinux_1_2_i686`](https://quay.io/pypa/musllinux_1_2_i686))
|
||||
- `CIBW_MUSLLINUX_AARCH64_IMAGE` ([`quay.io/pypa/musllinux_1_2_aarch64`](https://quay.io/pypa/musllinux_1_2_aarch64))
|
||||
- `CIBW_MUSLLINUX_PPC64LE_IMAGE` ([`quay.io/pypa/musllinux_1_2_ppc64le`](https://quay.io/pypa/musllinux_1_2_ppc64le))
|
||||
- `CIBW_MUSLLINUX_S390X_IMAGE` ([`quay.io/pypa/musllinux_1_2_s390x`](https://quay.io/pypa/musllinux_1_2_s390x))
|
||||
|
||||
Set an alternative Docker image to be used for building [manylinux / musllinux](https://github.com/pypa/manylinux) wheels.
|
||||
|
||||
@@ -1004,7 +1184,7 @@ For `CIBW_MUSLLINUX_*_IMAGE`, the value of this option can either be set to `mus
|
||||
|
||||
If this option is blank, it will fall though to the next available definition (environment variable -> pyproject.toml -> default).
|
||||
|
||||
If setting a custom image, you'll need to make sure it can be used in the same way as the default images: all necessary Python and pip versions need to be present in `/opt/python/`, and the auditwheel tool needs to be present for cibuildwheel to work. Apart from that, the architecture and relevant shared system libraries need to be compatible to the relevant standard to produce valid manylinux1/manylinux2010/manylinux2014/manylinux_2_24/manylinux_2_28/musllinux_1_1 wheels (see [pypa/manylinux on GitHub](https://github.com/pypa/manylinux), [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/), [PEP 599](https://www.python.org/dev/peps/pep-0599/), [PEP 600](https://www.python.org/dev/peps/pep-0600/) and [PEP 656](https://www.python.org/dev/peps/pep-0656/) for more details).
|
||||
If setting a custom image, you'll need to make sure it can be used in the same way as the default images: all necessary Python and pip versions need to be present in `/opt/python/`, and the auditwheel tool needs to be present for cibuildwheel to work. Apart from that, the architecture and relevant shared system libraries need to be compatible to the relevant standard to produce valid manylinux1/manylinux2010/manylinux2014/manylinux_2_24/manylinux_2_28/musllinux_1_1/musllinux_1_2 wheels (see [pypa/manylinux on GitHub](https://github.com/pypa/manylinux), [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/), [PEP 599](https://www.python.org/dev/peps/pep-0599/), [PEP 600](https://www.python.org/dev/peps/pep-0600/) and [PEP 656](https://www.python.org/dev/peps/pep-0656/) for more details).
|
||||
|
||||
Auditwheel detects the version of the manylinux / musllinux standard in the image through the `AUDITWHEEL_PLAT` environment variable, as cibuildwheel has no way of detecting the correct `--plat` command line argument to pass to auditwheel for a custom image. If a custom image does not correctly set this `AUDITWHEEL_PLAT` environment variable, the `CIBW_ENVIRONMENT` option can be used to do so (e.g., `CIBW_ENVIRONMENT='AUDITWHEEL_PLAT="manylinux2010_$(uname -m)"'`).
|
||||
|
||||
@@ -1035,6 +1215,10 @@ Auditwheel detects the version of the manylinux / musllinux standard in the imag
|
||||
# Build using a different image from the docker registry
|
||||
CIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64
|
||||
CIBW_MANYLINUX_I686_IMAGE: dockcross/manylinux-x86
|
||||
|
||||
# Build musllinux wheels using the musllinux_1_1 image
|
||||
CIBW_MUSLLINUX_X86_64_IMAGE: musllinux_1_1
|
||||
CIBW_MUSLLINUX_I686_IMAGE: musllinux_1_1
|
||||
```
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
@@ -1062,6 +1246,10 @@ Auditwheel detects the version of the manylinux / musllinux standard in the imag
|
||||
# Build using a different image from the docker registry
|
||||
manylinux-x86_64-image = "dockcross/manylinux-x64"
|
||||
manylinux-i686-image = "dockcross/manylinux-x86"
|
||||
|
||||
# Build musllinux wheels using the musllinux_1_1 image
|
||||
musllinux-x86_64-image = "musllinux_1_1"
|
||||
musllinux-i686-image = "musllinux_1_1"
|
||||
```
|
||||
|
||||
Like any other option, these can be placed in `[tool.cibuildwheel.linux]`
|
||||
@@ -1073,8 +1261,8 @@ Auditwheel detects the version of the manylinux / musllinux standard in the imag
|
||||
|
||||
Options:
|
||||
|
||||
- `docker[;create_args: ...]`
|
||||
- `podman[;create_args: ...]`
|
||||
- `docker[;create_args: ...][;disable_host_mount: true/false]`
|
||||
- `podman[;create_args: ...][;disable_host_mount: true/false]`
|
||||
|
||||
Default: `docker`
|
||||
|
||||
@@ -1083,11 +1271,13 @@ Set the container engine to use. Docker is the default, or you can switch to
|
||||
running and `docker` available on PATH. To use Podman, it needs to be
|
||||
installed and `podman` available on PATH.
|
||||
|
||||
Arguments can be supplied to the container engine. Currently, the only option
|
||||
that's customisable is 'create_args'. Parameters to create_args are
|
||||
space-separated strings, which are passed to the container engine on the
|
||||
command line when it's creating the container. If you want to include spaces
|
||||
inside a parameter, use shell-style quoting.
|
||||
Options can be supplied after the name.
|
||||
|
||||
| Option name | Description
|
||||
|---|---
|
||||
| `create_args` | Space-separated strings, which are passed to the container engine on the command line when it's creating the container. If you want to include spaces inside a parameter, use shell-style quoting.
|
||||
| `disable_host_mount` | By default, cibuildwheel will mount the root of the host filesystem as a volume at `/host` in the container. To disable the host mount, pass `true` to this option.
|
||||
|
||||
|
||||
!!! tip
|
||||
|
||||
@@ -1108,6 +1298,9 @@ inside a parameter, use shell-style quoting.
|
||||
|
||||
# pass command line options to 'docker create'
|
||||
CIBW_CONTAINER_ENGINE: "docker; create_args: --gpus all"
|
||||
|
||||
# disable the /host mount
|
||||
CIBW_CONTAINER_ENGINE: "docker; disable_host_mount: true"
|
||||
```
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
@@ -1119,6 +1312,9 @@ inside a parameter, use shell-style quoting.
|
||||
|
||||
# pass command line options to 'docker create'
|
||||
container-engine = { name = "docker", create-args = ["--gpus", "all"]}
|
||||
|
||||
# disable the /host mount
|
||||
container-engine = { name = "docker", disable-host-mount = true }
|
||||
```
|
||||
|
||||
|
||||
@@ -1150,7 +1346,7 @@ here and it will be used instead.
|
||||
`./constraints.txt` if that's not found.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS`
|
||||
`CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS` | `CIBW_DEPENDENCY_VERSIONS_PYODIDE`
|
||||
|
||||
!!! note
|
||||
This option does not affect the tools used on the Linux build - those versions
|
||||
@@ -1208,16 +1404,13 @@ not be installed after building.
|
||||
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_TEST_COMMAND_MACOS` | `CIBW_TEST_COMMAND_WINDOWS` | `CIBW_TEST_COMMAND_LINUX`
|
||||
`CIBW_TEST_COMMAND_MACOS` | `CIBW_TEST_COMMAND_WINDOWS` | `CIBW_TEST_COMMAND_LINUX` | `CIBW_TEST_COMMAND_PYODIDE`
|
||||
|
||||
#### Examples
|
||||
|
||||
!!! tab examples "Environment variables"
|
||||
|
||||
```yaml
|
||||
# Run the project tests against the installed wheel using `nose`
|
||||
CIBW_TEST_COMMAND: nosetests {project}/tests
|
||||
|
||||
# Run the package tests using `pytest`
|
||||
CIBW_TEST_COMMAND: pytest {package}/tests
|
||||
|
||||
@@ -1234,9 +1427,6 @@ Platform-specific environment variables are also available:<br/>
|
||||
|
||||
```toml
|
||||
[tool.cibuildwheel]
|
||||
# Run the project tests against the installed wheel using `nose`
|
||||
test-command = "nosetests {project}/tests"
|
||||
|
||||
# Run the package tests using `pytest`
|
||||
test-command = "pytest {package}/tests"
|
||||
|
||||
@@ -1271,7 +1461,7 @@ The active Python binary can be accessed using `python`, and pip with `pip`; cib
|
||||
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_BEFORE_TEST_MACOS` | `CIBW_BEFORE_TEST_WINDOWS` | `CIBW_BEFORE_TEST_LINUX`
|
||||
`CIBW_BEFORE_TEST_MACOS` | `CIBW_BEFORE_TEST_WINDOWS` | `CIBW_BEFORE_TEST_LINUX` | `CIBW_BEFORE_TEST_PYODIDE`
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -1331,7 +1521,7 @@ Platform-specific environment variables are also available:<br/>
|
||||
Space-separated list of dependencies required for running the tests.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX`
|
||||
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX` | `CIBW_TEST_REQUIRES_PYODIDE`
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -1342,7 +1532,7 @@ Platform-specific environment variables are also available:<br/>
|
||||
CIBW_TEST_REQUIRES: pytest
|
||||
|
||||
# Install specific versions of test dependencies
|
||||
CIBW_TEST_REQUIRES: nose==1.3.7 moto==0.4.31
|
||||
CIBW_TEST_REQUIRES: pytest==8.2.2 packaging==24.1
|
||||
```
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
@@ -1354,7 +1544,7 @@ Platform-specific environment variables are also available:<br/>
|
||||
|
||||
# Install specific versions of test dependencies
|
||||
[tool.cibuildwheel]
|
||||
test-requires = ["nose==1.3.7", "moto==0.4.31"]
|
||||
test-requires = ["pytest==8.2.2", "packaging==24.1"]
|
||||
```
|
||||
|
||||
In configuration files, you can use an array, and the items will be joined with a space.
|
||||
@@ -1371,7 +1561,7 @@ tests. This can be used to avoid having to redefine test dependencies in
|
||||
`setup.cfg` or `setup.py`.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_TEST_EXTRAS_MACOS` | `CIBW_TEST_EXTRAS_WINDOWS` | `CIBW_TEST_EXTRAS_LINUX`
|
||||
`CIBW_TEST_EXTRAS_MACOS` | `CIBW_TEST_EXTRAS_WINDOWS` | `CIBW_TEST_EXTRAS_LINUX` | `CIBW_TEST_EXTRAS_PYODIDE`
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -1426,7 +1616,37 @@ This option is not supported in the overrides section in `pyproject.toml`.
|
||||
test-skip = "*-macosx_arm64 *-macosx_universal2:arm64"
|
||||
```
|
||||
|
||||
## Other
|
||||
## Debugging
|
||||
|
||||
### `CIBW_DEBUG_KEEP_CONTAINER`
|
||||
|
||||
Enable this flag to keep the container around for inspection after a build. This
|
||||
option is provided for debugging purposes only.
|
||||
|
||||
Default: Off (0).
|
||||
|
||||
!!! caution
|
||||
This option can only be set as environment variable on the host machine
|
||||
|
||||
#### Examples
|
||||
|
||||
```shell
|
||||
export CIBW_DEBUG_KEEP_CONTAINER=TRUE
|
||||
```
|
||||
|
||||
### `CIBW_DEBUG_TRACEBACK`
|
||||
> Print full traceback when errors occur.
|
||||
|
||||
Print a full traceback for the cibuildwheel process when errors occur. This
|
||||
option is provided for debugging cibuildwheel.
|
||||
|
||||
This option can also be set using the [command-line option](#command-line) `--debug-traceback`.
|
||||
|
||||
#### Examples
|
||||
|
||||
```shell
|
||||
export CIBW_DEBUG_TRACEBACK=TRUE
|
||||
```
|
||||
|
||||
### `CIBW_BUILD_VERBOSITY` {: #build-verbosity}
|
||||
> Increase/decrease the output of pip wheel
|
||||
@@ -1434,7 +1654,7 @@ This option is not supported in the overrides section in `pyproject.toml`.
|
||||
A number from 1 to 3 to increase the level of verbosity (corresponding to invoking pip with `-v`, `-vv`, and `-vvv`), between -1 and -3 (`-q`, `-qq`, and `-qqq`), or just 0 (default verbosity). These flags are useful while debugging a build when the output of the actual build invoked by `pip wheel` is required. Has no effect on the `build` backend, which produces verbose output by default.
|
||||
|
||||
Platform-specific environment variables are also available:<br/>
|
||||
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX`
|
||||
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX` | `CIBW_BUILD_VERBOSITY_PYODIDE`
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -1454,12 +1674,25 @@ Platform-specific environment variables are also available:<br/>
|
||||
```
|
||||
|
||||
|
||||
## Command line options {: #command-line}
|
||||
## Command line {: #command-line}
|
||||
|
||||
### Options
|
||||
|
||||
```text
|
||||
« subprocess_run("cibuildwheel", "--help") »
|
||||
```
|
||||
|
||||
### Return codes
|
||||
|
||||
cibuildwheel exits 0 on success, or >0 if an error occurs.
|
||||
|
||||
Specific error codes are defined:
|
||||
|
||||
- 2 means a configuration error
|
||||
- 3 means no builds are selected (and [`--allow-empty`](#allow-empty) wasn't passed)
|
||||
- 4 means you specified an option that has been deprecated.
|
||||
|
||||
|
||||
## Placeholders
|
||||
|
||||
Some options support placeholders, like `{project}`, `{package}` or `{wheel}`, that are substituted by cibuildwheel before they are used. If, for some reason, you need to write the literal name of a placeholder, e.g. literally `{project}` in a command that would ordinarily substitute `{project}`, prefix it with a hash character - `#{project}`. This is only necessary in commands where the specific string between the curly brackets would be substituted - otherwise, strings not modified.
|
||||
@@ -1575,7 +1808,7 @@ Some options support placeholders, like `{project}`, `{package}` or `{wheel}`, t
|
||||
}
|
||||
|
||||
var optionNames = option.name.trim().split(', ')
|
||||
var url = 'https://cibuildwheel.readthedocs.io/en/stable/options/#'+option.id;
|
||||
var url = 'https://cibuildwheel.pypa.io/en/stable/options/#'+option.id;
|
||||
var namesMarkdown = $.map(optionNames, function(n) {
|
||||
return '[`'+n+'`]('+url+') '
|
||||
}).join(' <br> ')
|
||||
|
||||
+31
-51
@@ -11,45 +11,14 @@ locally to quickly iterate and track down issues without even touching CI.
|
||||
|
||||
Install cibuildwheel and run a build like this:
|
||||
|
||||
!!! tab "Linux"
|
||||
```sh
|
||||
# using pipx (https://github.com/pypa/pipx)
|
||||
pipx run cibuildwheel
|
||||
|
||||
Using [pipx](https://github.com/pypa/pipx):
|
||||
```sh
|
||||
pipx run cibuildwheel --platform linux
|
||||
```
|
||||
|
||||
Or,
|
||||
```sh
|
||||
pip install cibuildwheel
|
||||
cibuildwheel --platform linux
|
||||
```
|
||||
|
||||
!!! tab "macOS"
|
||||
|
||||
Using [pipx](https://github.com/pypa/pipx):
|
||||
```sh
|
||||
pipx run cibuildwheel --platform macos
|
||||
```
|
||||
|
||||
Or,
|
||||
```sh
|
||||
pip install cibuildwheel
|
||||
cibuildwheel --platform macos
|
||||
```
|
||||
|
||||
|
||||
!!! tab "Windows"
|
||||
|
||||
Using [pipx](https://github.com/pypa/pipx):
|
||||
```bat
|
||||
pipx run cibuildwheel --platform windows
|
||||
```
|
||||
|
||||
Or,
|
||||
```bat
|
||||
pip install cibuildwheel
|
||||
cibuildwheel --platform windows
|
||||
```
|
||||
# or,
|
||||
pip install cibuildwheel
|
||||
cibuildwheel
|
||||
```
|
||||
|
||||
You should see the builds taking place. You can experiment with options using environment variables or pyproject.toml.
|
||||
|
||||
@@ -61,17 +30,17 @@ You should see the builds taking place. You can experiment with options using en
|
||||
|
||||
```sh
|
||||
# run a command to set up the build system
|
||||
export CIBW_BEFORE_ALL='apt install libpng-dev'
|
||||
export CIBW_BEFORE_ALL='uname -a'
|
||||
|
||||
cibuildwheel --platform linux
|
||||
cibuildwheel
|
||||
```
|
||||
|
||||
> CMD (Windows)
|
||||
|
||||
```bat
|
||||
set CIBW_BEFORE_ALL='apt install libpng-dev'
|
||||
set CIBW_BEFORE_ALL='uname -a'
|
||||
|
||||
cibuildwheel --platform linux
|
||||
cibuildwheel
|
||||
```
|
||||
|
||||
!!! tab "pyproject.toml"
|
||||
@@ -82,13 +51,13 @@ You should see the builds taking place. You can experiment with options using en
|
||||
|
||||
```
|
||||
[tool.cibuildwheel]
|
||||
before-all = "apt install libpng-dev"
|
||||
before-all = "uname -a"
|
||||
```
|
||||
|
||||
Then invoke cibuildwheel, like:
|
||||
|
||||
```console
|
||||
cibuildwheel --platform linux
|
||||
cibuildwheel
|
||||
```
|
||||
|
||||
### Linux builds
|
||||
@@ -138,6 +107,13 @@ You can override the cache folder using the ``CIBW_CACHE_PATH`` environment vari
|
||||
Download link: https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg
|
||||
```
|
||||
|
||||
### Pyodide (WebAssembly) builds (experimental)
|
||||
|
||||
Pre-requisite: you need to have a matching host version of Python (unlike all
|
||||
other cibuildwheel platforms). Linux host highly recommended; macOS hosts may
|
||||
work (e.g. invoking `pytest` directly in [`CIBW_TEST_COMMAND`](options.md#test-command) is [currently failing](https://github.com/pyodide/pyodide/issues/4802)) and Windows hosts will not work.
|
||||
|
||||
You must target pyodide with `--platform pyodide` (or use `--only` on the identifier).
|
||||
|
||||
## Configure a CI service
|
||||
|
||||
@@ -178,16 +154,18 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
# macos-13 is an intel runner, macos-14 is apple silicon
|
||||
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
run: pipx run cibuildwheel==2.16.0
|
||||
run: pipx run cibuildwheel==2.20.0
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
```
|
||||
|
||||
@@ -210,22 +188,24 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
# macos-13 is an intel runner, macos-14 is apple silicon
|
||||
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Used to host cibuildwheel
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: actions/setup-python@v5
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: python -m pip install cibuildwheel==2.16.0
|
||||
run: python -m pip install cibuildwheel==2.20.0
|
||||
|
||||
- name: Build wheels
|
||||
run: python -m cibuildwheel --output-dir wheelhouse
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
```
|
||||
|
||||
|
||||
+83
-75
@@ -12,18 +12,18 @@ 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. |
|
||||
| [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 |
|
||||
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
|
||||
| [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 |
|
||||
| [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. |
|
||||
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
|
||||
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
|
||||
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an in-process SQL OLAP Database Management System |
|
||||
| [MemRay][] | ![github icon][] | ![linux icon][] | Memray is a memory profiler for Python |
|
||||
| [Triton][] | ![github icon][] | ![linux icon][] | Self hosted runners |
|
||||
| [uvloop][] | ![github icon][] | ![apple icon][] ![linux icon][] | Ultra fast asyncio event loop. |
|
||||
| [psutil][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Cross-platform lib for process and system monitoring in Python |
|
||||
| [Triton][] | ![github icon][] | ![linux icon][] | Self hosted runners |
|
||||
| [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 🚀 |
|
||||
| [Google Benchmark][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A microbenchmark support library |
|
||||
| [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. |
|
||||
| [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. |
|
||||
| [asyncpg][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A fast PostgreSQL Database Client Library for Python/asyncio. |
|
||||
@@ -31,105 +31,109 @@ title: Working examples
|
||||
| [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. |
|
||||
| [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. |
|
||||
| [PyOxidizer][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A modern Python application packaging and distribution tool |
|
||||
| [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. |
|
||||
| [cvxpy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A Python-embedded modeling language for convex optimization problems. |
|
||||
| [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. |
|
||||
| [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 |
|
||||
| [UltraJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Ultra fast JSON decoder and encoder written in C with Python bindings |
|
||||
| [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. |
|
||||
| [pyzmq][] | ![github icon][] ![circleci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python bindings for zeromq, the networking library. Uses Cython on CPython and CFFI on PyPy. ARM wheels for linux are built natively on CircleCI. |
|
||||
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
|
||||
| [Implicit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes GPU support for linux wheels |
|
||||
| [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI |
|
||||
| [pyzmq][] | ![github icon][] ![circleci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python bindings for zeromq, the networking library. Uses Cython on CPython and CFFI on PyPy. ARM wheels for linux are built natively on CircleCI. |
|
||||
| [Implicit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes GPU support for linux wheels |
|
||||
| [vispy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Main repository for Vispy |
|
||||
| [tinyobjloader][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Tiny but powerful single file wavefront obj loader |
|
||||
| [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. |
|
||||
| [coverage.py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The coverage tool for Python |
|
||||
| [PyCryptodome][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A self-contained cryptographic library for Python |
|
||||
| [PyYAML][] | ![github icon][] | ![apple icon][] | Canonical source repository for PyYAML |
|
||||
| [Line Profiler][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Line-by-line profiling for Python |
|
||||
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, PyTables, pandas, bcolz and more |
|
||||
| [PyYAML][] | ![github icon][] | ![apple icon][] | Canonical source repository for PyYAML |
|
||||
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
|
||||
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, Pandas, PyTables and more |
|
||||
| [pikepdf][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by QPDF |
|
||||
| [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. |
|
||||
| [Wrapt][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python module for decorators, wrappers and monkey patching. |
|
||||
| [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. |
|
||||
| [pikepdf][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by QPDF |
|
||||
| [envd][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | 🏕️ Reproducible development environment |
|
||||
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
|
||||
| [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. |
|
||||
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
|
||||
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
|
||||
| [Psycopg 3][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A modern implementation of a PostgreSQL adapter for Python |
|
||||
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
|
||||
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
|
||||
| [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data |
|
||||
| [Psycopg 3][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A modern implementation of a PostgreSQL adapter for Python |
|
||||
| [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. |
|
||||
| [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. |
|
||||
| [DeepForest][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | An Efficient, Scalable and Optimized Python Framework for Deep Forest (2021.2.1) |
|
||||
| [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 |
|
||||
| [mosec][] | ![github icon][] | ![linux icon][] ![apple icon][] | A high-performance ML model serving framework, offers dynamic batching and CPU/GPU pipelines to fully exploit your compute machine |
|
||||
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS ¶ |
|
||||
| [mosec][] | ![github icon][] | ![linux icon][] ![apple icon][] | A machine learning model serving framework powered by Rust |
|
||||
| [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. |
|
||||
| [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 |
|
||||
| [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. |
|
||||
| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python |
|
||||
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
|
||||
| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
|
||||
| [tgcalls][] | ![github icon][] | ![apple icon][] ![windows icon][] | Python `pybind11` binding to Telegram's WebRTC library with third party dependencies like `OpenSSL`, `MozJPEG`, `FFmpeg`, etc. |
|
||||
| [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. |
|
||||
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
|
||||
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
|
||||
| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
|
||||
| [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. |
|
||||
| [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Quickly search, compare, and analyze genomic and metagenomic data sets. |
|
||||
| [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing |
|
||||
| [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. |
|
||||
| [abess][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A fast best-subset selection library. It uses cibuildwheel to build a large project with C++ extensions. |
|
||||
| [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq |
|
||||
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 |
|
||||
| [Tokenizer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast and customizable text tokenization library with BPE and SentencePiece support |
|
||||
| [keyvi][] | ![github icon][] | ![linux icon][] ![apple icon][] | FST based key value index highly optimized for size and lookup performance, utilizes ccache action for improved runtime |
|
||||
| [PyGLM][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Fast OpenGL Mathematics (GLM) for Python |
|
||||
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
|
||||
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
|
||||
| [iDynTree][] | ![github icon][] | ![linux icon][] | Uses manylinux_2_24 |
|
||||
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. |
|
||||
| [pillow-heif][] | ![github icon][] ![cirrusci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Bindings to libheif library with third party dependencies. Fully automated CI for tests and publishing including Apple Silicon builds. |
|
||||
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
|
||||
| [iDynTree][] | ![github icon][] | ![linux icon][] | Uses manylinux_2_24 |
|
||||
| [streaming-form-data][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Streaming parser for multipart/form-data written in Cython |
|
||||
| [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 |
|
||||
| [pybase64][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast Base64 encoding/decoding in Python |
|
||||
| [Arbor][] | ![github icon][] | ![apple icon][] ![linux icon][] | Arbor is a multi-compartment neuron simulation library; compatible with next-generation accelerators; best-practices applied to research software; focused on community-driven development. Includes a [small script](https://github.com/arbor-sim/arbor/blob/master/scripts/patchwheel.py) patching `rpath` in bundled libraries. |
|
||||
| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
|
||||
| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
|
||||
| [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. |
|
||||
| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. |
|
||||
| [etebase-py][] | ![travisci icon][] | ![linux icon][] | Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. |
|
||||
| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
|
||||
| [Arbor][] | ![github icon][] | ![apple icon][] ![linux icon][] | Arbor is a multi-compartment neuron simulation library; compatible with next-generation accelerators; best-practices applied to research software; focused on community-driven development. Includes a [small script](https://github.com/arbor-sim/arbor/blob/master/scripts/patchwheel.py) patching `rpath` in bundled libraries. |
|
||||
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
|
||||
| [cf-units][] | ![github icon][] | ![apple icon][] ![linux icon][] | Units of measure as required by the Climate and Forecast (CF) Metadata Conventions |
|
||||
| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. |
|
||||
| [clang-format][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Scikit-build wrapper around LLVM's CMake, all platforms, generic wheels. |
|
||||
| [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 |
|
||||
| [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
|
||||
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy |
|
||||
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
|
||||
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
|
||||
| [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. |
|
||||
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
|
||||
| [SiPM][] | ![github icon][] | ![apple icon][] ![linux icon][] | High performance library for SiPM detectors simulation using C++17, OpenMP and AVX2 intrinsics. |
|
||||
| [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. |
|
||||
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
|
||||
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
|
||||
| [aalink][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Async Python interface for Ableton Link. |
|
||||
| [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. |
|
||||
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
|
||||
| [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). |
|
||||
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
|
||||
| [pybind11 cross build example][] | ![github icon][] ![gitlab icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Same as pybind11 cmake_example but used to demo Linux ARM + Windows + macOS builds on GitLab |
|
||||
|
||||
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
|
||||
[pytorch-fairseq]: https://github.com/pytorch/fairseq
|
||||
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
|
||||
[NumPy]: https://github.com/numpy/numpy
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
[NCNN]: https://github.com/Tencent/ncnn
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
|
||||
[Kivy]: https://github.com/kivy/kivy
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
[MemRay]: https://github.com/bloomberg/memray
|
||||
[Triton]: https://github.com/openai/triton
|
||||
[uvloop]: https://github.com/MagicStack/uvloop
|
||||
[psutil]: https://github.com/giampaolo/psutil
|
||||
[Triton]: https://github.com/openai/triton
|
||||
[vaex]: https://github.com/vaexio/vaex
|
||||
[Google Benchmark]: https://github.com/google/benchmark
|
||||
[vaex]: https://github.com/vaexio/vaex
|
||||
[Apache Beam]: https://github.com/apache/beam
|
||||
[PyGame]: https://github.com/pygame/pygame
|
||||
[asyncpg]: https://github.com/MagicStack/asyncpg
|
||||
@@ -137,87 +141,91 @@ title: Working examples
|
||||
[scikit-image]: https://github.com/scikit-image/scikit-image
|
||||
[twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport
|
||||
[PyOxidizer]: https://github.com/indygreg/PyOxidizer
|
||||
[websockets]: https://github.com/aaugustin/websockets
|
||||
[cvxpy]: https://github.com/cvxpy/cvxpy
|
||||
[websockets]: https://github.com/python-websockets/websockets
|
||||
[pedalboard]: https://github.com/spotify/pedalboard
|
||||
[River]: https://github.com/online-ml/river
|
||||
[UltraJSON]: https://github.com/ultrajson/ultrajson
|
||||
[OpenSpiel]: https://github.com/deepmind/open_spiel
|
||||
[OpenSpiel]: https://github.com/google-deepmind/open_spiel
|
||||
[aiortc]: https://github.com/aiortc/aiortc
|
||||
[pyzmq]: https://github.com/zeromq/pyzmq
|
||||
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
|
||||
[Implicit]: https://github.com/benfred/implicit
|
||||
[Dependency Injector]: https://github.com/ets-labs/python-dependency-injector
|
||||
[pyzmq]: https://github.com/zeromq/pyzmq
|
||||
[Implicit]: https://github.com/benfred/implicit
|
||||
[vispy]: https://github.com/vispy/vispy
|
||||
[tinyobjloader]: https://github.com/tinyobjloader/tinyobjloader
|
||||
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
|
||||
[coverage.py]: https://github.com/nedbat/coveragepy
|
||||
[PyCryptodome]: https://github.com/Legrandin/pycryptodome
|
||||
[PyYAML]: https://github.com/yaml/pyyaml
|
||||
[Line Profiler]: https://github.com/pyutils/line_profiler
|
||||
[numexpr]: https://github.com/pydata/numexpr
|
||||
[PyYAML]: https://github.com/yaml/pyyaml
|
||||
[PyAV]: https://github.com/PyAV-Org/PyAV
|
||||
[numexpr]: https://github.com/pydata/numexpr
|
||||
[pikepdf]: https://github.com/pikepdf/pikepdf
|
||||
[h5py]: https://github.com/h5py/h5py
|
||||
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
|
||||
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
|
||||
[pikepdf]: https://github.com/pikepdf/pikepdf
|
||||
[envd]: https://github.com/tensorchord/envd
|
||||
[SimpleJSON]: https://github.com/simplejson/simplejson
|
||||
[OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO
|
||||
[SimpleJSON]: https://github.com/simplejson/simplejson
|
||||
[aioquic]: https://github.com/aiortc/aioquic
|
||||
[ruptures]: https://github.com/deepcharles/ruptures
|
||||
[OpenTimelineIO]: https://github.com/PixarAnimationStudios/OpenTimelineIO
|
||||
[PyTables]: https://github.com/PyTables/PyTables
|
||||
[Psycopg 3]: https://github.com/psycopg/psycopg
|
||||
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
|
||||
[ruptures]: https://github.com/deepcharles/ruptures
|
||||
[OpenTimelineIO]: https://github.com/AcademySoftwareFoundation/OpenTimelineIO
|
||||
[PyTables]: https://github.com/PyTables/PyTables
|
||||
[google neuroglancer]: https://github.com/google/neuroglancer
|
||||
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
|
||||
[DeepForest]: https://github.com/LAMDA-NJU/Deep-Forest
|
||||
[AutoPy]: https://github.com/autopilot-rs/autopy
|
||||
[H3-py]: https://github.com/uber/h3-py
|
||||
[mosec]: https://github.com/mosecorg/mosec
|
||||
[Rtree]: https://github.com/Toblerity/rtree
|
||||
[time-machine]: https://github.com/adamchainz/time-machine
|
||||
[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
|
||||
[time-machine]: https://github.com/adamchainz/time-machine
|
||||
[KDEpy]: https://github.com/tommyod/KDEpy
|
||||
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
|
||||
[python-snappy]: https://github.com/andrix/python-snappy
|
||||
[tgcalls]: https://github.com/MarshalX/tgcalls
|
||||
[dd-trace-py]: https://github.com/DataDog/dd-trace-py
|
||||
[tgcalls]: https://github.com/MarshalX/tgcalls
|
||||
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
|
||||
[pybind11 python_example]: https://github.com/pybind/python_example
|
||||
[sourmash]: https://github.com/dib-lab/sourmash
|
||||
[python-snappy]: https://github.com/intake/python-snappy
|
||||
[abess]: https://github.com/abess-team/abess
|
||||
[sourmash]: https://github.com/sourmash-bio/sourmash
|
||||
[cyvcf2]: https://github.com/brentp/cyvcf2
|
||||
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
|
||||
[abess]: https://github.com/abess-team/abess
|
||||
[jq.py]: https://github.com/mwilliamson/jq.py
|
||||
[iminuit]: https://github.com/scikit-hep/iminuit
|
||||
[Tokenizer]: https://github.com/OpenNMT/Tokenizer
|
||||
[keyvi]: https://github.com/KeyviDev/keyvi
|
||||
[PyGLM]: https://github.com/Zuzu-Typ/PyGLM
|
||||
[TgCrypto]: https://github.com/pyrogram/tgcrypto
|
||||
[bx-python]: https://github.com/bxlab/bx-python
|
||||
[iDynTree]: https://github.com/robotology/idyntree
|
||||
[boost-histogram]: https://github.com/scikit-hep/boost-histogram
|
||||
[pillow-heif]: https://github.com/bigcat88/pillow_heif
|
||||
[TgCrypto]: https://github.com/pyrogram/tgcrypto
|
||||
[iDynTree]: https://github.com/robotology/idyntree
|
||||
[streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data
|
||||
[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
|
||||
[power-grid-model]: https://github.com/PowerGridModel/power-grid-model
|
||||
[pybase64]: https://github.com/mayeut/pybase64
|
||||
[Arbor]: https://github.com/arbor-sim/arbor
|
||||
[fathon]: https://github.com/stfbnc/fathon
|
||||
[power-grid-model]: https://github.com/alliander-opensource/power-grid-model
|
||||
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
|
||||
[polaroid]: https://github.com/daggy1234/polaroid
|
||||
[etebase-py]: https://github.com/etesync/etebase-py
|
||||
[fathon]: https://github.com/stfbnc/fathon
|
||||
[Arbor]: https://github.com/arbor-sim/arbor
|
||||
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
|
||||
[cf-units]: https://github.com/SciTools/cf-units
|
||||
[polaroid]: https://github.com/daggy1234/polaroid
|
||||
[clang-format]: https://github.com/ssciwr/clang-format-wheel
|
||||
[etebase-py]: https://github.com/etesync/etebase-py
|
||||
[cf-units]: https://github.com/SciTools/cf-units
|
||||
[ninja]: https://github.com/scikit-build/ninja-python-distributions
|
||||
[numpythia]: https://github.com/scikit-hep/numpythia
|
||||
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
|
||||
[pyjet]: https://github.com/scikit-hep/pyjet
|
||||
[ril]: https://github.com/Cryptex-github/ril-py
|
||||
[GSD]: https://github.com/glotzerlab/gsd
|
||||
[SiPM]: https://github.com/EdoPro98/SimSiPM
|
||||
[CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib
|
||||
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
|
||||
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
|
||||
[aalink]: https://github.com/artfwo/aalink
|
||||
[CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib
|
||||
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
|
||||
[werpy]: https://github.com/analyticsinmotion/werpy
|
||||
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
|
||||
[pybind11 cross build example]: https://github.com/wbarnha/pybind_cmake_example_crossbuild
|
||||
|
||||
[appveyor icon]: data/readme_icons/appveyor.svg
|
||||
|
||||
@@ -12,7 +12,7 @@ stack: python 3.7
|
||||
init:
|
||||
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
|
||||
|
||||
install: python -m pip install cibuildwheel==2.16.0
|
||||
install: python -m pip install cibuildwheel==2.20.0
|
||||
|
||||
build_script: python -m cibuildwheel --output-dir wheelhouse
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ jobs:
|
||||
- bash: |
|
||||
set -o errexit
|
||||
python3 -m pip install --upgrade pip
|
||||
pip3 install cibuildwheel==2.16.0
|
||||
pip3 install cibuildwheel==2.20.0
|
||||
displayName: Install dependencies
|
||||
- bash: cibuildwheel --output-dir wheelhouse .
|
||||
displayName: Build wheels
|
||||
@@ -14,13 +14,13 @@ jobs:
|
||||
inputs: {pathtoPublish: 'wheelhouse'}
|
||||
|
||||
- job: macos
|
||||
pool: {vmImage: 'macOS-11'}
|
||||
pool: {vmImage: 'macOS-12'}
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
- bash: |
|
||||
set -o errexit
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install cibuildwheel==2.16.0
|
||||
python3 -m pip install cibuildwheel==2.20.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==2.16.0
|
||||
pip install cibuildwheel==2.20.0
|
||||
displayName: Install dependencies
|
||||
- bash: cibuildwheel --output-dir wheelhouse .
|
||||
displayName: Build wheels
|
||||
|
||||
@@ -4,14 +4,14 @@ jobs:
|
||||
linux-wheels:
|
||||
working_directory: ~/linux-wheels
|
||||
docker:
|
||||
- image: circleci/python:3.9
|
||||
- image: cimg/python:3.12
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- run:
|
||||
name: Build the Linux wheels.
|
||||
command: |
|
||||
pip3 install --user cibuildwheel==2.16.0
|
||||
python3 -m pip install --user cibuildwheel==2.20.0
|
||||
cibuildwheel --output-dir wheelhouse
|
||||
- store_artifacts:
|
||||
path: wheelhouse/
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
linux-aarch64-wheels:
|
||||
working_directory: ~/linux-aarch64-wheels
|
||||
machine:
|
||||
image: ubuntu-2004:2022.04.1
|
||||
image: default
|
||||
# resource_class is what tells CircleCI to use an ARM worker for native arm builds
|
||||
# https://circleci.com/product/features/resource-classes/
|
||||
resource_class: arm.medium
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- run:
|
||||
name: Build the Linux aarch64 wheels.
|
||||
command: |
|
||||
python3 -m pip install --user cibuildwheel==2.16.0
|
||||
python3 -m pip install --user cibuildwheel==2.20.0
|
||||
python3 -m cibuildwheel --output-dir wheelhouse
|
||||
- store_artifacts:
|
||||
path: wheelhouse/
|
||||
@@ -36,13 +36,15 @@ jobs:
|
||||
osx-wheels:
|
||||
working_directory: ~/osx-wheels
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
xcode: 15.4.0
|
||||
resource_class: macos.m1.medium.gen1
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Build the OS X wheels.
|
||||
command: |
|
||||
pip3 install cibuildwheel==2.16.0
|
||||
sudo softwareupdate --install-rosetta --agree-to-license # for python<=3.8 or x86_64/universal2 tests
|
||||
pip3 install cibuildwheel==2.20.0
|
||||
cibuildwheel --output-dir wheelhouse
|
||||
- store_artifacts:
|
||||
path: wheelhouse/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
|
||||
install_cibuildwheel_script:
|
||||
- python -m pip install cibuildwheel==2.16.0
|
||||
- python -m pip install cibuildwheel==2.20.0
|
||||
run_cibuildwheel_script:
|
||||
- cibuildwheel
|
||||
wheels_artifacts:
|
||||
@@ -10,12 +10,12 @@ build_and_store_wheels: &BUILD_AND_STORE_WHEELS
|
||||
macos_task:
|
||||
name: Build macOS x86_64 and arm64 wheels.
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-monterey-xcode
|
||||
|
||||
image: ghcr.io/cirruslabs/macos-sonoma-xcode
|
||||
env:
|
||||
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
|
||||
VENV_ROOT: ${HOME}/venv-cibuildwheel
|
||||
PATH: ${VENV_ROOT}/bin:${PATH}
|
||||
CIBW_ARCHS_MACOS: x86_64 arm64
|
||||
install_pre_requirements_script:
|
||||
- brew install python@3.10
|
||||
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
|
||||
- brew install python@3.12
|
||||
- python3.12 -m venv ${VENV_ROOT}
|
||||
<<: *BUILD_AND_STORE_WHEELS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
|
||||
install_cibuildwheel_script:
|
||||
- python -m pip install cibuildwheel==2.16.0
|
||||
- python -m pip install cibuildwheel==2.20.0
|
||||
run_cibuildwheel_script:
|
||||
- cibuildwheel
|
||||
wheels_artifacts:
|
||||
@@ -15,9 +15,14 @@ linux_x86_task:
|
||||
platform: linux
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
|
||||
env:
|
||||
VENV_ROOT: ${HOME}/venv-cibuildwheel
|
||||
PATH: ${VENV_ROOT}/bin:${PATH}
|
||||
install_pre_requirements_script:
|
||||
- apt install -y python3-venv python-is-python3
|
||||
- add-apt-repository -y ppa:deadsnakes/ppa
|
||||
- apt-get update
|
||||
- apt-get install -y python3.12-venv
|
||||
- python3.12 -m venv ${VENV_ROOT}
|
||||
<<: *BUILD_AND_STORE_WHEELS
|
||||
|
||||
linux_aarch64_task:
|
||||
@@ -29,9 +34,14 @@ linux_aarch64_task:
|
||||
platform: linux
|
||||
cpu: 4
|
||||
memory: 4G
|
||||
|
||||
env:
|
||||
VENV_ROOT: ${HOME}/venv-cibuildwheel
|
||||
PATH: ${VENV_ROOT}/bin:${PATH}
|
||||
install_pre_requirements_script:
|
||||
- apt install -y python3-venv python-is-python3
|
||||
- add-apt-repository -y ppa:deadsnakes/ppa
|
||||
- apt-get update
|
||||
- apt-get install -y python3.12-venv
|
||||
- python3.12 -m venv ${VENV_ROOT}
|
||||
<<: *BUILD_AND_STORE_WHEELS
|
||||
|
||||
windows_x86_task:
|
||||
@@ -42,7 +52,7 @@ windows_x86_task:
|
||||
memory: 4G
|
||||
|
||||
install_pre_requirements_script:
|
||||
- choco install -y --no-progress python3 --version 3.10.6
|
||||
- choco install -y --no-progress python3 --version 3.12.4
|
||||
- refreshenv
|
||||
- echo PATH=%PATH% >> "%CIRRUS_ENV%"
|
||||
<<: *BUILD_AND_STORE_WHEELS
|
||||
@@ -50,11 +60,11 @@ windows_x86_task:
|
||||
macos_arm64_task:
|
||||
name: Build macOS arm64 wheels.
|
||||
macos_instance:
|
||||
image: ghcr.io/cirruslabs/macos-monterey-xcode
|
||||
|
||||
image: ghcr.io/cirruslabs/macos-sonoma-xcode
|
||||
env:
|
||||
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
|
||||
VENV_ROOT: ${HOME}/venv-cibuildwheel
|
||||
PATH: ${VENV_ROOT}/bin:${PATH}
|
||||
install_pre_requirements_script:
|
||||
- brew install python@3.10
|
||||
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
|
||||
- brew install python@3.12
|
||||
- python3.12 -m venv ${VENV_ROOT}
|
||||
<<: *BUILD_AND_STORE_WHEELS
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build_wheels_macos:
|
||||
name: Build wheels on macos-11
|
||||
runs-on: macos-11
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.16.0
|
||||
env:
|
||||
CIBW_ARCHS_MACOS: x86_64 arm64
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: ./wheelhouse/*.whl
|
||||
@@ -16,16 +16,18 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-22.04, windows-2022, macos-11]
|
||||
# macos-13 is an intel runner, macos-14 is apple silicon
|
||||
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.16.0
|
||||
uses: pypa/cibuildwheel@v2.20.0
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
|
||||
build_sdist:
|
||||
@@ -37,8 +39,9 @@ jobs:
|
||||
- name: Build sdist
|
||||
run: pipx run build --sdist
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-sdist
|
||||
path: dist/*.tar.gz
|
||||
|
||||
upload_pypi:
|
||||
@@ -51,12 +54,12 @@ jobs:
|
||||
# or, alternatively, upload to PyPI on every tag starting with 'v' (remove on: release above to use this)
|
||||
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
# unpacks default artifact into dist/
|
||||
# if `name: artifact` is omitted, the action will create extra parent dir
|
||||
name: artifact
|
||||
# unpacks all CIBW artifacts into dist/
|
||||
pattern: cibw-*
|
||||
path: dist
|
||||
merge-multiple: true
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
|
||||
@@ -8,13 +8,14 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
# macos-13 is an intel runner, macos-14 is apple silicon
|
||||
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.16.0
|
||||
uses: pypa/cibuildwheel@v2.20.0
|
||||
# env:
|
||||
# CIBW_SOME_OPTION: value
|
||||
# ...
|
||||
@@ -23,6 +24,7 @@ jobs:
|
||||
# output-dir: wheelhouse
|
||||
# config-file: "{package}/pyproject.toml"
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
|
||||
@@ -8,7 +8,8 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
# macos-13 is an intel runner, macos-14 is apple silicon
|
||||
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -20,12 +21,13 @@ jobs:
|
||||
platforms: all
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.16.0
|
||||
uses: pypa/cibuildwheel@v2.20.0
|
||||
env:
|
||||
# configure cibuildwheel to build native archs ('auto'), and some
|
||||
# emulated ones
|
||||
CIBW_ARCHS_LINUX: auto aarch64 ppc64le s390x
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
||||
path: ./wheelhouse/*.whl
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
linux:
|
||||
image: python:3.8
|
||||
image: python:3.12
|
||||
# make a docker daemon available for cibuildwheel to use
|
||||
services:
|
||||
- name: docker:dind
|
||||
@@ -12,7 +12,7 @@ linux:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
script:
|
||||
- curl -sSL https://get.docker.com/ | sh
|
||||
- python -m pip install cibuildwheel==2.16.0
|
||||
- python -m pip install cibuildwheel==2.20.0
|
||||
- cibuildwheel --output-dir wheelhouse
|
||||
artifacts:
|
||||
paths:
|
||||
@@ -21,13 +21,25 @@ linux:
|
||||
windows:
|
||||
image: mcr.microsoft.com/windows/servercore:1809
|
||||
before_script:
|
||||
- choco install python -y --version 3.8.6
|
||||
- choco install python -y --version 3.12.4
|
||||
- choco install git.install -y
|
||||
- py -m pip install cibuildwheel==2.16.0
|
||||
- py -m pip install cibuildwheel==2.20.0
|
||||
script:
|
||||
- py -m cibuildwheel --output-dir wheelhouse --platform windows
|
||||
artifacts:
|
||||
paths:
|
||||
- wheelhouse/
|
||||
tags:
|
||||
- windows
|
||||
- saas-windows-medium-amd64
|
||||
|
||||
macos:
|
||||
image: macos-14-xcode-15
|
||||
before_script:
|
||||
- python3 -m pip install cibuildwheel==2.20.0
|
||||
script:
|
||||
- python3 -m cibuildwheel --output-dir wheelhouse
|
||||
artifacts:
|
||||
paths:
|
||||
- wheelhouse/
|
||||
tags:
|
||||
- saas-macos-medium-m1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
linux:
|
||||
image: python:3.8
|
||||
image: python:3.12
|
||||
# make a docker daemon available for cibuildwheel to use
|
||||
services:
|
||||
- name: docker:dind
|
||||
@@ -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==2.16.0
|
||||
- python -m pip install cibuildwheel==2.20.0
|
||||
# Assuming your CI runner's default architecture is x86_64...
|
||||
- cibuildwheel --output-dir wheelhouse --platform linux --archs aarch64
|
||||
artifacts:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
os: linux
|
||||
dist: focal
|
||||
language: python
|
||||
python: "3.9"
|
||||
python: "3.12"
|
||||
|
||||
jobs:
|
||||
include:
|
||||
@@ -14,13 +14,13 @@ jobs:
|
||||
- os: windows
|
||||
language: shell
|
||||
before_install:
|
||||
- choco upgrade python -y --version 3.8.6
|
||||
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
||||
- 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/Python38/python.exe /c/Python38/python3.exe
|
||||
- ln -s /c/Python312/python.exe /c/Python312/python3.exe
|
||||
|
||||
install:
|
||||
- python3 -m pip install cibuildwheel==2.16.0
|
||||
- python3 -m pip install cibuildwheel==2.20.0
|
||||
|
||||
script:
|
||||
# build the wheels, put them into './dist'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
os: linux
|
||||
dist: focal
|
||||
language: python
|
||||
python: "3.9"
|
||||
python: "3.12"
|
||||
|
||||
jobs:
|
||||
include:
|
||||
@@ -20,13 +20,13 @@ jobs:
|
||||
- os: windows
|
||||
language: shell
|
||||
before_install:
|
||||
- choco upgrade python -y --version 3.8.6
|
||||
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
||||
- 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/Python38/python.exe /c/Python38/python3.exe
|
||||
- ln -s /c/Python312/python.exe /c/Python312/python3.exe
|
||||
|
||||
install:
|
||||
- python3 -m pip install cibuildwheel==2.16.0
|
||||
- python3 -m pip install cibuildwheel==2.20.0
|
||||
|
||||
script:
|
||||
# build the wheels, put them into './wheelhouse'
|
||||
|
||||
@@ -8,17 +8,15 @@
|
||||
os: linux
|
||||
dist: focal
|
||||
language: python
|
||||
python:
|
||||
- 3.7
|
||||
- 3.8
|
||||
python: "3.12"
|
||||
|
||||
before_install:
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" = windows ]]; then
|
||||
choco upgrade python -y --version 3.8.6
|
||||
export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
||||
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/Python38/python.exe /c/Python38/python3.exe
|
||||
ln -s /c/Python312/python.exe /c/Python312/python3.exe
|
||||
fi
|
||||
|
||||
install:
|
||||
@@ -54,7 +52,7 @@ jobs:
|
||||
- stage: deploy
|
||||
name: Build and deploy Linux wheels
|
||||
services: docker
|
||||
install: python3 -m pip install cibuildwheel==2.16.0 twine
|
||||
install: python3 -m pip install cibuildwheel==2.20.0 twine
|
||||
script: python3 -m cibuildwheel --output-dir wheelhouse
|
||||
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
|
||||
# Deploy on windows
|
||||
@@ -62,7 +60,7 @@ jobs:
|
||||
name: Build and deploy Windows wheels
|
||||
os: windows
|
||||
language: shell
|
||||
install: python3 -m pip install cibuildwheel==2.16.0 twine
|
||||
install: python3 -m pip install cibuildwheel==2.20.0 twine
|
||||
script: python3 -m cibuildwheel --output-dir wheelhouse
|
||||
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
|
||||
|
||||
|
||||
@@ -49,3 +49,5 @@ plugins:
|
||||
module_name: docs/main
|
||||
j2_variable_start_string: «
|
||||
j2_variable_end_string: »
|
||||
on_error_fail: true
|
||||
on_undefined: strict
|
||||
|
||||
+84
-44
@@ -4,17 +4,21 @@ import os
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import nox
|
||||
|
||||
nox.needs_version = ">=2024.4.15"
|
||||
nox.options.sessions = ["lint", "pylint", "check_manifest", "tests"]
|
||||
|
||||
PYTHON_ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
nox.options.default_venv_backend = "uv|virtualenv"
|
||||
|
||||
DIR = Path(__file__).parent.resolve()
|
||||
|
||||
if os.environ.get("CI", None):
|
||||
nox.options.error_on_missing_interpreters = True
|
||||
|
||||
def install_and_run(session: nox.Session, script: str, *args: str, **kwargs: Any) -> str | None:
|
||||
deps = nox.project.load_toml(script)["dependencies"]
|
||||
session.install(*deps)
|
||||
return session.run("python", script, *args, **kwargs)
|
||||
|
||||
|
||||
@nox.session
|
||||
@@ -22,11 +26,11 @@ def tests(session: nox.Session) -> None:
|
||||
"""
|
||||
Run the unit and regular tests.
|
||||
"""
|
||||
unit_test_args = ["--run-docker"] if sys.platform.startswith("linux") else []
|
||||
session.install("-e", ".[test]")
|
||||
session.install("-e.[test]")
|
||||
if session.posargs:
|
||||
session.run("pytest", *session.posargs)
|
||||
else:
|
||||
unit_test_args = ["--run-docker"] if sys.platform.startswith("linux") else []
|
||||
session.run("pytest", "unit_test", *unit_test_args)
|
||||
session.run("pytest", "test", "-x", "--durations", "0", "--timeout=2400", "test")
|
||||
|
||||
@@ -46,7 +50,7 @@ def pylint(session: nox.Session) -> None:
|
||||
Run pylint.
|
||||
"""
|
||||
|
||||
session.install("pylint", ".")
|
||||
session.install("pylint>=3.2", "-e.")
|
||||
session.run("pylint", "cibuildwheel", *session.posargs)
|
||||
|
||||
|
||||
@@ -60,31 +64,57 @@ def check_manifest(session: nox.Session) -> None:
|
||||
session.run("check-manifest", *session.posargs)
|
||||
|
||||
|
||||
@nox.session(python=PYTHON_ALL_VERSIONS)
|
||||
@nox.session
|
||||
def update_constraints(session: nox.Session) -> None:
|
||||
"""
|
||||
Update the dependencies inplace.
|
||||
"""
|
||||
session.install("pip-tools")
|
||||
assert isinstance(session.python, str)
|
||||
python_version = session.python.replace(".", "")
|
||||
env = os.environ.copy()
|
||||
# CUSTOM_COMPILE_COMMAND is a pip-compile option that tells users how to
|
||||
# regenerate the constraints files
|
||||
env["CUSTOM_COMPILE_COMMAND"] = f"nox -s {session.name}"
|
||||
session.run(
|
||||
"pip-compile",
|
||||
"--allow-unsafe",
|
||||
"--upgrade",
|
||||
"cibuildwheel/resources/constraints.in",
|
||||
f"--output-file=cibuildwheel/resources/constraints-python{python_version}.txt",
|
||||
env=env,
|
||||
|
||||
resources = Path("cibuildwheel/resources")
|
||||
|
||||
if session.venv_backend != "uv":
|
||||
session.install("uv>=0.1.23")
|
||||
|
||||
for minor_version in range(7, 14):
|
||||
python_version = f"3.{minor_version}"
|
||||
env = os.environ.copy()
|
||||
# CUSTOM_COMPILE_COMMAND is a pip-compile option that tells users how to
|
||||
# regenerate the constraints files
|
||||
env["UV_CUSTOM_COMPILE_COMMAND"] = f"nox -s {session.name}"
|
||||
output_file = resources / f"constraints-python{python_version.replace('.', '')}.txt"
|
||||
session.run(
|
||||
"uv",
|
||||
"pip",
|
||||
"compile",
|
||||
f"--python-version={python_version}",
|
||||
"--upgrade",
|
||||
resources / "constraints.in",
|
||||
f"--output-file={output_file}",
|
||||
env=env,
|
||||
)
|
||||
|
||||
shutil.copyfile(
|
||||
resources / "constraints-python312.txt",
|
||||
resources / "constraints.txt",
|
||||
)
|
||||
if session.python == PYTHON_ALL_VERSIONS[-1]:
|
||||
RESOURCES = DIR / "cibuildwheel" / "resources"
|
||||
shutil.copyfile(
|
||||
RESOURCES / f"constraints-python{python_version}.txt",
|
||||
RESOURCES / "constraints.txt",
|
||||
|
||||
build_platforms = nox.project.load_toml(resources / "build-platforms.toml")
|
||||
pyodides = build_platforms["pyodide"]["python_configurations"]
|
||||
for pyodide in pyodides:
|
||||
python_version = ".".join(pyodide["version"].split(".")[:2])
|
||||
pyodide_version = pyodide["pyodide_version"]
|
||||
output_file = resources / f"constraints-pyodide{python_version.replace('.', '')}.txt"
|
||||
tmp_file = Path(session.create_tmp()) / "constraints-pyodide.in"
|
||||
tmp_file.write_text(f"pip\nbuild[virtualenv]\npyodide-build=={pyodide_version}")
|
||||
session.run(
|
||||
"uv",
|
||||
"pip",
|
||||
"compile",
|
||||
f"--python-version={python_version}",
|
||||
"--upgrade",
|
||||
tmp_file,
|
||||
f"--output-file={output_file}",
|
||||
env=env,
|
||||
)
|
||||
|
||||
|
||||
@@ -93,41 +123,51 @@ def update_pins(session: nox.Session) -> None:
|
||||
"""
|
||||
Update the python, docker and virtualenv pins version inplace.
|
||||
"""
|
||||
session.install("-e", ".[bin]")
|
||||
session.install("-e.[bin]")
|
||||
session.run("python", "bin/update_pythons.py", "--force")
|
||||
session.run("python", "bin/update_docker.py")
|
||||
session.run("python", "bin/update_virtualenv.py", "--force")
|
||||
session.run("python", "bin/update_nodejs.py", "--force")
|
||||
|
||||
|
||||
@nox.session
|
||||
@nox.session(reuse_venv=True)
|
||||
def update_proj(session: nox.Session) -> None:
|
||||
"""
|
||||
Update the README inplace.
|
||||
"""
|
||||
session.install("-e", ".[bin]")
|
||||
session.run(
|
||||
"python",
|
||||
install_and_run(
|
||||
session,
|
||||
"bin/projects.py",
|
||||
"docs/data/projects.yml",
|
||||
*session.posargs,
|
||||
)
|
||||
|
||||
|
||||
@nox.session(python="3.9")
|
||||
@nox.session(reuse_venv=True)
|
||||
def generate_schema(session: nox.Session) -> None:
|
||||
"""
|
||||
Generate the cibuildwheel.schema.json file.
|
||||
"""
|
||||
output = install_and_run(session, "bin/generate_schema.py", silent=True)
|
||||
assert isinstance(output, str)
|
||||
DIR.joinpath("cibuildwheel/resources/cibuildwheel.schema.json").write_text(output)
|
||||
|
||||
|
||||
@nox.session(reuse_venv=True)
|
||||
def bump_version(session: nox.Session) -> None:
|
||||
"""
|
||||
Bump cibuildwheel's version. Interactive.
|
||||
"""
|
||||
install_and_run(session, "bin/bump_version.py")
|
||||
|
||||
|
||||
@nox.session(python="3.12")
|
||||
def docs(session: nox.Session) -> None:
|
||||
"""
|
||||
Build the docs.
|
||||
Build the docs. Will serve unless --non-interactive
|
||||
"""
|
||||
session.install("-e", ".[docs]")
|
||||
session.run("pip", "list")
|
||||
|
||||
if session.posargs:
|
||||
if "serve" in session.posargs:
|
||||
session.run("mkdocs", "serve")
|
||||
else:
|
||||
session.error("Unrecognized args, use 'serve'")
|
||||
else:
|
||||
session.run("mkdocs", "build")
|
||||
session.install("-e.[docs]")
|
||||
session.run("mkdocs", "serve" if session.interactive else "build", "--strict", *session.posargs)
|
||||
|
||||
|
||||
@nox.session
|
||||
|
||||
+109
-30
@@ -1,14 +1,96 @@
|
||||
[build-system]
|
||||
requires = [
|
||||
"setuptools>=42",
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "cibuildwheel"
|
||||
version = "2.20.0"
|
||||
description = "Build Python wheels on CI with minimal configuration."
|
||||
readme = "README.md"
|
||||
license = "BSD-2-Clause"
|
||||
requires-python = ">=3.8"
|
||||
authors = [
|
||||
{ name = "Joe Rickerby", email = "joerick@mac.com" },
|
||||
]
|
||||
keywords = [
|
||||
"appveyor",
|
||||
"ci",
|
||||
"linux",
|
||||
"macos",
|
||||
"packaging",
|
||||
"pypi",
|
||||
"travis",
|
||||
"wheel",
|
||||
"windows",
|
||||
]
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Natural Language :: English",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Topic :: Software Development :: Build Tools",
|
||||
]
|
||||
dependencies = [
|
||||
"bashlex!=0.13",
|
||||
"bracex",
|
||||
"certifi",
|
||||
"filelock",
|
||||
"packaging>=20.9",
|
||||
"platformdirs",
|
||||
"tomli;python_version < '3.11'",
|
||||
"typing-extensions>=4.1.0;python_version < '3.11'",
|
||||
]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project.optional-dependencies]
|
||||
bin = [
|
||||
"click",
|
||||
"packaging>=21.0",
|
||||
"pip-tools",
|
||||
"pygithub",
|
||||
"pyyaml",
|
||||
"requests",
|
||||
"rich>=9.6",
|
||||
]
|
||||
dev = [
|
||||
"cibuildwheel[test,bin]",
|
||||
]
|
||||
docs = [
|
||||
"jinja2>=3.1.2",
|
||||
"mkdocs-include-markdown-plugin==2.8.0",
|
||||
"mkdocs-macros-plugin",
|
||||
"mkdocs==1.3.1",
|
||||
"pymdown-extensions",
|
||||
]
|
||||
test = [
|
||||
"build",
|
||||
"jinja2",
|
||||
"pytest-timeout",
|
||||
"pytest-xdist",
|
||||
"pytest>=6",
|
||||
"setuptools",
|
||||
"tomli_w",
|
||||
"validate-pyproject",
|
||||
]
|
||||
uv = ["uv"]
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
target-version = ['py38', 'py39', 'py310', 'py311']
|
||||
[project.scripts]
|
||||
cibuildwheel = "cibuildwheel.__main__:main"
|
||||
|
||||
[project.entry-points."validate_pyproject.tool_schema"]
|
||||
cibuildwheel = "cibuildwheel.schema:get_schema"
|
||||
|
||||
[project.urls]
|
||||
Changelog = "https://github.com/pypa/cibuildwheel#changelog"
|
||||
Documentation = "https://cibuildwheel.pypa.io"
|
||||
Homepage = "https://github.com/pypa/cibuildwheel"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "6.0"
|
||||
@@ -20,7 +102,7 @@ log_cli_level = "info"
|
||||
|
||||
|
||||
[tool.mypy]
|
||||
python_version = 3.8
|
||||
python_version = "3.8"
|
||||
files = [
|
||||
"cibuildwheel/*.py",
|
||||
"test/**/*.py",
|
||||
@@ -29,7 +111,6 @@ files = [
|
||||
"noxfile.py",
|
||||
]
|
||||
warn_unused_configs = true
|
||||
show_error_codes = true
|
||||
|
||||
warn_redundant_casts = true
|
||||
no_implicit_reexport = true
|
||||
@@ -55,6 +136,8 @@ disallow_untyped_decorators = true
|
||||
[[tool.mypy.overrides]]
|
||||
module = [
|
||||
"setuptools",
|
||||
"setuptools._distutils", # needed even if only directly import setuptools._distutils.util
|
||||
"setuptools._distutils.util",
|
||||
"pytest", # ignored in pre-commit to speed up check
|
||||
"bashlex",
|
||||
"bashlex.*",
|
||||
@@ -63,21 +146,6 @@ module = [
|
||||
ignore_missing_imports = true
|
||||
|
||||
|
||||
[tool.check-manifest]
|
||||
ignore = [
|
||||
".*",
|
||||
".circleci/**",
|
||||
"test/**",
|
||||
"unit_test/**",
|
||||
"docs/**",
|
||||
"examples/**",
|
||||
"bin/**",
|
||||
"*.yml",
|
||||
"CI.md", # TODO: can change test/test_ssl and remove this
|
||||
"requirements-dev.txt",
|
||||
"noxfile.py",
|
||||
]
|
||||
|
||||
[tool.pylint]
|
||||
py-version = "3.8"
|
||||
jobs = "0"
|
||||
@@ -112,11 +180,16 @@ messages_control.disable = [
|
||||
"wrong-import-position",
|
||||
"unused-argument", # Handled by Ruff
|
||||
"broad-exception-raised", # Could be improved eventually
|
||||
"consider-using-in", # MyPy can't narrow "in"
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
select = [
|
||||
"E", "F", "W", # flake8
|
||||
target-version = "py38"
|
||||
line-length = 100
|
||||
|
||||
|
||||
[tool.ruff.lint]
|
||||
extend-select = [
|
||||
"B", # flake8-bugbear
|
||||
"I", # isort
|
||||
"ARG", # flake8-unused-arguments
|
||||
@@ -136,19 +209,21 @@ select = [
|
||||
"UP", # pyupgrade
|
||||
"YTT", # flake8-2020
|
||||
"EXE", # flake8-executable
|
||||
"PYI", # flake8-pyi
|
||||
]
|
||||
extend-ignore = [
|
||||
ignore = [
|
||||
"PLR", # Design related pylint codes
|
||||
"E501", # Line too long
|
||||
"RET504", "RET505", "RET508", # else after control flow
|
||||
"PT004", # Rename suggested for returnless fixtures
|
||||
"PT007", # False positive (fixed upstream)
|
||||
"PT007", # False positive
|
||||
"PYI025", # Set as AbstractSet
|
||||
"ISC001", # Conflicts with formatter
|
||||
]
|
||||
target-version = "py38"
|
||||
typing-modules = ["cibuildwheel._compat.typing"]
|
||||
flake8-unused-arguments.ignore-variadic-names = true
|
||||
|
||||
[tool.ruff.flake8-tidy-imports.banned-api]
|
||||
[tool.ruff.lint.flake8-tidy-imports.banned-api]
|
||||
"typing.Mapping".msg = "Use collections.abc.Mapping instead."
|
||||
"typing.Callable".msg = "Use collections.abc.Callable instead."
|
||||
"typing.Iterator".msg = "Use collections.abc.Iterator instead."
|
||||
@@ -159,6 +234,10 @@ flake8-unused-arguments.ignore-variadic-names = true
|
||||
"tomllib".msg = "Use cibuildwheel._compat.tomllib instead."
|
||||
"tomli".msg = "Use cibuildwheel._compat.tomllib instead."
|
||||
|
||||
[tool.ruff.per-file-ignores]
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"unit_test/*" = ["PLC1901"]
|
||||
"cibuildwheel/_compat/**.py" = ["TID251"]
|
||||
"bin/*" = ["TID251"]
|
||||
|
||||
[tool.repo-review]
|
||||
ignore = ["PC170", "PP303"]
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
[metadata]
|
||||
name = cibuildwheel
|
||||
version = 2.16.0
|
||||
description = Build Python wheels on CI with minimal configuration.
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown
|
||||
url = https://github.com/pypa/cibuildwheel
|
||||
author = Joe Rickerby
|
||||
author_email = joerick@mac.com
|
||||
license = BSD-2-Clause
|
||||
license_files = LICENSE
|
||||
classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: BSD License
|
||||
Natural Language :: English
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Topic :: Software Development :: Build Tools
|
||||
keywords = ci,wheel,packaging,pypi,travis,appveyor,macos,linux,windows
|
||||
project_urls =
|
||||
Changelog=https://github.com/pypa/cibuildwheel#changelog
|
||||
Documentation=https://cibuildwheel.readthedocs.io/
|
||||
|
||||
[options]
|
||||
packages = find:
|
||||
install_requires =
|
||||
bashlex!=0.13
|
||||
bracex
|
||||
certifi
|
||||
filelock
|
||||
packaging>=20.9
|
||||
platformdirs
|
||||
tomli;python_version < '3.11'
|
||||
typing-extensions>=4.1.0;python_version < '3.11'
|
||||
python_requires = >=3.8
|
||||
include_package_data = True
|
||||
zip_safe = False
|
||||
|
||||
[options.packages.find]
|
||||
include =
|
||||
cibuildwheel
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
cibuildwheel = cibuildwheel.__main__:main
|
||||
|
||||
[options.package_data]
|
||||
cibuildwheel = resources/*
|
||||
@@ -1,37 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
extras = {
|
||||
"docs": [
|
||||
"mkdocs-include-markdown-plugin==2.8.0",
|
||||
"mkdocs==1.3.1",
|
||||
"jinja2>=3.1.2",
|
||||
"pymdown-extensions",
|
||||
"mkdocs-macros-plugin",
|
||||
],
|
||||
"test": [
|
||||
"jinja2",
|
||||
"pytest>=6",
|
||||
"pytest-timeout",
|
||||
"pytest-xdist",
|
||||
"build",
|
||||
"tomli_w",
|
||||
],
|
||||
"bin": [
|
||||
"click",
|
||||
"pip-tools",
|
||||
"pygithub",
|
||||
"pyyaml",
|
||||
"requests",
|
||||
"rich>=9.6",
|
||||
"packaging>=21.0",
|
||||
],
|
||||
}
|
||||
|
||||
extras["dev"] = [
|
||||
*extras["test"],
|
||||
*extras["bin"],
|
||||
]
|
||||
|
||||
setup(extras_require=extras)
|
||||
+25
-14
@@ -6,14 +6,18 @@ from typing import Generator
|
||||
|
||||
import pytest
|
||||
|
||||
from cibuildwheel.util import detect_ci_provider
|
||||
from cibuildwheel.util import detect_ci_provider, find_uv
|
||||
|
||||
from .utils import platform
|
||||
from .utils import EMULATED_ARCHS, platform
|
||||
|
||||
|
||||
def pytest_addoption(parser) -> None:
|
||||
parser.addoption(
|
||||
"--run-emulation", action="store_true", default=False, help="run emulation tests"
|
||||
"--run-emulation",
|
||||
action="store",
|
||||
default=None,
|
||||
help="run emulation tests",
|
||||
choices=("all", *EMULATED_ARCHS),
|
||||
)
|
||||
parser.addoption("--run-podman", action="store_true", default=False, help="run podman tests")
|
||||
parser.addoption(
|
||||
@@ -24,16 +28,29 @@ def pytest_addoption(parser) -> None:
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=[{"CIBW_BUILD_FRONTEND": "pip"}, {"CIBW_BUILD_FRONTEND": "build"}], ids=["pip", "build"]
|
||||
)
|
||||
def build_frontend_env(request) -> dict[str, str]:
|
||||
return request.param # type: ignore[no-any-return]
|
||||
@pytest.fixture(params=["pip", "build"])
|
||||
def build_frontend_env_nouv(request: pytest.FixtureRequest) -> dict[str, str]:
|
||||
frontend = request.param
|
||||
if platform == "pyodide" and frontend == "pip":
|
||||
pytest.skip("Can't use pip as build frontend for pyodide platform")
|
||||
|
||||
return {"CIBW_BUILD_FRONTEND": frontend}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def build_frontend_env(build_frontend_env_nouv: dict[str, str]) -> dict[str, str]:
|
||||
frontend = build_frontend_env_nouv["CIBW_BUILD_FRONTEND"]
|
||||
if frontend != "build" or platform == "pyodide" or find_uv() is None:
|
||||
return build_frontend_env_nouv
|
||||
|
||||
return {"CIBW_BUILD_FRONTEND": "build[uv]"}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def docker_cleanup() -> Generator[None, None, None]:
|
||||
def get_images() -> set[str]:
|
||||
if detect_ci_provider() is None or platform != "linux":
|
||||
return set()
|
||||
images = subprocess.run(
|
||||
["docker", "image", "ls", "--format", "{{json .ID}}"],
|
||||
text=True,
|
||||
@@ -42,12 +59,6 @@ def docker_cleanup() -> Generator[None, None, None]:
|
||||
).stdout
|
||||
return {json.loads(image.strip()) for image in images.splitlines() if image.strip()}
|
||||
|
||||
if detect_ci_provider() is None or platform != "linux":
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
pass
|
||||
return
|
||||
images_before = get_images()
|
||||
try:
|
||||
yield
|
||||
|
||||
+11
-3
@@ -69,7 +69,15 @@ def test_build_identifiers(tmp_path):
|
||||
), f"{expected_wheels} vs {build_identifiers}"
|
||||
|
||||
|
||||
def test_allow_empty(tmp_path):
|
||||
@pytest.mark.parametrize(
|
||||
("add_args", "env_allow_empty"),
|
||||
[
|
||||
(["--allow-empty"], {}),
|
||||
(["--allow-empty"], {"CIBW_ALLOW_EMPTY": "0"}),
|
||||
(None, {"CIBW_ALLOW_EMPTY": "1"}),
|
||||
],
|
||||
)
|
||||
def test_allow_empty(tmp_path, add_args, env_allow_empty):
|
||||
project_dir = tmp_path / "project"
|
||||
basic_project.generate(project_dir)
|
||||
|
||||
@@ -77,8 +85,8 @@ def test_allow_empty(tmp_path):
|
||||
# without error
|
||||
actual_wheels = utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
add_env={"CIBW_BUILD": "BUILD_NOTHING_AT_ALL"},
|
||||
add_args=["--allow-empty"],
|
||||
add_env={"CIBW_BUILD": "BUILD_NOTHING_AT_ALL", **env_allow_empty},
|
||||
add_args=add_args,
|
||||
)
|
||||
|
||||
# check that nothing was built
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user