Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7da7df1efc | ||
|
|
9deb1b6794 | ||
|
|
271c5fe6e4 | ||
|
|
c716cfaeb8 | ||
|
|
099d397aee | ||
|
|
72222654f4 | ||
|
|
7a8b8012ff | ||
|
|
0ccf1dc016 | ||
|
|
ba11212a13 | ||
|
|
6d0890e7e0 | ||
|
|
cf7586ce7e | ||
|
|
137dc1a2cf | ||
|
|
1646b08659 | ||
|
|
a873dd9cbf | ||
|
|
e8ba0d49ed | ||
|
|
f0feaffbaa | ||
|
|
80a54b0226 | ||
|
|
76dba0b9ba | ||
|
|
0954ffaa65 | ||
|
|
753cbd1ca5 | ||
|
|
825d89818a | ||
|
|
f5e60d647f | ||
|
|
adc991c47b | ||
|
|
cc50337ecd | ||
|
|
db6d3095b9 | ||
|
|
f6a95d3d0b | ||
|
|
028455f481 | ||
|
|
05d5c9bada | ||
|
|
f34ae7731d | ||
|
|
4f888e27c3 | ||
|
|
e5d0cc0b0d | ||
|
|
a449142802 | ||
|
|
82a1f99268 | ||
|
|
1280565f7f | ||
|
|
386d36f5ad | ||
|
|
be0e07ac31 | ||
|
|
001f11c755 | ||
|
|
5f37a3bb02 | ||
|
|
5311f88684 | ||
|
|
81ef5fac43 | ||
|
|
53b641caaf | ||
|
|
ae6b3d40b5 | ||
|
|
061ea627e2 | ||
|
|
297e4a6099 | ||
|
|
e8bb208374 | ||
|
|
18ff2c57c2 | ||
|
|
98b83afe63 | ||
|
|
25428deff2 | ||
|
|
ce71f445de | ||
|
|
12d548865f | ||
|
|
9afd31017a | ||
|
|
7508943e06 | ||
|
|
26c5e18e62 | ||
|
|
c655dbdaab | ||
|
|
39a63b5912 | ||
|
|
47e5d3c2cd | ||
|
|
a63e11a1c4 | ||
|
|
df94b5db67 | ||
|
|
8946bfb2e8 | ||
|
|
36049d86a2 | ||
|
|
229f8570b4 | ||
|
|
5b32ee7d7b | ||
|
|
3f3bd9cff6 | ||
|
|
8df6d59adf | ||
|
|
4135c0a01d | ||
|
|
6282bc5a83 | ||
|
|
ddbcf561db | ||
|
|
f21bb8376a | ||
|
|
a5b2e543e5 | ||
|
|
bd9675d05b | ||
|
|
661ba2d0de | ||
|
|
66b46d0868 | ||
|
|
b0a5c951f5 | ||
|
|
f5960020cd | ||
|
|
8bfc92df50 | ||
|
|
9afee48243 | ||
|
|
7f6fe8a031 | ||
|
|
c824c7e87a | ||
|
|
f44d2784f8 | ||
|
|
740f081606 | ||
|
|
8c6ff25315 | ||
|
|
b77cedba39 | ||
|
|
6415878631 | ||
|
|
ac34701e98 | ||
|
|
4b19db8454 | ||
|
|
af42be1f3b | ||
|
|
aeb0a3ee83 | ||
|
|
33f02f2e1d | ||
|
|
062a745fc9 | ||
|
|
b8a3cfa4f9 | ||
|
|
cee0848b49 | ||
|
|
2b769c9052 | ||
|
|
8f569c42ec | ||
|
|
28b03782f8 | ||
|
|
5ef9f081bd | ||
|
|
1ce209198a | ||
|
|
3192cdcbfa | ||
|
|
983347f370 | ||
|
|
b1929b7eaf | ||
|
|
0a7800c9d9 | ||
|
|
43cb682c24 | ||
|
|
c9e0981955 | ||
|
|
aae0524f8a | ||
|
|
ada476e3c1 | ||
|
|
0ecddd92b6 | ||
|
|
f35d309173 | ||
|
|
3160e8dbca | ||
|
|
012ae48172 | ||
|
|
1c3b8e112e | ||
|
|
ca7b0f75c6 | ||
|
|
8d126bc281 | ||
|
|
2ca5ff2dcd | ||
|
|
7d45cf3dac | ||
|
|
f6edc817df | ||
|
|
3fa6615e92 | ||
|
|
d9ca5fa476 | ||
|
|
89aea5681c | ||
|
|
dd4c36f68a | ||
|
|
3cf96726f6 | ||
|
|
51f5c7fe68 | ||
|
|
8499628a5b | ||
|
|
b2bc6fdda6 | ||
|
|
754a47388d | ||
|
|
f25c8a64f6 | ||
|
|
9b904777d4 | ||
|
|
e14b8e8e2f | ||
|
|
da9be0a27b | ||
|
|
301dca264f | ||
|
|
c74083cfda | ||
|
|
d16375e101 | ||
|
|
abc10b603b | ||
|
|
4a7aeffbf5 | ||
|
|
6bf13bff03 | ||
|
|
3486f0f207 | ||
|
|
580205affc | ||
|
|
2afeca62a1 | ||
|
|
bf5db55bfa | ||
|
|
e56b444cd8 | ||
|
|
5fdbbcbe3a | ||
|
|
635c64eeb7 | ||
|
|
f29da13c2c | ||
|
|
290a55097d | ||
|
|
bda7ff6351 | ||
|
|
da2726449c | ||
|
|
4b88d36b20 | ||
|
|
58c647acf0 | ||
|
|
7a7e53e8d4 | ||
|
|
5cb0964111 | ||
|
|
de419eef44 | ||
|
|
d7759bf876 | ||
|
|
2bd344260e | ||
|
|
c2fb0e4e96 | ||
|
|
00f6526ff5 | ||
|
|
7efc7dbb91 | ||
|
|
ba4a993591 | ||
|
|
f8ef7fa826 | ||
|
|
5e15bb25b4 | ||
|
|
52572ccdd0 | ||
|
|
c6027e4fc7 | ||
|
|
aff6dd5adc | ||
|
|
31bd9c9174 | ||
|
|
d996af554a | ||
|
|
e42f243b52 | ||
|
|
9f18d385cb | ||
|
|
dfbc6c3902 | ||
|
|
8c5f89c035 | ||
|
|
6d038dfbdf | ||
|
|
ec9919a088 | ||
|
|
1512427455 | ||
|
|
440e18c275 | ||
|
|
063161f5af | ||
|
|
2246313344 | ||
|
|
fdc0eae932 | ||
|
|
fa72100d49 | ||
|
|
7c9b837780 | ||
|
|
1c1df68a50 | ||
|
|
4a9d2a37a9 | ||
|
|
05bf46f059 | ||
|
|
420ef86679 | ||
|
|
ae0ac92167 | ||
|
|
26dd3f399e | ||
|
|
33f642dc0b | ||
|
|
3ed1b65b3e | ||
|
|
e0a01d9986 | ||
|
|
c0873c9198 | ||
|
|
374d786812 | ||
|
|
8a307031a9 | ||
|
|
0036ac5254 | ||
|
|
2f3949953a | ||
|
|
d018570bc4 | ||
|
|
bd5294b3f3 | ||
|
|
f16ccf4e3d | ||
|
|
e6c926f7f8 | ||
|
|
7c64170c33 | ||
|
|
177cb142b5 | ||
|
|
2d89ecc140 | ||
|
|
7106da2c6b | ||
|
|
03ece1f81d | ||
|
|
93e1464e6a | ||
|
|
6e4dfaefad | ||
|
|
a2efed2aeb | ||
|
|
8812101cc6 | ||
|
|
a6028923d6 | ||
|
|
cd6c1409fb | ||
|
|
e049c2bd83 | ||
|
|
37c749e507 | ||
|
|
04a0ca0e04 | ||
|
|
2c3e01287a | ||
|
|
b2d0292204 | ||
|
|
cd32569937 | ||
|
|
02ad79a31b | ||
|
|
1d6ee75d21 | ||
|
|
0b1b539450 | ||
|
|
2e48667e29 | ||
|
|
c6818608d2 | ||
|
|
7190b1a6a7 | ||
|
|
16380b8555 | ||
|
|
94efa61f76 | ||
|
|
acdbe87e3d | ||
|
|
49b736d1c7 | ||
|
|
c72e27e65a | ||
|
|
422509e168 | ||
|
|
a604902a76 | ||
|
|
fbebb732e6 | ||
|
|
ed320412b0 | ||
|
|
567fe2a923 | ||
|
|
c7643f08e7 | ||
|
|
a4ac064b0f | ||
|
|
c33d88a9d2 | ||
|
|
96cffc2c7c | ||
|
|
cc0bb5da34 | ||
|
|
5be1d17d5f | ||
|
|
f55b78bb31 | ||
|
|
7eefde5200 | ||
|
|
5ab3b55378 | ||
|
|
4ce2a3e157 | ||
|
|
b29a3c9e6f | ||
|
|
bc804d0a2b | ||
|
|
e42277a692 | ||
|
|
0ea495ecba | ||
|
|
c8b037ba3e | ||
|
|
80a8ec7f32 | ||
|
|
3420e4a61c | ||
|
|
a808017c39 | ||
|
|
4e1fcb8df6 | ||
|
|
4afa12ed06 | ||
|
|
92cb1d8990 | ||
|
|
06c4927798 | ||
|
|
9b0d63b2f4 | ||
|
|
6df156807a | ||
|
|
27fc88e638 | ||
|
|
a7e9ece1d4 | ||
|
|
b9a3ed8c6a | ||
|
|
3dcc2ff07e | ||
|
|
1c9ec7664e | ||
|
|
22b433dc5f | ||
|
|
98fdf8c269 | ||
|
|
cefc5a5a0a | ||
|
|
e53253d7d9 | ||
|
|
e9ecc65ca5 | ||
|
|
e8e31505f3 | ||
|
|
5be731dfd0 | ||
|
|
c8a2671f2d | ||
|
|
ff8e121fac | ||
|
|
41daa4bd26 | ||
|
|
a34a6b0f72 | ||
|
|
1e2cc2fc37 | ||
|
|
61b6cc8574 | ||
|
|
ecce3d9bf8 | ||
|
|
63ef1b00b7 | ||
|
|
ba9a82eae0 | ||
|
|
46372e1ff1 | ||
|
|
a157a51225 | ||
|
|
9850864851 | ||
|
|
56359fba70 | ||
|
|
99f62f53f9 | ||
|
|
a5c5f5e0f0 | ||
|
|
ec878dc393 | ||
|
|
b00547cd97 | ||
|
|
5c7fc8d7ca | ||
|
|
d5a237699b | ||
|
|
2420bda8c1 | ||
|
|
0c2c86f06b | ||
|
|
636ea18338 | ||
|
|
906ce0cd13 | ||
|
|
8f07b73fec | ||
|
|
2f500c2f77 | ||
|
|
c777af1f60 | ||
|
|
bbaed15c9a | ||
|
|
76e56f08f2 | ||
|
|
8d05681491 | ||
|
|
c417dce602 | ||
|
|
9c6416d4ac | ||
|
|
e139a77819 | ||
|
|
2d18de8aac | ||
|
|
bcbcba73b5 | ||
|
|
93134e21ae | ||
|
|
d9d4c050b8 | ||
|
|
4e1d18250b | ||
|
|
4ab5f48693 | ||
|
|
d34e6eb63b | ||
|
|
733563021e | ||
|
|
5bb2619054 | ||
|
|
e4cbe81f3f | ||
|
|
2e6cbe2435 | ||
|
|
5556a7ed28 | ||
|
|
546cb939be | ||
|
|
e772d48b94 | ||
|
|
e2f948c33c | ||
|
|
4786f528a9 |
@@ -1,3 +1,5 @@
|
||||
skip: changesIncludeOnly('docs/*', '.pre-commit-config.yaml')
|
||||
|
||||
run_tests: &RUN_TESTS
|
||||
install_cibuildwheel_script:
|
||||
- python -m pip install -e ".[dev]" pytest-custom-exit-code
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
* text=auto
|
||||
|
||||
*.py diff=python
|
||||
*.md diff=markdown
|
||||
|
||||
*.svg -diff
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
dist:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build SDist and wheel
|
||||
run: pipx run build
|
||||
@@ -27,6 +27,9 @@ jobs:
|
||||
needs: [dist]
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
environment: pypi
|
||||
permissions:
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
@@ -34,7 +37,4 @@ jobs:
|
||||
name: artifact
|
||||
path: dist
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@v1.5.1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_password }}
|
||||
- uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
||||
@@ -7,6 +7,7 @@ on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- .pre-commit-config.yaml
|
||||
workflow_dispatch:
|
||||
# allow manual runs on branches without a PR
|
||||
|
||||
@@ -19,7 +20,7 @@ jobs:
|
||||
name: Linters (mypy, flake8, etc.)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
@@ -37,11 +38,14 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-18.04, windows-latest, macos-11]
|
||||
os: [ubuntu-20.04, windows-latest, macos-11]
|
||||
python_version: ['3.11']
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
python_version: '3.8'
|
||||
timeout-minutes: 180
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
name: Install Python ${{ matrix.python_version }}
|
||||
with:
|
||||
@@ -56,9 +60,15 @@ jobs:
|
||||
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
|
||||
curl -sSfL "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
sudo apt-get -y upgrade
|
||||
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: |
|
||||
python -m pip install ".[test]"
|
||||
@@ -90,7 +100,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 180
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.x"
|
||||
@@ -100,7 +110,7 @@ jobs:
|
||||
|
||||
- name: Set up QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: all
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ jobs:
|
||||
update-dependencies:
|
||||
name: Update dependencies
|
||||
if: github.repository_owner == 'pypa' || github.event_name != 'schedule'
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: wntrblm/nox@2022.8.7
|
||||
- uses: wntrblm/nox@2023.04.22
|
||||
with:
|
||||
python-versions: "3.6, 3.7, 3.8, 3.9, 3.10, 3.11-dev"
|
||||
python-versions: "3.7, 3.8, 3.9, 3.10, 3.11, 3.12-dev"
|
||||
|
||||
- name: "Run update: dependencies"
|
||||
run: nox --force-color -s update_constraints
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
|
||||
# we use this step to grab a Github App auth token, so that PRs generated by this workflow
|
||||
# run the GHA tests.
|
||||
- uses: tibdex/github-app-token@v1
|
||||
- uses: tibdex/github-app-token@v2
|
||||
id: generate-token
|
||||
if: github.ref == 'refs/heads/main' && github.repository == 'pypa/cibuildwheel'
|
||||
with:
|
||||
@@ -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@v4
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: Update dependencies
|
||||
title: '[Bot] Update dependencies'
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
name: Update the vX.Y tag
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
TAG_NAME:
|
||||
description: 'Tag name that the major.minor tag will point to'
|
||||
required: true
|
||||
|
||||
env:
|
||||
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
||||
|
||||
jobs:
|
||||
update_tag:
|
||||
name: Update the major.minor tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
||||
environment:
|
||||
name: releaseNewActionVersion
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
id: update-major-minor-tag
|
||||
uses: joerick/update-vX.Y-tag-action@v1.0
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
@@ -26,7 +26,6 @@ windows:
|
||||
- choco install python -y --version 3.8.6
|
||||
script:
|
||||
- py -m pip install -e ".[dev]" pytest-custom-exit-code
|
||||
- py -m cibuildwheel --output-dir wheelhouse --platform windows
|
||||
- py bin\run_tests.py
|
||||
tags:
|
||||
- windows
|
||||
|
||||
+20
-60
@@ -1,7 +1,7 @@
|
||||
repos:
|
||||
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.3.0
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-case-conflict
|
||||
- id: check-merge-conflict
|
||||
@@ -13,91 +13,51 @@ repos:
|
||||
- id: mixed-line-ending
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.1.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: ["--py37-plus"]
|
||||
exclude: ^cibuildwheel/resources/.*py$
|
||||
|
||||
# Autoremoves unused imports
|
||||
- repo: https://github.com/hadialqattan/pycln
|
||||
rev: v2.1.1
|
||||
hooks:
|
||||
- id: pycln
|
||||
args: [--all]
|
||||
stages: [manual]
|
||||
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.10.1
|
||||
hooks:
|
||||
- id: isort
|
||||
args: ["-a", "from __future__ import annotations"]
|
||||
exclude: ^cibuildwheel/resources/.*py$
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.10.0
|
||||
- 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.291
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: ["--fix", "--show-fixes"]
|
||||
|
||||
- repo: https://github.com/asottile/setup-cfg-fmt
|
||||
rev: v2.1.0
|
||||
rev: v2.4.0
|
||||
hooks:
|
||||
- id: setup-cfg-fmt
|
||||
args: [--include-version-classifiers, --max-py-version=3.11]
|
||||
args: [--include-version-classifiers, --min-py-version=3.8, --max-py-version=3.11]
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v0.982
|
||||
rev: v1.5.1
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy 3.7 on cibuildwheel/
|
||||
name: mypy 3.8 on cibuildwheel/
|
||||
exclude: ^cibuildwheel/resources/.*py$
|
||||
args: ["--python-version=3.7"]
|
||||
args: ["--python-version=3.8"]
|
||||
additional_dependencies: &mypy-dependencies
|
||||
- nox
|
||||
- packaging>=21.0
|
||||
- packaging
|
||||
- pygithub
|
||||
- rich
|
||||
- tomli
|
||||
- tomli_w
|
||||
- types-certifi
|
||||
- types-click
|
||||
- types-dataclasses
|
||||
- types-jinja2
|
||||
- types-pyyaml
|
||||
- types-requests
|
||||
- bracex
|
||||
- dataclasses
|
||||
- id: mypy
|
||||
name: mypy 3.10
|
||||
args: ["--python-version=3.10"]
|
||||
name: mypy 3.11
|
||||
exclude: ^cibuildwheel/resources/.*py$
|
||||
args: ["--python-version=3.11"]
|
||||
additional_dependencies: *mypy-dependencies
|
||||
|
||||
- repo: https://github.com/asottile/yesqa
|
||||
rev: v1.4.0
|
||||
hooks:
|
||||
- id: yesqa
|
||||
additional_dependencies: &flake8-dependencies
|
||||
- flake8-bugbear
|
||||
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 5.0.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
exclude: ^cibuildwheel/resources/
|
||||
additional_dependencies: *flake8-dependencies
|
||||
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.9.0
|
||||
hooks:
|
||||
- id: python-check-blanket-noqa
|
||||
stages: [manual]
|
||||
- id: python-no-log-warn
|
||||
- id: python-no-eval
|
||||
- id: python-use-type-annotations
|
||||
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.8.0.4
|
||||
rev: v0.9.0.5
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
|
||||
@@ -117,7 +77,7 @@ repos:
|
||||
files: ^docs/changelog.md$
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.2
|
||||
rev: v2.2.5
|
||||
hooks:
|
||||
- id: codespell
|
||||
args: ["-L", "sur"]
|
||||
|
||||
+7
-3
@@ -2,13 +2,17 @@
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
version: 2
|
||||
|
||||
mkdocs:
|
||||
configuration: mkdocs.yml
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
|
||||
python:
|
||||
version: 3.8
|
||||
install:
|
||||
- method: pip
|
||||
path: .
|
||||
extra_requirements:
|
||||
- docs
|
||||
|
||||
mkdocs:
|
||||
configuration: mkdocs.yml
|
||||
|
||||
+11
-13
@@ -8,21 +8,21 @@ branches:
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- name: Linux | x86_64 + i686 | Python 3.7
|
||||
python: 3.7
|
||||
- name: Linux | x86_64 + i686 | Python 3.9
|
||||
python: 3.9
|
||||
services: docker
|
||||
env: PYTHON=python
|
||||
|
||||
- name: Linux | arm64 | Python 3.7
|
||||
python: 3.7
|
||||
- name: Linux | arm64 | Python 3.9
|
||||
python: 3.9
|
||||
services: docker
|
||||
arch: arm64-graviton2
|
||||
group: edge
|
||||
virt: vm
|
||||
env: PYTHON=python
|
||||
|
||||
- name: Linux | ppc64le | Python 3.7
|
||||
python: 3.7
|
||||
- name: Linux | ppc64le | Python 3.9
|
||||
python: 3.9
|
||||
services: docker
|
||||
arch: ppc64le
|
||||
allow_failure: True
|
||||
@@ -32,18 +32,16 @@ jobs:
|
||||
# c.f. https://travis-ci.community/t/running-out-of-disk-space-quota-when-using-docker-on-ppc64le/11634
|
||||
- PYTEST_ADDOPTS='-k "not test_manylinuxXXXX_only"'
|
||||
|
||||
- name: Windows | x86_64 | Python 3.7
|
||||
- name: Windows | x86_64 | Python 3.9
|
||||
os: windows
|
||||
language: shell
|
||||
before_install:
|
||||
- choco upgrade python3 -y --version 3.7.9 --limit-output
|
||||
# Update root certificates to fix SSL error; see http://www.chawn.com/RootCerts.htm
|
||||
- powershell "md C:\temp\certs; CertUtil -generateSSTFromWU C:\temp\certs\RootStore.sst; Get-ChildItem -Path C:\\temp\certs\Rootstore.sst | Import-Certificate -CertStoreLocation Cert:\\LocalMachine\\Root\\ | out-null"
|
||||
- choco upgrade python3 -y --version 3.9.13 --limit-output --params "/InstallDir:C:\\Python39"
|
||||
env:
|
||||
- PYTHON=C:\\Python37\\python
|
||||
- PYTHON=C:\\Python39\\python
|
||||
|
||||
- name: Linux | s390x | Python 3.7
|
||||
python: 3.7
|
||||
- name: Linux | s390x | Python 3.9
|
||||
python: 3.9
|
||||
services: docker
|
||||
arch: s390x
|
||||
env: PYTHON=python
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
This is a summary of the Python versions and platforms covered by the different CI platforms:
|
||||
|
||||
| | 3.7 | 3.8 | 3.9 | 3.10 | 3.11 |
|
||||
|---------|-----------------------|--------------------------|----------|-----------|----------------|
|
||||
| Linux | AppVeyor¹ / Travis CI | Azure Pipelines / GitLab | CircleCI | Cirrus CI | GitHub Actions |
|
||||
| macOS | AppVeyor¹ / Travis CI | Azure Pipelines | CircleCI | Cirrus CI | GitHub Actions |
|
||||
| Windows | AppVeyor¹ / Travis CI | Azure Pipelines | | Cirrus CI | GitHub Actions |
|
||||
| | 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 |
|
||||
|
||||
> ¹ AppVeyor only runs the "basic" test to reduce load.
|
||||
> ¹ Runs a reduced set of tests to reduce CI load
|
||||
|
||||
Non-x86 architectures are covered on Travis CI using Python 3.7.
|
||||
Non-x86 architectures are covered on Travis CI using Python 3.9.
|
||||
|
||||
@@ -24,20 +24,24 @@ 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 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| 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 | N/A |
|
||||
| PyPy 3.9 v7.3 | ✅ | N/A | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
|
||||
|----------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|
|
||||
| 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 |
|
||||
|
||||
<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>
|
||||
|
||||
- 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
|
||||
@@ -87,13 +91,13 @@ jobs:
|
||||
os: [ubuntu-20.04, windows-2019, macOS-11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Used to host cibuildwheel
|
||||
- uses: actions/setup-python@v3
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: python -m pip install cibuildwheel==2.11.2
|
||||
run: python -m pip install cibuildwheel==2.16.1
|
||||
|
||||
- name: Build wheels
|
||||
run: python -m cibuildwheel --output-dir wheelhouse
|
||||
@@ -157,26 +161,26 @@ Here are some repos that use cibuildwheel.
|
||||
| Name | CI | OS | Notes |
|
||||
|-----------------------------------|----|----|:------|
|
||||
| [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. |
|
||||
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
|
||||
| [Tornado][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. |
|
||||
| [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 |
|
||||
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
|
||||
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
|
||||
| [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. |
|
||||
| [pydantic][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Data parsing and validation using Python type hints |
|
||||
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
|
||||
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
|
||||
| [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
|
||||
[NumPy]: https://github.com/numpy/numpy
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[pytorch-fairseq]: https://github.com/pytorch/fairseq
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[NCNN]: https://github.com/Tencent/ncnn
|
||||
[Kivy]: https://github.com/kivy/kivy
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
|
||||
[pydantic]: https://github.com/samuelcolvin/pydantic
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
[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
|
||||
@@ -209,50 +213,47 @@ Changelog
|
||||
|
||||
<!-- this section was generated by bin/update_readme_changelog.py -- do not edit manually -->
|
||||
|
||||
### v2.11.2
|
||||
### v2.16.1
|
||||
|
||||
_26 October 2022_
|
||||
_26 September 2023_
|
||||
|
||||
- 🛠 Updates CPython 3.11 to 3.11.0 - final release (#1327)
|
||||
- 🛠 Simplify the default macOS repair command (#1322)
|
||||
- 🛠 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)
|
||||
- 📚 Other docs improvements
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0rc3 (#1625)
|
||||
- 🛠 Only calls `linux32` in containers when necessary (#1599)
|
||||
|
||||
### v2.11.1
|
||||
### v2.16.0
|
||||
|
||||
_13 October 2022_
|
||||
_18 September 2023_
|
||||
|
||||
- 🛠 Updates to the latest manylinux images, and updates CPython 3.10 to 3.10.8.
|
||||
- ✨ 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.11.0
|
||||
### v2.15.0
|
||||
|
||||
_13 October 2022_
|
||||
_8 August 2023_
|
||||
|
||||
- 🌟 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 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)
|
||||
- ✨ Adds the ability to test `cp38-macosx_arm64` wheels on a native arm64 runner. To do this, you'll need to preinstall the (experimental) [universal2 version of CPython 3.8](https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg) on your arm64 runner before invoking cibuildwheel. Note: it is not recommended to build x86_64 wheels with this setup, your wheels will have limited compatibility wrt macOS versions. (#1283)
|
||||
- 🛠 Improved error messages when using custom Docker images and Python cannot be found at the correct path. (#1298)
|
||||
- 📚 Sample configs for Azure Pipelines and Travis CI updated (#1296)
|
||||
- 📚 Other docs improvements - including more information about using Homebrew for build dependencies (#1290)
|
||||
- 🌟 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.10.2
|
||||
### v2.14.1
|
||||
|
||||
_25 September 2022_
|
||||
_15 July 2023_
|
||||
|
||||
- 🐛 Fix a bug that caused `win32` identifiers to fail when used with `--only`. (#1282)
|
||||
- 🐛 Fix computation of `auto`/`auto64`/`auto32` archs when targeting a different platform to the one that you're running cibuildwheel on. (#1266)
|
||||
- 📚 Fix an mistake in the 'how it works' diagram. (#1274)
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0b4 (#1550)
|
||||
|
||||
### v2.10.1
|
||||
### v2.14.0
|
||||
|
||||
_18 September 2022_
|
||||
_10 July 2023_
|
||||
|
||||
- 🐛 Fix a bug that stopped environment variables specified in TOML from being expanded. (#1273)
|
||||
- ✨ 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)
|
||||
|
||||
<!-- END bin/update_readme_changelog.py -->
|
||||
|
||||
|
||||
+17
-3
@@ -28,7 +28,7 @@ runs:
|
||||
- uses: actions/setup-python@v4
|
||||
id: python
|
||||
with:
|
||||
python-version: "3.7 - 3.11"
|
||||
python-version: "3.8 - 3.11"
|
||||
update-environment: false
|
||||
|
||||
# Redirecting stderr to stdout to fix interleaving issue in Actions.
|
||||
@@ -37,9 +37,23 @@ runs:
|
||||
--python '${{ steps.python.outputs.python-path }}'
|
||||
--spec '${{ github.action_path }}'
|
||||
cibuildwheel
|
||||
${{ inputs.package-dir }}
|
||||
--output-dir ${{ inputs.output-dir }}
|
||||
"${{ inputs.package-dir }}"
|
||||
--output-dir "${{ inputs.output-dir }}"
|
||||
--config-file "${{ inputs.config-file }}"
|
||||
--only "${{ 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
|
||||
"${{ inputs.package-dir }}"
|
||||
--output-dir '"${{ inputs.output-dir }}"'
|
||||
--config-file '"${{ inputs.config-file }}"'
|
||||
--only '"${{ inputs.only }}"'
|
||||
shell: pwsh
|
||||
if: runner.os == 'Windows'
|
||||
|
||||
+6
-6
@@ -1,18 +1,18 @@
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu
|
||||
APPVEYOR_JOB_NAME: "python37-x64-ubuntu"
|
||||
APPVEYOR_JOB_NAME: "python38-x64-ubuntu"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
APPVEYOR_JOB_NAME: "python37-x64-vs2015"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos-mojave
|
||||
APPVEYOR_JOB_NAME: "python37-x64-macos-mojave"
|
||||
APPVEYOR_JOB_NAME: "python38-x64-vs2015"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos
|
||||
APPVEYOR_JOB_NAME: "python38-x64-macos"
|
||||
|
||||
stack: python 3.7
|
||||
stack: python 3.8
|
||||
|
||||
build: off
|
||||
|
||||
init:
|
||||
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
|
||||
- cmd: set PATH=C:\Python38;C:\Python38\Scripts;%PATH%
|
||||
- ps: |
|
||||
$BRANCH = if ($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH) { $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH } else { $env:APPVEYOR_REPO_BRANCH }
|
||||
if (-not ($BRANCH -eq 'main' -or $BRANCH.ToLower().StartsWith('appveyor-'))) {
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
pr:
|
||||
paths:
|
||||
exclude:
|
||||
- docs/*
|
||||
- .pre-commit-config.yaml
|
||||
|
||||
jobs:
|
||||
- job: linux_38
|
||||
timeoutInMinutes: 120
|
||||
|
||||
+4
-3
@@ -60,7 +60,7 @@ def bump_version() -> None:
|
||||
print(e)
|
||||
print("Failed to get previous version tag information.")
|
||||
|
||||
git_changes_result = subprocess.run(["git diff-index --quiet HEAD --"], shell=True)
|
||||
git_changes_result = subprocess.run(["git diff-index --quiet HEAD --"], shell=True, check=False)
|
||||
repo_has_uncommitted_changes = git_changes_result.returncode != 0
|
||||
|
||||
if repo_has_uncommitted_changes:
|
||||
@@ -68,7 +68,7 @@ def bump_version() -> None:
|
||||
sys.exit(1)
|
||||
|
||||
# fmt: off
|
||||
print( 'Current version:', current_version) # noqa: E201 whitespace
|
||||
print( 'Current version:', current_version)
|
||||
new_version = input(' New version: ').strip()
|
||||
# fmt: on
|
||||
|
||||
@@ -142,7 +142,8 @@ def bump_version() -> None:
|
||||
"pre-commit",
|
||||
"run",
|
||||
"--files=docs/changelog.md",
|
||||
]
|
||||
],
|
||||
check=False,
|
||||
)
|
||||
|
||||
# run pre-commit to check that no errors occurred on the second run
|
||||
|
||||
@@ -15,8 +15,8 @@ the results without the `--online` setting.
|
||||
from __future__ import annotations
|
||||
|
||||
import ast
|
||||
from collections.abc import Iterable, Iterator
|
||||
from pathlib import Path
|
||||
from typing import Iterator
|
||||
|
||||
import click
|
||||
import yaml
|
||||
@@ -97,7 +97,7 @@ class MaybeRemote:
|
||||
with open(filename, "w") as f:
|
||||
yaml.safe_dump(self.contents, f, default_flow_style=False)
|
||||
|
||||
def on_each(self, repos: list[str]) -> Iterator[tuple[str, str, str | None]]:
|
||||
def on_each(self, repos: Iterable[str]) -> Iterator[tuple[str, str, str | None]]:
|
||||
for repo in repos:
|
||||
print(f"[bold]{repo}:")
|
||||
for filename in sorted(self.contents, reverse=True):
|
||||
|
||||
@@ -12,13 +12,13 @@ from subprocess import run
|
||||
import click
|
||||
|
||||
|
||||
def shell(cmd, **kwargs):
|
||||
return run([cmd], shell=True, **kwargs)
|
||||
def shell(cmd, *, check: bool, **kwargs):
|
||||
return run([cmd], shell=True, check=check, **kwargs)
|
||||
|
||||
|
||||
def git_repo_has_changes():
|
||||
unstaged_changes = shell("git diff-index --quiet HEAD --").returncode != 0
|
||||
staged_changes = shell("git diff-index --quiet --cached HEAD --").returncode != 0
|
||||
unstaged_changes = shell("git diff-index --quiet HEAD --", check=False).returncode != 0
|
||||
staged_changes = shell("git diff-index --quiet --cached HEAD --", check=False).returncode != 0
|
||||
return unstaged_changes or staged_changes
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ def main():
|
||||
print("Done.")
|
||||
finally:
|
||||
# remove any local changes
|
||||
shell("git checkout -- .")
|
||||
shell("git checkout -- .", check=True)
|
||||
shell(f"git checkout {previous_branch}", check=True)
|
||||
shell(f"git branch -D --force {branch_name}", check=True)
|
||||
|
||||
|
||||
Regular → Executable
+6
-5
@@ -16,6 +16,7 @@ import functools
|
||||
import textwrap
|
||||
import urllib.request
|
||||
import xml.dom.minidom
|
||||
from collections.abc import Iterable, Mapping, Sequence
|
||||
from datetime import datetime
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
@@ -42,7 +43,7 @@ ICONS = (
|
||||
class Project:
|
||||
NAME: int = 0
|
||||
|
||||
def __init__(self, config: dict[str, Any], github: Github | None = None):
|
||||
def __init__(self, config: Mapping[str, Any], github: Github | None = None):
|
||||
try:
|
||||
self.name: str = config["name"]
|
||||
self.gh: str = config["gh"]
|
||||
@@ -149,7 +150,7 @@ def path_for_icon(icon_name: str, relative_to: Path | None = None) -> Path:
|
||||
|
||||
|
||||
def get_projects(
|
||||
config: list[dict[str, Any]],
|
||||
config: Iterable[Mapping[str, Any]],
|
||||
*,
|
||||
online: bool = True,
|
||||
auth: str | None = None,
|
||||
@@ -163,7 +164,7 @@ def get_projects(
|
||||
return sorted((Project(item, github) for item in config), reverse=online)
|
||||
|
||||
|
||||
def render_projects(projects: list[Project], *, dest_path: Path, include_info: bool = True):
|
||||
def render_projects(projects: Sequence[Project], *, dest_path: Path, include_info: bool = True):
|
||||
io = StringIO()
|
||||
print = functools.partial(builtins.print, file=io)
|
||||
|
||||
@@ -191,7 +192,7 @@ def render_projects(projects: list[Project], *, dest_path: Path, include_info: b
|
||||
def insert_projects_table(
|
||||
file: Path,
|
||||
*,
|
||||
projects: list[Project],
|
||||
projects: Sequence[Project],
|
||||
input_filename: str,
|
||||
include_info: bool = True,
|
||||
):
|
||||
@@ -243,7 +244,7 @@ def projects(
|
||||
README_FILE, projects=projects[:10], input_filename=input.name, include_info=False
|
||||
)
|
||||
insert_projects_table(
|
||||
DOCS_PAGE, projects=projects, input_filename=input.name, include_info=True
|
||||
DOCS_PAGE, projects=projects, input_filename=input.name, include_info=False
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -16,13 +16,13 @@ from urllib.parse import quote
|
||||
import click
|
||||
|
||||
|
||||
def shell(cmd, **kwargs):
|
||||
return run([cmd], shell=True, **kwargs)
|
||||
def shell(cmd, *, check: bool, **kwargs):
|
||||
return run([cmd], shell=True, check=check, **kwargs)
|
||||
|
||||
|
||||
def git_repo_has_changes():
|
||||
unstaged_changes = shell("git diff-index --quiet HEAD --").returncode != 0
|
||||
staged_changes = shell("git diff-index --quiet --cached HEAD --").returncode != 0
|
||||
unstaged_changes = shell("git diff-index --quiet HEAD --", check=False).returncode != 0
|
||||
staged_changes = shell("git diff-index --quiet --cached HEAD --", check=False).returncode != 0
|
||||
return unstaged_changes or staged_changes
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ def run_example_ci_configs(config_files=None):
|
||||
finally:
|
||||
# remove any local changes
|
||||
shutil.rmtree(example_project, ignore_errors=True)
|
||||
shell("git checkout -- .")
|
||||
shell("git checkout -- .", check=True)
|
||||
shell(f"git checkout {previous_branch}", check=True)
|
||||
shell(f"git branch -D --force {branch_name}", check=True)
|
||||
|
||||
|
||||
+5
-1
@@ -24,4 +24,8 @@ if __name__ == "__main__":
|
||||
check=True,
|
||||
)
|
||||
|
||||
sys.exit(subprocess.run([sys.executable, "-m", "cibuildwheel"], cwd=project_dir).returncode)
|
||||
sys.exit(
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "cibuildwheel"], cwd=project_dir, check=False
|
||||
).returncode
|
||||
)
|
||||
|
||||
@@ -59,6 +59,12 @@ images = [
|
||||
Image("musllinux_1_1", "aarch64", "quay.io/pypa/musllinux_1_1_aarch64", None),
|
||||
Image("musllinux_1_1", "ppc64le", "quay.io/pypa/musllinux_1_1_ppc64le", None),
|
||||
Image("musllinux_1_1", "s390x", "quay.io/pypa/musllinux_1_1_s390x", None),
|
||||
# musllinux_1_2 images
|
||||
Image("musllinux_1_2", "x86_64", "quay.io/pypa/musllinux_1_2_x86_64", None),
|
||||
Image("musllinux_1_2", "i686", "quay.io/pypa/musllinux_1_2_i686", None),
|
||||
Image("musllinux_1_2", "aarch64", "quay.io/pypa/musllinux_1_2_aarch64", None),
|
||||
Image("musllinux_1_2", "ppc64le", "quay.io/pypa/musllinux_1_2_ppc64le", None),
|
||||
Image("musllinux_1_2", "s390x", "quay.io/pypa/musllinux_1_2_s390x", None),
|
||||
]
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
|
||||
Regular → Executable
+1
-1
@@ -19,7 +19,7 @@ except ImportError:
|
||||
|
||||
|
||||
def main():
|
||||
subprocess.run(["mkdocs", "build"])
|
||||
subprocess.run(["mkdocs", "build"], check=True)
|
||||
|
||||
hti = Html2Image(custom_flags=["--force-device-scale-factor=2"])
|
||||
|
||||
|
||||
+24
-31
@@ -5,26 +5,20 @@ from __future__ import annotations
|
||||
import copy
|
||||
import difflib
|
||||
import logging
|
||||
import sys
|
||||
from collections.abc import Mapping, MutableMapping
|
||||
from pathlib import Path
|
||||
from typing import Any, Union
|
||||
from typing import Any, Final, Literal, TypedDict, Union
|
||||
|
||||
import click
|
||||
import requests
|
||||
import rich
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
import tomli as tomllib
|
||||
|
||||
from packaging.specifiers import Specifier
|
||||
from packaging.version import Version
|
||||
from rich.logging import RichHandler
|
||||
from rich.syntax import Syntax
|
||||
|
||||
from cibuildwheel._compat import tomllib
|
||||
from cibuildwheel.extra import dump_python_configurations
|
||||
from cibuildwheel.typing import Final, Literal, TypedDict
|
||||
|
||||
log = logging.getLogger("cibw")
|
||||
|
||||
@@ -65,7 +59,6 @@ AnyConfig = Union[ConfigWinCP, ConfigWinPP, ConfigMacOS]
|
||||
|
||||
class WindowsVersions:
|
||||
def __init__(self, arch_str: ArchStr) -> None:
|
||||
|
||||
response = requests.get("https://api.nuget.org/v3/index.json")
|
||||
response.raise_for_status()
|
||||
api_info = response.json()
|
||||
@@ -88,14 +81,13 @@ class WindowsVersions:
|
||||
self.version_dict = {Version(v): v for v in cp_info["versions"]}
|
||||
|
||||
def update_version_windows(self, spec: Specifier) -> ConfigWinCP | None:
|
||||
|
||||
# Specifier.filter selects all non pre-releases that match the spec,
|
||||
# unless there are only pre-releases, then it selects pre-releases
|
||||
# instead (like pip)
|
||||
unsorted_versions = spec.filter(self.version_dict)
|
||||
versions = sorted(unsorted_versions, reverse=True)
|
||||
|
||||
log.debug(f"Windows {self.arch} {spec} has {', '.join(str(v) for v in versions)}")
|
||||
log.debug("Windows %s %s has %s", self.arch, spec, ", ".join(str(v) for v in versions))
|
||||
|
||||
if not versions:
|
||||
return None
|
||||
@@ -111,7 +103,6 @@ class WindowsVersions:
|
||||
|
||||
class PyPyVersions:
|
||||
def __init__(self, arch_str: ArchStr):
|
||||
|
||||
response = requests.get("https://downloads.python.org/pypy/versions.json")
|
||||
response.raise_for_status()
|
||||
|
||||
@@ -127,7 +118,7 @@ class PyPyVersions:
|
||||
]
|
||||
self.arch = arch_str
|
||||
|
||||
def get_arch_file(self, release: dict[str, Any]) -> str:
|
||||
def get_arch_file(self, release: Mapping[str, Any]) -> str:
|
||||
urls: list[str] = [
|
||||
rf["download_url"]
|
||||
for rf in release["files"]
|
||||
@@ -137,7 +128,7 @@ class PyPyVersions:
|
||||
|
||||
def update_version_windows(self, spec: Specifier) -> ConfigWinCP:
|
||||
releases = [r for r in self.releases if spec.contains(r["python_version"])]
|
||||
releases = sorted(releases, key=lambda r: r["pypy_version"]) # type: ignore[no-any-return]
|
||||
releases = sorted(releases, key=lambda r: r["pypy_version"])
|
||||
releases = [r for r in releases if self.get_arch_file(r)]
|
||||
|
||||
if not releases:
|
||||
@@ -159,12 +150,12 @@ class PyPyVersions:
|
||||
)
|
||||
|
||||
def update_version_macos(self, spec: Specifier) -> ConfigMacOS:
|
||||
if self.arch != "64":
|
||||
msg = "Other archs not supported yet on macOS"
|
||||
if self.arch not in {"64", "ARM64"}:
|
||||
msg = f"'{self.arch}' arch not supported yet on macOS"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
releases = [r for r in self.releases if spec.contains(r["python_version"])]
|
||||
releases = sorted(releases, key=lambda r: r["pypy_version"]) # type: ignore[no-any-return]
|
||||
releases = sorted(releases, key=lambda r: r["pypy_version"])
|
||||
|
||||
if not releases:
|
||||
msg = f"PyPy macOS {self.arch} not found for {spec}!"
|
||||
@@ -172,12 +163,14 @@ class PyPyVersions:
|
||||
|
||||
release = releases[-1]
|
||||
version = release["python_version"]
|
||||
identifier = f"pp{version.major}{version.minor}-macosx_x86_64"
|
||||
arch = "x86_64" if self.arch == "64" else self.arch.lower()
|
||||
identifier = f"pp{version.major}{version.minor}-macosx_{arch}"
|
||||
|
||||
arch = "x64" if self.arch == "64" else self.arch.lower()
|
||||
(url,) = (
|
||||
rf["download_url"]
|
||||
for rf in release["files"]
|
||||
if "" in rf["platform"] == "darwin" and rf["arch"] == "x64"
|
||||
if "" in rf["platform"] == "darwin" and rf["arch"] == arch
|
||||
)
|
||||
|
||||
return ConfigMacOS(
|
||||
@@ -189,7 +182,6 @@ class PyPyVersions:
|
||||
|
||||
class CPythonVersions:
|
||||
def __init__(self) -> None:
|
||||
|
||||
response = requests.get(
|
||||
"https://www.python.org/api/v2/downloads/release/?is_published=true"
|
||||
)
|
||||
@@ -208,7 +200,6 @@ class CPythonVersions:
|
||||
def update_version_macos(
|
||||
self, identifier: str, version: Version, spec: Specifier
|
||||
) -> ConfigMacOS | None:
|
||||
|
||||
# see note above on Specifier.filter
|
||||
unsorted_versions = spec.filter(self.versions_dict)
|
||||
sorted_versions = sorted(unsorted_versions, reverse=True)
|
||||
@@ -251,21 +242,25 @@ class AllVersions:
|
||||
|
||||
self.macos_cpython = CPythonVersions()
|
||||
self.macos_pypy = PyPyVersions("64")
|
||||
self.macos_pypy_arm64 = PyPyVersions("ARM64")
|
||||
|
||||
def update_config(self, config: dict[str, str]) -> None:
|
||||
def update_config(self, config: MutableMapping[str, str]) -> None:
|
||||
identifier = config["identifier"]
|
||||
version = Version(config["version"])
|
||||
spec = Specifier(f"=={version.major}.{version.minor}.*")
|
||||
log.info(f"Reading in '{identifier}' -> {spec} @ {version}")
|
||||
log.info("Reading in %r -> %s @ %s", str(identifier), spec, version)
|
||||
orig_config = copy.copy(config)
|
||||
config_update: AnyConfig | None = None
|
||||
|
||||
# We need to use ** in update due to MyPy (probably a bug)
|
||||
if "macos" in identifier:
|
||||
if "macosx" in identifier:
|
||||
if identifier.startswith("cp"):
|
||||
config_update = self.macos_cpython.update_version_macos(identifier, version, spec)
|
||||
elif identifier.startswith("pp"):
|
||||
config_update = self.macos_pypy.update_version_macos(spec)
|
||||
if "macosx_x86_64" in identifier:
|
||||
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)
|
||||
@@ -274,15 +269,14 @@ class AllVersions:
|
||||
config_update = self.windows_64.update_version_windows(spec)
|
||||
elif identifier.startswith("pp"):
|
||||
config_update = self.windows_pypy_64.update_version_windows(spec)
|
||||
elif "win_arm64" in identifier:
|
||||
if identifier.startswith("cp"):
|
||||
config_update = self.windows_arm64.update_version_windows(spec)
|
||||
elif "win_arm64" in identifier and identifier.startswith("cp"):
|
||||
config_update = self.windows_arm64.update_version_windows(spec)
|
||||
|
||||
assert config_update is not None, f"{identifier} not found!"
|
||||
config.update(**config_update)
|
||||
|
||||
if config != orig_config:
|
||||
log.info(f" Updated {orig_config} to {config}")
|
||||
log.info(" Updated %s to %s", orig_config, config)
|
||||
|
||||
|
||||
@click.command()
|
||||
@@ -291,7 +285,6 @@ class AllVersions:
|
||||
"--level", default="INFO", type=click.Choice(["WARNING", "INFO", "DEBUG"], case_sensitive=False)
|
||||
)
|
||||
def update_pythons(force: bool, level: str) -> None:
|
||||
|
||||
logging.basicConfig(
|
||||
level="INFO",
|
||||
format="%(message)s",
|
||||
|
||||
@@ -5,23 +5,17 @@ from __future__ import annotations
|
||||
import difflib
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
import click
|
||||
import rich
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
import tomli as tomllib
|
||||
|
||||
from packaging.version import InvalidVersion, Version
|
||||
from rich.logging import RichHandler
|
||||
from rich.syntax import Syntax
|
||||
|
||||
from cibuildwheel.typing import Final
|
||||
from cibuildwheel._compat import tomllib
|
||||
|
||||
log = logging.getLogger("cibw")
|
||||
|
||||
@@ -54,14 +48,18 @@ def git_ls_remote_versions(url) -> list[VersionTuple]:
|
||||
try:
|
||||
version = Version(version_string)
|
||||
if version.is_devrelease:
|
||||
log.info(f"Ignoring development release '{version}'")
|
||||
log.info("Ignoring development release %r", str(version))
|
||||
continue
|
||||
if version.is_prerelease:
|
||||
log.info(f"Ignoring pre-release '{version}'")
|
||||
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(f"Ignoring ref '{ref}'")
|
||||
log.warning("Ignoring ref %r", ref)
|
||||
versions.sort(reverse=True)
|
||||
return versions
|
||||
|
||||
@@ -72,7 +70,6 @@ def git_ls_remote_versions(url) -> list[VersionTuple]:
|
||||
"--level", default="INFO", type=click.Choice(["WARNING", "INFO", "DEBUG"], case_sensitive=False)
|
||||
)
|
||||
def update_virtualenv(force: bool, level: str) -> None:
|
||||
|
||||
logging.basicConfig(
|
||||
level="INFO",
|
||||
format="%(message)s",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
from __future__ import annotations
|
||||
|
||||
__version__ = "2.11.2"
|
||||
__version__ = "2.16.1"
|
||||
|
||||
+110
-95
@@ -7,24 +7,29 @@ import sys
|
||||
import tarfile
|
||||
import textwrap
|
||||
import typing
|
||||
from collections.abc import Iterable, Sequence, Set
|
||||
from pathlib import Path
|
||||
from tempfile import mkdtemp
|
||||
from typing import Protocol
|
||||
|
||||
import cibuildwheel
|
||||
import cibuildwheel.linux
|
||||
import cibuildwheel.macos
|
||||
import cibuildwheel.util
|
||||
import cibuildwheel.windows
|
||||
from cibuildwheel._compat.typing import assert_never
|
||||
from cibuildwheel.architecture import Architecture, allowed_architectures_check
|
||||
from cibuildwheel.logger import log
|
||||
from cibuildwheel.options import CommandLineArguments, Options, compute_options
|
||||
from cibuildwheel.typing import PLATFORMS, PlatformName, assert_never
|
||||
from cibuildwheel.typing import PLATFORMS, GenericPythonConfiguration, PlatformName
|
||||
from cibuildwheel.util import (
|
||||
CIBW_CACHE_PATH,
|
||||
BuildSelector,
|
||||
CIProvider,
|
||||
Unbuffered,
|
||||
chdir,
|
||||
detect_ci_provider,
|
||||
fix_ansi_codes_for_github_actions,
|
||||
)
|
||||
|
||||
|
||||
@@ -165,71 +170,103 @@ def main() -> None:
|
||||
log.warning(f"Can't delete temporary folder '{temp_dir}'")
|
||||
|
||||
|
||||
def build_in_directory(args: CommandLineArguments) -> None:
|
||||
def _compute_platform_only(only: str) -> PlatformName:
|
||||
if "linux_" in only:
|
||||
return "linux"
|
||||
if "macosx_" in only:
|
||||
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)
|
||||
|
||||
|
||||
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)
|
||||
if sys.platform.startswith("linux"):
|
||||
return "linux"
|
||||
elif sys.platform == "darwin":
|
||||
return "macos"
|
||||
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,
|
||||
)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def _compute_platform(args: CommandLineArguments) -> PlatformName:
|
||||
platform_option_value = args.platform or os.environ.get("CIBW_PLATFORM", "auto")
|
||||
platform: PlatformName
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
if platform_option_value not in PLATFORMS | {"auto"}:
|
||||
print(f"cibuildwheel: Unsupported platform: {platform_option_value}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
if args.only:
|
||||
if "linux_" in args.only:
|
||||
platform = "linux"
|
||||
elif "macosx_" in args.only:
|
||||
platform = "macos"
|
||||
elif "win_" in args.only or "win32" in args.only:
|
||||
platform = "windows"
|
||||
else:
|
||||
print(
|
||||
f"Invalid --only='{args.only}', must be a build selector with a known platform",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
if args.platform is not None:
|
||||
print(
|
||||
"--platform cannot be specified with --only, it is computed from --only",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
if args.archs is not None:
|
||||
print(
|
||||
"--arch cannot be specified with --only, it is computed from --only",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(2)
|
||||
return _compute_platform_only(args.only)
|
||||
elif platform_option_value != "auto":
|
||||
if platform_option_value not in PLATFORMS:
|
||||
print(f"cibuildwheel: Unsupported platform: {platform_option_value}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
return typing.cast(PlatformName, platform_option_value)
|
||||
|
||||
platform = typing.cast(PlatformName, platform_option_value)
|
||||
else:
|
||||
ci_provider = detect_ci_provider()
|
||||
if 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)
|
||||
if sys.platform.startswith("linux"):
|
||||
platform = "linux"
|
||||
elif sys.platform == "darwin":
|
||||
platform = "macos"
|
||||
elif sys.platform == "win32":
|
||||
platform = "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,
|
||||
)
|
||||
sys.exit(2)
|
||||
return _compute_platform_ci()
|
||||
|
||||
options = compute_options(platform=platform, command_line_arguments=args)
|
||||
|
||||
class PlatformModule(Protocol):
|
||||
# note that as per PEP544, the self argument is ignored when the protocol
|
||||
# is applied to a module
|
||||
def get_python_configurations(
|
||||
self, build_selector: BuildSelector, architectures: Set[Architecture]
|
||||
) -> Sequence[GenericPythonConfiguration]:
|
||||
...
|
||||
|
||||
def build(self, options: Options, tmp_path: Path) -> None:
|
||||
...
|
||||
|
||||
|
||||
# pylint: disable-next=inconsistent-return-statements
|
||||
def get_platform_module(platform: PlatformName) -> PlatformModule:
|
||||
if platform == "linux":
|
||||
return cibuildwheel.linux
|
||||
if platform == "windows":
|
||||
return cibuildwheel.windows
|
||||
if platform == "macos":
|
||||
return cibuildwheel.macos
|
||||
assert_never(platform)
|
||||
|
||||
|
||||
def build_in_directory(args: CommandLineArguments) -> None:
|
||||
platform: PlatformName = _compute_platform(args)
|
||||
options = compute_options(platform=platform, command_line_arguments=args, env=os.environ)
|
||||
|
||||
package_dir = options.globals.package_dir
|
||||
package_files = {"setup.py", "setup.cfg", "pyproject.toml"}
|
||||
@@ -240,8 +277,9 @@ def build_in_directory(args: CommandLineArguments) -> None:
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
platform_module = get_platform_module(platform)
|
||||
identifiers = get_build_identifiers(
|
||||
platform=platform,
|
||||
platform_module=platform_module,
|
||||
build_selector=options.globals.build_selector,
|
||||
architectures=options.globals.architectures,
|
||||
)
|
||||
@@ -287,14 +325,7 @@ def build_in_directory(args: CommandLineArguments) -> None:
|
||||
with cibuildwheel.util.print_new_wheels(
|
||||
"\n{n} wheels produced in {m:.0f} minutes:", output_dir
|
||||
):
|
||||
if platform == "linux":
|
||||
cibuildwheel.linux.build(options, tmp_path)
|
||||
elif platform == "windows":
|
||||
cibuildwheel.windows.build(options, tmp_path)
|
||||
elif platform == "macos":
|
||||
cibuildwheel.macos.build(options, tmp_path)
|
||||
else:
|
||||
assert_never(platform)
|
||||
platform_module.build(options, tmp_path)
|
||||
finally:
|
||||
# avoid https://github.com/python/cpython/issues/86962 by performing
|
||||
# cleanup manually
|
||||
@@ -303,7 +334,7 @@ def build_in_directory(args: CommandLineArguments) -> None:
|
||||
log.warning(f"Can't delete temporary folder '{tmp_path}'")
|
||||
|
||||
|
||||
def print_preamble(platform: str, options: Options, identifiers: list[str]) -> None:
|
||||
def print_preamble(platform: str, options: Options, identifiers: Sequence[str]) -> None:
|
||||
print(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
@@ -318,9 +349,13 @@ def print_preamble(platform: str, options: Options, identifiers: list[str]) -> N
|
||||
print(f"cibuildwheel version {cibuildwheel.__version__}\n")
|
||||
|
||||
print("Build options:")
|
||||
print(f" platform: {platform!r}")
|
||||
print(textwrap.indent(options.summary(identifiers), " "))
|
||||
print(f" platform: {platform}")
|
||||
options_summary = textwrap.indent(options.summary(identifiers), " ")
|
||||
if detect_ci_provider() == CIProvider.github_actions:
|
||||
options_summary = fix_ansi_codes_for_github_actions(options_summary)
|
||||
print(options_summary)
|
||||
|
||||
print()
|
||||
print(f"Cache folder: {CIBW_CACHE_PATH}")
|
||||
|
||||
warnings = detect_warnings(options=options, identifiers=identifiers)
|
||||
@@ -333,33 +368,13 @@ def print_preamble(platform: str, options: Options, identifiers: list[str]) -> N
|
||||
|
||||
|
||||
def get_build_identifiers(
|
||||
platform: PlatformName, build_selector: BuildSelector, architectures: set[Architecture]
|
||||
platform_module: PlatformModule, build_selector: BuildSelector, architectures: Set[Architecture]
|
||||
) -> list[str]:
|
||||
python_configurations: (
|
||||
list[cibuildwheel.linux.PythonConfiguration]
|
||||
| list[cibuildwheel.windows.PythonConfiguration]
|
||||
| list[cibuildwheel.macos.PythonConfiguration]
|
||||
)
|
||||
|
||||
if platform == "linux":
|
||||
python_configurations = cibuildwheel.linux.get_python_configurations(
|
||||
build_selector, architectures
|
||||
)
|
||||
elif platform == "windows":
|
||||
python_configurations = cibuildwheel.windows.get_python_configurations(
|
||||
build_selector, architectures
|
||||
)
|
||||
elif platform == "macos":
|
||||
python_configurations = cibuildwheel.macos.get_python_configurations(
|
||||
build_selector, architectures
|
||||
)
|
||||
else:
|
||||
assert_never(platform)
|
||||
|
||||
python_configurations = platform_module.get_python_configurations(build_selector, architectures)
|
||||
return [config.identifier for config in python_configurations]
|
||||
|
||||
|
||||
def detect_warnings(*, options: Options, identifiers: list[str]) -> list[str]:
|
||||
def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str]:
|
||||
warnings = []
|
||||
|
||||
# warn about deprecated {python} and {pip}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import annotations
|
||||
@@ -0,0 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
from tomllib import load
|
||||
else:
|
||||
from tomli import load
|
||||
|
||||
__all__ = ("load",)
|
||||
@@ -0,0 +1,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3, 11):
|
||||
from typing_extensions import NotRequired, assert_never
|
||||
else:
|
||||
from typing import NotRequired, assert_never
|
||||
|
||||
__all__ = (
|
||||
"assert_never",
|
||||
"NotRequired",
|
||||
)
|
||||
@@ -4,11 +4,18 @@ import functools
|
||||
import platform as platform_module
|
||||
import re
|
||||
import sys
|
||||
from collections.abc import Set
|
||||
from enum import Enum
|
||||
from typing import Final, Literal
|
||||
|
||||
from .typing import Final, Literal, PlatformName, assert_never
|
||||
from ._compat.typing import assert_never
|
||||
from .typing import PlatformName
|
||||
|
||||
PRETTY_NAMES: Final = {"linux": "Linux", "macos": "macOS", "windows": "Windows"}
|
||||
PRETTY_NAMES: Final[dict[PlatformName, str]] = {
|
||||
"linux": "Linux",
|
||||
"macos": "macOS",
|
||||
"windows": "Windows",
|
||||
}
|
||||
|
||||
ARCH_SYNONYMS: Final[list[dict[PlatformName, str | None]]] = [
|
||||
{"linux": "x86_64", "macos": "x86_64", "windows": "AMD64"},
|
||||
@@ -43,6 +50,9 @@ class Architecture(Enum):
|
||||
def __lt__(self, other: Architecture) -> bool:
|
||||
return self.value < other.value
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
@staticmethod
|
||||
def parse_config(config: str, platform: PlatformName) -> set[Architecture]:
|
||||
result = set()
|
||||
@@ -129,9 +139,8 @@ class Architecture(Enum):
|
||||
|
||||
def allowed_architectures_check(
|
||||
platform: PlatformName,
|
||||
architectures: set[Architecture],
|
||||
architectures: Set[Architecture],
|
||||
) -> None:
|
||||
|
||||
allowed_architectures = Architecture.all_archs(platform)
|
||||
|
||||
msg = f"{PRETTY_NAMES[platform]} only supports {sorted(allowed_architectures)} at the moment."
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from collections.abc import Iterable, Mapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from typing import Callable, Dict, List, Sequence
|
||||
from typing import Callable, Dict, List # noqa: TID251
|
||||
|
||||
import bashlex
|
||||
|
||||
@@ -10,7 +11,7 @@ import bashlex
|
||||
EnvironmentExecutor = Callable[[List[str], Dict[str, str]], str]
|
||||
|
||||
|
||||
def local_environment_executor(command: list[str], env: dict[str, str]) -> str:
|
||||
def local_environment_executor(command: Sequence[str], env: Mapping[str, str]) -> str:
|
||||
return subprocess.run(command, env=env, text=True, stdout=subprocess.PIPE, check=True).stdout
|
||||
|
||||
|
||||
@@ -22,7 +23,7 @@ class NodeExecutionContext:
|
||||
|
||||
|
||||
def evaluate(
|
||||
value: str, environment: dict[str, str], executor: EnvironmentExecutor | None = None
|
||||
value: str, environment: Mapping[str, str], executor: EnvironmentExecutor | None = None
|
||||
) -> str:
|
||||
if not value:
|
||||
# empty string evaluates to empty string
|
||||
@@ -40,7 +41,9 @@ def evaluate(
|
||||
return evaluate_node(
|
||||
value_word_node,
|
||||
context=NodeExecutionContext(
|
||||
environment=environment, input=value, executor=executor or local_environment_executor
|
||||
environment=dict(environment),
|
||||
input=value,
|
||||
executor=executor or local_environment_executor,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -105,7 +108,7 @@ def evaluate_nodes_as_compound_command(
|
||||
|
||||
|
||||
def evaluate_nodes_as_simple_command(
|
||||
nodes: list[bashlex.ast.node], context: NodeExecutionContext
|
||||
nodes: Iterable[bashlex.ast.node], context: NodeExecutionContext
|
||||
) -> str:
|
||||
command = [evaluate_node(part, context=context) for part in nodes]
|
||||
return context.executor(command, context.environment)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
from typing import Any, Mapping, Sequence
|
||||
from collections.abc import Mapping, Sequence
|
||||
from typing import Any, Protocol
|
||||
|
||||
import bashlex
|
||||
import bashlex.errors
|
||||
|
||||
from cibuildwheel.typing import Protocol
|
||||
|
||||
from . import bashlex_eval
|
||||
|
||||
|
||||
@@ -54,7 +53,7 @@ class EnvironmentAssignment(Protocol):
|
||||
def evaluated_value(
|
||||
self,
|
||||
*,
|
||||
environment: dict[str, str],
|
||||
environment: Mapping[str, str],
|
||||
executor: bashlex_eval.EnvironmentExecutor | None = None,
|
||||
) -> str:
|
||||
"""Returns the value of this assignment, as evaluated in the environment"""
|
||||
@@ -70,7 +69,7 @@ class EnvironmentAssignmentRaw:
|
||||
self.value = value
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.name}: {self.value}"
|
||||
return f"{self.name}={self.value}"
|
||||
|
||||
def evaluated_value(self, **_: Any) -> str:
|
||||
return self.value
|
||||
@@ -91,7 +90,7 @@ class EnvironmentAssignmentBash:
|
||||
|
||||
def evaluated_value(
|
||||
self,
|
||||
environment: dict[str, str],
|
||||
environment: Mapping[str, str],
|
||||
executor: bashlex_eval.EnvironmentExecutor | None = None,
|
||||
) -> str:
|
||||
return bashlex_eval.evaluate(self.value, environment=environment, executor=executor)
|
||||
@@ -117,7 +116,7 @@ class ParsedEnvironment:
|
||||
prev_environment: Mapping[str, str],
|
||||
executor: bashlex_eval.EnvironmentExecutor | None = None,
|
||||
) -> dict[str, str]:
|
||||
environment = dict(**prev_environment)
|
||||
environment = {**prev_environment}
|
||||
|
||||
for assignment in self.assignments:
|
||||
value = assignment.evaluated_value(environment=environment, executor=executor)
|
||||
@@ -131,6 +130,9 @@ class ParsedEnvironment:
|
||||
def __repr__(self) -> str:
|
||||
return f"{self.__class__.__name__}({[repr(a) for a in self.assignments]!r})"
|
||||
|
||||
def options_summary(self) -> Any:
|
||||
return self.assignments
|
||||
|
||||
|
||||
def parse_environment(env_string: str) -> ParsedEnvironment:
|
||||
env_items = split_env_items(env_string)
|
||||
|
||||
@@ -4,9 +4,9 @@ These are utilities for the `/bin` scripts, not for the `cibuildwheel` program.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping, Sequence
|
||||
from io import StringIO
|
||||
|
||||
from .typing import Protocol
|
||||
from typing import Protocol
|
||||
|
||||
__all__ = ("Printable", "dump_python_configurations")
|
||||
|
||||
@@ -16,7 +16,9 @@ class Printable(Protocol):
|
||||
...
|
||||
|
||||
|
||||
def dump_python_configurations(inp: dict[str, dict[str, list[dict[str, Printable]]]]) -> str:
|
||||
def dump_python_configurations(
|
||||
inp: Mapping[str, Mapping[str, Sequence[Mapping[str, Printable]]]]
|
||||
) -> str:
|
||||
output = StringIO()
|
||||
for header, values in inp.items():
|
||||
output.write(f"[{header}]\n")
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from threading import RLock
|
||||
from typing import Any, Callable, Generic, TypeVar, overload
|
||||
|
||||
__all__ = ["cached_property"]
|
||||
|
||||
_NOT_FOUND = object()
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
||||
|
||||
class cached_property(Generic[_T]):
|
||||
def __init__(self, func: Callable[[Any], _T]):
|
||||
self.func = func
|
||||
self.attrname: str | None = None
|
||||
self.__doc__ = func.__doc__
|
||||
self.lock = RLock()
|
||||
|
||||
def __set_name__(self, owner: type[Any], name: str) -> None:
|
||||
if self.attrname is None:
|
||||
self.attrname = name
|
||||
elif name != self.attrname:
|
||||
msg = f"Cannot assign the same cached_property to two different names ({self.attrname!r} and {name!r})."
|
||||
raise TypeError(msg)
|
||||
|
||||
@overload
|
||||
def __get__(self, instance: None, owner: type[Any] | None = ...) -> cached_property[_T]:
|
||||
...
|
||||
|
||||
@overload
|
||||
def __get__(self, instance: object, owner: type[Any] | None = ...) -> _T:
|
||||
...
|
||||
|
||||
def __get__(self, instance: object | None, owner: type[Any] | None = None) -> Any:
|
||||
if instance is None:
|
||||
return self
|
||||
if self.attrname is None:
|
||||
msg = "Cannot use cached_property instance without calling __set_name__ on it."
|
||||
raise TypeError(msg)
|
||||
try:
|
||||
cache = instance.__dict__
|
||||
except AttributeError: # not all objects have __dict__ (e.g. class defines slots)
|
||||
msg = (
|
||||
f"No '__dict__' attribute on {type(instance).__name__!r} "
|
||||
f"instance to cache {self.attrname!r} property."
|
||||
)
|
||||
raise TypeError(msg) from None
|
||||
val = cache.get(self.attrname, _NOT_FOUND)
|
||||
if val is _NOT_FOUND:
|
||||
with self.lock:
|
||||
# check if another thread filled cache while we awaited lock
|
||||
val = cache.get(self.attrname, _NOT_FOUND)
|
||||
if val is _NOT_FOUND:
|
||||
val = self.func(instance)
|
||||
try:
|
||||
cache[self.attrname] = val
|
||||
except TypeError:
|
||||
msg = (
|
||||
f"The '__dict__' attribute on {type(instance).__name__!r} instance "
|
||||
f"does not support item assignment for caching {self.attrname!r} property."
|
||||
)
|
||||
raise TypeError(msg) from None
|
||||
return val
|
||||
+37
-26
@@ -3,17 +3,20 @@ from __future__ import annotations
|
||||
import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
from collections.abc import Iterable, Iterator, Sequence, Set
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
from typing import Iterator, Tuple
|
||||
from typing import OrderedDict, Tuple
|
||||
|
||||
from ._compat.typing import assert_never
|
||||
from .architecture import Architecture
|
||||
from .logger import log
|
||||
from .oci_container import OCIContainer
|
||||
from .options import Options
|
||||
from .typing import OrderedDict, PathOrStr, assert_never
|
||||
from .typing import PathOrStr
|
||||
from .util import (
|
||||
AlreadyBuiltWheelError,
|
||||
BuildFrontendConfig,
|
||||
BuildSelector,
|
||||
NonPlatformWheelError,
|
||||
find_compatible_wheel,
|
||||
@@ -21,6 +24,7 @@ from .util import (
|
||||
prepare_command,
|
||||
read_python_configs,
|
||||
split_config_settings,
|
||||
test_fail_cwd_file,
|
||||
unwrap,
|
||||
)
|
||||
|
||||
@@ -45,9 +49,8 @@ class BuildStep:
|
||||
|
||||
def get_python_configurations(
|
||||
build_selector: BuildSelector,
|
||||
architectures: set[Architecture],
|
||||
architectures: Set[Architecture],
|
||||
) -> list[PythonConfiguration]:
|
||||
|
||||
full_python_configs = read_python_configs("linux")
|
||||
|
||||
python_configurations = [PythonConfiguration(**item) for item in full_python_configs]
|
||||
@@ -111,7 +114,7 @@ def get_build_steps(
|
||||
|
||||
|
||||
def check_all_python_exist(
|
||||
*, platform_configs: list[PythonConfiguration], container: OCIContainer
|
||||
*, platform_configs: Iterable[PythonConfiguration], container: OCIContainer
|
||||
) -> None:
|
||||
exist = True
|
||||
messages = []
|
||||
@@ -136,7 +139,7 @@ def check_all_python_exist(
|
||||
def build_in_container(
|
||||
*,
|
||||
options: Options,
|
||||
platform_configs: list[PythonConfiguration],
|
||||
platform_configs: Sequence[PythonConfiguration],
|
||||
container: OCIContainer,
|
||||
container_project_path: PurePath,
|
||||
container_package_dir: PurePath,
|
||||
@@ -174,6 +177,7 @@ def build_in_container(
|
||||
for config in platform_configs:
|
||||
log.build_start(config.identifier)
|
||||
build_options = options.build_options(config.identifier)
|
||||
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
|
||||
|
||||
dependency_constraint_flags: list[PathOrStr] = []
|
||||
|
||||
@@ -181,7 +185,7 @@ def build_in_container(
|
||||
constraints_file = build_options.dependency_constraints.get_for_python_version(
|
||||
config.version
|
||||
)
|
||||
container_constraints_file = PurePath("/constraints.txt")
|
||||
container_constraints_file = PurePosixPath("/constraints.txt")
|
||||
|
||||
container.copy_into(constraints_file, container_constraints_file)
|
||||
dependency_constraint_flags = ["-c", container_constraints_file]
|
||||
@@ -223,7 +227,6 @@ def build_in_container(
|
||||
)
|
||||
repaired_wheels = [compatible_wheel]
|
||||
else:
|
||||
|
||||
if build_options.before_build:
|
||||
log.step("Running before_build...")
|
||||
before_build_prepared = prepare_command(
|
||||
@@ -240,11 +243,11 @@ def build_in_container(
|
||||
container.call(["rm", "-rf", built_wheel_dir])
|
||||
container.call(["mkdir", "-p", built_wheel_dir])
|
||||
|
||||
verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||
extra_flags = split_config_settings(build_options.config_settings)
|
||||
extra_flags = split_config_settings(build_options.config_settings, build_frontend.name)
|
||||
extra_flags += build_frontend.args
|
||||
|
||||
if build_options.build_frontend == "pip":
|
||||
extra_flags += verbosity_flags
|
||||
if build_frontend.name == "pip":
|
||||
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||
container.call(
|
||||
[
|
||||
"python",
|
||||
@@ -258,9 +261,10 @@ def build_in_container(
|
||||
],
|
||||
env=env,
|
||||
)
|
||||
elif build_options.build_frontend == "build":
|
||||
verbosity_setting = " ".join(verbosity_flags)
|
||||
extra_flags += (f"--config-setting={verbosity_setting}",)
|
||||
elif build_frontend.name == "build":
|
||||
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)
|
||||
container.call(
|
||||
[
|
||||
"python",
|
||||
@@ -274,7 +278,7 @@ def build_in_container(
|
||||
env=env,
|
||||
)
|
||||
else:
|
||||
assert_never(build_options.build_frontend)
|
||||
assert_never(build_frontend)
|
||||
|
||||
built_wheel = container.glob(built_wheel_dir, "*.whl")[0]
|
||||
|
||||
@@ -306,9 +310,11 @@ def build_in_container(
|
||||
# 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)
|
||||
venv_dir = (
|
||||
PurePath(container.call(["mktemp", "-d"], capture_output=True).strip()) / "venv"
|
||||
|
||||
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)
|
||||
|
||||
@@ -344,11 +350,16 @@ def build_in_container(
|
||||
build_options.test_command,
|
||||
project=container_project_path,
|
||||
package=container_package_dir,
|
||||
wheel=wheel_to_test,
|
||||
)
|
||||
container.call(["sh", "-c", test_command_prepared], cwd="/root", env=virtualenv_env)
|
||||
test_cwd = testing_temp_dir / "test_cwd"
|
||||
container.call(["mkdir", "-p", test_cwd])
|
||||
container.copy_into(test_fail_cwd_file, test_cwd / "test_fail.py")
|
||||
|
||||
container.call(["sh", "-c", test_command_prepared], cwd=test_cwd, env=virtualenv_env)
|
||||
|
||||
# clean up test environment
|
||||
container.call(["rm", "-rf", venv_dir])
|
||||
container.call(["rm", "-rf", testing_temp_dir])
|
||||
|
||||
# move repaired wheels to output
|
||||
if compatible_wheel is None:
|
||||
@@ -366,11 +377,13 @@ def build_in_container(
|
||||
log.step_end()
|
||||
|
||||
|
||||
def build(options: Options, tmp_path: Path) -> None: # pylint: disable=unused-argument
|
||||
def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
||||
try:
|
||||
# check the container engine is installed
|
||||
subprocess.run(
|
||||
[options.globals.container_engine, "--version"], check=True, stdout=subprocess.DEVNULL
|
||||
[options.globals.container_engine.name, "--version"],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
print(
|
||||
@@ -410,11 +423,10 @@ def build(options: Options, tmp_path: Path) -> None: # pylint: disable=unused-a
|
||||
|
||||
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,
|
||||
) as container:
|
||||
|
||||
build_in_container(
|
||||
options=options,
|
||||
platform_configs=build_step.platform_configs,
|
||||
@@ -431,7 +443,7 @@ def build(options: Options, tmp_path: Path) -> None: # pylint: disable=unused-a
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def _matches_prepared_command(error_cmd: list[str], command_template: str) -> bool:
|
||||
def _matches_prepared_command(error_cmd: Sequence[str], command_template: str) -> bool:
|
||||
if len(error_cmd) < 3 or error_cmd[0:2] != ["sh", "-c"]:
|
||||
return False
|
||||
command_prefix = command_template.split("{", maxsplit=1)[0].strip()
|
||||
@@ -439,7 +451,6 @@ def _matches_prepared_command(error_cmd: list[str], command_template: str) -> bo
|
||||
|
||||
|
||||
def troubleshoot(options: Options, error: Exception) -> None:
|
||||
|
||||
if isinstance(error, subprocess.CalledProcessError) and (
|
||||
error.cmd[0:4] == ["python", "-m", "pip", "wheel"]
|
||||
or error.cmd[0:3] == ["python", "-m", "build"]
|
||||
|
||||
+11
-6
@@ -5,19 +5,19 @@ import os
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
from typing import IO, AnyStr
|
||||
from typing import IO, AnyStr, Final, Tuple
|
||||
|
||||
from cibuildwheel.typing import Final
|
||||
from cibuildwheel.util import CIProvider, detect_ci_provider
|
||||
from .util import CIProvider, detect_ci_provider
|
||||
|
||||
DEFAULT_FOLD_PATTERN: Final = ("{name}", "")
|
||||
FOLD_PATTERNS: Final = {
|
||||
FoldPattern = Tuple[str, str]
|
||||
DEFAULT_FOLD_PATTERN: Final[FoldPattern] = ("{name}", "")
|
||||
FOLD_PATTERNS: Final[dict[str, FoldPattern]] = {
|
||||
"azure": ("##[group]{name}", "##[endgroup]"),
|
||||
"travis": ("travis_fold:start:{identifier}\n{name}", "travis_fold:end:{identifier}"),
|
||||
"github": ("::group::{name}", "::endgroup::{name}"),
|
||||
}
|
||||
|
||||
PLATFORM_IDENTIFIER_DESCRIPTIONS: Final = {
|
||||
PLATFORM_IDENTIFIER_DESCRIPTIONS: Final[dict[str, str]] = {
|
||||
"manylinux_x86_64": "manylinux x86_64",
|
||||
"manylinux_i686": "manylinux i686",
|
||||
"manylinux_aarch64": "manylinux aarch64",
|
||||
@@ -126,6 +126,10 @@ class Logger:
|
||||
self.step_end(success=False)
|
||||
self.error(error)
|
||||
|
||||
def quiet(self, message: str) -> None:
|
||||
c = self.colors
|
||||
print(f"{c.gray}{message}{c.end}", file=sys.stderr)
|
||||
|
||||
def notice(self, message: str) -> None:
|
||||
if self.fold_mode == "github":
|
||||
print(f"::notice::{message}\n", file=sys.stderr)
|
||||
@@ -228,6 +232,7 @@ class Colors:
|
||||
self.bright_red = "\033[91m" if enabled else ""
|
||||
self.bright_green = "\033[92m" if enabled else ""
|
||||
self.white = "\033[37m\033[97m" if enabled else ""
|
||||
self.gray = "\033[38;5;244m" if enabled else ""
|
||||
|
||||
self.bg_grey = "\033[48;5;235m" if enabled else ""
|
||||
|
||||
|
||||
+57
-21
@@ -8,21 +8,25 @@ import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import typing
|
||||
from collections.abc import Sequence, Set
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Sequence, Tuple, cast
|
||||
from typing import Literal, Tuple
|
||||
|
||||
from filelock import FileLock
|
||||
|
||||
from ._compat.typing import assert_never
|
||||
from .architecture import Architecture
|
||||
from .environment import ParsedEnvironment
|
||||
from .logger import log
|
||||
from .options import Options
|
||||
from .typing import Literal, PathOrStr, assert_never
|
||||
from .typing import PathOrStr
|
||||
from .util import (
|
||||
CIBW_CACHE_PATH,
|
||||
AlreadyBuiltWheelError,
|
||||
BuildFrontend,
|
||||
BuildFrontendConfig,
|
||||
BuildFrontendName,
|
||||
BuildSelector,
|
||||
NonPlatformWheelError,
|
||||
call,
|
||||
@@ -36,6 +40,7 @@ from .util import (
|
||||
read_python_configs,
|
||||
shell,
|
||||
split_config_settings,
|
||||
test_fail_cwd_file,
|
||||
unwrap,
|
||||
virtualenv,
|
||||
)
|
||||
@@ -52,7 +57,7 @@ def get_macos_version() -> tuple[int, int]:
|
||||
"""
|
||||
version_str, _, _ = platform.mac_ver()
|
||||
version = tuple(map(int, version_str.split(".")[:2]))
|
||||
return cast(Tuple[int, int], version)
|
||||
return typing.cast(Tuple[int, int], version)
|
||||
|
||||
|
||||
def get_macos_sdks() -> list[str]:
|
||||
@@ -68,9 +73,8 @@ class PythonConfiguration:
|
||||
|
||||
|
||||
def get_python_configurations(
|
||||
build_selector: BuildSelector, architectures: set[Architecture]
|
||||
build_selector: BuildSelector, architectures: Set[Architecture]
|
||||
) -> list[PythonConfiguration]:
|
||||
|
||||
full_python_configs = read_python_configs("macos")
|
||||
|
||||
python_configurations = [PythonConfiguration(**item) for item in full_python_configs]
|
||||
@@ -83,7 +87,31 @@ def get_python_configurations(
|
||||
]
|
||||
|
||||
# skip builds as required by BUILD/SKIP
|
||||
return [c for c in python_configurations if build_selector(c.identifier)]
|
||||
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
|
||||
|
||||
# filter-out some cross-compilation configs with PyPy:
|
||||
# can't build arm64 on x86_64
|
||||
# rosetta allows to build x86_64 on arm64
|
||||
if platform.machine() == "x86_64":
|
||||
python_configurations_before = set(python_configurations)
|
||||
python_configurations = [
|
||||
c
|
||||
for c in python_configurations
|
||||
if not (c.identifier.startswith("pp") and c.identifier.endswith("arm64"))
|
||||
]
|
||||
removed_elements = python_configurations_before - set(python_configurations)
|
||||
if removed_elements:
|
||||
ids = ", ".join(c.identifier for c in removed_elements)
|
||||
log.quiet(
|
||||
unwrap(
|
||||
f"""
|
||||
Note: {ids} {'was' if len(removed_elements) == 1 else 'were'}
|
||||
selected, but can't be built on x86_64 so will be skipped automatically.
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
return python_configurations
|
||||
|
||||
|
||||
def install_cpython(tmp: Path, version: str, url: str) -> Path:
|
||||
@@ -137,7 +165,7 @@ def setup_python(
|
||||
python_configuration: PythonConfiguration,
|
||||
dependency_constraint_flags: Sequence[PathOrStr],
|
||||
environment: ParsedEnvironment,
|
||||
build_frontend: BuildFrontend,
|
||||
build_frontend: BuildFrontendName,
|
||||
) -> dict[str, str]:
|
||||
tmp.mkdir()
|
||||
implementation_id = python_configuration.identifier.split("-")[0]
|
||||
@@ -306,6 +334,7 @@ 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")
|
||||
log.build_start(config.identifier)
|
||||
|
||||
identifier_tmp_dir = tmp_path / config.identifier
|
||||
@@ -328,7 +357,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
config,
|
||||
dependency_constraint_flags,
|
||||
build_options.environment,
|
||||
build_options.build_frontend,
|
||||
build_frontend.name,
|
||||
)
|
||||
|
||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||
@@ -349,11 +378,13 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
log.step("Building wheel...")
|
||||
built_wheel_dir.mkdir()
|
||||
|
||||
verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||
extra_flags = split_config_settings(build_options.config_settings)
|
||||
extra_flags = split_config_settings(
|
||||
build_options.config_settings, build_frontend.name
|
||||
)
|
||||
extra_flags += build_frontend.args
|
||||
|
||||
if build_options.build_frontend == "pip":
|
||||
extra_flags += verbosity_flags
|
||||
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
|
||||
# see https://github.com/pypa/cibuildwheel/pull/369
|
||||
call(
|
||||
@@ -367,9 +398,10 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
*extra_flags,
|
||||
env=env,
|
||||
)
|
||||
elif build_options.build_frontend == "build":
|
||||
verbosity_setting = " ".join(verbosity_flags)
|
||||
extra_flags += (f"--config-setting={verbosity_setting}",)
|
||||
elif build_frontend.name == "build":
|
||||
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 = (
|
||||
@@ -390,7 +422,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
env=build_env,
|
||||
)
|
||||
else:
|
||||
assert_never(build_options.build_frontend)
|
||||
assert_never(build_frontend)
|
||||
|
||||
built_wheel = next(built_wheel_dir.glob("*.whl"))
|
||||
|
||||
@@ -563,17 +595,21 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
"pip", "install", *build_options.test_requires, env=virtualenv_env
|
||||
)
|
||||
|
||||
# run the tests from $HOME, with an absolute path in the command
|
||||
# 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(),
|
||||
wheel=repaired_wheel,
|
||||
)
|
||||
shell_with_arch(
|
||||
test_command_prepared, cwd=os.environ["HOME"], env=virtualenv_env
|
||||
)
|
||||
|
||||
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_with_arch(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:
|
||||
|
||||
@@ -8,16 +8,48 @@ import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import typing
|
||||
import uuid
|
||||
from collections.abc import Mapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path, PurePath, PurePosixPath
|
||||
from types import TracebackType
|
||||
from typing import IO, Dict, Sequence, cast
|
||||
from typing import IO, Dict, Literal
|
||||
|
||||
from cibuildwheel.util import CIProvider, detect_ci_provider
|
||||
from .typing import PathOrStr, PopenBytes
|
||||
from .util import CIProvider, call, detect_ci_provider, parse_key_value_string
|
||||
|
||||
from .typing import Literal, PathOrStr, PopenBytes
|
||||
ContainerEngineName = Literal["docker", "podman"]
|
||||
|
||||
ContainerEngine = Literal["docker", "podman"]
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class OCIContainerEngineConfig:
|
||||
name: ContainerEngineName
|
||||
create_args: Sequence[str] = ()
|
||||
|
||||
@staticmethod
|
||||
def from_config_string(config_string: str) -> OCIContainerEngineConfig:
|
||||
config_dict = parse_key_value_string(
|
||||
config_string, ["name"], ["create_args", "create-args"]
|
||||
)
|
||||
name = " ".join(config_dict["name"])
|
||||
if name not in {"docker", "podman"}:
|
||||
msg = f"unknown container engine {name}"
|
||||
raise ValueError(msg)
|
||||
|
||||
name = typing.cast(ContainerEngineName, name)
|
||||
# some flexibility in the option name 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)
|
||||
|
||||
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)}
|
||||
|
||||
|
||||
DEFAULT_ENGINE = OCIContainerEngineConfig("docker")
|
||||
|
||||
|
||||
class OCIContainer:
|
||||
@@ -53,22 +85,21 @@ class OCIContainer:
|
||||
self,
|
||||
*,
|
||||
image: str,
|
||||
simulate_32_bit: bool = False,
|
||||
enforce_32_bit: bool = False,
|
||||
cwd: PathOrStr | None = None,
|
||||
engine: ContainerEngine = "docker",
|
||||
engine: OCIContainerEngineConfig = DEFAULT_ENGINE,
|
||||
):
|
||||
if not image:
|
||||
msg = "Must have a non-empty image to run."
|
||||
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:
|
||||
|
||||
self.name = f"cibuildwheel-{uuid.uuid4()}"
|
||||
|
||||
# work-around for Travis-CI PPC64le Docker runs since 2021:
|
||||
@@ -79,17 +110,29 @@ 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(
|
||||
[
|
||||
self.engine,
|
||||
self.engine.name,
|
||||
"create",
|
||||
"--env=CIBUILDWHEEL",
|
||||
"--env=SOURCE_DATE_EPOCH",
|
||||
f"--name={self.name}",
|
||||
"--interactive",
|
||||
"--volume=/:/host", # ignored on CircleCI
|
||||
*network_args,
|
||||
*self.engine.create_args,
|
||||
self.image,
|
||||
*shell_args,
|
||||
],
|
||||
@@ -98,7 +141,7 @@ class OCIContainer:
|
||||
|
||||
self.process = subprocess.Popen(
|
||||
[
|
||||
self.engine,
|
||||
self.engine.name,
|
||||
"start",
|
||||
"--attach",
|
||||
"--interactive",
|
||||
@@ -108,7 +151,8 @@ class OCIContainer:
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
assert self.process.stdin and self.process.stdout
|
||||
assert self.process.stdin
|
||||
assert self.process.stdout
|
||||
self.bash_stdin = self.process.stdin
|
||||
self.bash_stdout = self.process.stdout
|
||||
|
||||
@@ -129,14 +173,13 @@ class OCIContainer:
|
||||
exc_val: BaseException | None,
|
||||
exc_tb: TracebackType | None,
|
||||
) -> None:
|
||||
|
||||
self.bash_stdin.write(b"exit 0\n")
|
||||
self.bash_stdin.flush()
|
||||
self.process.wait(timeout=30)
|
||||
self.bash_stdin.close()
|
||||
self.bash_stdout.close()
|
||||
|
||||
if self.engine == "podman":
|
||||
if self.engine.name == "podman":
|
||||
# This works around what seems to be a race condition in the podman
|
||||
# backend. The full reason is not understood. See PR #966 for a
|
||||
# discussion on possible causes and attempts to remove this line.
|
||||
@@ -146,7 +189,7 @@ class OCIContainer:
|
||||
assert isinstance(self.name, str)
|
||||
|
||||
subprocess.run(
|
||||
[self.engine, "rm", "--force", "-v", self.name],
|
||||
[self.engine.name, "rm", "--force", "-v", self.name],
|
||||
stdout=subprocess.DEVNULL,
|
||||
check=False,
|
||||
)
|
||||
@@ -161,15 +204,16 @@ class OCIContainer:
|
||||
if from_path.is_dir():
|
||||
self.call(["mkdir", "-p", to_path])
|
||||
subprocess.run(
|
||||
f"tar cf - . | {self.engine} exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -",
|
||||
f"tar cf - . | {self.engine.name} exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -",
|
||||
shell=True,
|
||||
check=True,
|
||||
cwd=from_path,
|
||||
)
|
||||
else:
|
||||
exec_process: subprocess.Popen[bytes]
|
||||
with subprocess.Popen(
|
||||
[
|
||||
self.engine,
|
||||
self.engine.name,
|
||||
"exec",
|
||||
"-i",
|
||||
str(self.name),
|
||||
@@ -179,10 +223,10 @@ class OCIContainer:
|
||||
],
|
||||
stdin=subprocess.PIPE,
|
||||
) as exec_process:
|
||||
exec_process.stdin = cast(IO[bytes], exec_process.stdin)
|
||||
|
||||
assert exec_process.stdin
|
||||
with open(from_path, "rb") as from_file:
|
||||
shutil.copyfileobj(from_file, exec_process.stdin)
|
||||
# Bug in mypy, https://github.com/python/mypy/issues/15031
|
||||
shutil.copyfileobj(from_file, exec_process.stdin) # type: ignore[misc]
|
||||
|
||||
exec_process.stdin.close()
|
||||
exec_process.wait()
|
||||
@@ -196,10 +240,10 @@ class OCIContainer:
|
||||
# note: we assume from_path is a dir
|
||||
to_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if self.engine == "podman":
|
||||
if self.engine.name == "podman":
|
||||
subprocess.run(
|
||||
[
|
||||
self.engine,
|
||||
self.engine.name,
|
||||
"cp",
|
||||
f"{self.name}:{from_path}/.",
|
||||
str(to_path),
|
||||
@@ -207,10 +251,10 @@ class OCIContainer:
|
||||
check=True,
|
||||
cwd=to_path,
|
||||
)
|
||||
elif self.engine == "docker":
|
||||
elif self.engine.name == "docker":
|
||||
# There is a bug in docker that prevents a simple 'cp' invocation
|
||||
# from working https://github.com/moby/moby/issues/38995
|
||||
command = f"{self.engine} exec -i {self.name} tar -cC {shell_quote(from_path)} -f - . | tar -xf -"
|
||||
command = f"{self.engine.name} exec -i {self.name} tar -cC {shell_quote(from_path)} -f - . | tar -xf -"
|
||||
subprocess.run(
|
||||
command,
|
||||
shell=True,
|
||||
@@ -218,7 +262,7 @@ class OCIContainer:
|
||||
cwd=to_path,
|
||||
)
|
||||
else:
|
||||
raise KeyError(self.engine)
|
||||
raise KeyError(self.engine.name)
|
||||
|
||||
def glob(self, path: PurePosixPath, pattern: str) -> list[PurePosixPath]:
|
||||
glob_pattern = path.joinpath(pattern)
|
||||
@@ -239,11 +283,10 @@ class OCIContainer:
|
||||
def call(
|
||||
self,
|
||||
args: Sequence[PathOrStr],
|
||||
env: dict[str, str] | None = None,
|
||||
env: Mapping[str, str] | None = None,
|
||||
capture_output: bool = False,
|
||||
cwd: PathOrStr | None = None,
|
||||
) -> str:
|
||||
|
||||
if cwd is None:
|
||||
# Podman does not start the a container in a specific working dir
|
||||
# so we always need to specify it when making calls.
|
||||
@@ -330,17 +373,17 @@ class OCIContainer:
|
||||
capture_output=True,
|
||||
)
|
||||
)
|
||||
return cast(Dict[str, str], env)
|
||||
return typing.cast(Dict[str, str], env)
|
||||
|
||||
def environment_executor(self, command: list[str], environment: dict[str, str]) -> str:
|
||||
def environment_executor(self, command: Sequence[str], environment: dict[str, str]) -> str:
|
||||
# used as an EnvironmentExecutor to evaluate commands and capture output
|
||||
return self.call(command, env=environment, capture_output=True)
|
||||
|
||||
def debug_info(self) -> str:
|
||||
if self.engine == "podman":
|
||||
command = f"{self.engine} info --debug"
|
||||
if self.engine.name == "podman":
|
||||
command = f"{self.engine.name} info --debug"
|
||||
else:
|
||||
command = f"{self.engine} info"
|
||||
command = f"{self.engine.name} info"
|
||||
completed = subprocess.run(
|
||||
command,
|
||||
shell=True,
|
||||
|
||||
+168
-49
@@ -1,33 +1,33 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import collections
|
||||
import configparser
|
||||
import contextlib
|
||||
import dataclasses
|
||||
import difflib
|
||||
import functools
|
||||
import os
|
||||
import shlex
|
||||
import sys
|
||||
import textwrap
|
||||
import traceback
|
||||
from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Set
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, Dict, Generator, Iterator, List, Mapping, Union, cast
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
import tomli as tomllib
|
||||
from typing import Any, Dict, List, Literal, TypedDict, Union
|
||||
|
||||
from packaging.specifiers import SpecifierSet
|
||||
|
||||
from ._compat import tomllib
|
||||
from ._compat.typing import NotRequired
|
||||
from .architecture import Architecture
|
||||
from .environment import EnvironmentParseError, ParsedEnvironment, parse_environment
|
||||
from .oci_container import ContainerEngine
|
||||
from .logger import log
|
||||
from .oci_container import OCIContainerEngineConfig
|
||||
from .projectfiles import get_requires_python_str
|
||||
from .typing import PLATFORMS, Literal, NotRequired, PlatformName, TypedDict
|
||||
from .typing import PLATFORMS, PlatformName
|
||||
from .util import (
|
||||
MANYLINUX_ARCHS,
|
||||
MUSLLINUX_ARCHS,
|
||||
BuildFrontend,
|
||||
BuildFrontendConfig,
|
||||
BuildSelector,
|
||||
DependencyConstraints,
|
||||
TestSelector,
|
||||
@@ -52,6 +52,20 @@ class CommandLineArguments:
|
||||
allow_empty: bool
|
||||
prerelease_pythons: bool
|
||||
|
||||
@staticmethod
|
||||
def defaults() -> CommandLineArguments:
|
||||
return CommandLineArguments(
|
||||
platform="auto",
|
||||
allow_empty=False,
|
||||
archs=None,
|
||||
only=None,
|
||||
config_file="",
|
||||
output_dir=Path("wheelhouse"),
|
||||
package_dir=Path("."),
|
||||
prerelease_pythons=False,
|
||||
print_build_identifiers=False,
|
||||
)
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class GlobalOptions:
|
||||
@@ -60,7 +74,7 @@ class GlobalOptions:
|
||||
build_selector: BuildSelector
|
||||
test_selector: TestSelector
|
||||
architectures: set[Architecture]
|
||||
container_engine: ContainerEngine
|
||||
container_engine: OCIContainerEngineConfig
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
@@ -78,7 +92,7 @@ class BuildOptions:
|
||||
test_requires: list[str]
|
||||
test_extras: str
|
||||
build_verbosity: int
|
||||
build_frontend: BuildFrontend
|
||||
build_frontend: BuildFrontendConfig | None
|
||||
config_settings: str
|
||||
|
||||
@property
|
||||
@@ -121,8 +135,14 @@ DISALLOWED_OPTIONS = {
|
||||
|
||||
|
||||
class TableFmt(TypedDict):
|
||||
# a format string, used with '.format', with `k` and `v` parameters
|
||||
# e.g. "{k}={v}"
|
||||
item: str
|
||||
# the string that is inserted between items
|
||||
# e.g. " "
|
||||
sep: str
|
||||
# a quoting function that, if supplied, is called to quote each value
|
||||
# e.g. shlex.quote
|
||||
quote: NotRequired[Callable[[str], str]]
|
||||
|
||||
|
||||
@@ -176,9 +196,11 @@ class OptionsReader:
|
||||
config_file_path: Path | None = None,
|
||||
*,
|
||||
platform: PlatformName,
|
||||
disallow: dict[str, set[str]] | None = None,
|
||||
env: Mapping[str, str],
|
||||
disallow: Mapping[str, Set[str]] | None = None,
|
||||
) -> None:
|
||||
self.platform = platform
|
||||
self.env = env
|
||||
self.disallow = disallow or {}
|
||||
|
||||
# Open defaults.toml, loading both global and platform sections
|
||||
@@ -319,8 +341,8 @@ class OptionsReader:
|
||||
# get the option from the environment, then the config file, then finally the default.
|
||||
# platform-specific options are preferred, if they're allowed.
|
||||
result = _dig_first(
|
||||
(os.environ if env_plat else {}, plat_envvar), # type: ignore[arg-type]
|
||||
(os.environ, envvar),
|
||||
(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),
|
||||
@@ -362,13 +384,21 @@ def _inner_fmt(k: str, v: Any, table: TableFmt) -> Iterator[str]:
|
||||
|
||||
|
||||
class Options:
|
||||
def __init__(self, platform: PlatformName, command_line_arguments: CommandLineArguments):
|
||||
def __init__(
|
||||
self,
|
||||
platform: PlatformName,
|
||||
command_line_arguments: CommandLineArguments,
|
||||
env: Mapping[str, str],
|
||||
read_config_file: bool = True,
|
||||
):
|
||||
self.platform = platform
|
||||
self.command_line_arguments = command_line_arguments
|
||||
self.env = env
|
||||
|
||||
self.reader = OptionsReader(
|
||||
self.config_file_path,
|
||||
self.config_file_path if read_config_file else None,
|
||||
platform=platform,
|
||||
env=env,
|
||||
disallow=DISALLOWED_OPTIONS,
|
||||
)
|
||||
|
||||
@@ -402,13 +432,13 @@ class Options:
|
||||
test_skip = self.reader.get("test-skip", env_plat=False, sep=" ")
|
||||
|
||||
prerelease_pythons = args.prerelease_pythons or strtobool(
|
||||
os.environ.get("CIBW_PRERELEASE_PYTHONS", "0")
|
||||
self.env.get("CIBW_PRERELEASE_PYTHONS", "0")
|
||||
)
|
||||
|
||||
# This is not supported in tool.cibuildwheel, as it comes from a standard location.
|
||||
# Passing this in as an environment variable will override pyproject.toml, setup.cfg, or setup.py
|
||||
requires_python_str: str | None = (
|
||||
os.environ.get("CIBW_PROJECT_REQUIRES_PYTHON") or self.package_requires_python_str
|
||||
self.env.get("CIBW_PROJECT_REQUIRES_PYTHON") or self.package_requires_python_str
|
||||
)
|
||||
requires_python = None if requires_python_str is None else SpecifierSet(requires_python_str)
|
||||
|
||||
@@ -420,6 +450,7 @@ class Options:
|
||||
build_config = args.only
|
||||
skip_config = ""
|
||||
architectures = Architecture.all_archs(self.platform)
|
||||
prerelease_pythons = True
|
||||
|
||||
build_selector = BuildSelector(
|
||||
build_config=build_config,
|
||||
@@ -429,15 +460,17 @@ class Options:
|
||||
)
|
||||
test_selector = TestSelector(skip_config=test_skip)
|
||||
|
||||
container_engine_str = self.reader.get("container-engine")
|
||||
container_engine_str = self.reader.get(
|
||||
"container-engine", table={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote}
|
||||
)
|
||||
|
||||
if container_engine_str not in ["docker", "podman"]:
|
||||
msg = f"cibuildwheel: Unrecognised container_engine {container_engine_str!r}, only 'docker' and 'podman' are supported"
|
||||
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)
|
||||
|
||||
container_engine = cast(ContainerEngine, container_engine_str)
|
||||
|
||||
return GlobalOptions(
|
||||
package_dir=package_dir,
|
||||
output_dir=output_dir,
|
||||
@@ -455,7 +488,6 @@ class Options:
|
||||
with self.reader.identifier(identifier):
|
||||
before_all = self.reader.get("before-all", sep=" && ")
|
||||
|
||||
build_frontend_str = self.reader.get("build-frontend", env_plat=False)
|
||||
environment_config = self.reader.get(
|
||||
"environment", table={"item": '{k}="{v}"', "sep": " "}
|
||||
)
|
||||
@@ -473,15 +505,20 @@ class Options:
|
||||
test_extras = self.reader.get("test-extras", sep=",")
|
||||
build_verbosity_str = self.reader.get("build-verbosity")
|
||||
|
||||
build_frontend: BuildFrontend
|
||||
if build_frontend_str == "build":
|
||||
build_frontend = "build"
|
||||
elif build_frontend_str == "pip":
|
||||
build_frontend = "pip"
|
||||
build_frontend_str = self.reader.get(
|
||||
"build-frontend",
|
||||
env_plat=False,
|
||||
table={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
||||
)
|
||||
build_frontend: BuildFrontendConfig | None
|
||||
if not build_frontend_str or build_frontend_str == "default":
|
||||
build_frontend = None
|
||||
else:
|
||||
msg = f"cibuildwheel: Unrecognised build frontend {build_frontend_str!r}, only 'pip' and 'build' are supported"
|
||||
print(msg, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
try:
|
||||
build_frontend = BuildFrontendConfig.from_config_string(build_frontend_str)
|
||||
except ValueError as e:
|
||||
print(f"cibuildwheel: {e}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
try:
|
||||
environment = parse_environment(environment_config)
|
||||
@@ -497,7 +534,7 @@ class Options:
|
||||
if self.platform == "linux":
|
||||
for env_var_name in environment_pass:
|
||||
with contextlib.suppress(KeyError):
|
||||
environment.add(env_var_name, os.environ[env_var_name])
|
||||
environment.add(env_var_name, self.env[env_var_name])
|
||||
|
||||
if dependency_versions == "pinned":
|
||||
dependency_constraints: None | (
|
||||
@@ -571,7 +608,7 @@ class Options:
|
||||
config_settings=config_settings,
|
||||
)
|
||||
|
||||
def check_for_invalid_configuration(self, identifiers: list[str]) -> None:
|
||||
def check_for_invalid_configuration(self, identifiers: Iterable[str]) -> None:
|
||||
if self.platform in {"macos", "windows"}:
|
||||
before_all_values = {self.build_options(i).before_all for i in identifiers}
|
||||
|
||||
@@ -594,37 +631,119 @@ class Options:
|
||||
deprecated_selectors("CIBW_SKIP", build_selector.skip_config)
|
||||
deprecated_selectors("CIBW_TEST_SKIP", test_selector.skip_config)
|
||||
|
||||
def summary(self, identifiers: list[str]) -> str:
|
||||
lines = [
|
||||
f"{option_name}: {option_value!r}"
|
||||
for option_name, option_value in sorted(dataclasses.asdict(self.globals).items())
|
||||
]
|
||||
@cached_property
|
||||
def defaults(self) -> Options:
|
||||
return Options(
|
||||
platform=self.platform,
|
||||
command_line_arguments=CommandLineArguments.defaults(),
|
||||
env={},
|
||||
read_config_file=False,
|
||||
)
|
||||
|
||||
build_option_defaults = self.build_options(identifier=None)
|
||||
def summary(self, identifiers: Iterable[str]) -> str:
|
||||
lines = []
|
||||
global_option_names = sorted(f.name for f in dataclasses.fields(self.globals))
|
||||
|
||||
for option_name in global_option_names:
|
||||
option_value = getattr(self.globals, option_name)
|
||||
default_value = getattr(self.defaults.globals, option_name)
|
||||
lines.append(self.option_summary(option_name, option_value, default_value))
|
||||
|
||||
build_options = self.build_options(identifier=None)
|
||||
build_options_defaults = self.defaults.build_options(identifier=None)
|
||||
build_options_for_identifier = {
|
||||
identifier: self.build_options(identifier) for identifier in identifiers
|
||||
}
|
||||
|
||||
for option_name, default_value in sorted(dataclasses.asdict(build_option_defaults).items()):
|
||||
build_option_names = sorted(f.name for f in dataclasses.fields(build_options))
|
||||
|
||||
for option_name in build_option_names:
|
||||
if option_name == "globals":
|
||||
continue
|
||||
|
||||
lines.append(f"{option_name}: {default_value!r}")
|
||||
option_value = getattr(build_options, option_name)
|
||||
default_value = getattr(build_options_defaults, option_name)
|
||||
overrides = {
|
||||
i: getattr(build_options_for_identifier[i], option_name) for i in identifiers
|
||||
}
|
||||
|
||||
# if any identifiers have an overridden value, print that too
|
||||
for identifier in identifiers:
|
||||
option_value = getattr(build_options_for_identifier[identifier], option_name)
|
||||
if option_value != default_value:
|
||||
lines.append(f" {identifier}: {option_value!r}")
|
||||
lines.append(
|
||||
self.option_summary(option_name, option_value, default_value, overrides=overrides)
|
||||
)
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
def option_summary(
|
||||
self,
|
||||
option_name: str,
|
||||
option_value: Any,
|
||||
default_value: Any,
|
||||
overrides: Mapping[str, Any] | None = None,
|
||||
) -> str:
|
||||
"""
|
||||
Return a summary of the option value, including any overrides, with
|
||||
ANSI 'dim' color if it's the default.
|
||||
"""
|
||||
value_str = self.option_summary_value(option_value)
|
||||
default_value_str = self.option_summary_value(default_value)
|
||||
overrides_value_strs = {
|
||||
k: self.option_summary_value(v) for k, v in (overrides or {}).items()
|
||||
}
|
||||
# if the override value is the same as the non-overridden value, don't print it
|
||||
overrides_value_strs = {k: v for k, v in overrides_value_strs.items() if v != value_str}
|
||||
|
||||
has_been_set = (value_str != default_value_str) or overrides_value_strs
|
||||
c = log.colors
|
||||
|
||||
result = c.gray if not has_been_set else ""
|
||||
result += f"{option_name}: "
|
||||
|
||||
if overrides_value_strs:
|
||||
overrides_groups = collections.defaultdict(list)
|
||||
for k, v in overrides_value_strs.items():
|
||||
overrides_groups[v].append(k)
|
||||
|
||||
result += "\n *: "
|
||||
result += self.indent_if_multiline(value_str, " ")
|
||||
|
||||
for override_value_str, identifiers in overrides_groups.items():
|
||||
result += f"\n {', '.join(identifiers)}: "
|
||||
result += self.indent_if_multiline(override_value_str, " ")
|
||||
else:
|
||||
result += self.indent_if_multiline(value_str, " ")
|
||||
|
||||
result += c.end
|
||||
|
||||
return result
|
||||
|
||||
def indent_if_multiline(self, value: str, indent: str) -> str:
|
||||
if "\n" in value:
|
||||
return "\n" + textwrap.indent(value.strip(), indent)
|
||||
else:
|
||||
return value
|
||||
|
||||
def option_summary_value(self, option_value: Any) -> str:
|
||||
if hasattr(option_value, "options_summary"):
|
||||
option_value = option_value.options_summary()
|
||||
|
||||
if isinstance(option_value, list):
|
||||
return "".join(f"{el}\n" for el in option_value)
|
||||
|
||||
if isinstance(option_value, set):
|
||||
return ", ".join(str(el) for el in sorted(option_value))
|
||||
|
||||
if isinstance(option_value, dict):
|
||||
return "".join(f"{k}: {v}\n" for k, v in option_value.items())
|
||||
|
||||
return str(option_value)
|
||||
|
||||
|
||||
def compute_options(
|
||||
platform: PlatformName,
|
||||
command_line_arguments: CommandLineArguments,
|
||||
env: Mapping[str, str],
|
||||
) -> Options:
|
||||
options = Options(platform=platform, command_line_arguments=command_line_arguments)
|
||||
options = Options(platform=platform, command_line_arguments=command_line_arguments, env=env)
|
||||
options.check_for_deprecated_options()
|
||||
return options
|
||||
|
||||
|
||||
@@ -3,26 +3,46 @@ from __future__ import annotations
|
||||
import ast
|
||||
import configparser
|
||||
import contextlib
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
import tomli as tomllib
|
||||
from ._compat import tomllib
|
||||
|
||||
if sys.version_info < (3, 8):
|
||||
Constant = ast.Str
|
||||
|
||||
def get_constant(x: ast.Str) -> str:
|
||||
return x.s
|
||||
def get_parent(node: ast.AST | None, depth: int = 1) -> ast.AST | None:
|
||||
for _ in range(depth):
|
||||
node = getattr(node, "parent", None)
|
||||
return node
|
||||
|
||||
else:
|
||||
Constant = ast.Constant
|
||||
|
||||
def get_constant(x: ast.Constant) -> Any:
|
||||
return x.value
|
||||
def is_main(parent: ast.AST | None) -> bool:
|
||||
if parent is None:
|
||||
return False
|
||||
|
||||
# This would be much nicer with 3.10's pattern matching!
|
||||
if not isinstance(parent, ast.If):
|
||||
return False
|
||||
if not isinstance(parent.test, ast.Compare):
|
||||
return False
|
||||
|
||||
try:
|
||||
(op,) = parent.test.ops
|
||||
(comp,) = parent.test.comparators
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
if not isinstance(op, ast.Eq):
|
||||
return False
|
||||
|
||||
values = {comp, parent.test.left}
|
||||
|
||||
mains = {x for x in values if isinstance(x, ast.Constant) and x.value == "__main__"}
|
||||
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
|
||||
|
||||
|
||||
class Analyzer(ast.NodeVisitor):
|
||||
@@ -36,14 +56,24 @@ class Analyzer(ast.NodeVisitor):
|
||||
super().visit(node)
|
||||
|
||||
def visit_keyword(self, node: ast.keyword) -> None:
|
||||
# Must not be nested except for if __name__ == "__main__"
|
||||
|
||||
self.generic_visit(node)
|
||||
if node.arg == "python_requires":
|
||||
# Must not be nested in an if or other structure
|
||||
# This will be Module -> Expr -> Call -> keyword
|
||||
if not hasattr(node.parent.parent.parent, "parent") and isinstance( # type: ignore[attr-defined]
|
||||
node.value, Constant
|
||||
):
|
||||
self.requires_python = get_constant(node.value)
|
||||
# This will be Module -> Expr -> Call -> keyword
|
||||
parent = get_parent(node, 4)
|
||||
unnested = parent is None
|
||||
|
||||
# This will be Module -> If -> Expr -> Call -> keyword
|
||||
name_main_unnested = (
|
||||
parent is not None and get_parent(parent) is None and is_main(get_parent(node, 3))
|
||||
)
|
||||
|
||||
if (
|
||||
node.arg == "python_requires"
|
||||
and isinstance(node.value, ast.Constant)
|
||||
and (unnested or name_main_unnested)
|
||||
):
|
||||
self.requires_python = node.value.value
|
||||
|
||||
|
||||
def setup_py_python_requires(content: str) -> str | None:
|
||||
@@ -73,8 +103,8 @@ def get_requires_python_str(package_dir: Path) -> str | None:
|
||||
with contextlib.suppress(KeyError, IndexError, TypeError):
|
||||
return str(config["options"]["python_requires"])
|
||||
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
with (package_dir / "setup.py").open(encoding="utf8") as f2:
|
||||
return setup_py_python_requires(f2.read())
|
||||
setup_py = package_dir / "setup.py"
|
||||
with contextlib.suppress(FileNotFoundError), setup_py.open(encoding="utf8") as f2:
|
||||
return setup_py_python_requires(f2.read())
|
||||
|
||||
return None
|
||||
|
||||
@@ -6,69 +6,82 @@ python_configurations = [
|
||||
{ identifier = "cp39-manylinux_x86_64", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "cp39-manylinux_i686", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "pp310-manylinux_x86_64", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" },
|
||||
{ identifier = "cp36-manylinux_aarch64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-manylinux_aarch64", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-manylinux_aarch64", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
{ identifier = "cp39-manylinux_aarch64", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "cp39-manylinux_ppc64le", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "cp39-manylinux_s390x", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "pp310-manylinux_aarch64", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" },
|
||||
{ identifier = "pp37-manylinux_i686", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
|
||||
{ identifier = "pp38-manylinux_i686", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" },
|
||||
{ identifier = "pp39-manylinux_i686", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" },
|
||||
{ identifier = "pp310-manylinux_i686", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" },
|
||||
{ identifier = "cp36-musllinux_x86_64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
|
||||
{ identifier = "cp37-musllinux_x86_64", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
|
||||
{ identifier = "cp38-musllinux_x86_64", version = "3.8", path_str = "/opt/python/cp38-cp38" },
|
||||
{ identifier = "cp39-musllinux_x86_64", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "cp39-musllinux_i686", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "cp39-musllinux_aarch64", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "cp39-musllinux_ppc64le", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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 = "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" },
|
||||
{ identifier = "cp39-musllinux_s390x", version = "3.9", path_str = "/opt/python/cp39-cp39" },
|
||||
{ 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" },
|
||||
]
|
||||
|
||||
[macos]
|
||||
@@ -81,15 +94,22 @@ python_configurations = [
|
||||
{ identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.13/python-3.9.13-macos11.pkg" },
|
||||
{ identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.13/python-3.9.13-macos11.pkg" },
|
||||
{ identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.13/python-3.9.13-macos11.pkg" },
|
||||
{ identifier = "cp310-macosx_x86_64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.8/python-3.10.8-macos11.pkg" },
|
||||
{ identifier = "cp310-macosx_arm64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.8/python-3.10.8-macos11.pkg" },
|
||||
{ identifier = "cp310-macosx_universal2", version = "3.10", url = "https://www.python.org/ftp/python/3.10.8/python-3.10.8-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_x86_64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.0/python-3.11.0-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.0/python-3.11.0-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.0/python-3.11.0-macos11.pkg" },
|
||||
{ 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.0rc3-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0rc3-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0rc3-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.9-osx64.tar.bz2" },
|
||||
{ identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-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" },
|
||||
]
|
||||
|
||||
[windows]
|
||||
@@ -102,14 +122,18 @@ python_configurations = [
|
||||
{ identifier = "cp38-win_amd64", version = "3.8.10", arch = "64" },
|
||||
{ identifier = "cp39-win32", version = "3.9.13", arch = "32" },
|
||||
{ identifier = "cp39-win_amd64", version = "3.9.13", arch = "64" },
|
||||
{ identifier = "cp310-win32", version = "3.10.8", arch = "32" },
|
||||
{ identifier = "cp310-win_amd64", version = "3.10.8", arch = "64" },
|
||||
{ identifier = "cp311-win32", version = "3.11.0", arch = "32" },
|
||||
{ identifier = "cp311-win_amd64", version = "3.11.0", 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-rc3", arch = "32" },
|
||||
{ identifier = "cp312-win_amd64", version = "3.12.0-rc3", arch = "64" },
|
||||
{ identifier = "cp39-win_arm64", version = "3.9.10", arch = "ARM64" },
|
||||
{ identifier = "cp310-win_arm64", version = "3.10.8", arch = "ARM64" },
|
||||
{ identifier = "cp311-win_arm64", version = "3.11.0", 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-rc3", 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.9-win64.zip" },
|
||||
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-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" },
|
||||
]
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.10
|
||||
# To update, run:
|
||||
# This file is autogenerated by pip-compile with Python 3.10
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.10
|
||||
#
|
||||
delocate==0.10.2
|
||||
delocate==0.10.4
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.6
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
filelock==3.8.0
|
||||
filelock==3.12.4
|
||||
# via virtualenv
|
||||
platformdirs==2.5.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.4.0
|
||||
packaging==23.1
|
||||
# via delocate
|
||||
virtualenv==20.16.5
|
||||
platformdirs==3.10.0
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
# -r cibuildwheel/resources/constraints.in
|
||||
# delocate
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==22.3
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==65.5.0
|
||||
setuptools==68.2.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.11
|
||||
# To update, run:
|
||||
# This file is autogenerated by pip-compile with Python 3.11
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.11
|
||||
#
|
||||
delocate==0.10.2
|
||||
delocate==0.10.4
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.6
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
filelock==3.8.0
|
||||
filelock==3.12.4
|
||||
# via virtualenv
|
||||
platformdirs==2.5.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.4.0
|
||||
packaging==23.1
|
||||
# via delocate
|
||||
virtualenv==20.16.5
|
||||
platformdirs==3.10.0
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
# -r cibuildwheel/resources/constraints.in
|
||||
# delocate
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==22.3
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==65.5.0
|
||||
setuptools==68.2.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -0,0 +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
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
filelock==3.12.4
|
||||
# via virtualenv
|
||||
packaging==23.1
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
# 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
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
@@ -20,7 +20,7 @@ typing-extensions==4.1.1
|
||||
# via
|
||||
# delocate
|
||||
# importlib-metadata
|
||||
virtualenv==20.16.5
|
||||
virtualenv==20.17.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.7
|
||||
# To update, run:
|
||||
# This file is autogenerated by pip-compile with Python 3.7
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.7
|
||||
#
|
||||
delocate==0.10.2
|
||||
delocate==0.10.4
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.6
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
filelock==3.8.0
|
||||
filelock==3.12.2
|
||||
# via virtualenv
|
||||
importlib-metadata==5.0.0
|
||||
importlib-metadata==6.7.0
|
||||
# via virtualenv
|
||||
platformdirs==2.5.2
|
||||
packaging==23.1
|
||||
# via delocate
|
||||
platformdirs==3.10.0
|
||||
# via virtualenv
|
||||
typing-extensions==4.4.0
|
||||
typing-extensions==4.7.1
|
||||
# via
|
||||
# delocate
|
||||
# importlib-metadata
|
||||
virtualenv==20.16.5
|
||||
# platformdirs
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
# -r cibuildwheel/resources/constraints.in
|
||||
# delocate
|
||||
zipp==3.10.0
|
||||
wheel==0.41.2
|
||||
# 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==22.3
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==65.5.0
|
||||
setuptools==68.0.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.8
|
||||
# To update, run:
|
||||
# This file is autogenerated by pip-compile with Python 3.8
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.8
|
||||
#
|
||||
delocate==0.10.2
|
||||
delocate==0.10.4
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.6
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
filelock==3.8.0
|
||||
filelock==3.12.4
|
||||
# via virtualenv
|
||||
platformdirs==2.5.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.4.0
|
||||
packaging==23.1
|
||||
# via delocate
|
||||
virtualenv==20.16.5
|
||||
platformdirs==3.10.0
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
# -r cibuildwheel/resources/constraints.in
|
||||
# delocate
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==22.3
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==65.5.0
|
||||
setuptools==68.2.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.9
|
||||
# To update, run:
|
||||
# This file is autogenerated by pip-compile with Python 3.9
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.9
|
||||
#
|
||||
delocate==0.10.2
|
||||
delocate==0.10.4
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.6
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
filelock==3.8.0
|
||||
filelock==3.12.4
|
||||
# via virtualenv
|
||||
platformdirs==2.5.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.4.0
|
||||
packaging==23.1
|
||||
# via delocate
|
||||
virtualenv==20.16.5
|
||||
platformdirs==3.10.0
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
# -r cibuildwheel/resources/constraints.in
|
||||
# delocate
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==22.3
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==65.5.0
|
||||
setuptools==68.2.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with python 3.11
|
||||
# To update, run:
|
||||
# This file is autogenerated by pip-compile with Python 3.12
|
||||
# by the following command:
|
||||
#
|
||||
# nox -s update_constraints-3.11
|
||||
# nox -s update_constraints-3.12
|
||||
#
|
||||
delocate==0.10.2
|
||||
delocate==0.10.4
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.6
|
||||
distlib==0.3.7
|
||||
# via virtualenv
|
||||
filelock==3.8.0
|
||||
filelock==3.12.4
|
||||
# via virtualenv
|
||||
platformdirs==2.5.2
|
||||
# via virtualenv
|
||||
typing-extensions==4.4.0
|
||||
packaging==23.1
|
||||
# via delocate
|
||||
virtualenv==20.16.5
|
||||
platformdirs==3.10.0
|
||||
# via virtualenv
|
||||
typing-extensions==4.8.0
|
||||
# via delocate
|
||||
virtualenv==20.24.5
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.41.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
wheel==0.37.1
|
||||
# via
|
||||
# -r cibuildwheel/resources/constraints.in
|
||||
# delocate
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
pip==22.3
|
||||
pip==23.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
setuptools==65.5.0
|
||||
setuptools==68.2.2
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
|
||||
@@ -4,7 +4,7 @@ skip = ""
|
||||
test-skip = ""
|
||||
|
||||
archs = ["auto"]
|
||||
build-frontend = "pip"
|
||||
build-frontend = "default"
|
||||
config-settings = {}
|
||||
dependency-versions = "pinned"
|
||||
environment = {}
|
||||
|
||||
@@ -1,49 +1,54 @@
|
||||
[x86_64]
|
||||
manylinux1 = quay.io/pypa/manylinux1_x86_64:2022-10-15-7701e25
|
||||
manylinux1 = quay.io/pypa/manylinux1_x86_64:2023-09-12-f07b683
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-10-25-fbea779
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2022-10-25-fbea779
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-09-24-36b93e4
|
||||
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-24-36b93e4
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2023-09-24-36b93e4
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2023-09-24-36b93e4
|
||||
|
||||
[i686]
|
||||
manylinux1 = quay.io/pypa/manylinux1_i686:2022-10-15-7701e25
|
||||
manylinux1 = quay.io/pypa/manylinux1_i686:2023-09-12-f07b683
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-10-25-fbea779
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-09-24-36b93e4
|
||||
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-24-36b93e4
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2023-09-24-36b93e4
|
||||
|
||||
[pypy_x86_64]
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-10-25-fbea779
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-09-24-36b93e4
|
||||
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-24-36b93e4
|
||||
|
||||
[pypy_i686]
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-09-24-36b93e4
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
|
||||
|
||||
[aarch64]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-10-25-fbea779
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2022-10-25-fbea779
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-09-24-36b93e4
|
||||
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-24-36b93e4
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2023-09-24-36b93e4
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2023-09-24-36b93e4
|
||||
|
||||
[ppc64le]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-10-25-fbea779
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2022-10-25-fbea779
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2023-09-24-36b93e4
|
||||
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-24-36b93e4
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2023-09-24-36b93e4
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2023-09-24-36b93e4
|
||||
|
||||
[s390x]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-10-25-fbea779
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2022-10-25-fbea779
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2023-09-24-36b93e4
|
||||
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-24-36b93e4
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2023-09-24-36b93e4
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2023-09-24-36b93e4
|
||||
|
||||
[pypy_aarch64]
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2022-10-25-fbea779
|
||||
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-10-25-fbea779
|
||||
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2022-10-25-fbea779
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-09-24-36b93e4
|
||||
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-24-36b93e4
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# this file is copied to the testing cwd, to raise the below error message if
|
||||
# pytest/unittest is run from there.
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestStringMethods(unittest.TestCase):
|
||||
def test_fail(self):
|
||||
self.fail(
|
||||
"cibuildwheel executes tests from a different working directory to "
|
||||
"your project. This ensures only your wheel is imported, preventing "
|
||||
"Python from accessing files that haven't been packaged into the "
|
||||
"wheel. Please specify a path to your tests when invoking pytest "
|
||||
"using the {project} placeholder, e.g. `pytest {project}` or "
|
||||
"`pytest {project}/tests`. cibuildwheel will replace {project} with "
|
||||
"the path to your project."
|
||||
)
|
||||
@@ -1,2 +1,2 @@
|
||||
version = "20.16.5"
|
||||
url = "https://github.com/pypa/get-virtualenv/blob/20.16.5/public/virtualenv.pyz?raw=true"
|
||||
version = "20.21.1"
|
||||
url = "https://github.com/pypa/get-virtualenv/blob/20.21.1/public/virtualenv.pyz?raw=true"
|
||||
|
||||
+9
-21
@@ -2,37 +2,19 @@ from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
if sys.version_info < (3, 8):
|
||||
from typing_extensions import Final, Literal, OrderedDict, Protocol, TypedDict
|
||||
else:
|
||||
from typing import Final, Literal, OrderedDict, Protocol, TypedDict
|
||||
|
||||
if sys.version_info < (3, 11):
|
||||
from typing_extensions import NotRequired, assert_never
|
||||
else:
|
||||
from typing import NotRequired, assert_never
|
||||
import typing
|
||||
from typing import Final, Literal, Protocol, Union
|
||||
|
||||
__all__ = (
|
||||
"Final",
|
||||
"Literal",
|
||||
"PLATFORMS",
|
||||
"PathOrStr",
|
||||
"PlatformName",
|
||||
"Protocol",
|
||||
"PLATFORMS",
|
||||
"PopenBytes",
|
||||
"Protocol",
|
||||
"TypedDict",
|
||||
"OrderedDict",
|
||||
"assert_never",
|
||||
"NotRequired",
|
||||
)
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
if typing.TYPE_CHECKING:
|
||||
PopenBytes = subprocess.Popen[bytes]
|
||||
PathOrStr = Union[str, os.PathLike[str]]
|
||||
else:
|
||||
@@ -42,3 +24,9 @@ else:
|
||||
|
||||
PlatformName = Literal["linux", "macos", "windows"]
|
||||
PLATFORMS: Final[set[PlatformName]] = {"linux", "macos", "windows"}
|
||||
|
||||
|
||||
class GenericPythonConfiguration(Protocol):
|
||||
@property
|
||||
def identifier(self) -> str:
|
||||
...
|
||||
|
||||
+145
-40
@@ -11,32 +11,19 @@ import subprocess
|
||||
import sys
|
||||
import textwrap
|
||||
import time
|
||||
import typing
|
||||
import urllib.request
|
||||
from collections import defaultdict
|
||||
from collections.abc import Generator, Iterable, Mapping, Sequence
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
from functools import lru_cache
|
||||
from functools import cached_property, lru_cache
|
||||
from pathlib import Path, PurePath
|
||||
from time import sleep
|
||||
from typing import (
|
||||
Any,
|
||||
ClassVar,
|
||||
Generator,
|
||||
Iterable,
|
||||
Sequence,
|
||||
TextIO,
|
||||
TypeVar,
|
||||
cast,
|
||||
overload,
|
||||
)
|
||||
from typing import Any, ClassVar, Final, Literal, TextIO, TypeVar
|
||||
|
||||
import bracex
|
||||
import certifi
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
import tomli as tomllib
|
||||
|
||||
from filelock import FileLock
|
||||
from packaging.requirements import InvalidRequirement, Requirement
|
||||
from packaging.specifiers import SpecifierSet
|
||||
@@ -44,7 +31,8 @@ from packaging.utils import parse_wheel_filename
|
||||
from packaging.version import Version
|
||||
from platformdirs import user_cache_path
|
||||
|
||||
from cibuildwheel.typing import Final, Literal, PathOrStr, PlatformName
|
||||
from ._compat import tomllib
|
||||
from .typing import PathOrStr, PlatformName
|
||||
|
||||
__all__ = [
|
||||
"resources_dir",
|
||||
@@ -67,7 +55,8 @@ resources_dir: Final[Path] = Path(__file__).parent / "resources"
|
||||
|
||||
install_certifi_script: Final[Path] = resources_dir / "install_certifi.py"
|
||||
|
||||
BuildFrontend = Literal["pip", "build"]
|
||||
test_fail_cwd_file: Final[Path] = resources_dir / "testing_temp_dir_file.py"
|
||||
|
||||
|
||||
MANYLINUX_ARCHS: Final[tuple[str, ...]] = (
|
||||
"x86_64",
|
||||
@@ -96,20 +85,20 @@ CIBW_CACHE_PATH: Final[Path] = Path(
|
||||
IS_WIN: Final[bool] = sys.platform.startswith("win")
|
||||
|
||||
|
||||
@overload
|
||||
@typing.overload
|
||||
def call(
|
||||
*args: PathOrStr,
|
||||
env: dict[str, str] | None = None,
|
||||
env: Mapping[str, str] | None = None,
|
||||
cwd: PathOrStr | None = None,
|
||||
capture_stdout: Literal[False] = ...,
|
||||
) -> None:
|
||||
...
|
||||
|
||||
|
||||
@overload
|
||||
@typing.overload
|
||||
def call(
|
||||
*args: PathOrStr,
|
||||
env: dict[str, str] | None = None,
|
||||
env: Mapping[str, str] | None = None,
|
||||
cwd: PathOrStr | None = None,
|
||||
capture_stdout: Literal[True],
|
||||
) -> str:
|
||||
@@ -118,7 +107,7 @@ def call(
|
||||
|
||||
def call(
|
||||
*args: PathOrStr,
|
||||
env: dict[str, str] | None = None,
|
||||
env: Mapping[str, str] | None = None,
|
||||
cwd: PathOrStr | None = None,
|
||||
capture_stdout: bool = False,
|
||||
) -> str | None:
|
||||
@@ -138,10 +127,12 @@ def call(
|
||||
result = subprocess.run(args_, check=True, shell=IS_WIN, env=env, cwd=cwd, **kwargs)
|
||||
if not capture_stdout:
|
||||
return None
|
||||
return cast(str, result.stdout)
|
||||
return typing.cast(str, result.stdout)
|
||||
|
||||
|
||||
def shell(*commands: str, env: dict[str, str] | None = None, cwd: PathOrStr | None = None) -> None:
|
||||
def shell(
|
||||
*commands: str, env: Mapping[str, str] | None = None, cwd: PathOrStr | None = None
|
||||
) -> None:
|
||||
command = " ".join(commands)
|
||||
print(f"+ {command}")
|
||||
subprocess.run(command, env=env, cwd=cwd, shell=True, check=True)
|
||||
@@ -206,9 +197,10 @@ def get_build_verbosity_extra_flags(level: int) -> list[str]:
|
||||
return []
|
||||
|
||||
|
||||
def split_config_settings(config_settings: str) -> list[str]:
|
||||
def split_config_settings(config_settings: str, frontend: Literal["pip", "build"]) -> list[str]:
|
||||
config_settings_list = shlex.split(config_settings)
|
||||
return [f"--config-setting={setting}" for setting in config_settings_list]
|
||||
s = "s" if frontend == "pip" else ""
|
||||
return [f"--config-setting{s}={setting}" for setting in config_settings_list]
|
||||
|
||||
|
||||
def read_python_configs(config: PlatformName) -> list[dict[str, str]]:
|
||||
@@ -270,6 +262,14 @@ class BuildSelector:
|
||||
|
||||
return should_build and not should_skip
|
||||
|
||||
def options_summary(self) -> Any:
|
||||
return {
|
||||
"build_config": self.build_config,
|
||||
"skip_config": self.skip_config,
|
||||
"requires_python": str(self.requires_python),
|
||||
"prerelease_pythons": self.prerelease_pythons,
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TestSelector:
|
||||
@@ -283,6 +283,9 @@ class TestSelector:
|
||||
should_skip = selector_matches(self.skip_config, build_id)
|
||||
return not should_skip
|
||||
|
||||
def options_summary(self) -> Any:
|
||||
return {"skip_config": self.skip_config}
|
||||
|
||||
|
||||
# Taken from https://stackoverflow.com/a/107717
|
||||
class Unbuffered:
|
||||
@@ -356,6 +359,40 @@ class DependencyConstraints:
|
||||
|
||||
return self.base_file_path == o.base_file_path
|
||||
|
||||
def options_summary(self) -> Any:
|
||||
if self == DependencyConstraints.with_defaults():
|
||||
return "pinned"
|
||||
else:
|
||||
return self.base_file_path.name
|
||||
|
||||
|
||||
BuildFrontendName = Literal["pip", "build"]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BuildFrontendConfig:
|
||||
name: BuildFrontendName
|
||||
args: Sequence[str] = ()
|
||||
|
||||
@staticmethod
|
||||
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"
|
||||
raise ValueError(msg)
|
||||
|
||||
name = typing.cast(BuildFrontendName, name)
|
||||
|
||||
args = config_dict.get("args") or []
|
||||
return BuildFrontendConfig(name=name, args=args)
|
||||
|
||||
def options_summary(self) -> str | dict[str, str]:
|
||||
if not self.args:
|
||||
return self.name
|
||||
else:
|
||||
return {"name": self.name, "args": repr(self.args)}
|
||||
|
||||
|
||||
class NonPlatformWheelError(Exception):
|
||||
def __init__(self) -> None:
|
||||
@@ -478,7 +515,7 @@ def print_new_wheels(msg: str, output_dir: Path) -> Generator[None, None, None]:
|
||||
)
|
||||
|
||||
|
||||
def get_pip_version(env: dict[str, str]) -> str:
|
||||
def get_pip_version(env: Mapping[str, str]) -> str:
|
||||
versions_output_text = call(
|
||||
"python", "-m", "pip", "freeze", "--all", capture_stdout=True, env=env
|
||||
)
|
||||
@@ -524,8 +561,8 @@ def _parse_constraints_for_virtualenv(
|
||||
constraint_path = Path(dependency_constraint_flags[1])
|
||||
assert constraint_path.exists()
|
||||
with constraint_path.open(encoding="utf-8") as constraint_file:
|
||||
for line in constraint_file:
|
||||
line = line.strip()
|
||||
for line_ in constraint_file:
|
||||
line = line_.strip()
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith("#"):
|
||||
@@ -587,7 +624,7 @@ def virtualenv(
|
||||
else:
|
||||
paths = [str(venv_path / "bin")]
|
||||
env = os.environ.copy()
|
||||
env["PATH"] = os.pathsep.join(paths + [env["PATH"]])
|
||||
env["PATH"] = os.pathsep.join([*paths, env["PATH"]])
|
||||
return env
|
||||
|
||||
|
||||
@@ -629,7 +666,7 @@ def find_compatible_wheel(wheels: Sequence[T], identifier: str) -> T | None:
|
||||
continue
|
||||
else:
|
||||
# Windows should exactly match
|
||||
if not tag.platform == platform:
|
||||
if tag.platform != platform:
|
||||
continue
|
||||
|
||||
# If all the filters above pass, then the wheel is a previously built compatible wheel.
|
||||
@@ -638,12 +675,6 @@ def find_compatible_wheel(wheels: Sequence[T], identifier: str) -> T | None:
|
||||
return None
|
||||
|
||||
|
||||
if sys.version_info >= (3, 8):
|
||||
from functools import cached_property
|
||||
else:
|
||||
from .functools_cached_property_38 import cached_property
|
||||
|
||||
|
||||
# Can be replaced by contextlib.chdir in Python 3.11
|
||||
@contextlib.contextmanager
|
||||
def chdir(new_path: Path | str) -> Generator[None, None, None]:
|
||||
@@ -655,3 +686,77 @@ def chdir(new_path: Path | str) -> Generator[None, None, None]:
|
||||
yield
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
def fix_ansi_codes_for_github_actions(text: str) -> str:
|
||||
"""
|
||||
Github Actions forgets the current ANSI style on every new line. This
|
||||
function repeats the current ANSI style on every new line.
|
||||
"""
|
||||
ansi_code_regex = re.compile(r"(\033\[[0-9;]*m)")
|
||||
ansi_codes: list[str] = []
|
||||
output = ""
|
||||
|
||||
for line in text.splitlines(keepends=True):
|
||||
# add the current ANSI codes to the beginning of the line
|
||||
output += "".join(ansi_codes) + line
|
||||
|
||||
# split the line at each ANSI code
|
||||
parts = ansi_code_regex.split(line)
|
||||
# if there are any ANSI codes, save them
|
||||
if len(parts) > 1:
|
||||
# iterate over the ANSI codes in this line
|
||||
for code in parts[1::2]:
|
||||
if code == "\033[0m":
|
||||
# reset the list of ANSI codes when the clear code is found
|
||||
ansi_codes = []
|
||||
else:
|
||||
ansi_codes.append(code)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def parse_key_value_string(
|
||||
key_value_string: str,
|
||||
positional_arg_names: Sequence[str] | None = None,
|
||||
kw_arg_names: Sequence[str] | None = None,
|
||||
) -> dict[str, list[str]]:
|
||||
"""
|
||||
Parses a string like "docker; create_args: --some-option=value another-option"
|
||||
"""
|
||||
if positional_arg_names is None:
|
||||
positional_arg_names = []
|
||||
if kw_arg_names is None:
|
||||
kw_arg_names = []
|
||||
|
||||
all_field_names = [*positional_arg_names, *kw_arg_names]
|
||||
|
||||
shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";:")
|
||||
shlexer.commenters = ""
|
||||
parts = list(shlexer)
|
||||
# parts now looks like
|
||||
# ['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)
|
||||
for field_i, field in enumerate(fields):
|
||||
if len(field) > 1 and field[1] == ":":
|
||||
field_name = field[0]
|
||||
values = field[2:]
|
||||
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)
|
||||
else:
|
||||
try:
|
||||
field_name = positional_arg_names[field_i]
|
||||
except IndexError:
|
||||
msg = f"Failed to parse {key_value_string!r}. Too many positional arguments - expected a maximum of {len(positional_arg_names)}"
|
||||
raise ValueError(msg) from None
|
||||
|
||||
values = field
|
||||
|
||||
result[field_name] += values
|
||||
|
||||
return result
|
||||
|
||||
+47
-33
@@ -6,24 +6,27 @@ 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 typing import Sequence
|
||||
from zipfile import ZipFile
|
||||
|
||||
from filelock import FileLock
|
||||
from packaging.version import Version
|
||||
|
||||
from ._compat.typing import assert_never
|
||||
from .architecture import Architecture
|
||||
from .environment import ParsedEnvironment
|
||||
from .logger import log
|
||||
from .options import Options
|
||||
from .typing import PathOrStr, assert_never
|
||||
from .typing import PathOrStr
|
||||
from .util import (
|
||||
CIBW_CACHE_PATH,
|
||||
AlreadyBuiltWheelError,
|
||||
BuildFrontend,
|
||||
BuildFrontendConfig,
|
||||
BuildFrontendName,
|
||||
BuildSelector,
|
||||
NonPlatformWheelError,
|
||||
call,
|
||||
@@ -35,6 +38,7 @@ from .util import (
|
||||
read_python_configs,
|
||||
shell,
|
||||
split_config_settings,
|
||||
test_fail_cwd_file,
|
||||
unwrap,
|
||||
virtualenv,
|
||||
)
|
||||
@@ -70,9 +74,8 @@ class PythonConfiguration:
|
||||
|
||||
def get_python_configurations(
|
||||
build_selector: BuildSelector,
|
||||
architectures: set[Architecture],
|
||||
architectures: Set[Architecture],
|
||||
) -> list[PythonConfiguration]:
|
||||
|
||||
full_python_configs = read_python_configs("windows")
|
||||
|
||||
python_configurations = [PythonConfiguration(**item) for item in full_python_configs]
|
||||
@@ -115,7 +118,8 @@ def install_cpython(version: str, arch: str) -> Path:
|
||||
|
||||
|
||||
def install_pypy(tmp: Path, arch: str, url: str) -> Path:
|
||||
assert arch == "64" and "win64" in url
|
||||
assert arch == "64"
|
||||
assert "win64" in url
|
||||
# Inside the PyPy zip file is a directory with the same name
|
||||
zip_filename = url.rsplit("/", 1)[-1]
|
||||
extension = ".zip"
|
||||
@@ -134,7 +138,7 @@ def setup_setuptools_cross_compile(
|
||||
tmp: Path,
|
||||
python_configuration: PythonConfiguration,
|
||||
python_libs_base: Path,
|
||||
env: dict[str, str],
|
||||
env: MutableMapping[str, str],
|
||||
) -> None:
|
||||
distutils_cfg = tmp / "extra-setup.cfg"
|
||||
env["DIST_EXTRA_CONFIG"] = str(distutils_cfg)
|
||||
@@ -177,13 +181,12 @@ def setup_setuptools_cross_compile(
|
||||
env["SETUPTOOLS_USE_DISTUTILS"] = "local"
|
||||
|
||||
|
||||
# these cross-compile setup functions have the same signature by design
|
||||
# pylint: disable=unused-argument
|
||||
# These cross-compile setup functions have the same signature by design
|
||||
def setup_rust_cross_compile(
|
||||
tmp: Path,
|
||||
tmp: Path, # noqa: ARG001
|
||||
python_configuration: PythonConfiguration,
|
||||
python_libs_base: Path,
|
||||
env: dict[str, str],
|
||||
python_libs_base: Path, # noqa: ARG001
|
||||
env: MutableMapping[str, str],
|
||||
) -> None:
|
||||
# Assume that MSVC will be used, because we already know that we are
|
||||
# cross-compiling. MinGW users can set CARGO_BUILD_TARGET themselves
|
||||
@@ -213,7 +216,7 @@ def setup_python(
|
||||
python_configuration: PythonConfiguration,
|
||||
dependency_constraint_flags: Sequence[PathOrStr],
|
||||
environment: ParsedEnvironment,
|
||||
build_frontend: BuildFrontend,
|
||||
build_frontend: BuildFrontendName,
|
||||
) -> dict[str, str]:
|
||||
tmp.mkdir()
|
||||
implementation_id = python_configuration.identifier.split("-")[0]
|
||||
@@ -366,6 +369,7 @@ 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")
|
||||
log.build_start(config.identifier)
|
||||
|
||||
identifier_tmp_dir = tmp_path / config.identifier
|
||||
@@ -386,7 +390,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
config,
|
||||
dependency_constraint_flags,
|
||||
build_options.environment,
|
||||
build_options.build_frontend,
|
||||
build_frontend.name,
|
||||
)
|
||||
|
||||
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
|
||||
@@ -410,11 +414,13 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
log.step("Building wheel...")
|
||||
built_wheel_dir.mkdir()
|
||||
|
||||
verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
|
||||
extra_flags = split_config_settings(build_options.config_settings)
|
||||
extra_flags = split_config_settings(
|
||||
build_options.config_settings, build_frontend.name
|
||||
)
|
||||
extra_flags += build_frontend.args
|
||||
|
||||
if build_options.build_frontend == "pip":
|
||||
extra_flags += verbosity_flags
|
||||
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
|
||||
# see https://github.com/pypa/cibuildwheel/pull/369
|
||||
call(
|
||||
@@ -428,9 +434,10 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
*extra_flags,
|
||||
env=env,
|
||||
)
|
||||
elif build_options.build_frontend == "build":
|
||||
verbosity_setting = " ".join(verbosity_flags)
|
||||
extra_flags += (f"--config-setting={verbosity_setting}",)
|
||||
elif build_frontend.name == "build":
|
||||
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 = (
|
||||
@@ -461,7 +468,7 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
env=build_env,
|
||||
)
|
||||
else:
|
||||
assert_never(build_options.build_frontend)
|
||||
assert_never(build_frontend)
|
||||
|
||||
built_wheel = next(built_wheel_dir.glob("*.whl"))
|
||||
|
||||
@@ -487,20 +494,19 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
|
||||
raise AlreadyBuiltWheelError(repaired_wheel.name)
|
||||
|
||||
if build_options.test_command and options.globals.test_selector(config.identifier):
|
||||
if config.arch == "ARM64" != platform_module.machine():
|
||||
log.warning(
|
||||
unwrap(
|
||||
"""
|
||||
test_selected = options.globals.test_selector(config.identifier)
|
||||
if test_selected and config.arch == "ARM64" != platform_module.machine():
|
||||
log.warning(
|
||||
unwrap(
|
||||
"""
|
||||
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`.
|
||||
"""
|
||||
)
|
||||
)
|
||||
# skip this test
|
||||
continue
|
||||
|
||||
)
|
||||
# skip this test
|
||||
elif test_selected and build_options.test_command:
|
||||
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.
|
||||
@@ -542,18 +548,26 @@ def build(options: Options, tmp_path: Path) -> None:
|
||||
if build_options.test_requires:
|
||||
call("pip", "install", *build_options.test_requires, env=virtualenv_env)
|
||||
|
||||
# run the tests from c:\, with an absolute path in the command
|
||||
# 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=options.globals.package_dir.resolve(),
|
||||
wheel=repaired_wheel,
|
||||
)
|
||||
shell(test_command_prepared, cwd="c:\\", env=virtualenv_env)
|
||||
test_cwd = identifier_tmp_dir / "test_cwd"
|
||||
test_cwd.mkdir()
|
||||
(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 (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)
|
||||
|
||||
|
||||
@@ -4,6 +4,109 @@ title: Changelog
|
||||
|
||||
# Changelog
|
||||
|
||||
### 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).
|
||||
- ✨ 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
|
||||
|
||||
_8 August 2023_
|
||||
|
||||
- 🌟 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
|
||||
|
||||
_15 July 2023_
|
||||
|
||||
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0b4 (#1550)
|
||||
|
||||
### v2.14.0
|
||||
|
||||
_10 July 2023_
|
||||
|
||||
- ✨ 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)
|
||||
|
||||
### 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.13.0
|
||||
|
||||
_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.
|
||||
|
||||
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)
|
||||
|
||||
### v2.12.3
|
||||
|
||||
_19 April 2023_
|
||||
|
||||
- 🐛 Fix an import error when running on Python 3.7. (#1479)
|
||||
|
||||
### v2.12.2
|
||||
|
||||
_18 April 2023_
|
||||
|
||||
- 🐛 Fix a bug that caused an extra empty config-setting to be passed to the backend when CIBW_BUILD_FRONTEND is set to `build`. (#1474)
|
||||
- 🐛 Fix a crash that occurred when overwriting an existing wheel on Windows. (#1464)
|
||||
- 🛠 Pinned version updates, including CPython 3.10.11, 3.11.3, pip 23.1 and wheel 0.40.0.
|
||||
|
||||
### v2.12.1
|
||||
|
||||
_11 March 2023_
|
||||
|
||||
- 🐛 Fix a bug that prevented the use of CIBW_CONFIG_SETTINGS with the 'pip' build backend. (#1430)
|
||||
|
||||
### v2.12.0
|
||||
|
||||
_16 Jan 2023_
|
||||
|
||||
- ✨ Adds support for PyPy arm64 wheels. This means that you can build PyPy wheels for Apple Silicon machines. Cross-compilation is not supported for these wheels, so you'll have to build on an Apple Silicon machine. (#1372)
|
||||
- 🛠 Pinned version updates, including PyPy to v7.3.11 and setuptools to 66.0.0.
|
||||
|
||||
### v2.11.4
|
||||
|
||||
_24 Dec 2022_
|
||||
|
||||
- 🐛 Fix a bug that caused missing wheels on Windows when a test was skipped using CIBW_TEST_SKIP (#1377)
|
||||
- 🛠 Updates CPython 3.11 to 3.11.1 (#1371)
|
||||
- 🛠 Updates PyPy to 7.3.10, except on macOS which remains on 7.3.9 due to a bug on that platform. (#1371)
|
||||
- 📚 Added a reference to abi3audit to the docs (#1347)
|
||||
|
||||
### v2.11.3
|
||||
|
||||
_5 Dec 2022_
|
||||
|
||||
- ✨ Improves the 'build options' log output that's printed at the start of each run (#1352)
|
||||
- ✨ Added a friendly error message to a common misconfiguration of the `CIBW_TEST_COMMAND` option - not specifying path using the `{project}` placeholder (#1336)
|
||||
- 🛠 The GitHub Action now uses Powershell on Windows to avoid occasional incompabilities with bash (#1346)
|
||||
|
||||
### v2.11.2
|
||||
|
||||
_26 October 2022_
|
||||
|
||||
+20
-10
@@ -401,9 +401,9 @@
|
||||
- name: pillow-heif
|
||||
gh: bigcat88/pillow_heif
|
||||
pypi: pillow-heif
|
||||
ci: [github]
|
||||
os: [apple, linux]
|
||||
notes: Python CFFI binding to libheif library with third party dependencies like `libde265`, `x265`, `libaom` with test & publishing on PyPi.
|
||||
ci: [github, cirrusci]
|
||||
os: [apple, linux, windows]
|
||||
notes: Bindings to libheif library with third party dependencies. Fully automated CI for tests and publishing including Apple Silicon builds.
|
||||
|
||||
- name: clang-format
|
||||
gh: ssciwr/clang-format-wheel
|
||||
@@ -413,8 +413,9 @@
|
||||
|
||||
- name: Tornado
|
||||
gh: tornadoweb/tornado
|
||||
ci: [travisci]
|
||||
os: [apple, linux]
|
||||
ci: [github]
|
||||
os: [linux, apple, windows]
|
||||
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
|
||||
@@ -431,11 +432,6 @@
|
||||
ci: [github]
|
||||
os: [apple, linux, windows]
|
||||
|
||||
- name: pydantic
|
||||
gh: samuelcolvin/pydantic
|
||||
ci: [github]
|
||||
os: [apple, linux, windows]
|
||||
|
||||
- name: vaex
|
||||
gh: vaexio/vaex
|
||||
ci: [github]
|
||||
@@ -621,3 +617,17 @@
|
||||
os: [windows, apple, linux]
|
||||
pypi: pyril
|
||||
notes: A python binding to Rust Imaging library using maturin and Pyo3, utilizes Github Action cache to improve speed. Builds abi3 wheels.
|
||||
|
||||
- name: Picologging
|
||||
gh: microsoft/picologging
|
||||
ci: [github]
|
||||
os: [windows, apple, linux]
|
||||
pypi: picologging
|
||||
notes: A high-performance logging library for Python.
|
||||
|
||||
- name: aalink
|
||||
gh: artfwo/aalink
|
||||
ci: [github]
|
||||
os: [windows, apple, linux]
|
||||
pypi: aalink
|
||||
notes: Async Python interface for Ableton Link.
|
||||
|
||||
@@ -48,7 +48,7 @@ well as several useful actions. Alongside your existing job(s) that runs cibuild
|
||||
name: Make SDist
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Optional, use if you use setuptools_scm
|
||||
submodules: true # Optional, use if you have submodules
|
||||
@@ -61,13 +61,16 @@ well as several useful actions. Alongside your existing job(s) that runs cibuild
|
||||
path: dist/*.tar.gz
|
||||
```
|
||||
|
||||
Then, you need to publish the artifacts that the previous jobs have built. This final job should run only on release or tag, depending on your preference. It gathers the artifacts from the sdist and wheel jobs and uploads them to PyPI.
|
||||
Then, you need to publish the artifacts that the previous jobs have built. This final job should run only on release or tag, depending on your preference. It gathers the artifacts from the sdist and wheel jobs and uploads them to PyPI. The release environment (`pypi` in the example below) will be created the first time this workflow runs.
|
||||
|
||||
This requires a [PyPI upload token](https://pypi.org/manage/account/token/), stored in your [GitHub repo's secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) as `pypi_password`.
|
||||
This requires setting this GitHub workflow in your project's PyPI settings (for a [new project](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc)/[existing project](https://docs.pypi.org/trusted-publishers/adding-a-publisher)).
|
||||
|
||||
```yaml
|
||||
upload_all:
|
||||
needs: [build_wheels, make_sdist]
|
||||
environment: pypi
|
||||
permissions:
|
||||
id-token: write
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
steps:
|
||||
@@ -76,10 +79,7 @@ This requires a [PyPI upload token](https://pypi.org/manage/account/token/), sto
|
||||
name: artifact
|
||||
path: dist
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@v1.5.0
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_password }}
|
||||
- uses: pypa/gh-action-pypi-publish@release/v1
|
||||
```
|
||||
|
||||
You should use Dependabot to keep the publish action up to date. In the above
|
||||
|
||||
+39
-23
@@ -20,9 +20,13 @@ Linux wheels are built in [`manylinux`/`musllinux` containers](https://github.co
|
||||
|
||||
### Building macOS wheels for Apple Silicon {: #apple-silicon}
|
||||
|
||||
`cibuildwheel` supports cross-compiling `universal2` and `arm64` wheels on `x86_64` runners. With the introduction of Apple Silicon, you now have several choices for wheels for Python 3.8+:
|
||||
`cibuildwheel` supports cross-compiling `universal2` and `arm64` wheels on `x86_64` runners.
|
||||
|
||||
#### `x86_64`
|
||||
#### Overview of Mac architectures
|
||||
|
||||
With the introduction of Apple Silicon, you now have several choices for wheels for Python 3.8+:
|
||||
|
||||
##### `x86_64`
|
||||
|
||||
The traditional wheel for Apple, loads on Intel machines, and on
|
||||
Apple Silicon when running Python under Rosetta 2 emulation.
|
||||
@@ -30,51 +34,61 @@ Apple Silicon when running Python under Rosetta 2 emulation.
|
||||
Due to a change in naming, Pip 20.3+ (or an installer using packaging 20.5+)
|
||||
is required to install a binary wheel on macOS Big Sur.
|
||||
|
||||
#### `arm64`
|
||||
##### `arm64`
|
||||
|
||||
The native wheel for macOS on Apple Silicon.
|
||||
|
||||
Requires Pip 20.3+ (or packaging 20.5+) to install.
|
||||
|
||||
#### `universal2`
|
||||
##### `universal2`
|
||||
|
||||
This wheel contains both architectures, causing it to be up to twice the
|
||||
size (data files do not get doubled, only compiled code). It requires
|
||||
Pip 20.3 (Packaging 20.6+) to load on Intel, and Pip 21.0.1 (Packaging 20.9+)
|
||||
to load on Apple Silicon.
|
||||
|
||||
!!! note
|
||||
The dual-architecture `universal2` has a few benefits, but a key benefit
|
||||
to a universal wheel is that a user can bundle these wheels into an
|
||||
application and ship a single binary.
|
||||
The dual-architecture `universal2` has a few benefits, but a key benefit
|
||||
to a universal wheel is that a user can bundle these wheels into an
|
||||
application and ship a single binary.
|
||||
|
||||
However, if you have a large library, then you might prefer to ship
|
||||
the two single-arch wheels instead - `x86_64` and `arm64`. In rare cases,
|
||||
you might want to build all three, but in that case, pip will not download
|
||||
the universal wheels, because it prefers the most specific wheel
|
||||
available.
|
||||
However, if you have a large library, then you might prefer to ship
|
||||
the two single-arch wheels instead - `x86_64` and `arm64`. In rare cases,
|
||||
you might want to build all three, but in that case, pip will not download
|
||||
the universal wheels, because it prefers the most specific wheel
|
||||
available.
|
||||
|
||||
#### What to provide?
|
||||
|
||||
Generally speaking, because Pip 20.3 is required for the `universal2` wheel,
|
||||
most packages should provide both `x86_64` and one of `universal2`/`arm64`
|
||||
wheels for now. When Pip 20.3+ is common on macOS, then it might be possible
|
||||
to ship only the `universal2` wheel.
|
||||
wheels. When Pip 20.3+ is common on macOS, then it might be possible to ship
|
||||
only the `universal2` wheel.
|
||||
|
||||
**Apple Silicon wheels are not built by default on Intel runners**, but 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.
|
||||
Opinions vary on which of arch-specific or `universal2` wheels are best - some packagers prefer `universal2` because it's one wheel for all Mac users, so simpler, and easier to build into apps for downstream users. However, because they contain code for both architectures, their file size is larger, meaning they consume more disk space and bandwidth, and are harder to build for some projects.
|
||||
|
||||
See [GitHub issue 1333](https://github.com/pypa/cibuildwheel/issues/1333) for more discussion.
|
||||
|
||||
#### How to cross-compile
|
||||
|
||||
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.
|
||||
|
||||
!!! important
|
||||
When cross-compiling on Intel, it is not possible to test `arm64` and the `arm64` part of a `universal2` wheel.
|
||||
|
||||
`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`.
|
||||
|
||||
Hopefully, cross-compilation is a temporary situation. Once we have widely
|
||||
available Apple Silicon CI runners, we can build and test `arm64` and
|
||||
`universal2` wheels natively. That's why `universal2`/`arm64` wheels require opt-in by setting `CIBW_ARCHS_MACOS`.
|
||||
|
||||
!!! note
|
||||
Your runner needs Xcode Command Line Tools 12.2 or later to build `universal2` or `arm64`.
|
||||
|
||||
Only CPython 3.8 and newer support `universal2` and `arm64` wheels.
|
||||
|
||||
!!! 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
|
||||
@@ -118,6 +132,8 @@ The CPython Limited API is a subset of the Python C Extension API that's declare
|
||||
|
||||
To create a package that builds ABI3 wheels, you'll need to configure your build backend to compile libraries correctly create wheels with the right tags. [Check this repo](https://github.com/joerick/python-abi3-package-sample) for an example of how to do this with setuptools.
|
||||
|
||||
You could also consider running [abi3audit](https://github.com/trailofbits/abi3audit) against the produced wheels in order to check for abi3 violations or inconsistencies. You can run it alongside the default in your [CIBW_REPAIR_WHEEL_COMMAND](options.md#repair-wheel-command).
|
||||
|
||||
### Packages with optional C extensions {: #optional-extensions}
|
||||
|
||||
`cibuildwheel` defines the environment variable `CIBUILDWHEEL` to the value `1` allowing projects for which the C extension is optional to make it mandatory when building wheels.
|
||||
@@ -143,7 +159,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.11.2
|
||||
uses: pypa/cibuildwheel@v2.16.1
|
||||
```
|
||||
|
||||
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.
|
||||
@@ -165,7 +181,7 @@ The second option, and the only one that supports other CI systems, is using a `
|
||||
|
||||
```bash
|
||||
# requirements-cibw.txt
|
||||
cibuildwheel==2.11.2
|
||||
cibuildwheel==2.16.1
|
||||
```
|
||||
|
||||
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:
|
||||
@@ -309,7 +325,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.11.2 --output-dir wheelhouse
|
||||
pipx run cibuildwheel==2.16.1 --output-dir wheelhouse
|
||||
pipx run twine upload wheelhouse/*.whl
|
||||
```
|
||||
|
||||
|
||||
+98
-25
@@ -92,8 +92,8 @@ 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 natually a list. Multiline strings also work just
|
||||
like in in the environment variables. Environment variables will take
|
||||
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:
|
||||
@@ -218,17 +218,19 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
|
||||
|
||||
<div class="build-id-table-marker"></div>
|
||||
|
||||
| | macOS | Windows | Linux Intel | Linux Other |
|
||||
|--------------|------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Python 3.6 | cp36-macosx_x86_64 | cp36-win_amd64<br/>cp36-win32 | cp36-manylinux_x86_64<br/>cp36-manylinux_i686<br/>cp36-musllinux_x86_64<br/>cp36-musllinux_i686 | cp36-manylinux_aarch64<br/>cp36-manylinux_ppc64le<br/>cp36-manylinux_s390x<br/>cp36-musllinux_aarch64<br/>cp36-musllinux_ppc64le<br/>cp36-musllinux_s390x |
|
||||
| Python 3.7 | cp37-macosx_x86_64 | cp37-win_amd64<br/>cp37-win32 | cp37-manylinux_x86_64<br/>cp37-manylinux_i686<br/>cp37-musllinux_x86_64<br/>cp37-musllinux_i686 | cp37-manylinux_aarch64<br/>cp37-manylinux_ppc64le<br/>cp37-manylinux_s390x<br/>cp37-musllinux_aarch64<br/>cp37-musllinux_ppc64le<br/>cp37-musllinux_s390x |
|
||||
| Python 3.8 | cp38-macosx_x86_64<br/>cp38-macosx_universal2<br/>cp38-macosx_arm64 | cp38-win_amd64<br/>cp38-win32 | cp38-manylinux_x86_64<br/>cp38-manylinux_i686<br/>cp38-musllinux_x86_64<br/>cp38-musllinux_i686 | cp38-manylinux_aarch64<br/>cp38-manylinux_ppc64le<br/>cp38-manylinux_s390x<br/>cp38-musllinux_aarch64<br/>cp38-musllinux_ppc64le<br/>cp38-musllinux_s390x |
|
||||
| Python 3.9 | cp39-macosx_x86_64<br/>cp39-macosx_universal2<br/>cp39-macosx_arm64 | cp39-win_amd64<br/>cp39-win32<br/>cp39-win_arm64 | cp39-manylinux_x86_64<br/>cp39-manylinux_i686<br/>cp39-musllinux_x86_64<br/>cp39-musllinux_i686 | cp39-manylinux_aarch64<br/>cp39-manylinux_ppc64le<br/>cp39-manylinux_s390x<br/>cp39-musllinux_aarch64<br/>cp39-musllinux_ppc64le<br/>cp39-musllinux_s390x |
|
||||
| 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 |
|
||||
| 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 | pp38-win_amd64 | pp38-manylinux_x86_64<br/>pp38-manylinux_i686 | pp38-manylinux_aarch64 |
|
||||
| PyPy3.9 v7.3 | pp39-macosx_x86_64 | pp39-win_amd64 | pp39-manylinux_x86_64<br/>pp39-manylinux_i686 | pp39-manylinux_aarch64 |
|
||||
| | macOS | Windows | Linux Intel | Linux Other |
|
||||
|---------------|------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Python 3.6 | cp36-macosx_x86_64 | cp36-win_amd64<br/>cp36-win32 | cp36-manylinux_x86_64<br/>cp36-manylinux_i686<br/>cp36-musllinux_x86_64<br/>cp36-musllinux_i686 | cp36-manylinux_aarch64<br/>cp36-manylinux_ppc64le<br/>cp36-manylinux_s390x<br/>cp36-musllinux_aarch64<br/>cp36-musllinux_ppc64le<br/>cp36-musllinux_s390x |
|
||||
| Python 3.7 | cp37-macosx_x86_64 | cp37-win_amd64<br/>cp37-win32 | cp37-manylinux_x86_64<br/>cp37-manylinux_i686<br/>cp37-musllinux_x86_64<br/>cp37-musllinux_i686 | cp37-manylinux_aarch64<br/>cp37-manylinux_ppc64le<br/>cp37-manylinux_s390x<br/>cp37-musllinux_aarch64<br/>cp37-musllinux_ppc64le<br/>cp37-musllinux_s390x |
|
||||
| Python 3.8 | cp38-macosx_x86_64<br/>cp38-macosx_universal2<br/>cp38-macosx_arm64 | cp38-win_amd64<br/>cp38-win32 | cp38-manylinux_x86_64<br/>cp38-manylinux_i686<br/>cp38-musllinux_x86_64<br/>cp38-musllinux_i686 | cp38-manylinux_aarch64<br/>cp38-manylinux_ppc64le<br/>cp38-manylinux_s390x<br/>cp38-musllinux_aarch64<br/>cp38-musllinux_ppc64le<br/>cp38-musllinux_s390x |
|
||||
| Python 3.9 | cp39-macosx_x86_64<br/>cp39-macosx_universal2<br/>cp39-macosx_arm64 | cp39-win_amd64<br/>cp39-win32<br/>cp39-win_arm64 | cp39-manylinux_x86_64<br/>cp39-manylinux_i686<br/>cp39-musllinux_x86_64<br/>cp39-musllinux_i686 | cp39-manylinux_aarch64<br/>cp39-manylinux_ppc64le<br/>cp39-manylinux_s390x<br/>cp39-musllinux_aarch64<br/>cp39-musllinux_ppc64le<br/>cp39-musllinux_s390x |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| PyPy3.10 v7.3 | pp310-macosx_x86_64<br/>pp310-macosx_arm64 | pp310-win_amd64 | pp310-manylinux_x86_64<br/>pp310-manylinux_i686 | pp310-manylinux_aarch64 |
|
||||
|
||||
The list of supported and currently selected build identifiers can also be retrieved by passing the `--print-build-identifiers` flag to cibuildwheel.
|
||||
The format is `python_tag-platform_tag`, with tags similar to those in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details).
|
||||
@@ -237,7 +239,7 @@ 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.
|
||||
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) for past end-of-life versions of Python, and PyPy2.7.
|
||||
|
||||
#### Examples
|
||||
|
||||
@@ -314,7 +316,7 @@ See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.
|
||||
|
||||
It is generally recommended to set `CIBW_BUILD` as an environment variable, though `skip`
|
||||
tends to be useful in a config file; you can statically declare that you don't
|
||||
support pypy, for example.
|
||||
support PyPy, for example.
|
||||
|
||||
<style>
|
||||
.build-id-table-marker + table {
|
||||
@@ -502,9 +504,19 @@ This option can also be set using the [command-line option](#command-line) `--pr
|
||||
### `CIBW_BUILD_FRONTEND` {: #build-frontend}
|
||||
> Set the tool to use to build, either "pip" (default for now) or "build"
|
||||
|
||||
Choose which build backend to use. Can either be "pip", which will run
|
||||
Options:
|
||||
|
||||
- `pip[;args: ...]`
|
||||
- `build[;args: ...]`
|
||||
|
||||
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 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
|
||||
default. However, we expect that at some point in the future, cibuildwheel
|
||||
@@ -524,6 +536,9 @@ Choose which build backend to use. Can either be "pip", which will run
|
||||
|
||||
# Ensure pip is used even if the default changes in the future
|
||||
CIBW_BUILD_FRONTEND: "pip"
|
||||
|
||||
# supply an extra argument to 'pip wheel'
|
||||
CIBW_BUILD_FRONTEND: "pip; args: --no-build-isolation"
|
||||
```
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
@@ -535,6 +550,9 @@ Choose which build backend to use. Can either be "pip", which will run
|
||||
|
||||
# Ensure pip is used even if the default changes in the future
|
||||
build-frontend = "pip"
|
||||
|
||||
# supply an extra argument to 'pip wheel'
|
||||
build-frontend = { name = "pip", args = ["--no-build-isolation"] }
|
||||
```
|
||||
|
||||
### `CIBW_CONFIG_SETTINGS` {: #config-settings}
|
||||
@@ -549,7 +567,7 @@ a table of items, including arrays.
|
||||
single values.
|
||||
|
||||
Platform-specific environment variables also available:<br/>
|
||||
`CIBW_BEFORE_ALL_MACOS` | `CIBW_BEFORE_ALL_WINDOWS` | `CIBW_BEFORE_ALL_LINUX`
|
||||
`CIBW_CONFIG_SETTINGS_MACOS` | `CIBW_CONFIG_SETTINGS_WINDOWS` | `CIBW_CONFIG_SETTINGS_LINUX`
|
||||
|
||||
|
||||
#### Examples
|
||||
@@ -658,10 +676,13 @@ Platform-specific environment variables are also available:<br/>
|
||||
### `CIBW_ENVIRONMENT_PASS_LINUX` {: #environment-pass}
|
||||
> Set environment variables on the host to pass-through to the container during the build.
|
||||
|
||||
A list of environment variables to pass into the linux container during the build. It has no affect on the other platforms, which can already access all environment variables directly.
|
||||
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.
|
||||
|
||||
To specify more than one environment variable, separate the variable names by spaces.
|
||||
|
||||
!!! note
|
||||
cibuildwheel automatically passes the environment variable [`SOURCE_DATE_EPOCH`](https://reproducible-builds.org/docs/source-date-epoch/) if defined.
|
||||
|
||||
#### Examples
|
||||
|
||||
!!! tab examples "Environment passthrough"
|
||||
@@ -898,6 +919,18 @@ Platform-specific environment variables are also available:<br/>
|
||||
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} &&
|
||||
pipx run abi3audit --strict --report {wheel}
|
||||
CIBW_REPAIR_WHEEL_COMMAND_MACOS: >
|
||||
delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} &&
|
||||
pipx run abi3audit --strict --report {wheel}
|
||||
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >
|
||||
pipx run abi3audit --strict --report {wheel}
|
||||
```
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
|
||||
```toml
|
||||
@@ -922,6 +955,22 @@ Platform-specific environment variables are also available:<br/>
|
||||
]
|
||||
```
|
||||
|
||||
```toml
|
||||
# Use abi3audit to catch issues with Limited API wheels
|
||||
[tool.cibuildwheel.linux]
|
||||
repair-wheel-command = [
|
||||
"auditwheel repair -w {dest_dir} {wheel}",
|
||||
"pipx run abi3audit --strict --report {wheel}",
|
||||
]
|
||||
[tool.cibuildwheel.macos]
|
||||
repair-wheel-command = [
|
||||
"delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
|
||||
"pipx run abi3audit --strict --report {wheel}",
|
||||
]
|
||||
[tool.cibuildwheel.windows]
|
||||
repair-wheel-command = "pipx run abi3audit --strict --report {wheel}"
|
||||
```
|
||||
|
||||
In configuration mode, you can use an inline array, and the items will be joined with `&&`.
|
||||
|
||||
|
||||
@@ -951,7 +1000,7 @@ Set an alternative Docker image to be used for building [manylinux / musllinux](
|
||||
For `CIBW_MANYLINUX_*_IMAGE`, the value of this option can either be set to `manylinux1`, `manylinux2010`, `manylinux2014`, `manylinux_2_24` or `manylinux_2_28` to use a pinned version of the [official manylinux images](https://github.com/pypa/manylinux). Alternatively, set these options to any other valid Docker image name. For PyPy, the `manylinux1` image is not available. For architectures other
|
||||
than x86 (x86\_64 and i686) `manylinux2014`, `manylinux_2_24` or `manylinux_2_28` must be used, because the first version of the manylinux specification that supports additional architectures is `manylinux2014`. `manylinux_2_28` is not supported for `i686` architecture.
|
||||
|
||||
For `CIBW_MUSLLINUX_*_IMAGE`, the value of this option can either be set to `musllinux_1_1` to use a pinned version of the [official musllinux images](https://github.com/pypa/musllinux). Alternatively, set these options to any other valid Docker image name.
|
||||
For `CIBW_MUSLLINUX_*_IMAGE`, the value of this option can either be set to `musllinux_1_1` or `musllinux_1_2` to use a pinned version of the [official musllinux images](https://github.com/pypa/musllinux). Alternatively, set these options to any other valid Docker image name.
|
||||
|
||||
If this option is blank, it will fall though to the next available definition (environment variable -> pyproject.toml -> default).
|
||||
|
||||
@@ -1020,9 +1069,12 @@ Auditwheel detects the version of the manylinux / musllinux standard in the imag
|
||||
|
||||
|
||||
### `CIBW_CONTAINER_ENGINE` {: #container-engine}
|
||||
> Specify which container engine to use when building Linux wheels
|
||||
> Specify the container engine to use when building Linux wheels
|
||||
|
||||
Options: `docker` `podman`
|
||||
Options:
|
||||
|
||||
- `docker[;create_args: ...]`
|
||||
- `podman[;create_args: ...]`
|
||||
|
||||
Default: `docker`
|
||||
|
||||
@@ -1031,6 +1083,12 @@ 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.
|
||||
|
||||
!!! tip
|
||||
|
||||
While most users will stick with Docker, Podman is available in different
|
||||
@@ -1045,14 +1103,22 @@ installed and `podman` available on PATH.
|
||||
!!! tab examples "Environment variables"
|
||||
|
||||
```yaml
|
||||
# use podman instead of docker
|
||||
CIBW_CONTAINER_ENGINE: podman
|
||||
|
||||
# pass command line options to 'docker create'
|
||||
CIBW_CONTAINER_ENGINE: "docker; create_args: --gpus all"
|
||||
```
|
||||
|
||||
!!! tab examples "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.cibuildwheel]
|
||||
# use podman instead of docker
|
||||
container-engine = "podman"
|
||||
|
||||
# pass command line options to 'docker create'
|
||||
container-engine = { name = "docker", create-args = ["--gpus", "all"]}
|
||||
```
|
||||
|
||||
|
||||
@@ -1186,6 +1252,13 @@ Platform-specific environment variables are also available:<br/>
|
||||
|
||||
In configuration files, you can use an array, and the items will be joined with `&&`.
|
||||
|
||||
!!! note
|
||||
|
||||
It isn't recommended to `cd` to your project directory before running tests,
|
||||
because Python might resolve `import yourpackage` relative to the working dir,
|
||||
and we want to test the wheel you just built. However, if you're sure that's not
|
||||
an issue for you and your workflow requires it, on Windows you should do `cd /d`,
|
||||
because the CWD and project dir might be on different drives.
|
||||
|
||||
### `CIBW_BEFORE_TEST` {: #before-test}
|
||||
> Execute a shell command before testing each wheel
|
||||
@@ -1291,11 +1364,11 @@ Platform-specific environment variables are also available:<br/>
|
||||
> Install your wheel for testing using `extras_require`
|
||||
|
||||
List of
|
||||
[extras_require](https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies)
|
||||
[extras_require](https://setuptools.pypa.io/en/latest/userguide/dependency_management.html#declaring-required-dependency)
|
||||
options that should be included when installing the wheel prior to running the
|
||||
tests. This can be used to avoid having to redefine test dependencies in
|
||||
`CIBW_TEST_REQUIRES` if they are already defined in `setup.py` or
|
||||
`setup.cfg`.
|
||||
`CIBW_TEST_REQUIRES` if they are already defined in `pyproject.toml`,
|
||||
`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`
|
||||
@@ -1358,7 +1431,7 @@ This option is not supported in the overrides section in `pyproject.toml`.
|
||||
### `CIBW_BUILD_VERBOSITY` {: #build-verbosity}
|
||||
> Increase/decrease the output of pip wheel
|
||||
|
||||
An 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.
|
||||
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`
|
||||
|
||||
+4
-4
@@ -181,10 +181,10 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
run: pipx run cibuildwheel==2.11.2
|
||||
run: pipx run cibuildwheel==2.16.1
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -213,13 +213,13 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Used to host cibuildwheel
|
||||
- uses: actions/setup-python@v3
|
||||
|
||||
- name: Install cibuildwheel
|
||||
run: python -m pip install cibuildwheel==2.11.2
|
||||
run: python -m pip install cibuildwheel==2.16.1
|
||||
|
||||
- name: Build wheels
|
||||
run: python -m cibuildwheel --output-dir wheelhouse
|
||||
|
||||
+79
-182
@@ -9,74 +9,75 @@ title: Working examples
|
||||
| Name | CI | OS | Notes |
|
||||
|-----------------------------------|----|----|:------|
|
||||
| [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. |
|
||||
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
|
||||
| [Tornado][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. |
|
||||
| [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 |
|
||||
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
|
||||
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
|
||||
| [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. |
|
||||
| [pydantic][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Data parsing and validation using Python type hints |
|
||||
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
|
||||
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
|
||||
| [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 |
|
||||
| [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 🚀 |
|
||||
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an in-process SQL OLAP Database Management System |
|
||||
| [Google Benchmark][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A microbenchmark support library |
|
||||
| [Apache Beam][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Apache Beam is a unified programming model for Batch and Streaming data processing. |
|
||||
| [asyncpg][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A fast PostgreSQL Database Client Library for Python/asyncio. |
|
||||
| [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. |
|
||||
| [cmake][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
|
||||
| [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. |
|
||||
| [Triton][] | ![github icon][] | ![linux icon][] | Self hosted runners |
|
||||
| [UltraJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Ultra fast JSON decoder and encoder written in C with Python bindings |
|
||||
| [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. |
|
||||
| [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. |
|
||||
| [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. |
|
||||
| [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 |
|
||||
| [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 |
|
||||
| [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI |
|
||||
| [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 |
|
||||
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, PyTables, pandas, bcolz and more |
|
||||
| [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. |
|
||||
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
|
||||
| [pikepdf][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by qpdf |
|
||||
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
|
||||
| [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 |
|
||||
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
|
||||
| [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. |
|
||||
| [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. |
|
||||
| [Wrapt][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python module for decorators, wrappers and monkey patching. |
|
||||
| [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 |
|
||||
| [OpenColorIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A color management framework for visual effects and animation. |
|
||||
| [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data |
|
||||
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
|
||||
| [envd][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | 🏕️ Development environment for AI/ML |
|
||||
| [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 |
|
||||
| [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. |
|
||||
| [DeepForest][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | An Efficient, Scalable and Optimized Python Framework for Deep Forest (2021.2.1) |
|
||||
| [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. |
|
||||
| [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 ¶ |
|
||||
| [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. |
|
||||
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
|
||||
| [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system |
|
||||
| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
|
||||
| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python |
|
||||
| [tgcalls][] | ![github icon][] | ![apple icon][] ![windows icon][] | Python `pybind11` binding to Telegram's WebRTC library with third party dependencies like `OpenSSL`, `MozJPEG`, `FFmpeg`, etc. |
|
||||
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
|
||||
| [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub |
|
||||
| [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. |
|
||||
| [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 |
|
||||
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
|
||||
| [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. |
|
||||
@@ -85,103 +86,104 @@ title: Working examples
|
||||
| [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 |
|
||||
| [PyGLM][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Fast OpenGL Mathematics (GLM) for Python |
|
||||
| [mosec][] | ![github icon][] | ![linux icon][] ![apple icon][] | A high-performance serving framework for ML models, offers dynamic batching and multi-stage pipeline to fully exploit your compute machine |
|
||||
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
|
||||
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
|
||||
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. |
|
||||
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
|
||||
| [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. |
|
||||
| [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 |
|
||||
| [etebase-py][] | ![travisci icon][] | ![linux icon][] | Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. |
|
||||
| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. |
|
||||
| [pillow-heif][] | ![github icon][] | ![apple icon][] ![linux icon][] | Python CFFI binding to libheif library with third party dependencies like `libde265`, `x265`, `libaom` with test & publishing on PyPi. |
|
||||
| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
|
||||
| [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. |
|
||||
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
|
||||
| [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 |
|
||||
| [clang-format][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Scikit-build wrapper around LLVM's CMake, all platforms, generic wheels. |
|
||||
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
|
||||
| [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 |
|
||||
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
|
||||
| [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
|
||||
| [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 |
|
||||
| [SiPM][] | ![github icon][] | ![apple icon][] ![linux icon][] | High performance library for SiPM detectors simulation using C++17, OpenMP and AVX2 intrinsics. |
|
||||
| [ril][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A python binding to Rust Imaging library using maturin and Pyo3, utilizes Github Action cache to improve speed. Builds abi3 wheels. |
|
||||
| [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. |
|
||||
| [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
|
||||
[NumPy]: https://github.com/numpy/numpy
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[pytorch-fairseq]: https://github.com/pytorch/fairseq
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[NCNN]: https://github.com/Tencent/ncnn
|
||||
[Kivy]: https://github.com/kivy/kivy
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
|
||||
[pydantic]: https://github.com/samuelcolvin/pydantic
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
[Kivy]: https://github.com/kivy/kivy
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
[MemRay]: https://github.com/bloomberg/memray
|
||||
[uvloop]: https://github.com/MagicStack/uvloop
|
||||
[psutil]: https://github.com/giampaolo/psutil
|
||||
[Triton]: https://github.com/openai/triton
|
||||
[vaex]: https://github.com/vaexio/vaex
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
[Google Benchmark]: https://github.com/google/benchmark
|
||||
[Apache Beam]: https://github.com/apache/beam
|
||||
[asyncpg]: https://github.com/MagicStack/asyncpg
|
||||
[PyGame]: https://github.com/pygame/pygame
|
||||
[asyncpg]: https://github.com/MagicStack/asyncpg
|
||||
[cmake]: https://github.com/scikit-build/cmake-python-distributions
|
||||
[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
|
||||
[Triton]: https://github.com/openai/triton
|
||||
[UltraJSON]: https://github.com/ultrajson/ultrajson
|
||||
[websockets]: https://github.com/aaugustin/websockets
|
||||
[River]: https://github.com/online-ml/river
|
||||
[UltraJSON]: https://github.com/ultrajson/ultrajson
|
||||
[OpenSpiel]: https://github.com/deepmind/open_spiel
|
||||
[pyzmq]: https://github.com/zeromq/pyzmq
|
||||
[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
|
||||
[vispy]: https://github.com/vispy/vispy
|
||||
[tinyobjloader]: https://github.com/tinyobjloader/tinyobjloader
|
||||
[Dependency Injector]: https://github.com/ets-labs/python-dependency-injector
|
||||
[coverage.py]: https://github.com/nedbat/coveragepy
|
||||
[PyCryptodome]: https://github.com/Legrandin/pycryptodome
|
||||
[PyYAML]: https://github.com/yaml/pyyaml
|
||||
[numexpr]: https://github.com/pydata/numexpr
|
||||
[h5py]: https://github.com/h5py/h5py
|
||||
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
|
||||
[PyAV]: https://github.com/PyAV-Org/PyAV
|
||||
[pikepdf]: https://github.com/pikepdf/pikepdf
|
||||
[SimpleJSON]: https://github.com/simplejson/simplejson
|
||||
[Line Profiler]: https://github.com/pyutils/line_profiler
|
||||
[OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO
|
||||
[PyTables]: https://github.com/PyTables/PyTables
|
||||
[OpenTimelineIO]: https://github.com/PixarAnimationStudios/OpenTimelineIO
|
||||
[numexpr]: https://github.com/pydata/numexpr
|
||||
[PyAV]: https://github.com/PyAV-Org/PyAV
|
||||
[h5py]: https://github.com/h5py/h5py
|
||||
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
|
||||
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
|
||||
[pikepdf]: https://github.com/pikepdf/pikepdf
|
||||
[envd]: https://github.com/tensorchord/envd
|
||||
[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
|
||||
[DeepForest]: https://github.com/LAMDA-NJU/Deep-Forest
|
||||
[google neuroglancer]: https://github.com/google/neuroglancer
|
||||
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
|
||||
[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
|
||||
[Picologging]: https://github.com/microsoft/picologging
|
||||
[markupsafe]: https://github.com/pallets/markupsafe
|
||||
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
|
||||
[pybind11 cmake_example]: https://github.com/pybind/cmake_example
|
||||
[python-snappy]: https://github.com/andrix/python-snappy
|
||||
[KDEpy]: https://github.com/tommyod/KDEpy
|
||||
[tgcalls]: https://github.com/MarshalX/tgcalls
|
||||
[pybind11 python_example]: https://github.com/pybind/python_example
|
||||
[dd-trace-py]: https://github.com/DataDog/dd-trace-py
|
||||
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
|
||||
[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
|
||||
[pybind11 python_example]: https://github.com/pybind/python_example
|
||||
[sourmash]: https://github.com/dib-lab/sourmash
|
||||
[cyvcf2]: https://github.com/brentp/cyvcf2
|
||||
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
|
||||
@@ -190,32 +192,32 @@ title: Working examples
|
||||
[iminuit]: https://github.com/scikit-hep/iminuit
|
||||
[Tokenizer]: https://github.com/OpenNMT/Tokenizer
|
||||
[PyGLM]: https://github.com/Zuzu-Typ/PyGLM
|
||||
[mosec]: https://github.com/mosecorg/mosec
|
||||
[bx-python]: https://github.com/bxlab/bx-python
|
||||
[TgCrypto]: https://github.com/pyrogram/tgcrypto
|
||||
[boost-histogram]: https://github.com/scikit-hep/boost-histogram
|
||||
[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
|
||||
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
|
||||
[pybase64]: https://github.com/mayeut/pybase64
|
||||
[Arbor]: https://github.com/arbor-sim/arbor
|
||||
[fathon]: https://github.com/stfbnc/fathon
|
||||
[etebase-py]: https://github.com/etesync/etebase-py
|
||||
[polaroid]: https://github.com/daggy1234/polaroid
|
||||
[pillow-heif]: https://github.com/bigcat88/pillow_heif
|
||||
[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
|
||||
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
|
||||
[etebase-py]: https://github.com/etesync/etebase-py
|
||||
[cf-units]: https://github.com/SciTools/cf-units
|
||||
[clang-format]: https://github.com/ssciwr/clang-format-wheel
|
||||
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
|
||||
[ninja]: https://github.com/scikit-build/ninja-python-distributions
|
||||
[numpythia]: https://github.com/scikit-hep/numpythia
|
||||
[pyjet]: https://github.com/scikit-hep/pyjet
|
||||
[ninja]: https://github.com/scikit-build/ninja-python-distributions
|
||||
[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
|
||||
[SiPM]: https://github.com/EdoPro98/SimSiPM
|
||||
[ril]: https://github.com/Cryptex-github/ril-py
|
||||
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
|
||||
[aalink]: https://github.com/artfwo/aalink
|
||||
[pybind11 cross build example]: https://github.com/wbarnha/pybind_cmake_example_crossbuild
|
||||
|
||||
[appveyor icon]: data/readme_icons/appveyor.svg
|
||||
@@ -229,111 +231,6 @@ title: Working examples
|
||||
[apple icon]: data/readme_icons/apple.svg
|
||||
[linux icon]: data/readme_icons/linux.svg
|
||||
|
||||
<!-- scikit-learn: 51848, last pushed 0 days ago -->
|
||||
<!-- NumPy: 21783, last pushed 0 days ago -->
|
||||
<!-- Tornado: 20819, last pushed 9 days ago -->
|
||||
<!-- pytorch-fairseq: 19600, last pushed 0 days ago -->
|
||||
<!-- Matplotlib: 16308, last pushed 0 days ago -->
|
||||
<!-- NCNN: 15771, last pushed 0 days ago -->
|
||||
<!-- Kivy: 15142, last pushed 0 days ago -->
|
||||
<!-- Prophet: 15053, last pushed 4 days ago -->
|
||||
<!-- MyPy: 14010, last pushed 0 days ago -->
|
||||
<!-- pydantic: 11358, last pushed 0 days ago -->
|
||||
<!-- MemRay: 9471, last pushed 4 days ago -->
|
||||
<!-- uvloop: 8956, last pushed 23 days ago -->
|
||||
<!-- psutil: 8794, last pushed 2 days ago -->
|
||||
<!-- vaex: 7361, last pushed 7 days ago -->
|
||||
<!-- duckdb: 6941, last pushed 0 days ago -->
|
||||
<!-- Google Benchmark: 6940, last pushed 6 days ago -->
|
||||
<!-- Apache Beam: 5970, last pushed 0 days ago -->
|
||||
<!-- asyncpg: 5679, last pushed 13 days ago -->
|
||||
<!-- PyGame: 5309, last pushed 0 days ago -->
|
||||
<!-- cmake: 5181, last pushed 0 days ago -->
|
||||
<!-- scikit-image: 5093, last pushed 0 days ago -->
|
||||
<!-- twisted-iocpsupport: 4808, last pushed 0 days ago -->
|
||||
<!-- PyOxidizer: 4347, last pushed 21 days ago -->
|
||||
<!-- websockets: 4210, last pushed 1 days ago -->
|
||||
<!-- cvxpy: 4147, last pushed 3 days ago -->
|
||||
<!-- Triton: 4134, last pushed 0 days ago -->
|
||||
<!-- UltraJSON: 3872, last pushed 10 days ago -->
|
||||
<!-- River: 3762, last pushed 0 days ago -->
|
||||
<!-- OpenSpiel: 3363, last pushed 0 days ago -->
|
||||
<!-- pyzmq: 3187, last pushed 7 days ago -->
|
||||
<!-- aiortc: 3110, last pushed 6 days ago -->
|
||||
<!-- Confluent client for Kafka: 3002, last pushed 3 days ago -->
|
||||
<!-- Implicit: 2979, last pushed 20 days ago -->
|
||||
<!-- vispy: 2946, last pushed 0 days ago -->
|
||||
<!-- tinyobjloader: 2674, last pushed 2 days ago -->
|
||||
<!-- Dependency Injector: 2444, last pushed 46 days ago -->
|
||||
<!-- coverage.py: 2234, last pushed 1 days ago -->
|
||||
<!-- PyCryptodome: 2155, last pushed 24 days ago -->
|
||||
<!-- PyYAML: 1965, last pushed 8 days ago -->
|
||||
<!-- numexpr: 1827, last pushed 0 days ago -->
|
||||
<!-- h5py: 1794, last pushed 3 days ago -->
|
||||
<!-- Wrapt: 1772, last pushed 61 days ago -->
|
||||
<!-- PyAV: 1699, last pushed 5 days ago -->
|
||||
<!-- pikepdf: 1537, last pushed 3 days ago -->
|
||||
<!-- SimpleJSON: 1526, last pushed 115 days ago -->
|
||||
<!-- Line Profiler: 1430, last pushed 11 days ago -->
|
||||
<!-- OpenColorIO: 1385, last pushed 0 days ago -->
|
||||
<!-- PyTables: 1153, last pushed 0 days ago -->
|
||||
<!-- OpenTimelineIO: 1111, last pushed 1 days ago -->
|
||||
<!-- envd: 1101, last pushed 0 days ago -->
|
||||
<!-- aioquic: 1094, last pushed 6 days ago -->
|
||||
<!-- ruptures: 1068, last pushed 17 days ago -->
|
||||
<!-- Psycopg 3: 816, last pushed 3 days ago -->
|
||||
<!-- DeepForest: 786, last pushed 24 days ago -->
|
||||
<!-- google neuroglancer: 768, last pushed 0 days ago -->
|
||||
<!-- Parselmouth: 727, last pushed 14 days ago -->
|
||||
<!-- AutoPy: 681, last pushed 34 days ago -->
|
||||
<!-- H3-py: 570, last pushed 11 days ago -->
|
||||
<!-- Rtree: 505, last pushed 13 days ago -->
|
||||
<!-- markupsafe: 501, last pushed 21 days ago -->
|
||||
<!-- python-rapidjson: 462, last pushed 7 days ago -->
|
||||
<!-- pybind11 cmake_example: 462, last pushed 0 days ago -->
|
||||
<!-- python-snappy: 445, last pushed 222 days ago -->
|
||||
<!-- KDEpy: 417, last pushed 22 days ago -->
|
||||
<!-- tgcalls: 393, last pushed 115 days ago -->
|
||||
<!-- pybind11 python_example: 370, last pushed 1 days ago -->
|
||||
<!-- dd-trace-py: 364, last pushed 0 days ago -->
|
||||
<!-- CTranslate2: 350, last pushed 0 days ago -->
|
||||
<!-- time-machine: 345, last pushed 1 days ago -->
|
||||
<!-- sourmash: 326, last pushed 0 days ago -->
|
||||
<!-- cyvcf2: 307, last pushed 26 days ago -->
|
||||
<!-- matrixprofile: 290, last pushed 18 days ago -->
|
||||
<!-- abess: 289, last pushed 43 days ago -->
|
||||
<!-- jq.py: 237, last pushed 10 days ago -->
|
||||
<!-- iminuit: 212, last pushed 22 days ago -->
|
||||
<!-- Tokenizer: 196, last pushed 41 days ago -->
|
||||
<!-- PyGLM: 151, last pushed 210 days ago -->
|
||||
<!-- mosec: 146, last pushed 0 days ago -->
|
||||
<!-- bx-python: 121, last pushed 57 days ago -->
|
||||
<!-- TgCrypto: 117, last pushed 13 days ago -->
|
||||
<!-- boost-histogram: 117, last pushed 7 days ago -->
|
||||
<!-- iDynTree: 109, last pushed 14 days ago -->
|
||||
<!-- Python-WebRTC: 96, last pushed 228 days ago -->
|
||||
<!-- pybase64: 92, last pushed 0 days ago -->
|
||||
<!-- Arbor: 82, last pushed 0 days ago -->
|
||||
<!-- fathon: 71, last pushed 144 days ago -->
|
||||
<!-- etebase-py: 60, last pushed 110 days ago -->
|
||||
<!-- polaroid: 57, last pushed 5 days ago -->
|
||||
<!-- pillow-heif: 52, last pushed 0 days ago -->
|
||||
<!-- power-grid-model: 52, last pushed 0 days ago -->
|
||||
<!-- Imagecodecs (fork): 50, last pushed 28 days ago -->
|
||||
<!-- cf-units: 49, last pushed 0 days ago -->
|
||||
<!-- clang-format: 44, last pushed 23 days ago -->
|
||||
<!-- pybind11 scikit_build_example: 36, last pushed 1 days ago -->
|
||||
<!-- numpythia: 36, last pushed 23 days ago -->
|
||||
<!-- pyjet: 33, last pushed 23 days ago -->
|
||||
<!-- ninja: 26, last pushed 10 days ago -->
|
||||
<!-- GSD: 19, last pushed 21 days ago -->
|
||||
<!-- CorrectionLib: 11, last pushed 0 days ago -->
|
||||
<!-- pyinstrument_cext: 10, last pushed 381 days ago -->
|
||||
<!-- SiPM: 10, last pushed 145 days ago -->
|
||||
<!-- ril: 10, last pushed 41 days ago -->
|
||||
<!-- xmlstarlet: 8, last pushed 7 days ago -->
|
||||
<!-- pybind11 cross build example: 0, last pushed 11 days ago -->
|
||||
|
||||
<!-- END bin/projects.py -->
|
||||
|
||||
> Add your repo here! Let us know on [GitHub Discussions](https://github.com/pypa/cibuildwheel/discussions/485), or send a PR, adding your information to `docs/data/projects.yml`.
|
||||
|
||||
@@ -4,15 +4,15 @@ environment:
|
||||
APPVEYOR_JOB_NAME: "python37-x64-ubuntu"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
APPVEYOR_JOB_NAME: "python37-x64-vs2015"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos-mojave
|
||||
APPVEYOR_JOB_NAME: "python37-x64-macos-mojave"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos
|
||||
APPVEYOR_JOB_NAME: "python37-x64-macos"
|
||||
|
||||
stack: python 3.7
|
||||
|
||||
init:
|
||||
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
|
||||
|
||||
install: python -m pip install cibuildwheel==2.11.2
|
||||
install: python -m pip install cibuildwheel==2.16.1
|
||||
|
||||
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.11.2
|
||||
pip3 install cibuildwheel==2.16.1
|
||||
displayName: Install dependencies
|
||||
- bash: cibuildwheel --output-dir wheelhouse .
|
||||
displayName: Build wheels
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
- bash: |
|
||||
set -o errexit
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install cibuildwheel==2.11.2
|
||||
python3 -m pip install cibuildwheel==2.16.1
|
||||
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.11.2
|
||||
pip install cibuildwheel==2.16.1
|
||||
displayName: Install dependencies
|
||||
- bash: cibuildwheel --output-dir wheelhouse .
|
||||
displayName: Build wheels
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
- run:
|
||||
name: Build the Linux wheels.
|
||||
command: |
|
||||
pip3 install --user cibuildwheel==2.11.2
|
||||
pip3 install --user cibuildwheel==2.16.1
|
||||
cibuildwheel --output-dir wheelhouse
|
||||
- store_artifacts:
|
||||
path: wheelhouse/
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- run:
|
||||
name: Build the Linux aarch64 wheels.
|
||||
command: |
|
||||
python3 -m pip install --user cibuildwheel==2.11.2
|
||||
python3 -m pip install --user cibuildwheel==2.16.1
|
||||
python3 -m cibuildwheel --output-dir wheelhouse
|
||||
- store_artifacts:
|
||||
path: wheelhouse/
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
- run:
|
||||
name: Build the OS X wheels.
|
||||
command: |
|
||||
pip3 install cibuildwheel==2.11.2
|
||||
pip3 install cibuildwheel==2.16.1
|
||||
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.11.2
|
||||
- python -m pip install cibuildwheel==2.16.1
|
||||
run_cibuildwheel_script:
|
||||
- cibuildwheel
|
||||
wheels_artifacts:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
|
||||
install_cibuildwheel_script:
|
||||
- python -m pip install cibuildwheel==2.11.2
|
||||
- python -m pip install cibuildwheel==2.16.1
|
||||
run_cibuildwheel_script:
|
||||
- cibuildwheel
|
||||
wheels_artifacts:
|
||||
|
||||
@@ -7,10 +7,10 @@ jobs:
|
||||
name: Build wheels on macos-11
|
||||
runs-on: macos-11
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.11.2
|
||||
uses: pypa/cibuildwheel@v2.16.1
|
||||
env:
|
||||
CIBW_ARCHS_MACOS: x86_64 arm64
|
||||
|
||||
|
||||
+21
-21
@@ -1,14 +1,14 @@
|
||||
name: Build and upload to PyPI
|
||||
|
||||
# Build on every branch push, tag push, and pull request change:
|
||||
on: [push, pull_request]
|
||||
# Alternatively, to publish when a (published) GitHub Release is created, use the following:
|
||||
# on:
|
||||
# push:
|
||||
# pull_request:
|
||||
# release:
|
||||
# types:
|
||||
# - published
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
|
||||
jobs:
|
||||
build_wheels:
|
||||
@@ -16,13 +16,13 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
os: [ubuntu-22.04, windows-2022, macos-11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.11.2
|
||||
uses: pypa/cibuildwheel@v2.16.1
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
name: Build source distribution
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build sdist
|
||||
run: pipx run build --sdist
|
||||
@@ -44,10 +44,12 @@ jobs:
|
||||
upload_pypi:
|
||||
needs: [build_wheels, build_sdist]
|
||||
runs-on: ubuntu-latest
|
||||
# upload to PyPI on every tag starting with 'v'
|
||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||
# alternatively, to publish when a GitHub Release is created, use the following rule:
|
||||
# if: github.event_name == 'release' && github.event.action == 'published'
|
||||
environment: pypi
|
||||
permissions:
|
||||
id-token: write
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
# 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
|
||||
with:
|
||||
@@ -56,8 +58,6 @@ jobs:
|
||||
name: artifact
|
||||
path: dist
|
||||
|
||||
- uses: pypa/gh-action-pypi-publish@v1.5.0
|
||||
- uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_password }}
|
||||
# To test: repository_url: https://test.pypi.org/legacy/
|
||||
# To test: repository-url: https://test.pypi.org/legacy/
|
||||
|
||||
@@ -11,10 +11,10 @@ jobs:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.11.2
|
||||
uses: pypa/cibuildwheel@v2.16.1
|
||||
# env:
|
||||
# CIBW_SOME_OPTION: value
|
||||
# ...
|
||||
|
||||
@@ -11,16 +11,16 @@ jobs:
|
||||
os: [ubuntu-20.04, windows-2019, macos-11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
if: runner.os == 'Linux'
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: all
|
||||
|
||||
- name: Build wheels
|
||||
uses: pypa/cibuildwheel@v2.11.2
|
||||
uses: pypa/cibuildwheel@v2.16.1
|
||||
env:
|
||||
# configure cibuildwheel to build native archs ('auto'), and some
|
||||
# emulated ones
|
||||
|
||||
@@ -12,7 +12,7 @@ linux:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
script:
|
||||
- curl -sSL https://get.docker.com/ | sh
|
||||
- python -m pip install cibuildwheel==2.11.2
|
||||
- python -m pip install cibuildwheel==2.16.1
|
||||
- cibuildwheel --output-dir wheelhouse
|
||||
artifacts:
|
||||
paths:
|
||||
@@ -23,7 +23,7 @@ windows:
|
||||
before_script:
|
||||
- choco install python -y --version 3.8.6
|
||||
- choco install git.install -y
|
||||
- py -m pip install cibuildwheel==2.11.2
|
||||
- py -m pip install cibuildwheel==2.16.1
|
||||
script:
|
||||
- py -m cibuildwheel --output-dir wheelhouse --platform windows
|
||||
artifacts:
|
||||
|
||||
@@ -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.11.2
|
||||
- python -m pip install cibuildwheel==2.16.1
|
||||
# Assuming your CI runner's default architecture is x86_64...
|
||||
- cibuildwheel --output-dir wheelhouse --platform linux --archs aarch64
|
||||
artifacts:
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
||||
|
||||
install:
|
||||
- python3 -m pip install cibuildwheel==2.11.2
|
||||
- python3 -m pip install cibuildwheel==2.16.1
|
||||
|
||||
script:
|
||||
# build the wheels, put them into './dist'
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
||||
|
||||
install:
|
||||
- python3 -m pip install cibuildwheel==2.11.2
|
||||
- python3 -m pip install cibuildwheel==2.16.1
|
||||
|
||||
script:
|
||||
# build the wheels, put them into './wheelhouse'
|
||||
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
- stage: deploy
|
||||
name: Build and deploy Linux wheels
|
||||
services: docker
|
||||
install: python3 -m pip install cibuildwheel==2.11.2 twine
|
||||
install: python3 -m pip install cibuildwheel==2.16.1 twine
|
||||
script: python3 -m cibuildwheel --output-dir wheelhouse
|
||||
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
|
||||
# Deploy on windows
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
name: Build and deploy Windows wheels
|
||||
os: windows
|
||||
language: shell
|
||||
install: python3 -m pip install cibuildwheel==2.11.2 twine
|
||||
install: python3 -m pip install cibuildwheel==2.16.1 twine
|
||||
script: python3 -m cibuildwheel --output-dir wheelhouse
|
||||
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
|
||||
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import nox
|
||||
|
||||
nox.options.sessions = ["lint", "pylint", "check_manifest", "tests"]
|
||||
|
||||
PYTHON_ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
|
||||
PYTHON_ALL_VERSIONS = ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
|
||||
|
||||
DIR = Path(__file__).parent.resolve()
|
||||
|
||||
|
||||
+57
-15
@@ -2,34 +2,25 @@
|
||||
requires = [
|
||||
"setuptools>=42",
|
||||
]
|
||||
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
target-version = ['py37', 'py38', 'py39', 'py310']
|
||||
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
target-version = ['py38', 'py39', 'py310', 'py311']
|
||||
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "6.0"
|
||||
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
|
||||
junit_family = "xunit2"
|
||||
testpaths = [
|
||||
"test",
|
||||
"unit_test",
|
||||
]
|
||||
xfail_strict = true
|
||||
filterwarnings = ["error"]
|
||||
log_cli_level = "info"
|
||||
|
||||
|
||||
[tool.mypy]
|
||||
python_version = 3.7
|
||||
python_version = 3.8
|
||||
files = [
|
||||
"cibuildwheel/*.py",
|
||||
"test/**/*.py",
|
||||
@@ -88,10 +79,10 @@ ignore = [
|
||||
]
|
||||
|
||||
[tool.pylint]
|
||||
master.py-version = "3.7"
|
||||
master.jobs = "0"
|
||||
master.fail-on = ["E", "F"]
|
||||
master.fail-under = "9.8"
|
||||
py-version = "3.8"
|
||||
jobs = "0"
|
||||
fail-on = ["E", "F"]
|
||||
fail-under = "9.8"
|
||||
reports.output-format = "colorized"
|
||||
messages_control.enable = [
|
||||
"useless-suppression",
|
||||
@@ -119,4 +110,55 @@ messages_control.disable = [
|
||||
"too-many-statements",
|
||||
"unsubscriptable-object",
|
||||
"wrong-import-position",
|
||||
"unused-argument", # Handled by Ruff
|
||||
"broad-exception-raised", # Could be improved eventually
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
select = [
|
||||
"E", "F", "W", # flake8
|
||||
"B", # flake8-bugbear
|
||||
"I", # isort
|
||||
"ARG", # flake8-unused-arguments
|
||||
"C4", # flake8-comprehensions
|
||||
"EM", # flake8-errmsg
|
||||
"ICN", # flake8-import-conventions
|
||||
"ISC", # flake8-implicit-str-concat
|
||||
"G", # flake8-logging-format
|
||||
"PGH", # pygrep-hooks
|
||||
"PIE", # flake8-pie
|
||||
"PL", # pylint
|
||||
"PT", # flake8-pytest-style
|
||||
"RET", # flake8-return
|
||||
"RUF", # Ruff-specific
|
||||
"SIM", # flake8-simplify
|
||||
"TID251", # flake8-tidy-imports.banned-api
|
||||
"UP", # pyupgrade
|
||||
"YTT", # flake8-2020
|
||||
"EXE", # flake8-executable
|
||||
]
|
||||
extend-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)
|
||||
]
|
||||
target-version = "py38"
|
||||
typing-modules = ["cibuildwheel._compat.typing"]
|
||||
flake8-unused-arguments.ignore-variadic-names = true
|
||||
|
||||
[tool.ruff.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."
|
||||
"typing.Sequence".msg = "Use collections.abc.Sequence instead."
|
||||
"typing.Set".msg = "Use collections.abc.Set instead."
|
||||
"typing.NotRequired".msg = "Use cibuildwheel._compat.typing.NotRequired instead."
|
||||
"typing.assert_never".msg = "Use cibuildwheel._compat.typing.assert_never instead."
|
||||
"tomllib".msg = "Use cibuildwheel._compat.tomllib instead."
|
||||
"tomli".msg = "Use cibuildwheel._compat.tomllib instead."
|
||||
|
||||
[tool.ruff.per-file-ignores]
|
||||
"unit_test/*" = ["PLC1901"]
|
||||
"cibuildwheel/_compat/**.py" = ["TID251"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[metadata]
|
||||
name = cibuildwheel
|
||||
version = 2.11.2
|
||||
version = 2.16.1
|
||||
description = Build Python wheels on CI with minimal configuration.
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown
|
||||
@@ -8,7 +8,7 @@ url = https://github.com/pypa/cibuildwheel
|
||||
author = Joe Rickerby
|
||||
author_email = joerick@mac.com
|
||||
license = BSD-2-Clause
|
||||
license_file = LICENSE
|
||||
license_files = LICENSE
|
||||
classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Intended Audience :: Developers
|
||||
@@ -16,7 +16,6 @@ classifiers =
|
||||
Natural Language :: English
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
@@ -39,7 +38,7 @@ install_requires =
|
||||
platformdirs
|
||||
tomli;python_version < '3.11'
|
||||
typing-extensions>=4.1.0;python_version < '3.11'
|
||||
python_requires = >=3.7
|
||||
python_requires = >=3.8
|
||||
include_package_data = True
|
||||
zip_safe = False
|
||||
|
||||
@@ -53,18 +52,3 @@ console_scripts =
|
||||
|
||||
[options.package_data]
|
||||
cibuildwheel = resources/*
|
||||
|
||||
[flake8]
|
||||
extend-ignore = E203,E501,B950,B023
|
||||
extend-select = B9
|
||||
application-import-names = cibuildwheel
|
||||
exclude =
|
||||
cibuildwheel/resources/,
|
||||
dist/,
|
||||
build/,
|
||||
.git/,
|
||||
env/,
|
||||
env2/,
|
||||
env??/,
|
||||
.venv/,
|
||||
site/
|
||||
|
||||
@@ -27,20 +27,9 @@ extras = {
|
||||
"rich>=9.6",
|
||||
"packaging>=21.0",
|
||||
],
|
||||
"mypy": [
|
||||
"mypy>=0.901",
|
||||
"types-jinja2",
|
||||
"types-certifi",
|
||||
"types-toml",
|
||||
"types-jinja2",
|
||||
"types-pyyaml",
|
||||
"types-click",
|
||||
"types-requests",
|
||||
],
|
||||
}
|
||||
|
||||
extras["dev"] = [
|
||||
*extras["mypy"],
|
||||
*extras["test"],
|
||||
*extras["bin"],
|
||||
]
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import subprocess
|
||||
from typing import Generator
|
||||
|
||||
import pytest
|
||||
|
||||
from cibuildwheel.util import detect_ci_provider
|
||||
|
||||
from .utils import platform
|
||||
|
||||
|
||||
def pytest_addoption(parser) -> None:
|
||||
parser.addoption(
|
||||
@@ -21,3 +29,25 @@ def pytest_addoption(parser) -> None:
|
||||
)
|
||||
def build_frontend_env(request) -> dict[str, str]:
|
||||
return request.param # type: ignore[no-any-return]
|
||||
|
||||
|
||||
@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,
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
).stdout
|
||||
return {json.loads(image.strip()) for image in images.splitlines() if image.strip()}
|
||||
|
||||
images_before = get_images()
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
images_after = get_images()
|
||||
for image in images_after - images_before:
|
||||
subprocess.run(["docker", "rmi", image], check=False)
|
||||
|
||||
@@ -47,7 +47,7 @@ def test_abi3(tmp_path):
|
||||
expected_wheels = [
|
||||
w.replace("cp38-cp38", "cp38-abi3")
|
||||
for w in utils.expected_wheels("spam", "0.1.0")
|
||||
if "-pp" not in w and "-cp39" not in w and "-cp310" not in w and "-cp311" not in w
|
||||
if "-pp" not in w and "-cp39" not in w and "-cp31" not in w
|
||||
]
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
from . import utils
|
||||
from .test_projects.c import new_c_project
|
||||
|
||||
|
||||
@pytest.mark.parametrize("frontend_name", ["pip", "build"])
|
||||
def test_build_frontend_args(tmp_path, capfd, frontend_name):
|
||||
project = new_c_project()
|
||||
project_dir = tmp_path / "project"
|
||||
project.generate(project_dir)
|
||||
|
||||
# the build will fail because the frontend is called with '-h' - it prints the help message
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
add_env={
|
||||
"CIBW_BUILD": "cp311-*",
|
||||
"CIBW_BUILD_FRONTEND": f"{frontend_name}; args: -h",
|
||||
},
|
||||
)
|
||||
|
||||
captured = capfd.readouterr()
|
||||
print(captured.out)
|
||||
|
||||
# check that the help message was printed
|
||||
if frontend_name == "pip":
|
||||
assert "Usage:" in captured.out
|
||||
assert "Wheel Options:" in captured.out
|
||||
else:
|
||||
assert "usage:" in captured.out
|
||||
assert "A simple, correct Python build frontend." in captured.out
|
||||
@@ -7,7 +7,7 @@ from . import test_projects, utils
|
||||
basic_project = test_projects.new_c_project()
|
||||
|
||||
|
||||
def test(tmp_path, capfd, request):
|
||||
def test_podman(tmp_path, capfd, request):
|
||||
if utils.platform != "linux":
|
||||
pytest.skip("the test is only relevant to the linux build")
|
||||
|
||||
@@ -38,3 +38,29 @@ def test(tmp_path, capfd, request):
|
||||
# check that stdout is bring passed-though from container correctly
|
||||
captured = capfd.readouterr()
|
||||
assert "test log statement from before-all" in captured.out
|
||||
|
||||
|
||||
def test_create_args(tmp_path, capfd):
|
||||
if utils.platform != "linux":
|
||||
pytest.skip("the test is only relevant to the linux build")
|
||||
|
||||
project_dir = tmp_path / "project"
|
||||
basic_project.generate(project_dir)
|
||||
|
||||
# build a manylinux wheel, using create_args to set an environment variable
|
||||
actual_wheels = utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
add_env={
|
||||
"CIBW_BUILD": "cp310-manylinux_*",
|
||||
"CIBW_BEFORE_ALL": "echo TEST_CREATE_ARGS is set to $TEST_CREATE_ARGS",
|
||||
"CIBW_CONTAINER_ENGINE": "docker; create_args: --env=TEST_CREATE_ARGS=itworks",
|
||||
},
|
||||
)
|
||||
|
||||
expected_wheels = [
|
||||
w for w in utils.expected_wheels("spam", "0.1.0") if ("cp310-manylinux" in w)
|
||||
]
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
captured = capfd.readouterr()
|
||||
assert "TEST_CREATE_ARGS is set to itworks" in captured.out
|
||||
@@ -23,6 +23,7 @@ dockcross_only_project = test_projects.new_c_project(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("docker_cleanup")
|
||||
def test(tmp_path):
|
||||
if utils.platform != "linux":
|
||||
pytest.skip("the test is only relevant to the linux build")
|
||||
|
||||
@@ -70,7 +70,7 @@ def test_cpp11(tmp_path):
|
||||
cpp11_project.generate(project_dir)
|
||||
|
||||
actual_wheels = utils.cibuildwheel_run(project_dir)
|
||||
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0")]
|
||||
expected_wheels = list(utils.expected_wheels("spam", "0.1.0"))
|
||||
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
@@ -89,7 +89,7 @@ def test_cpp14(tmp_path):
|
||||
cpp14_project.generate(project_dir)
|
||||
|
||||
actual_wheels = utils.cibuildwheel_run(project_dir)
|
||||
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0")]
|
||||
expected_wheels = list(utils.expected_wheels("spam", "0.1.0"))
|
||||
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
@@ -118,7 +118,7 @@ def test_cpp17(tmp_path):
|
||||
|
||||
# Pypy's distutils sets the default compiler to 'msvc9compiler', which
|
||||
# is too old to support cpp17.
|
||||
add_env = {"CIBW_SKIP": "pp??-*"}
|
||||
add_env = {"CIBW_SKIP": "pp*"}
|
||||
|
||||
if utils.platform == "macos":
|
||||
add_env["MACOSX_DEPLOYMENT_TARGET"] = "10.13"
|
||||
|
||||
@@ -45,9 +45,7 @@ VERSION_REGEX = r"([\w-]+)==([^\s]+)"
|
||||
def get_versions_from_constraint_file(constraint_file):
|
||||
constraint_file_text = constraint_file.read_text(encoding="utf8")
|
||||
|
||||
return {
|
||||
package: version for package, version in re.findall(VERSION_REGEX, constraint_file_text)
|
||||
}
|
||||
return dict(re.findall(VERSION_REGEX, constraint_file_text))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("python_version", ["3.6", "3.8", "3.9"])
|
||||
@@ -122,10 +120,10 @@ def test_dependency_constraints_file(tmp_path, build_frontend_env):
|
||||
project_with_expected_version_checks.generate(project_dir)
|
||||
|
||||
tool_versions = {
|
||||
"pip": "20.0.2",
|
||||
"setuptools": "53.0.0",
|
||||
"wheel": "0.36.2",
|
||||
"virtualenv": "20.11.2",
|
||||
"pip": "23.1.2",
|
||||
"setuptools": "67.7.2",
|
||||
"wheel": "0.38.3",
|
||||
"virtualenv": "20.23.0",
|
||||
}
|
||||
|
||||
constraints_file = tmp_path / "constraints file.txt"
|
||||
@@ -157,11 +155,12 @@ def test_dependency_constraints_file(tmp_path, build_frontend_env):
|
||||
add_env={
|
||||
"CIBW_ENVIRONMENT": cibw_environment_option,
|
||||
"CIBW_DEPENDENCY_VERSIONS": str(constraints_file),
|
||||
"CIBW_SKIP": "cp36-*",
|
||||
**build_frontend_env,
|
||||
},
|
||||
)
|
||||
|
||||
# also check that we got the right wheels
|
||||
expected_wheels = utils.expected_wheels("spam", "0.1.0")
|
||||
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "-cp36" not in w]
|
||||
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
@@ -65,8 +65,8 @@ def test_overridden_path(tmp_path, capfd):
|
||||
output_dir.mkdir()
|
||||
|
||||
# mess up PATH, somehow
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
if utils.platform == "linux":
|
||||
if utils.platform == "linux":
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
output_dir=output_dir,
|
||||
@@ -75,11 +75,12 @@ def test_overridden_path(tmp_path, capfd):
|
||||
"CIBW_ENVIRONMENT": '''PATH="$(pwd)/new_path:$PATH"''',
|
||||
},
|
||||
)
|
||||
else:
|
||||
new_path = tmp_path / "another_bin"
|
||||
new_path.mkdir()
|
||||
(new_path / "python").touch(mode=0o777)
|
||||
else:
|
||||
new_path = tmp_path / "another_bin"
|
||||
new_path.mkdir()
|
||||
(new_path / "python").touch(mode=0o777)
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
output_dir=output_dir,
|
||||
|
||||
@@ -65,7 +65,7 @@ def test_cross_compiled_test(tmp_path, capfd, build_universal2):
|
||||
actual_wheels = utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
add_env={
|
||||
"CIBW_BUILD": "cp39-*",
|
||||
"CIBW_BUILD": "cp39-*" if build_universal2 else "*p39-*",
|
||||
"CIBW_TEST_COMMAND": '''python -c "import platform; print('running tests on ' + platform.machine())"''',
|
||||
"CIBW_ARCHS": "universal2" if build_universal2 else "x86_64 arm64",
|
||||
"CIBW_BUILD_VERBOSITY": "3",
|
||||
@@ -76,7 +76,8 @@ def test_cross_compiled_test(tmp_path, capfd, build_universal2):
|
||||
|
||||
assert DEPLOYMENT_TARGET_TOO_LOW_WARNING not in captured.err
|
||||
|
||||
if platform.machine() == "x86_64":
|
||||
platform_machine = platform.machine()
|
||||
if platform_machine == "x86_64":
|
||||
# ensure that tests were run on only x86_64
|
||||
assert "running tests on x86_64" in captured.out
|
||||
assert "running tests on arm64" not in captured.out
|
||||
@@ -89,15 +90,24 @@ def test_cross_compiled_test(tmp_path, capfd, build_universal2):
|
||||
assert (
|
||||
"While arm64 wheels can be built on x86_64, they cannot be tested" in captured.err
|
||||
)
|
||||
elif platform.machine() == "arm64":
|
||||
elif platform_machine == "arm64":
|
||||
# ensure that tests were run on both x86_64 and arm64
|
||||
assert "running tests on x86_64" in captured.out
|
||||
assert "running tests on arm64" in captured.out
|
||||
assert (
|
||||
"While universal2 wheels can be built on x86_64, the arm64 part of them cannot currently be tested"
|
||||
not in captured.err
|
||||
)
|
||||
assert (
|
||||
"While arm64 wheels can be built on x86_64, they cannot be tested" not in captured.err
|
||||
)
|
||||
|
||||
if build_universal2:
|
||||
expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" in w]
|
||||
else:
|
||||
expected_wheels = [w for w in ALL_MACOS_WHEELS if "cp39" in w and "universal2" not in w]
|
||||
expected_wheels = [w for w in ALL_MACOS_WHEELS if "p39-" in w and "universal2" not in w]
|
||||
if platform_machine == "x86_64":
|
||||
expected_wheels = [w for w in expected_wheels if not ("pp39" in w and "arm64" in w)]
|
||||
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ project_with_manylinux_symbols = test_projects.new_c_project(
|
||||
"manylinux_image",
|
||||
["manylinux1", "manylinux2010", "manylinux2014", "manylinux_2_24", "manylinux_2_28"],
|
||||
)
|
||||
@pytest.mark.usefixtures("docker_cleanup")
|
||||
def test(manylinux_image, tmp_path):
|
||||
if utils.platform != "linux":
|
||||
pytest.skip("the container image test is only relevant to the linux build")
|
||||
@@ -84,8 +85,11 @@ def test(manylinux_image, tmp_path):
|
||||
# We don't have a manylinux1 image for PyPy & CPython 3.10 and above
|
||||
add_env["CIBW_SKIP"] = "pp* cp31*"
|
||||
if manylinux_image in {"manylinux2010"}:
|
||||
# We don't have a manylinux2010 image for PyPy 3.9, CPython 3.11
|
||||
add_env["CIBW_SKIP"] = "pp39* cp311*"
|
||||
# We don't have a manylinux2010 image for PyPy 3.9+, CPython 3.11+
|
||||
add_env["CIBW_SKIP"] = "pp39* pp31* cp311* cp312*"
|
||||
if manylinux_image in {"manylinux_2_24"}:
|
||||
# We don't have a manylinux_2_24 image for PyPy 3.10+, CPython 3.12+
|
||||
add_env["CIBW_SKIP"] = "pp31* cp312*"
|
||||
if manylinux_image == "manylinux_2_28" and platform.machine() == "x86_64":
|
||||
# We don't have a manylinux_2_28 image for i686
|
||||
add_env["CIBW_ARCHS"] = "x86_64"
|
||||
@@ -108,8 +112,16 @@ def test(manylinux_image, tmp_path):
|
||||
expected_wheels = [w for w in expected_wheels if "-pp" not in w and "-cp31" not in w]
|
||||
|
||||
if manylinux_image in {"manylinux2010"}:
|
||||
# remove PyPy 3.9 & CPython 3.11
|
||||
expected_wheels = [w for w in expected_wheels if "-pp39" not in w and "-cp311" not in w]
|
||||
# remove PyPy 3.9+ & CPython 3.11
|
||||
expected_wheels = [
|
||||
w
|
||||
for w in expected_wheels
|
||||
if "-pp39" not in w and "-pp31" not in w and "-cp311" not in w and "-cp312" not in w
|
||||
]
|
||||
|
||||
if manylinux_image in {"manylinux_2_24"}:
|
||||
# remove PyPy 3.10+ & CPython 3.11 and above
|
||||
expected_wheels = [w for w in expected_wheels if "-pp31" not in w and "-cp312" not in w]
|
||||
|
||||
if manylinux_image == "manylinux_2_28" and platform.machine() == "x86_64":
|
||||
# We don't have a manylinux_2_28 image for i686
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
||||
from . import test_projects, utils
|
||||
|
||||
project_with_manylinux_symbols = test_projects.new_c_project(
|
||||
spam_c_top_level_add=textwrap.dedent(
|
||||
r"""
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__GLIBC_PREREQ)
|
||||
#error "Must not run on a glibc linux environment"
|
||||
#endif
|
||||
"""
|
||||
),
|
||||
spam_c_function_add=textwrap.dedent(
|
||||
r"""
|
||||
sts = 0;
|
||||
"""
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"musllinux_image",
|
||||
["musllinux_1_1", "musllinux_1_2"],
|
||||
)
|
||||
@pytest.mark.usefixtures("docker_cleanup")
|
||||
def test(musllinux_image, tmp_path):
|
||||
if utils.platform != "linux":
|
||||
pytest.skip("the container image test is only relevant to the linux build")
|
||||
|
||||
project_dir = tmp_path / "project"
|
||||
project_with_manylinux_symbols.generate(project_dir)
|
||||
|
||||
# build the wheels
|
||||
add_env = {
|
||||
"CIBW_BUILD": "*-musllinux*",
|
||||
"CIBW_MUSLLINUX_X86_64_IMAGE": musllinux_image,
|
||||
"CIBW_MUSLLINUX_I686_IMAGE": musllinux_image,
|
||||
"CIBW_MUSLLINUX_AARCH64_IMAGE": musllinux_image,
|
||||
"CIBW_MUSLLINUX_PPC64LE_IMAGE": musllinux_image,
|
||||
"CIBW_MUSLLINUX_S390X_IMAGE": musllinux_image,
|
||||
}
|
||||
|
||||
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
|
||||
expected_wheels = utils.expected_wheels(
|
||||
"spam",
|
||||
"0.1.0",
|
||||
manylinux_versions=[],
|
||||
musllinux_versions=[musllinux_image],
|
||||
)
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
+2
-3
@@ -9,7 +9,7 @@ basic_project = test_projects.new_c_project(
|
||||
"""
|
||||
# Will fail if PEP 518 does work
|
||||
import requests
|
||||
assert requests.__version__ == "2.23.0", "Requests found but wrong version ({0})".format(requests.__version__)
|
||||
assert requests.__version__ == "2.27.0", "Requests found but wrong version ({0})".format(requests.__version__)
|
||||
|
||||
# Just making sure environment is still set
|
||||
import os
|
||||
@@ -27,7 +27,7 @@ requires = [
|
||||
"setuptools >= 42",
|
||||
"setuptools_scm[toml]>=4.1.2",
|
||||
"wheel",
|
||||
"requests==2.23.0"
|
||||
"requests==2.27.0"
|
||||
]
|
||||
|
||||
build-backend = "setuptools.build_meta"
|
||||
@@ -35,7 +35,6 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
|
||||
def test_pep518(tmp_path, build_frontend_env):
|
||||
|
||||
project_dir = tmp_path / "project"
|
||||
basic_project.generate(project_dir)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class TestProject:
|
||||
|
||||
with file_path.open("w", encoding="utf8") as f:
|
||||
if isinstance(content, jinja2.Template):
|
||||
content = content.render(self.template_context)
|
||||
content = content.render(self.template_context) # noqa: PLW2901
|
||||
|
||||
f.write(content)
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ def test(tmp_path, capfd):
|
||||
pure_python_project.generate(project_dir)
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
actual_wheels = utils.cibuildwheel_run(project_dir)
|
||||
print("produced wheels:", actual_wheels)
|
||||
print("produced wheels:", utils.cibuildwheel_run(project_dir))
|
||||
|
||||
captured = capfd.readouterr()
|
||||
print("out", captured.out)
|
||||
|
||||
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
import os
|
||||
import subprocess
|
||||
import textwrap
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -151,3 +152,37 @@ def test_failing_test(tmp_path):
|
||||
)
|
||||
|
||||
assert len(os.listdir(output_dir)) == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize("test_runner", ["pytest", "unittest"])
|
||||
def test_bare_pytest_invocation(
|
||||
tmp_path: Path, capfd: pytest.CaptureFixture[str], test_runner: str
|
||||
):
|
||||
"""Check that if a user runs pytest in the the test cwd, it raises a helpful error"""
|
||||
project_dir = tmp_path / "project"
|
||||
output_dir = tmp_path / "output"
|
||||
project_with_a_test.generate(project_dir)
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
output_dir=output_dir,
|
||||
add_env={
|
||||
"CIBW_TEST_REQUIRES": "pytest" if test_runner == "pytest" else "",
|
||||
"CIBW_TEST_COMMAND": (
|
||||
"python -m pytest" if test_runner == "pytest" else "python -m unittest"
|
||||
),
|
||||
# Skip CPython 3.8 on macOS arm64, see comment above in
|
||||
# 'test_failing_test'
|
||||
"CIBW_SKIP": "cp38-macosx_arm64",
|
||||
},
|
||||
)
|
||||
|
||||
assert len(os.listdir(output_dir)) == 0
|
||||
|
||||
captured = capfd.readouterr()
|
||||
|
||||
assert (
|
||||
"Please specify a path to your tests when invoking pytest using the {project} placeholder"
|
||||
in captured.out + captured.err
|
||||
)
|
||||
|
||||
@@ -12,9 +12,9 @@ basic_project = test_projects.new_c_project()
|
||||
|
||||
|
||||
def skip_if_no_msvc(arm64=False):
|
||||
programfiles = os.getenv("ProgramFiles(x86)", "") or os.getenv("ProgramFiles", "")
|
||||
programfiles = os.getenv("PROGRAMFILES(X86)", "") or os.getenv("PROGRAMFILES", "")
|
||||
if not programfiles:
|
||||
pytest.skip("Requires %ProgramFiles(x86)% variable to be set")
|
||||
pytest.skip("Requires %PROGRAMFILES(X86)% variable to be set")
|
||||
|
||||
vswhere = os.path.join(programfiles, "Microsoft Visual Studio", "Installer", "vswhere.exe")
|
||||
if not os.path.isfile(vswhere):
|
||||
|
||||
+37
-10
@@ -170,14 +170,29 @@ def expected_wheels(
|
||||
"cp39-cp39",
|
||||
"cp310-cp310",
|
||||
"cp311-cp311",
|
||||
"cp312-cp312",
|
||||
]
|
||||
|
||||
if machine_arch in ["x86_64", "AMD64", "x86", "aarch64"]:
|
||||
python_abi_tags += ["pp37-pypy37_pp73", "pp38-pypy38_pp73", "pp39-pypy39_pp73"]
|
||||
python_abi_tags += [
|
||||
"pp37-pypy37_pp73",
|
||||
"pp38-pypy38_pp73",
|
||||
"pp39-pypy39_pp73",
|
||||
"pp310-pypy310_pp73",
|
||||
]
|
||||
|
||||
if platform == "macos" and machine_arch == "arm64":
|
||||
# arm64 macs are only supported by cp38+
|
||||
python_abi_tags = ["cp38-cp38", "cp39-cp39", "cp310-cp310", "cp311-cp311"]
|
||||
python_abi_tags = [
|
||||
"cp38-cp38",
|
||||
"cp39-cp39",
|
||||
"cp310-cp310",
|
||||
"cp311-cp311",
|
||||
"cp312-cp312",
|
||||
"pp38-pypy38_pp73",
|
||||
"pp39-pypy39_pp73",
|
||||
"pp310-pypy310_pp73",
|
||||
]
|
||||
|
||||
wheels = []
|
||||
|
||||
@@ -185,18 +200,19 @@ def expected_wheels(
|
||||
platform_tags = []
|
||||
|
||||
if platform == "linux":
|
||||
architectures = [machine_arch]
|
||||
architectures = [arch_name_for_linux(machine_arch)]
|
||||
|
||||
if machine_arch == "x86_64":
|
||||
architectures.append("i686")
|
||||
|
||||
platform_tags = [
|
||||
".".join(
|
||||
f"{manylinux_version}_{architecture}"
|
||||
for manylinux_version in manylinux_versions
|
||||
)
|
||||
for architecture in architectures
|
||||
]
|
||||
if len(manylinux_versions) > 0:
|
||||
platform_tags = [
|
||||
".".join(
|
||||
f"{manylinux_version}_{architecture}"
|
||||
for manylinux_version in manylinux_versions
|
||||
)
|
||||
for architecture in architectures
|
||||
]
|
||||
if len(musllinux_versions) > 0 and not python_abi_tag.startswith("pp"):
|
||||
platform_tags.extend(
|
||||
[
|
||||
@@ -248,3 +264,14 @@ def get_macos_version():
|
||||
"""
|
||||
version_str, _, _ = pm.mac_ver()
|
||||
return tuple(map(int, version_str.split(".")[:2]))
|
||||
|
||||
|
||||
def arch_name_for_linux(arch: str):
|
||||
"""
|
||||
Archs have different names on different platforms, but it's useful to be
|
||||
able to run linux tests on dev machines. This function translates between
|
||||
the different names.
|
||||
"""
|
||||
if arch == "arm64":
|
||||
return "aarch64"
|
||||
return arch
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
import tomllib
|
||||
else:
|
||||
import tomli as tomllib
|
||||
|
||||
from packaging.version import Version
|
||||
|
||||
from cibuildwheel._compat import tomllib
|
||||
from cibuildwheel.extra import Printable, dump_python_configurations
|
||||
from cibuildwheel.util import resources_dir
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user