Compare commits

..
497 Commits
Author SHA1 Message Date
Joe Rickerby d04cacbc98 Bump version: v2.23.2 2025-03-24 21:25:38 +00:00
Matthieu Darbois 5f4e019684 [2.x] Update dependencies (#2334) 2025-03-24 21:17:56 +00:00
Henry Schreiner 2efa648f38 fix: always resolve --python argument (#2328) (#2331)
fix: always resolve --python argument (#2328)

fix: always resolve the --python argument

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2025-03-23 15:03:30 -04:00
Joe Rickerby 42728e866b Bump version: v2.23.1 2025-03-15 17:58:14 +00:00
Joe Rickerby 6e1527b153 Fix unit test when other warnings are present 2025-03-15 17:54:37 +00:00
Matthieu Darbois c25fe60385 fix: image deprecation warning (#2314) 2025-03-15 17:54:37 +00:00
Henry SchreinerandJoe Rickerby a880bf5105 fix: warn on deprecated images being set (#2312)
* fix: warn on deprecated images being set

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: handle repeated warning messages

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Apply suggestions from code review

Co-authored-by: Joe Rickerby <joerick@mac.com>

* fix: try making the warnings once per Options

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2025-03-15 17:54:37 +00:00
Joe Rickerby c087d85b69 Update dependencies 2025-03-15 17:54:37 +00:00
Joe Rickerby 6cccd09a31 Bump version: v2.23.0 2025-03-01 13:27:50 +00:00
Matthieu Darbois aa1534d2a3 chore(2.x): update dependencies (#2294) 2025-03-01 11:49:19 +00:00
mayeut ee23dd147b fix(test): implement retry for test_container_removed
The test is flaky on some platforms. Implement retry rather than just skip.
2025-02-25 14:22:19 -05:00
Matthieu Darbois 55037e9716 ci/doc: move azure macOS build to macOS-13 (#2101)
The macOS-12 environment is deprecated.
2025-02-25 14:22:19 -05:00
Joe Rickerby 8874ee2048 Remove specific Python versions from the update-dependencies job
The requirements pinning is done by uv now, so we don't need to
run the versions of Python to do the pinning anymore.

Cherry-picked from 37f7f611b208f48d4bb80a35eb31e39e47102930
2025-02-25 14:22:19 -05:00
mayeut f76d345e81 chore: bump dependencies 2025-02-25 14:22:19 -05:00
Agriya Khetarpal 5a5e514fbd Bump to Pyodide 0.27 (#2117)
* Bump to Pyodide 0.27

* Update the Pyodide target's constraints
2025-02-25 14:22:19 -05:00
Matthieu Darbois 017abbba68 feature: add PyPy 3.11 (#2268) 2025-02-25 14:22:19 -05:00
Matthieu Darbois bb1fd3320e feat: Add support for ubuntu-24.04-arm GHA runner (#2135)
* ci(gha): add tests on ubuntu-24.04-arm

* address review comments
2025-02-25 14:22:19 -05:00
Matthieu Darbois 98a6f3bf64 chore: use pypa/manylinux for manylinux_2_31_armv7l (#2269) 2025-02-25 14:22:19 -05:00
Henry Schreiner ee63bf16da Bump version: v2.22.0 2024-11-23 01:44:09 -05:00
Alex Waygood d3eeba7967 chore: bump Ruff to 0.8.0 (#2092) 2024-11-22 16:18:12 -05:00
Agriya KhetarpalandHenry Schreiner 109020ed2d Updates for Pyodide builds after pyodide-build was unvendored (#2090)
* Fix typos and capitalise

* Add docstring for `install_xbuildenv` function

* Include Emscripten, Pyodide version in logger messages

* Mark separation of pyodide-build and Pyodide

* Bump to Pyodide 0.26.4 (py3.12.7) + pyodide-build 0.29.0

* Use pyodide-build version as the source of truth

* Update Pyodide constraints

* Use 3.12 as the Python version instead of 3.12.7

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>

* chore: appease the formatter

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2024-11-22 16:17:51 -05:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> fd990007be [pre-commit.ci] pre-commit autoupdate (#2087)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.7.3 → v0.7.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.3...v0.7.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-11-20 01:18:10 -05:00
Henry SchreinerandMatthieu Darbois e158f22d51 ci: update gitlab for dependency-groups (#2089)
* ci: update gitlab for dependency-groups

* Update .gitlab-ci.yml

* Apply suggestions from code review

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

---------

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-11-20 01:17:54 -05:00
8f21eb17be chore: use dependency-groups (#2064)
* chore: use dependency-groups

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* ci: use dep groups in other CIs

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Apply suggestions from code review

* chore: read dep groups in noxfile

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Apply suggestions from code review

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

* Add dev environment instructions

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-11-19 19:30:06 +01:00
aac31ae2fb docs: fix update scripts usage (#2067)
* Update contributing.md

* Update options.md

* Update options.md

* Update docs/contributing.md

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

* Update contributing.md

* Apply suggestions from code review

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-11-18 03:27:05 -05:00
Matthieu Darbois b882b84e47 fix: update the macOS image used on Cirrus CI (#2085)
Use `ghcr.io/cirruslabs/macos-runner:sonoma` instead of `ghcr.io/cirruslabs/macos-sonoma-xcode` which is not supported anymore.
2024-11-18 03:26:39 -05:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 243085f047 [Bot] Update dependencies (#2086)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-11-18 03:26:20 -05:00
Matthieu Darbois df6f886390 feat: add manylinux armv7l (#2052) 2024-11-15 19:07:24 -05:00
Matthieu Darbois 6f21f84a71 fix: capture stderr in utils.call when capture_stdout is True (#2076) 2024-11-14 11:40:59 -05:00
Henry Schreinerandmayeut 393e0352e8 feat: adding enable (#2048)
* feat: adding enable

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* refactor: use recommended term

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: use `cached_property` for `Options` properties

* fix: warn on PyPy default

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2024-11-14 11:39:52 -05:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 9459533408 chore(deps): bump actions/attest-build-provenance from 1.4.3 to 1.4.4 in the actions group (#2078)
chore(deps): bump actions/attest-build-provenance in the actions group

Bumps the actions group with 1 update: [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance).


Updates `actions/attest-build-provenance` from 1.4.3 to 1.4.4
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/1c608d11d69870c2092266b3f9a6f3abbf17002c...ef244123eb79f2f7a7e75d99086184180e6d0018)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-11-12 08:43:41 +01:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> d9f987df66 [pre-commit.ci] pre-commit autoupdate (#2079)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.7.2 → v0.7.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.2...v0.7.3)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-11-12 08:43:18 +01:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> f97c1fb99b [Bot] Update dependencies (#2077)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-11-11 09:15:02 +01:00
Matthieu Darbois 5cdddb2d46 fix: error message when manylinux-interpreters ensure ... failed (#2066)
* review: address review comments from #1630

* fix: error message when `manylinux-interpreters ensure ...` failed

* fix: error message when `manylinux-interpreters ensure ...` failed (option b)
2024-11-09 11:06:13 +01:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> e18a6e9eb0 [pre-commit.ci] pre-commit autoupdate (#2073)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.7.1 → v0.7.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.1...v0.7.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-11-05 01:58:32 -05:00
Aarni Koskela c42b1cecf1 tests: fix CIBW_CONFIG_SETTIGNS typo in test (#2071)
fix: Fix CIBW_CONFIG_SETTIGNS typo in test

Caught with https://github.com/crate-ci/typos
2024-11-05 01:57:51 -05:00
Grzegorz Bokota c940bed415 docs: fix travis link in readme (#2072)
fix travis link in readme
2024-11-05 01:57:17 -05:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 530f52dc9c [Bot] Update dependencies (#2059)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-11-05 07:41:08 +01:00
Henry SchreinerandMatthieu Darbois cc1d977359 feat: support test-groups (#2063)
* feat: support test-groups

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* refactor: address review comments

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* tests: add a integration test

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Apply suggestions from code review

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

* fix: better error messages based on feedback

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-11-04 21:25:01 +01:00
omahs d2c7614c3a docs: fix typos (#2061)
* docs: fix typo

* docs: fix typos

* docs: fix typos
2024-11-01 11:39:32 +00:00
Joe Rickerby 66d45de432 repair-wheel-command docs and error message improvements (#2058)
* Fix bug in docs for running abi3audit in repair-wheel-command on windows

* Better error message for misconfigured repair-wheel-command
2024-10-28 23:22:03 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
eaa861622a [pre-commit.ci] pre-commit autoupdate (#2060)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.7.0 → v0.7.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.7.0...v0.7.1)
- [github.com/pre-commit/mirrors-mypy: v1.12.1 → v1.13.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.12.1...v1.13.0)

* Update .pre-commit-config.yaml

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2024-10-28 23:17:29 -04:00
Matthieu DarboisandHenry Schreiner 7c3b0fbee8 chore: add warning when running cibuildwheel with python<3.11 (#2050)
* chore: add warning when running cibuildwheel with python<3.11

* fix: use `log.warning` to print warnings in `print_preamble`

* Better warning & doc update

* address review comments

* Update README.md

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2024-10-25 22:07:29 +02:00
Henry Schreiner b98602705f chore: stricter mypy (#2053)
* chore: improve mypy

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* chore(types): type functions in tests

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* chore(types): No partial types in tests

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-10-22 10:16:59 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
b4d1e17765 [pre-commit.ci] pre-commit autoupdate (#2054)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.6.9 → v0.7.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.9...v0.7.0)
- [github.com/pre-commit/mirrors-mypy: v1.11.2 → v1.12.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.11.2...v1.12.1)

* chore: mypy bug fixed

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-10-22 00:45:06 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 4e93d9153e [Bot] Update dependencies (#2051)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-10-21 10:38:46 -04:00
Matthieu Darbois 1001c837de fix: re-raise subprocess.CalledProcessError when uname -m fails on arm (#2049) 2024-10-19 23:02:40 -04:00
Henry Schreiner 18f54c08e2 docs: print a couple slighly more detailed error messages (#2044)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-10-18 08:52:05 -04:00
Matthieu Darbois 5b7119ecef linux: use Python 3.9 in before_all (#2043)
Also use Python 3.9 for utility python in oci_container.
2024-10-17 01:25:09 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> ddbd67cbde [Bot] Update dependencies (#2040)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-10-15 13:09:49 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 84ac771415 chore(deps): bump wntrblm/nox from 2024.04.15 to 2024.10.09 in the actions group (#2041)
chore(deps): bump wntrblm/nox in the actions group

Bumps the actions group with 1 update: [wntrblm/nox](https://github.com/wntrblm/nox).


Updates `wntrblm/nox` from 2024.04.15 to 2024.10.09
- [Release notes](https://github.com/wntrblm/nox/releases)
- [Changelog](https://github.com/wntrblm/nox/blob/main/CHANGELOG.md)
- [Commits](https://github.com/wntrblm/nox/compare/2024.04.15...2024.10.09)

---
updated-dependencies:
- dependency-name: wntrblm/nox
  dependency-type: direct:production
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-15 13:09:03 +02:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> e792bb9705 [pre-commit.ci] pre-commit autoupdate (#2042)
updates:
- [github.com/python-jsonschema/check-jsonschema: 0.29.3 → 0.29.4](https://github.com/python-jsonschema/check-jsonschema/compare/0.29.3...0.29.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-10-15 13:08:49 +02:00
Joe Rickerby 7940a4c0e7 Bump version: v2.21.3 2024-10-09 09:04:53 +01:00
Henry Schreiner 3d3159b37b docs: update for 3.13.0 final (#2035)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-10-08 10:26:58 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 0319c431de [Bot] Update dependencies (#2032)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-10-08 01:47:21 -04:00
Matthieu Darbois 80ae9a50c9 fix: do not subclass wheel.bdist_wheel command in ABI3 test (#2030)
fix: do not subclass bdist_wheel command in ABI3 test

With bdist_wheel becoming a first-class citizen command of setuptools, this trick might not work in the future.
2024-10-07 18:26:20 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 006f1e6ec6 [pre-commit.ci] pre-commit autoupdate (#2033)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.6.0 → v5.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.6.0...v5.0.0)
- [github.com/astral-sh/ruff-pre-commit: v0.6.8 → v0.6.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.8...v0.6.9)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-10-07 18:25:09 -04:00
Joe Rickerby f185952832 Bump version: v2.21.2 2024-10-02 22:51:53 +01:00
Henry Schreinerandmayeut d5c6a83aeb ci: update job slightly (#2028)
* ci: update job slightly

* Ignore check-wheel-content W002

---------

Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2024-10-02 14:52:36 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 2e8e511106 [Bot] Update dependencies (#2029)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-10-02 15:59:31 +02:00
Joe RickerbyHenry SchreinerMatthieu Darboispre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
ec591cdf47 Add note about the planned change of the manylinux default (#1992)
* Add note about the planned change of the manylinux default

* Update docs/options.md

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>

* Change date to 6th May

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

* no manylinux_2_28 pypy_i686 image

* no manylinux_2_28 i686 image

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-10-02 14:29:22 +02:00
Henry Schreiner ee7fa96f6d chore: remove a couple of things pylint is unhappy about (#2027)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-10-02 00:22:40 -04:00
Henry Schreiner d625d18b91 ci: add 3.13 classifier (#2026)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-10-02 00:22:31 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 895eae340a [Bot] Update dependencies (#2025)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-10-02 00:22:22 -04:00
Matthieu DarboisandHenry Schreiner 9fad66fcfb feat: add musllinux armv7l (#2017)
* feature: add musllinux armv7l

* fix: local armv7l images

* fix python 3.8 tests

* address review comments

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2024-10-01 10:33:57 -04:00
zachlewispre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>mayeut
dfd01af9aa fix: more reliably validate Podman API version (#2016)
* fix: parse version strings that include dashes

It's possible for some container engines to report their versions with a dash (e.g., "4.9.4-rhel"), which breaks packaging.version.Version's ability to parse the string. This commit introduces a version_from_string method which santizies the version string and returns an instance of Version.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* cleanup: pacify ruff

* cleanup: further pacify ruff

* fix: properly define _version_from_string method

Also, lift the method up and prefix with a "_" to better match the existing conventions

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* refactor: more robust podman ver check

Use the "podman --version" command instead of "podman version -f {{json .}}" for better reliability across distributions.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: oci engine version check

Lower Docker API check to 1.41
Podman versions are not PEP440 compliant, remove distro specific suffixes before parsing.
Add tests with real-world outputs and some made up ones.

* fix: UX on OCIEngineTooOldError

* Add FlexibleVersion

per review comment

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2024-10-01 01:10:58 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 735e88deba [Bot] Update dependencies (#2022)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-10-01 01:09:19 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> bb2f6652b7 [pre-commit.ci] pre-commit autoupdate (#2023)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.6.7 → v0.6.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.7...v0.6.8)
- [github.com/python-jsonschema/check-jsonschema: 0.29.2 → 0.29.3](https://github.com/python-jsonschema/check-jsonschema/compare/0.29.2...0.29.3)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-10-01 01:08:09 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 6dcd7dd34b [pre-commit.ci] pre-commit autoupdate (#2019)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.6.5 → v0.6.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.5...v0.6.7)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-24 08:37:07 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 1327af5077 [Bot] Update dependencies (#2018)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-09-23 13:19:50 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 311f64987b [Bot] Update dependencies (#2014)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-09-17 12:12:53 -04:00
Henry Schreiner 08e5b97e57 ci: modernize update workflow (#2010) 2024-09-17 07:54:17 +02:00
Henry Schreiner d4a2945fcc Bump version: v2.21.1 2024-09-16 21:04:46 -04:00
pre-commit-ci[bot] 9913c03128 [pre-commit.ci] pre-commit autoupdate (#2013) 2024-09-16 20:32:04 -04:00
cibuildwheel-bot[bot] c0e28d3401 fix: support uv 0.4.10+ on Linux and update dependencies (#2008) 2024-09-16 20:31:48 -04:00
Matthieu Darbois 8c42e7980c fix: file ownership of files copied into the container (#2007)
Revert to using `cat`/`tar` to copy files/folders into the container.
2024-09-16 23:12:19 +01:00
Henry Schreiner 01ecd4e011 docs: bump pinned versions (#2011)
Trying to fix ci; might need to add `pathspec` if this isn't enough.
2024-09-16 14:01:04 -04:00
Matthieu Darbois 33da1f7d14 fix: do not use uv to setup python on windows when conditions are not met (#2005)
* fix: do not use `uv` to setup python on windows when conditions are not met

* add `can_use_uv` on macOS
2024-09-16 12:03:19 -04:00
Joe Rickerby 79b0dd3287 Bump version: v2.21.0 2024-09-13 16:42:42 +01:00
Matthieu Darbois 0787a44d99 fix: enforce minimum version of docker/podman (#1961)
* fix: enforce minimum version of docker/podman

This allows to always pass `--platform` to the OCI engine
thus fixing issues with multiarch images.

* Allow older versions with warnings

* Upgrade docker on Travis CI

* fix: use `docker cp` instead of `tar`

* Enforce docker>=24.0

* move log to include container.copy_into

* fix: travis-ci, only update docker on aarch64

* skip test_multiarch_image on s390x / ppc64le

* skip flaky test

* chore: only install test deps on Travis CI

* fix: do not try to pull images tagged `cibw_local`

* use "--pull=never" for local images

* Use docker image inspect to check if an image needs to be pulled
2024-09-12 15:32:43 -04:00
cibuildwheel-bot[bot]cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>mayeut
fd11286290 [Bot] Update dependencies (#1998)
* Update dependencies

* fix: set minimal deployment target to macOS 10.13 with CPython 3.12

---------

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2024-09-12 15:32:22 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 22dc864d60 [pre-commit.ci] pre-commit autoupdate (#2000)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.6.3 → v0.6.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.3...v0.6.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-09-10 12:22:54 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 9d2f46ce4e chore(deps): bump the actions group with 2 updates (#1999)
Bumps the actions group with 2 updates: [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) and [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).


Updates `actions/attest-build-provenance` from 1.4.2 to 1.4.3
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/6149ea5740be74af77f260b9db67e633f6b0a9a1...1c608d11d69870c2092266b3f9a6f3abbf17002c)

Updates `peter-evans/create-pull-request` from 6 to 7
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 20:04:37 +01:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> b1ed7bb3bc [Bot] Update dependencies (#1993)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-09-03 17:16:41 -04:00
Joe RickerbyandMatthieu Darbois ca08f5fbcf Customise merge behaviour depending on option. Fix #1803 (#1984)
Fix for #1803, where the method used for merging the config-settings option - string concatenation - was of little use.

I broke out the TableFmt object into a protocol-like object called OptionFormat, where the formatting and merge rules can be customised more deeply. This is more explicit, and lets us be a bit more precise with how TOML object get converted into the options.

I intend to use the flexibility of the OptionsFormat structure to tackle the remaining abiguity around environment variable quoting, as seen in the xfails in the options_test.py unit test and discussed in #1271.


Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-09-03 16:05:00 +01:00
pre-commit-ci[bot] 229029e112 [pre-commit.ci] pre-commit autoupdate (#1994) 2024-09-03 07:43:40 +01:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 3294577c17 [pre-commit.ci] pre-commit autoupdate (#1987)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.6.1 → v0.6.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.6.1...v0.6.2)
- [github.com/pre-commit/mirrors-mypy: v1.11.1 → v1.11.2](https://github.com/pre-commit/mirrors-mypy/compare/v1.11.1...v1.11.2)
- [github.com/python-jsonschema/check-jsonschema: 0.29.1 → 0.29.2](https://github.com/python-jsonschema/check-jsonschema/compare/0.29.1...0.29.2)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-08-27 12:21:14 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 8f51efbc3e [Bot] Update dependencies (#1985)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-08-26 10:41:21 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> ebdbb3cbd5 chore(deps): bump actions/attest-build-provenance from 1.4.1 to 1.4.2 in the actions group (#1986)
chore(deps): bump actions/attest-build-provenance in the actions group

Bumps the actions group with 1 update: [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance).


Updates `actions/attest-build-provenance` from 1.4.1 to 1.4.2
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/310b0a4a3b0b78ef57ecda988ee04b132db73ef8...6149ea5740be74af77f260b9db67e633f6b0a9a1)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 10:40:32 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
3a30bec9ef [pre-commit.ci] pre-commit autoupdate (#1978)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.5.7 → v0.6.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.7...v0.6.1)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* chore: ruff python-version not needed

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2024-08-21 00:34:31 -04:00
Matthieu Darbois 126b81916d chore(ci): podman is now pre-installed on GHA runners (#1974)
podman is now pre-installed on GHA runners
2024-08-19 11:28:24 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 9abea5b73b [Bot] Update dependencies (#1976)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-08-19 11:26:53 -04:00
Matthieu Darbois 170e7aaeb9 fix: TravisCI failures & status (#1970)
* fix: TravisCI failures & status
* Allow failure on s390x
2024-08-15 17:48:24 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 5b570a2451 [Bot] Update dependencies (#1963)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-08-14 16:00:33 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> ffd7dddcc7 [pre-commit.ci] pre-commit autoupdate (#1967)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.5.6 → v0.5.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.6...v0.5.7)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-08-14 16:00:02 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> b0b13d3a16 chore(deps): bump actions/attest-build-provenance from 1.4.0 to 1.4.1 in the actions group (#1964)
chore(deps): bump actions/attest-build-provenance in the actions group

Bumps the actions group with 1 update: [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance).


Updates `actions/attest-build-provenance` from 1.4.0 to 1.4.1
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/210c1913531870065f03ce1f9440dd87bc0938cd...310b0a4a3b0b78ef57ecda988ee04b132db73ef8)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-14 15:59:47 -04:00
Matthieu Darbois b1781e4606 fix: AppVeyor CI tests & sample (#1971) 2024-08-14 15:57:17 -04:00
Henry Schreinerandmayeut 3580374b18 fix: support empty CIBW_PLATFORM (#1969)
* fix: support empty CIBW_PLATFORM

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: support empty CIBW_PLATFORM

* Add test

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2024-08-14 15:56:06 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> c6dd39bd83 [Bot] Update dependencies (#1954)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-08-07 16:08:57 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> dd8fe86308 [pre-commit.ci] pre-commit autoupdate (#1958)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.5.5 → v0.5.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.5...v0.5.6)
- [github.com/pre-commit/mirrors-mypy: v1.11.0 → v1.11.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.11.0...v1.11.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-08-07 16:07:39 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 2e12f05d5e chore(deps): bump actions/attest-build-provenance from 1.3.3 to 1.4.0 in the actions group (#1956)
chore(deps): bump actions/attest-build-provenance in the actions group

Bumps the actions group with 1 update: [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance).


Updates `actions/attest-build-provenance` from 1.3.3 to 1.4.0
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/5e9cb68e95676991667494a6a4e59b8a2f13e1d0...210c1913531870065f03ce1f9440dd87bc0938cd)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-07 16:07:28 -04:00
Henry Schreiner bd033a4447 Bump version: v2.20.0 2024-08-03 22:37:32 -04:00
Ewout ter Hoevenpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>mayeut
9d023cf77a Build CPython 3.13 by default (#1950)
* Build CPython 3.13 by default

Enable building with CPython 3.13 by default, no longer requiring prerelease_pythons flag to be set true.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* README.md: Add note about free-threaded support

* build_selector_test.py: cp313t still behind flag

Even with 3.13 being enabled by default, cp313t is still behind a flag for now.

This commit updates the test accordingly.

* fix unit tests

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2024-08-03 14:46:45 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 8a69dbd9d4 [Bot] Update dependencies (#1949)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-08-03 12:05:10 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 147de6f4f7 [pre-commit.ci] pre-commit autoupdate (#1947)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.5.4 → v0.5.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.4...v0.5.5)
- [github.com/python-jsonschema/check-jsonschema: 0.29.0 → 0.29.1](https://github.com/python-jsonschema/check-jsonschema/compare/0.29.0...0.29.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-07-30 10:01:48 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> e217e44661 [Bot] Update dependencies (#1946)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-07-29 11:02:55 -04:00
Matt Richards 871ef6b506 tests: show xfail traceback summaries again (#1943)
Revert "tests: don't print xfails (#1865)"

This reverts commit 8d86d3122b.
2024-07-23 09:14:06 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
fac72f024a [pre-commit.ci] pre-commit autoupdate (#1944)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.5.2 → v0.5.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.2...v0.5.4)
- [github.com/pre-commit/mirrors-mypy: v1.10.1 → v1.11.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.10.1...v1.11.0)

* chore: type ignore no longer needed

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2024-07-23 09:26:50 +01:00
Conor MacBrideandMatthieu Darbois d4c332104d feat: add CIBW_ALLOW_EMPTY environment variable (#1937)
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-07-23 09:25:09 +01:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 5af5df4e4f [Bot] Update dependencies (#1935)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-07-21 19:56:36 +02:00
Conor MacBride 6c5cf87871 docs: fix nox docs command (#1938) 2024-07-21 11:37:43 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 46f4108f23 chore(deps): bump actions/attest-build-provenance from 1.3.2 to 1.3.3 in the actions group (#1936)
chore(deps): bump actions/attest-build-provenance in the actions group

Bumps the actions group with 1 update: [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance).


Updates `actions/attest-build-provenance` from 1.3.2 to 1.3.3
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/bdd51370e0416ac948727f861e03c2f05d32d78e...5e9cb68e95676991667494a6a4e59b8a2f13e1d0)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-21 11:29:36 +02:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 1da439f8dc [pre-commit.ci] pre-commit autoupdate (#1939)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.5.1 → v0.5.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.1...v0.5.2)
- [github.com/python-jsonschema/check-jsonschema: 0.28.6 → 0.29.0](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.6...0.29.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-07-21 11:29:11 +02:00
Matthieu Darbois 7af9d039fb fix: do not use uv on Windows PyPy 3.8 (#1941)
fix: do not use uv on PyPy 3.8

uv 0.2.25+ does not work with PyPy 3.8
Given PyPy 3.8 is EOL, just disable uv for this config rather than ask for it to be supported again in uv.
2024-07-21 10:51:43 +02:00
MusicalNinjaDadJoe RickerbyHenry Schreinerpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
de84624d70 fix: set VSCMD_ARG_TGT_ARCH based on targeted architecture (#1876)
* set VSCMD_ARG_TGT_ARCH based on targetted architecture

* only set VSCMD_ARG_TGT_ARCH if not already set

* add unit tests to check setuptools correctly identifies windows arch

* only run tests on windows

* arm64 fails on azure pipelines (only)

* Update windows.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Apply suggestions from code review

Co-authored-by: Joe Rickerby <joerick@mac.com>

* update test_env_set to validate FatalError is raised on env collision

* remove noqa ARG001 (no longer needed)

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-07-12 14:32:42 -04:00
Matthieu Darbois cac121a67d chore: update examples to use python 3.12 (#1919) 2024-07-09 09:15:44 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 604da878cb [Bot] Update dependencies (#1923)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-07-09 09:14:32 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> eaf0051162 chore(deps): bump actions/attest-build-provenance from 1.1.2 to 1.3.2 in the actions group (#1925)
chore(deps): bump actions/attest-build-provenance in the actions group

Bumps the actions group with 1 update: [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance).


Updates `actions/attest-build-provenance` from 1.1.2 to 1.3.2
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/173725a1209d09b31f9d30a3890cf2757ebbff0d...bdd51370e0416ac948727f861e03c2f05d32d78e)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-07-09 09:14:08 -04:00
Mike Taves 8dcf71e02d DOC: fix link to correct PR number (#1928) 2024-07-09 09:13:20 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 92f0142a3e [pre-commit.ci] pre-commit autoupdate (#1927)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.5.0 → v0.5.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.5.0...v0.5.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-07-09 09:13:04 -04:00
Matthieu Darbois 6c8347f465 chore: use python from setup-python step to run nox (#1921) 2024-07-08 07:59:44 +02:00
Matthieu Darbois a4d24056ef chore: move AlreadyBuiltWheelError & NonPlatformWheelError to errors.py (#1920) 2024-07-07 09:47:03 +02:00
Henry Schreiner 7e5a838a63 Bump version: v2.19.2 2024-07-02 08:07:58 -04:00
Henry Schreiner 19e1b8a4b0 chore: attestations (#1916) 2024-07-02 07:55:40 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 73581ae579 [Bot] Update dependencies (#1917)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-07-02 07:55:10 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
f21ff5e84c [pre-commit.ci] pre-commit autoupdate (#1914)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.10 → v0.5.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.10...v0.5.0)
- [github.com/pre-commit/mirrors-mypy: v1.10.0 → v1.10.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.10.0...v1.10.1)

* style follow suggestion

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-07-01 22:08:31 -04:00
Henry Schreiner 973946b172 fix: support --no-isolation with build[uv] (#1889)
* fix: support --no-isolation with build[uv]

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* docs: mention caveat

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-07-01 20:15:09 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 5ea40e6ff3 [Bot] Update dependencies (#1913)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-07-01 10:58:15 -04:00
Matthieu Darbois 6a36f6494b feat: add macOS on GitLab (#1911) 2024-06-30 10:59:58 +02:00
Matthieu Darbois 31de15bcd9 chore: remove nosetests from tests and docs (#1898)
fix #499
2024-06-30 10:21:33 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 3179fd215a [Bot] Update dependencies (#1900)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-06-30 08:07:29 +02:00
Matthieu Darbois 184d4e1280 fix(ci): CircleCI / Azure Pipelines / GitLab (#1899)
* fix(ci): CircleCI

CircleCI does not support Intel macOS runners anymore.
c.f. https://discuss.circleci.com/t/macos-intel-support-deprecation-in-january-2024/48718

* fix(ci): Azure Pipelines

* fix(ci): GitLab
2024-06-29 14:12:13 -04:00
Eric LarsonandMatthieu Darbois 08165ffeed DOC: Document macOS 3.8 arm64 workaround (#1871)
* BUG: Fix bug with macOS 3.8 arm64 URL

* TST: Ping

* DOC: Update

* FIX: Remove old

* DOC: Both

* Apply suggestions from code review

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

---------

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-06-27 11:52:32 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 9bb03835e5 [pre-commit.ci] pre-commit autoupdate (#1895)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.9 → v0.4.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.9...v0.4.10)
- [github.com/python-jsonschema/check-jsonschema: 0.28.5 → 0.28.6](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.5...0.28.6)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-26 16:16:34 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 2552303ff3 [Bot] Update dependencies (#1894)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-06-25 07:54:08 +02:00
Matthieu Darbois 5b74582a72 chore: remove pip beta workaround (#1892) 2024-06-23 14:16:44 +02:00
Matthieu Darbois 4470eb0dd9 chore: remove pip beta workaround (#1891) 2024-06-22 14:38:46 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 8bda260d3a [Bot] Update dependencies (#1885)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-06-22 10:57:56 +02:00
Lukas Burgholzer 5b5a95bdc2 docs: properly escape extra in build[uv] (#1886) 2024-06-19 08:01:35 +02:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 561fa32683 [pre-commit.ci] pre-commit autoupdate (#1888)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.8 → v0.4.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.8...v0.4.9)
- [github.com/python-jsonschema/check-jsonschema: 0.28.4 → 0.28.5](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.4...0.28.5)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-18 15:17:45 -04:00
Matthieu Darbois 70913f0a49 chore: remove cached_property from utils (#1884) 2024-06-17 23:01:08 +02:00
Siddhant Goel f49397f151 docs: add streaming-form-data to projects.yml (#1883) 2024-06-17 09:43:38 -04:00
Matthieu Darbois c1b8a12cd5 chore(tests): run a project with tests using build[uv] frontend (#1880) 2024-06-17 01:07:35 -04:00
Henry Schreiner 932529cab1 Bump version: v2.19.1 2024-06-13 02:38:27 -04:00
Henry Schreiner 70fb1c4a1a fix: specify full path to non-venv Python (#1881)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-06-13 08:18:09 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 405a475ac7 [Bot] Update dependencies (#1879)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-06-12 23:16:49 -04:00
Nathan Goldbaum 78da7bafcc docs: update README.md (#1874) 2024-06-12 11:32:27 -04:00
Henry Schreiner 8d86d3122b tests: don't print xfails (#1865)
tests: skip warnings on xfails for now

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-06-12 10:46:24 -04:00
Eric Larson 89a5cfe272 DOC: Fix bug with link (#1870) 2024-06-11 21:24:44 +02:00
Henry Schreiner 8d5d84e0fc fix: accept current Python version if acceptable for Pyodide (#1868)
* fix: accept current Python version if acceptable for Pyodide

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-06-11 08:48:42 +02:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 4ada77dea4 [pre-commit.ci] pre-commit autoupdate (#1869)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.7 → v0.4.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.7...v0.4.8)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-11 00:32:52 -04:00
Henry Schreiner 829441f4a0 fix: warning in generate schema script (#1866)
* fix: warning in generate schema script

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* docs: add minor update to update process

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Update docs/contributing.md

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-06-11 00:32:38 -04:00
Henry Schreiner a8d190a111 Bump version: v2.19.0 2024-06-10 11:28:29 -04:00
bf817c6dc8 refactor: error handling to use exceptions (#1719)
* Refactor error handling to use exceptions

cibuildwheel has up until now handled most errors by printing an error message to sys.stderr and calling sys.exit. Others were handled using Logger.error, depending on the context. We also had return codes, but these weren't explicitly defined anywhere.

This makes that convention more explicit and codified. Now to halt the program, the correct thing to do is to throw a cibuildwheel.errors.FatalError exception - that is caught in main() and printed before exiting. The existing behaviour was kept - if an error occurs within a build step (probably something to do with the build itself), the Logger.error() method is used. Outside of a build step (e.g. a misconfiguration), the behaviour is still to print 'cibuildwheel: <message>'

I also took the opportunity to add a debugging option `--debug-traceback` (and `CIBW_DEBUG_TRACEBACK`), which you can enable to see a full traceback on errors.

(I've deactivated the flake8-errmsg lint rule, as it was throwing loads of errors and these error messages aren't generally seen in a traceback context)

* add noqa rule

* Apply suggestions from code review

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>

* Return to flake8-errmsg conformance

* Code review suggestions

* Subclass Exception rather than SystemExit

* apply error handling to new code and fix merge issues

* Apply review suggestion

* fix: merge issue

* Update cibuildwheel/errors.py

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2024-06-10 10:36:20 -04:00
Henry Schreiner 384c8d5c82 feat: build[uv] (#1856) 2024-06-09 15:45:31 -04:00
Matthieu Darbois c37e5a2d13 fix: util.move_file shall not use log.notice (#1862)
Using  `log.notice` result in many unwanted annotations, at least in GitHub Actions.
If we want to print some information about a specific file being moved, it shall be done by the caller - or adding an option to the function - and use `print`.
2024-06-09 19:03:12 +02:00
cibuildwheel-bot[bot]cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>Henry SchreinerMatthieu Darbois
130fdd2548 feat: free-threaded Python for macOS, MACOSX_DEPLOYMENT_TARGET updates (#1854)
* Update dependencies

* feat: macos free-threading

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: set min target to 10.13 for 3.13 and floor it always

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: tests and corrected pypy mins

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-06-08 10:15:04 +02:00
Henry Schreiner ed120540d9 chore: bump pyodide (#1859)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-06-08 01:38:06 -04:00
MusicalNinjaDadHenry Schreinerpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
6c6e0f6ba5 fix: handle case where output_dir does not already exist on macos & windows (#1851)
* replace `with suppress(FileNotFoundError)` by `.unlink(missing_ok=True)` for macos

* also use `.unlink(missing_ok=True)` in pyodide and windows for consistency

* remove contextlib imports which are no longer required

* Apply suggestions from code review

* explicity resolve and create output location

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* use explicit str for move

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* update comments based on review feedback

* Apply suggestions from code review

* Break out functionality to move files to util.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* raise instance of IsADirectoryError with meaningful message

* Don't need a comment and a exception message

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-07 11:37:20 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 877d3bf649 [pre-commit.ci] pre-commit autoupdate (#1852)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.5 → v0.4.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.5...v0.4.7)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-04 08:34:28 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 21e9ef1800 [Bot] Update dependencies (#1848)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-06-04 08:32:55 +02:00
Henry Schreiner c333b131d3 fix: include VIRTUAL_ENV variable (#1842)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-29 08:20:02 +02:00
Henry Schreiner 4c2ed1e632 chore: remove pip <21.3 workaround (#1841)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-29 07:57:06 +02:00
Hood ChathamMatthieu DarboisHenry Schreinerpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
9f2a3cb67c feat: add Pyodide support (#1456)
* feat: add Pyodide support

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

tests: fix two merge issues

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

fix: include schema

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Try to fix xbuildenv path

[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Try to install pyodide-build from main branch

Try again

Try again

Update constraints file

Try again

Remove unused variable

Drop constraints

Remove --download option

Fix xbuildenv install

Try again

Try again

[pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: remove pinning on pyodide

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Update for Pyodide 0.26.0a5

* Install pyodide-build from pypi

* Update docs/options.md

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>

* Unxfail things that look like they were just a version mismatch

* refactor: add constraints for pyodide

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* chore: minor cleanup

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Apply suggestions from code review

* Apply suggestion from code review

* refactor: minor touchup

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* ci: xfail the pyodide test

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* review: use a pinned version of node

* fix tests

* review: error out on Windows

* test: check node & test on macos arm64

* chore: minor cleanup

* Add reference to emscripten libc issue

* Apply suggestion from code review

* review: use a pinned pip in test virtual environment

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* chore: rework test virtual environment seed packages

* chore: workaround direct invocation of pytest

This allows to still test direct invocation of `pytest` on most platforms (including pyodide on Linux) but falls back to `python -m pytest` when running pyodide on macOS.

* Use release version of pyodide

* fix: tests for 0.26.0 & parallel initialization of xbuildenv

* Debug CI

* fix: test/test_build_frontend_args.py

* Revert "Debug CI"

This reverts commit 917646cffc96dbfc619c47d1c03a828f447bcdb7.

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-28 08:31:36 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 687406f664 [pre-commit.ci] pre-commit autoupdate (#1840)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.4 → v0.4.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.4...v0.4.5)
- [github.com/codespell-project/codespell: v2.2.6 → v2.3.0](https://github.com/codespell-project/codespell/compare/v2.2.6...v2.3.0)
- [github.com/python-jsonschema/check-jsonschema: 0.28.3 → 0.28.4](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.3...0.28.4)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-27 22:34:22 -04:00
Matthieu Darbois 2e6b11e10c chore(ci): split emulation tests per architecture (#1839) 2024-05-27 22:34:10 -04:00
Matthieu Darbois b713086763 chore: better determinism for the test virtual environment (#1838)
* chore: better determinism for the test virtual environment

* review: apply suggestions
2024-05-27 23:04:25 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 8f574d107b [Bot] Update dependencies (#1836)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-05-27 12:28:13 -04:00
Matthieu Darbois 97da90432e chore: rework single python tests (#1835)
* chore: rework single python tests

* chore(tests): limit number of builds in test_abi3

* chore(tests): limit number of builds in test_before_all

* apply review suggestion

use `os.path.samefile` rather than comparing `os.stat` directly.
2024-05-26 12:41:20 +02:00
Matthieu Darbois 67ee9dda92 chore(tests): do not use hard-coded paths in tests (#1834)
* chore(tests): do not use hard-coded paths in tests

* review suggestion

use `os.path.samefile` rather than comparing `os.stat` directly.
2024-05-26 12:40:11 +02:00
Henry Schreiner ba8be0d988 Bump version: v2.18.1 2024-05-20 07:22:33 -04:00
mayeut 90dd47640f doc: add documentation for the CIBW_FREE_THREADED_SUPPORT option 2024-05-20 07:12:10 -04:00
mayeut b61324914b chore: pass a PythonConfiguration to install_cpython 2024-05-20 07:12:10 -04:00
mayeut 3992d5719c feat: add option to opt-in free-threaded builds 2024-05-20 07:12:10 -04:00
mayeut 345467c6cf feat: add support for free-threaded (no-gil) Python 3.13 2024-05-20 07:12:10 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 791e41cfec [Bot] Update dependencies (#1832)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-05-20 10:08:57 +02:00
Joe Rickerby 9d5f5e60b8 Make container-engine a build (non-global) option (#1792) 2024-05-20 02:47:10 -04:00
Henry Schreiner 1b354cfa63 chore: move to hatchling (#1297) 2024-05-20 02:45:05 -04:00
Matthieu Darbois d1a4c9c074 chore: un-pin virtualenv update (#1830) 2024-05-20 02:21:42 -04:00
Matthieu Darbois 78bca57cb4 fix(tests): linux tests from macOS/Windows arm64 (#1829)
* fix(tests): linux tests from macOS/Windows arm64

When running on arm64, macOS reports machine as `arm64` and Windows as `ARM64`.
We need to override this to `aarch64` when running linux tests.

* fix(tests): fix tests when running with `--run-cp38-universal2`
2024-05-18 18:34:39 +02:00
Henry Schreiner f8894e67f5 chore: use the new github actions reporter for pylint (#1827)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-15 23:15:53 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 666a2c3f1a [pre-commit.ci] pre-commit autoupdate (#1826)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.3 → v0.4.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.3...v0.4.4)
- [github.com/python-jsonschema/check-jsonschema: 0.28.2 → 0.28.3](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.2...0.28.3)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-13 23:41:00 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 15447bd591 [Bot] Update dependencies (#1824)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-05-13 23:40:45 -04:00
Henry Schreiner 678ef21647 chore: more modern nox (#1823)
* chore: more modern nox

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* docs: fix running from unsourced venv

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* docs: minor typo fix

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* docs: fix wrong link #1825

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-13 23:40:34 -04:00
Henry Schreiner e82b1bfc44 docs: fix formatting on changelog (#1822)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-12 02:37:46 -04:00
Henry Schreiner ced16da65f ci: minor cleanup for readthedocs
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-12 01:06:26 -04:00
Henry Schreiner 63daa02352 docs: fix options page (#1821)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-12 00:51:20 -04:00
Henry Schreiner 711a3d017d Bump version: v2.18.0 2024-05-12 00:13:12 -04:00
Henry Schreiner 3873a1edf8 chore: update bump_version script
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-05-11 23:38:45 -04:00
Henry SchreinerandMatthieu Darbois 6dd4f15a0e docs: rust (#1816)
* docs: add FAQ entry on Rust

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* ci: make readthedocs faster

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Update docs/faq.md

* Update docs/faq.md

* Update faq.md

* Update docs/faq.md

* Update docs/faq.md

Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>

* Apply suggestions from code review

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-05-11 20:26:35 -04:00
Matthieu Darbois 44c4742477 feat: add Python 3.13 beta 1 (#1815) 2024-05-11 20:26:18 -04:00
Matthieu Darbois c0217440e8 feat: move default musllinux build to musllinux_1_2 (#1817) 2024-05-11 16:24:48 -04:00
Matthieu Darbois cf18014fce fix: do not pre-seed setuptools / wheel in virtual environment (#1819) 2024-05-11 16:24:01 -04:00
Matthieu Darbois 3ea0a6c2f0 fix: respect constraints when building with pip (#1818)
When building a project that has a `pyproject.toml`, constraints
are not respected when building with the `pip` frontend.

This commit fixes this by using the same tricks as for the `build` frontend.
2024-05-10 15:33:56 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 30a0decb47 [Bot] Update dependencies (#1812)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-05-07 17:29:50 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 988d512fb3 [pre-commit.ci] pre-commit autoupdate (#1813)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.4.1 → v0.4.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.4.1...v0.4.3)
- [github.com/pre-commit/mirrors-mypy: v1.9.0 → v1.10.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.9.0...v1.10.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-07 17:29:40 -04:00
Joe Rickerby 98d57d9547 Merge pull request #1766 from Czaki/delocate_info
Add information about new delocate error "Library dependencies do not satisfy target MacOS"
2024-04-26 10:57:22 +01:00
Joe Rickerby 8daac05d63 Merge pull request #1811 from radarhere/actions/setup-python
Updated actions/setup-python in docs
2024-04-26 10:54:23 +01:00
Andrew Murray 950fbd0a60 Updated actions/setup-python in docs 2024-04-25 09:43:01 +10:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> d24ebf4125 [Bot] Update dependencies (#1805)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-04-23 23:22:31 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 8a0d1d59c7 [pre-commit.ci] pre-commit autoupdate (#1807)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.3.5 → v0.4.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.3.5...v0.4.1)
- [github.com/python-jsonschema/check-jsonschema: 0.28.1 → 0.28.2](https://github.com/python-jsonschema/check-jsonschema/compare/0.28.1...0.28.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-04-23 23:22:22 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 208ca32050 chore(deps): bump wntrblm/nox from 2024.03.02 to 2024.04.15 in the actions group (#1810)
chore(deps): bump wntrblm/nox in the actions group

Bumps the actions group with 1 update: [wntrblm/nox](https://github.com/wntrblm/nox).


Updates `wntrblm/nox` from 2024.03.02 to 2024.04.15
- [Release notes](https://github.com/wntrblm/nox/releases)
- [Changelog](https://github.com/wntrblm/nox/blob/main/CHANGELOG.md)
- [Commits](https://github.com/wntrblm/nox/compare/2024.03.02...2024.04.15)

---
updated-dependencies:
- dependency-name: wntrblm/nox
  dependency-type: direct:production
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 23:22:12 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 9cf99e78bc [pre-commit.ci] pre-commit autoupdate (#1801)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v4.6.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-04-09 11:33:31 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 2fb3205ff1 [Bot] Update dependencies (#1799)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-04-08 22:07:14 -04:00
pre-commit-ci[bot] 376414dc69 [pre-commit.ci] pre-commit autoupdate (#1797) 2024-04-07 03:22:03 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 070e744d26 [Bot] Update dependencies (#1796)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-03-25 04:30:47 -04:00
Henry Schreiner 89e0a90bc5 Update docs/faq.md 2024-03-25 04:30:10 -04:00
Henry Schreiner 312cf1573e chore: use uv pip compile (#1778) 2024-03-21 15:41:31 -04:00
Joe Rickerby 6537b8f51f Merge pull request #1795 from pypa/pre-commit-ci-update-config 2024-03-19 18:55:38 +00:00
pre-commit-ci[bot] 3f00a2fded [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.3.2 → v0.3.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.3.2...v0.3.3)
- [github.com/shellcheck-py/shellcheck-py: v0.9.0.6 → v0.10.0.1](https://github.com/shellcheck-py/shellcheck-py/compare/v0.9.0.6...v0.10.0.1)
2024-03-18 19:44:26 +00:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> a8d1defda9 [Bot] Update dependencies (#1794)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-03-18 06:27:40 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 510382886d [pre-commit.ci] pre-commit autoupdate (#1791)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.2.2 → v0.3.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.2...v0.3.2)
- [github.com/pre-commit/mirrors-mypy: v1.8.0 → v1.9.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.8.0...v1.9.0)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-03-15 13:27:39 -04:00
Henry Schreiner b3c4d37885 fix(schema): use $refs instead of defines (#1788) 2024-03-12 11:25:23 -04:00
Joe Rickerby 3eb6dbbdd3 Fix typo in changelog 2024-03-11 21:28:09 +00:00
Joe Rickerby 90c14a333f Improve version push command 2024-03-11 21:24:21 +00:00
Joe Rickerby 8d945475ac Bump version: v2.17.0 2024-03-11 21:19:43 +00:00
Joe Rickerby ca06deb26f Merge pull request #1775 from pypa/doc-domain
Docs domain change to cibuildwheel.pypa.io
2024-03-11 21:17:51 +00:00
Joe Rickerby f7e1922225 CirrusCI fixes (#1786)
* Fix executable name, that doesn't always exist on windows

* Use the `python3` executable on macOS Cirrus

* Homebrew changed where it puts the python binaries

* Update examples to match new config
2024-03-11 20:54:37 +00:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 0d8e919dfc [Bot] Update dependencies (#1784)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-03-11 16:12:01 -04:00
Joe Rickerby 022de07dc1 Merge pull request #1785 from pypa/revert-1783
Remove manylinux1 docker pin
2024-03-11 09:21:03 +00:00
Joe Rickerby 920f574191 Remove manylinux1 docker pin 2024-03-11 09:05:43 +00:00
Joe Rickerby 5c06f3c289 docs: Add how to run tests in development (#1698)
* Add docs for how to run tests in development

* Update the docs to use nox primarily and not require CIBW_PLATFORM

* Reorganise this file
2024-03-10 21:37:07 -04:00
laggykillerJoe Rickerbypre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
e2a0839555 fix: set SYSTEM_VERSION_COMPAT=0 during pip install on macos (#1768)
* Set SYSTEM_VERSION_COMPAT=0 during pip install on macos (#1767)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Only set SYSTEM_VERSION_COMPAT=0 for CPython 3.8

* Set SYSTEM_VERSION_COMPAT=0 for CPython <= 3.8

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update cibuildwheel/macos.py

Co-authored-by: Joe Rickerby <joerick@mac.com>

* Update cibuildwheel/macos.py

Co-authored-by: Joe Rickerby <joerick@mac.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-03-10 21:36:36 -04:00
dependabot[bot]dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Joe Rickerby
87fff77282 chore(deps): bump the actions group with 1 update (#1776)
Bumps the actions group with 1 update: [wntrblm/nox](https://github.com/wntrblm/nox).


Updates `wntrblm/nox` from 2023.04.22 to 2024.03.02
- [Release notes](https://github.com/wntrblm/nox/releases)
- [Changelog](https://github.com/wntrblm/nox/blob/main/CHANGELOG.md)
- [Commits](https://github.com/wntrblm/nox/compare/2023.04.22...2024.03.02)

---
updated-dependencies:
- dependency-name: wntrblm/nox
  dependency-type: direct:production
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-03-10 21:33:59 -04:00
Peter SobotandJoe Rickerby 8ef9486aab Add pedalboard to projects.yml. (#1781)
* Add `pedalboard` to projects.yml.

* Update projects.yml

---------

Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-03-10 21:33:47 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 2a7fef07db [Bot] Update dependencies (#1774)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-03-10 21:33:37 -04:00
Joe Rickerby f7de18e291 Merge pull request #1675 from pypa/pip-constraints-fix
fix: Don't override PIP_CONSTRAINT if set by the user
2024-03-09 13:53:32 +00:00
Joe Rickerby 80095ac7af Merge pull request #1745 from mayeut/nopipx
chore(action): do not use pipx
2024-03-09 13:53:17 +00:00
Joe Rickerby df2e35a016 Merge pull request #1783 from henryiii/henryiii/ci/pinmanylinux1
ci: pin manylinux1 with missing tag
2024-03-09 13:43:46 +00:00
Henry Schreiner f654071fe2 ci: pin manylinux1 with missing tag
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-03-08 14:52:43 -05:00
Joe Rickerby b71a83d411 Docs domain change to cibuildwheel.pypa.io 2024-03-04 10:37:01 +00:00
mayeut a6ecded8c4 chore(action): do not use pipx 2024-03-04 11:05:20 +01:00
Henry SchreinerandJoe Rickerby 8f58f71c2e feat: add inherit to override (#1730)
* feat: add inherit to override

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* refactor: use dict and support prepend

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Refactor: simplifying by splitting the responsibilities of _dig_first

* Refactor to allow merging of string settings, and preserve table cascades

* docs: add some docs for inherit

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Apply suggestions from code review

Co-authored-by: Joe Rickerby <joerick@mac.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-03-02 16:58:18 -05:00
Joe Rickerby 6940c77cd3 style improvements from code review 2024-03-02 18:16:20 +00:00
Matthieu Darbois ae2451a199 chore(ci): speed-up tests (#1752)
* chore(ci): speed-up tests

* back to 2 processes on Azure macOS
2024-02-29 16:27:09 -05:00
JCGoranandJoe Rickerby 1fe6b1aa44 Replace deprecated runner in CircleCI example (#1762)
* Replace deprecated runner in CircleCI example

* Fix another deprecated image reference

---------

Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-02-29 16:25:28 -05:00
Joe Rickerby 554726e3c4 Merge pull request #1727 from pypa/dont-require-platform
Don't require `--platform` when running on a development machine
2024-02-28 09:20:25 +00:00
Joe Rickerby 8742ff2ef8 Merge pull request #1725 from pypa/constraints-cleanup
Don't preinstall setuptools and wheel, remove from constraints
2024-02-28 09:16:30 +00:00
Joe Rickerby 75627e8ca4 Limit line length to 100 cols 2024-02-28 09:11:06 +00:00
Joe Rickerby 3ae9aa1da5 Update constraints again to reapply changes to constraints.in after merge 2024-02-27 21:46:07 +00:00
Joe Rickerby f04a522d50 Merge remote-tracking branch 'origin/main' into constraints-cleanup 2024-02-27 21:44:03 +00:00
Joe Rickerby edd67e0d26 Merge pull request #1734 from pypa/gha-images-latest
Don't bother pinning OS images for Github Actions
2024-02-27 21:37:11 +00:00
Joe Rickerby 8a8c07d4f9 Merge pull request #1763 from pypa/update-dependencies-pr
[Bot] Update dependencies
2024-02-27 21:33:33 +00:00
Joe Rickerby 74afe329a1 Merge remote-tracking branch 'origin/main' into constraints-cleanup 2024-02-27 21:28:54 +00:00
Joe Rickerby 7ada127bfc Remove loop with single entry in test 2024-02-27 21:26:16 +00:00
cibuildwheel-bot[bot] 6b3122aff7 Update dependencies 2024-02-26 06:03:55 +00:00
Grzegorz BokotaandJoe Rickerby 86ed421c1b Update docs/faq.md
Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-02-21 11:10:58 +01:00
Grzegorz Bokota b4a22b6d5e add information about potential problem 2024-02-21 00:43:04 +01:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 7c02fa721c [pre-commit.ci] pre-commit autoupdate (#1765)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.2.1 → v0.2.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.1...v0.2.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-02-20 07:34:21 +01:00
Joe RickerbyandMatthieu Darbois 88d60dce89 Update .github/workflows/test.yml
Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com>
2024-02-18 18:52:42 +00:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 1dea9e4a14 [Bot] Update dependencies (#1753)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-02-16 23:50:32 -05:00
Matthieu Darbois 53e2c74ab0 chore(action): update cibuildwheel arguments passing (#1757)
chore(action): update cibw arguments passing

Only pass arguments that were set to cibuildwheel.
2024-02-16 23:49:21 -05:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 32343a3cf1 chore(deps): bump the actions group with 1 update (#1758)
Bumps the actions group with 1 update: [pre-commit/action](https://github.com/pre-commit/action).


Updates `pre-commit/action` from 3.0.0 to 3.0.1
- [Release notes](https://github.com/pre-commit/action/releases)
- [Commits](https://github.com/pre-commit/action/compare/v3.0.0...v3.0.1)

---
updated-dependencies:
- dependency-name: pre-commit/action
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-13 07:52:19 +01:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 2e0ab0176c [pre-commit.ci] pre-commit autoupdate (#1760)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.2.0 → v0.2.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.0...v0.2.1)
- [github.com/python-jsonschema/check-jsonschema: 0.27.4 → 0.28.0](https://github.com/python-jsonschema/check-jsonschema/compare/0.27.4...0.28.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-02-13 07:52:03 +01:00
Matthieu Darbois 75d6d9d55b Merge branch 'main' into gha-images-latest 2024-02-10 09:58:58 +01:00
81b0a578df chore(CI): test on GHA macOS-14 runner (#1700)
* chore(CI): test on GHA macOS-14 runner
* update error message for skipped arm64 tests
* Update docs, README and examples

---------

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
Co-authored-by: Andrew Murray <3112309+radarhere@users.noreply.github.com>
2024-02-10 09:55:38 +01:00
Joe Rickerby 27d0942e1c Merge pull request #1754 from pypa/dependabot/github_actions/actions-894fc5cb1d
chore(deps): bump the actions group with 1 update
2024-02-06 22:01:28 +00:00
Joe Rickerby 68f1058d7e Merge pull request #1755 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2024-02-06 21:56:27 +00:00
pre-commit-ci[bot] dfca0ce96a [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.14 → v0.2.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.14...v0.2.0)
- [github.com/python-jsonschema/check-jsonschema: 0.27.0 → 0.27.4](https://github.com/python-jsonschema/check-jsonschema/compare/0.27.0...0.27.4)
2024-02-05 18:23:05 +00:00
dependabot[bot] abd05a65ba chore(deps): bump the actions group with 1 update
Bumps the actions group with 1 update: [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).


Updates `peter-evans/create-pull-request` from 5 to 6
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v5...v6)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 13:29:35 +00:00
Joe Rickerby d65d46ca24 Merge remote-tracking branch 'origin/main' into pip-constraints-fix 2024-02-04 11:18:10 +00:00
Joe Rickerby 88c113402d Merge pull request #1750 from njzjz/macos-test-venv
test macos-x86_64 and arm64 in different venv dir
2024-02-03 14:55:58 +00:00
Henry Schreiner c7a653d6a9 chore: minor touchups to pyproject (#1751) 2024-02-02 21:02:42 -05:00
Joe Rickerby 6c93c131c4 Go back to macos-12 for the AS transition 2024-02-02 17:56:34 +00:00
Joe Rickerby d635c0eee6 Add integration test 2024-02-02 17:51:54 +00:00
Jinzhe Zeng a78facb861 test macos_x86-64 and arm64 in different venv dir 2024-02-01 00:33:33 -05:00
Joe Rickerby ce3fb78320 Bump version: v2.16.5 2024-01-30 23:14:28 +00:00
Henry SchreinerandJoe Rickerby 5b0b4583a8 fix: download pipx for action, allow support for M1 (#1743)
* fix: download pipx for action, allow support for M1

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Update action.yml

* Don't use the quotes on Powershell for command path

* Use & to invoke a command with a string argument

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2024-01-30 18:00:26 -05:00
Joe Rickerby a7ea5fb408 Merge pull request #1739 from henryiii/henryiii/chore/checkschemas
chore: check schemas
2024-01-30 20:27:46 +00:00
Joe Rickerby bc55e8bf0a Merge pull request #1741 from jborean93/pwsh-7.4
Add support for PowerShell 7.3 in GHA
2024-01-30 20:16:51 +00:00
Jordan Borean c753cd282d Add support for PowerShell 7.4 in GHA
Fixes compatibility with PowerShell 7.3 on Windows through GitHub
Actions when one of the options for cibuildwheel is empty.
2024-01-30 09:17:04 +10:00
Henry Schreiner 07bd78c4e6 chore: check schemas
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2024-01-29 15:39:04 -05:00
Hendrik Muhs d7db575b96 docs: add keyvi as an example that combines cibuildwheel with the ccache action to speedup runtime. (#1735)
* add keyvi to working-examples.md

Adding keyvi as example, it combines cibuildwheel with the ccache action to speedup runtime.

* Update projects.yml

* Update working-examples.md

revert changes in auto-generated file

* Update working-examples.md
2024-01-29 15:05:26 -05:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 7154e181e6 [Bot] Update dependencies (#1738)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-01-29 09:40:23 -05:00
Joe Rickerby 0b04ab1040 Bump version: v2.16.4 2024-01-28 17:21:43 +00:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 34b049f138 [Bot] Update dependencies (#1737)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-01-27 23:09:53 -05:00
Joe Rickerby 3bf1908dcb Don't bother pinning OS images for Github Actions
Fix #1612

The hassle of updating these pins (both for us and our users, most copy our documentation) seems to outweigh the benefit of the pin. The truth is that they're not really pins anyway, Github update them all the time, and they don't work for historical repeatability because old images are retired all the time.
2024-01-27 11:21:22 +00:00
Joe Rickerby 4a79413fe6 Remove the Cirrus CI badge from readme
It frequently gives false negatives because of limited compute credits
2024-01-27 11:09:41 +00:00
Joe Rickerby e250df5d5d Bump version: v2.16.3 2024-01-26 19:21:57 +00:00
Joe Rickerby ddc2c6e845 Make the note on environment variables clear 2024-01-26 18:52:47 +00:00
Joe Rickerby fd0aae31e3 Merge pull request #1686 from doronz88/refactor/doc-linux-clarification
doc: add clarification regarding linux docker environment
2024-01-26 18:48:27 +00:00
Joe Rickerby 2a83588552 Apply suggestions from code review 2024-01-26 18:48:10 +00:00
OlenaandSviatoslav Sydorenko a1e3efb81c fix: correct path when building sdist package (#1687)
* Edit path when building sdist package

This patch changes the working directory from the temp to the project
when building sdist package.This resolves issues with relative paths
in configuration files.

Resolves #1683

* Add a test for the `package` placeholder exposure

The change extends the existing test — `test_simple`. It checks that
the temporary wheel build directory is the project root extracted from
the source distribution. It does so by testing the presence of the
`setup.py` in the current working directory, as a side effect.

* Edit quotes in the CLI argument for Windows compatibility

Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>

* Use single quotes to avoid syntax errors from f-string

Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>

---------

Co-authored-by: Sviatoslav Sydorenko (Святослав Сидоренко) <wk.cvs.github@sydorenko.org.ua>
2024-01-24 14:19:24 -05:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> c0e4b16ab9 [Bot] Update dependencies (#1728)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-01-22 18:17:27 -05:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 40b63b834d [pre-commit.ci] pre-commit autoupdate (#1729)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.13 → v0.1.14](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.13...v0.1.14)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-22 18:14:54 -05:00
Joe Rickerby 4db49f5485 Don't require --platform when running on a development machine
Historically, we required `--platform` when running cibuildwheel outside of CI, because cibuildwheel would attempt to globally install Python interpreters and some packages.

That was fixed in https://github.com/pypa/cibuildwheel/pull/974 a couple of years ago. As a result, there's no reason to require --platform these days, the `auto` behaviour is perfectly fine for dev machines.

It also makes running tests locally simpler, one can just do `pytest test/test_0_basic.py` (or `nox -s tests -- test/test_0_basic.py`) and not have to worry about setting CIBW_PLATFORM most of the time.
2024-01-21 18:24:43 +00:00
Joe Rickerby 23a6e88b0c Merge pull request #1672 from pypa/disable-host-mount
feat: Adds disable_host_mount suboption to container-engine
2024-01-20 19:05:12 +00:00
Joe Rickerby 4ca5d7cd2a We can't update the 3.6 pins in CI 2024-01-20 19:04:10 +00:00
Joe Rickerby 9879937c63 Don't preinstall setuptools and wheel, remove from constraints
Reasons to do this:

- setuptools is no longer the only game in town. When cibuildwheel was created, setuptools was the only way to make wheels. these days, there are many build backends so special casing setuptools doesn't make so much sense
- we don't need to preinstall `wheel` any more, setuptools will do that itself when it needs it.
- projects with pyproject.toml (i.e. the vast majority of projects going forward) don't benefit from the pin anyway, because both `pip` and `build` create an isolated environment to install `build-system.requires` into.
- this makes it easier for end users (such as @webknjaz) to control build-system versions using `PIP_CONSTRAINT`, because there's less potential for a user-specified version to conflict with one of our pins.
  - (long-term, I'd love `build` to [support this directly](https://github.com/pypa/build/issues/292), and then we could have a proper way to keep pyproject.toml dependencies loose and forward-compatible while retaining build determinism. But PIP_CONSTRAINT is the best we have for now. PIP_CONSTRAINT isn't ideal because it affects other things, like the test virtualenv).

This PR also adds a pin for pypa/build. It appears that was missing before, but we should pin it.
2024-01-20 18:44:03 +00:00
Joe Rickerby c18f6cba12 Empty commit to trigger TravisCI 2024-01-19 17:30:38 +00:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 93542c397c [Bot] Update dependencies (#1715)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2024-01-16 14:21:29 -05:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 7a5515e3e0 [pre-commit.ci] pre-commit autoupdate (#1723)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.11 → v0.1.13](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.11...v0.1.13)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-16 14:20:57 -05:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> a6da0692ce [pre-commit.ci] pre-commit autoupdate (#1720)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.9 → v0.1.11](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.9...v0.1.11)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-15 11:30:43 -05:00
Joe Rickerby c9765e9dc2 Merge pull request #1712 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-12-29 12:03:11 +00:00
Adam Lugowski 53a38b70b2 Upgrade artifact actions in workflows to v4 (#1711) 2023-12-28 17:24:09 -05:00
cibuildwheel-bot[bot] fab2a86a3f Update dependencies 2023-12-28 22:22:25 +00:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> d0a527bfd5 [pre-commit.ci] pre-commit autoupdate (#1713)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.8 → v0.1.9](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.8...v0.1.9)
- [github.com/pre-commit/mirrors-mypy: v1.7.1 → v1.8.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.1...v1.8.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-12-28 17:18:44 -05:00
Henry Schreiner f11f1b2ef9 ci: group dependabot updates (#1707) 2023-12-21 13:41:56 -05:00
Joe Rickerby 056a543dd9 Merge pull request #1708 from alugowski/readme
docs: update to readme example to `upload-artifact` v4
2023-12-21 18:40:14 +00:00
Adam Lugowski bf6eacdf25 docs: update to readme example to upload-artifact v4 2023-12-20 20:00:20 -08:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 909d53b9b6 [Bot] Update dependencies (#1702)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-12-20 21:59:14 -05:00
Adam Lugowski 2c4974286f docs: update examples for v4 of upload-artifact and download-artifact actions (#1705)
* docs: update examples for v4 of `upload-artifact` and `download-artifact` actions

* docs: use more unique artifact name

* docs: update github example workflows to artifact actions v4
2023-12-20 17:32:28 -05:00
Joe Rickerby 6e2f4c00ab Merge pull request #1697 from abitrolly/diagram-html
Rename `diagram.md` to `diagram.html`, because it is HTML
2023-12-20 16:56:20 +00:00
Joe Rickerby d371852317 Merge pull request #1696 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-12-19 18:26:38 +00:00
pre-commit-ci[bot] c7b505db47 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-12-18 18:42:18 +00:00
pre-commit-ci[bot] 7ddddff94f [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.6 → v0.1.8](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.6...v0.1.8)
2023-12-18 18:41:35 +00:00
Anatoli Babenia 4136cb5969 Rename diagram.md to diagram.html, because it is HTML
Also use plain `include` directive
2023-12-13 12:40:35 +03:00
Joe Rickerby a3e5b541dc Update LICENSE year 2023-12-13 08:53:18 +00:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 9195da8c1a [Bot] Update dependencies (#1694)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-12-12 09:08:11 +01:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 606879f2d3 chore(deps): bump actions/setup-python from 4 to 5 (#1695)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-12 09:07:26 +01:00
doronz f2dc466d03 doc: refactor CIBW_BEFORE_ALL examples to working versions 2023-12-07 08:23:04 +02:00
doronz 0618babf0c doc: add clarification regarding linux docker environment 2023-12-07 08:21:42 +02:00
Joe Rickerby 886ba0f662 Merge pull request #1681 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-12-06 18:20:31 +00:00
Joe Rickerby 8e9a703abc Merge pull request #1678 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-12-06 18:20:09 +00:00
Joe Rickerby 4dba644b8d Merge pull request #1667 from pypa/joerick-patch-1
docs: Address some confusion around the CIBW_ENVIRONMENT option.
2023-12-06 18:19:12 +00:00
Joe Rickerby 4cedf1c603 Docs formatting tweaks 2023-11-27 22:51:13 +00:00
Joe Rickerby 796361d9f9 Merge pull request #1680 from webknjaz/patch-2
[docs] Drop `wheel` from `pyproject.toml` example @ options page
2023-11-27 22:41:27 +00:00
pre-commit-ci[bot] 22aff1bc25 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/pre-commit/mirrors-mypy: v1.7.0 → v1.7.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.7.0...v1.7.1)
2023-11-27 18:21:19 +00:00
Sviatoslav Sydorenko 86ef5eed8a [docs] Drop wheel from pyproject.toml example @ options page 2023-11-27 18:53:00 +01:00
Joe Rickerby a4f8eb3544 Merge pull request #1679 from webknjaz/patch-1
Stop suggesting adding `wheel` to `pyproject.toml`
2023-11-27 16:38:48 +00:00
Sviatoslav Sydorenko 270c626d6b Stop suggesting adding wheel to pyproject.toml
This was a historic mistake in the `setuptools`' docs that many projects copied. But `wheel` is already a dependency injected by `setuptools` when needed. So let's not suggest people to depend on it when producing sdists.
2023-11-27 16:29:10 +01:00
cibuildwheel-bot[bot] ae0c33b395 Update dependencies 2023-11-27 06:13:56 +00:00
Joe Rickerby 2a1edad716 Backslashes in Windows paths mess with CIBW_ENVIRONMENT string parsing 2023-11-24 19:08:04 +00:00
Joe Rickerby c2b03ead3e Fix test issue around container paths 2023-11-24 15:12:49 +00:00
Joe Rickerby d198c90f7a Allow the user to set PIP_CONSTRAINT and it affect build-system.requires 2023-11-24 11:49:26 +00:00
Joe Rickerby 6c6c51ef3b Merge pull request #1665 from hugovk/skip-quotes
Use quotes when silencing warning
2023-11-24 10:36:43 +00:00
Joe Rickerby a6345190fa Skip test on gitlab too 2023-11-24 10:33:21 +00:00
Joe Rickerby ebf48d4122 Merge pull request #1668 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-11-23 13:50:47 +00:00
Joe Rickerby 9213ca194d Merge pull request #1670 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-11-23 13:50:32 +00:00
Joe Rickerby b371ae35d1 Merge pull request #1674 from rossarmstrong/main
Update projects.yml to add new repo for working examples
2023-11-23 13:50:15 +00:00
pre-commit-ci[bot] 92ee0fda43 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-11-23 13:41:26 +00:00
pre-commit-ci[bot] 5baa3de6df [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-11-23 12:41:13 +00:00
Ross Armstrong a561ae0f9d Update projects.yml to add new repo for working examples 2023-11-23 23:32:42 +11:00
Joe Rickerby 7c99262c00 Adds disable_host_mount suboption to container-engine 2023-11-21 22:25:20 +00:00
pre-commit-ci[bot] 277abc5ffa [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.5 → v0.1.6](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.5...v0.1.6)
2023-11-20 18:21:27 +00:00
cibuildwheel-bot[bot] a70a6346c5 Update dependencies 2023-11-20 06:14:21 +00:00
pre-commit-ci[bot] 859ebaf371 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-11-19 13:05:54 +00:00
Joe Rickerby 39d9b00eeb [docs] Address some confusion around the CIBW_ENVIRONMENT option.
Ref #1666
2023-11-19 13:04:19 +00:00
Hugo van Kemenade e577a9fbdf Use quotes when silencing warning 2023-11-18 12:37:50 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 77c57bdfa8 [Bot] Update dependencies (#1660)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-11-14 18:05:32 -05:00
Joe Rickerby 81812d05a3 Merge pull request #1661 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-11-14 13:54:54 +00:00
pre-commit-ci[bot] cc25f71674 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.4 → v0.1.5](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.4...v0.1.5)
- [github.com/pre-commit/mirrors-mypy: v1.6.1 → v1.7.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.6.1...v1.7.0)
2023-11-13 18:39:50 +00:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 6853b08120 [Bot] Update dependencies (#1655)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-11-10 11:25:49 -05:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> c38a3d7026 [pre-commit.ci] pre-commit autoupdate (#1656)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.3 → v0.1.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.3...v0.1.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-11-10 11:25:30 -05:00
Matthieu Darbois 2090f0ddce chore: limit Cirrus CI usage (#1643)
New usage limits are now enforced on Cirrus CI.
Limit runs to the minimum.
2023-11-01 18:08:55 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> cec051f4b8 [Bot] Update dependencies (#1652)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-10-30 22:35:03 -04:00
Henry Schreiner 89d5bd58f5 chore: test and use 3.12 as host (#1650)
* chore: test and use 3.12 as host

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* chore: address feedback

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-10-27 01:21:59 -04:00
Henry Schreiner 4586062efb chore: move to ruff-format (#1651)
* chore: move to ruff-format

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Apply suggestions from code review

* Apply suggestions from code review

* chore: bump Ruff

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-10-27 01:21:20 -04:00
Henry Schreiner 1efccd03b5 fix: minor ruff updates (#1649)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-10-26 10:57:23 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> c4fdf66efc [pre-commit.ci] pre-commit autoupdate (#1647)
updates:
- [github.com/psf/black-pre-commit-mirror: 23.9.1 → 23.10.0](https://github.com/psf/black-pre-commit-mirror/compare/23.9.1...23.10.0)
- [github.com/astral-sh/ruff-pre-commit: v0.0.292 → v0.1.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.292...v0.1.1)
- [github.com/pre-commit/mirrors-mypy: v1.6.0 → v1.6.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.6.0...v1.6.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-10-25 10:48:37 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 75f6b45a75 [Bot] Update dependencies (#1644)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-10-23 11:51:44 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
c2e19fb391 [pre-commit.ci] pre-commit autoupdate (#1645)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/pre-commit/mirrors-mypy: v1.5.1 → v1.6.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.1...v1.6.0)

* chore: update ignore code

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2023-10-23 11:51:26 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> b29dda3b4d [pre-commit.ci] pre-commit autoupdate (#1640)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-10-13 11:19:33 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 0ec6d97029 [Bot] Update dependencies (#1639)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-10-09 09:37:22 -04:00
Henry Schreiner 36e40805e8 fix(schema): small bug + prepare for SchemaStore (#1638)
* fix(schema): small bug + prepare for SchemaStore

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix(schema): schema kw is supposed to have a number sign

* fix(schema): differing conventions

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-10-09 09:36:09 -04:00
Joe Rickerby fff9ec32ed Bump version: v2.16.2 2023-10-03 20:07:09 +01:00
Joe Rickerby f4291e7492 Merge pull request #1617 from pypa/env-order
fix: evaluate environment-pass before environment, so environment can reference or override those variables
2023-10-03 18:25:19 +01:00
Joe Rickerby 9da4ede616 Merge pull request #1620 from Helveg/cibw-debug-keep-container
feat: `CIBW_DEBUG_KEEP_CONTAINER`: debug container after build
2023-10-03 18:23:49 +01:00
Joe Rickerby 77d3a5f98e Merge pull request #1621 from pypa/parse-kvs-colons
fix: improve parse_key_value_string to allow colons in values
2023-10-03 18:20:24 +01:00
Joe Rickerby 9535d168fa Merge pull request #1629 from henryiii/henryiii/refactor/schemaref
refactor: use refs instead of copies
2023-10-03 18:19:53 +01:00
Joe Rickerby 70fae8d0b7 Merge pull request #1630 from mayeut/manylinux-interpreters
feat: use manylinux-interpreters tool if present
2023-10-03 18:16:59 +01:00
Joe Rickerby 7699db3017 Merge pull request #1632 from gdementen/patch-1
docs: fix typo in changelog
2023-10-03 18:13:57 +01:00
Joe Rickerby 6dceb29008 Merge pull request #1634 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-10-03 18:12:54 +01:00
Joe Rickerby 035f5a2297 Merge pull request #1635 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-10-03 18:12:08 +01:00
pre-commit-ci[bot] 951d453a2e [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-10-03 14:34:04 +00:00
Henry Schreiner b05d91ee01 docs: fix typo 2023-10-03 10:33:40 -04:00
pre-commit-ci[bot] cbffaf76d2 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-10-03 14:19:29 +00:00
Henry Schreiner 46a7bf14dc Update .pre-commit-config.yaml 2023-10-03 10:19:06 -04:00
cibuildwheel-bot[bot] 1e2942dd68 Update dependencies 2023-10-03 11:46:25 +00:00
pre-commit-ci[bot] de4fe44dc8 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.291 → v0.0.292](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.291...v0.0.292)
- [github.com/asottile/setup-cfg-fmt: v2.4.0 → v2.5.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.4.0...v2.5.0)
- [github.com/shellcheck-py/shellcheck-py: v0.9.0.5 → v0.9.0.6](https://github.com/shellcheck-py/shellcheck-py/compare/v0.9.0.5...v0.9.0.6)
- [github.com/codespell-project/codespell: v2.2.5 → v2.2.6](https://github.com/codespell-project/codespell/compare/v2.2.5...v2.2.6)
2023-10-03 00:39:29 +00:00
Joe Rickerby 96e0efe076 Merge pull request #1631 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-10-02 15:16:27 +01:00
pre-commit-ci[bot] 84ffe27f78 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-10-02 09:45:47 +00:00
Gaëtan de Menten 129137d894 fix typo in README.md 2023-10-02 11:44:49 +02:00
cibuildwheel-bot[bot] 35a8d6486e Update dependencies 2023-10-02 06:13:58 +00:00
mayeut 74c99e0d93 feat: use manylinux-interpreters tool if present
This will allow dropping some EOL (and maybe some none EOL) python interpreters in manylinux images which would allow to reduce its size (faster for a vast majority of user, a small slow-down for users of those interpreters).
2023-10-01 13:51:21 +02:00
Henry Schreiner 86248929ed fix: ensure 2+ items in each override in schema (#1628)
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-28 19:32:18 -04:00
Henry Schreiner 5fee29256d refactor: use refs instead of copies
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-28 12:35:07 -04:00
Henry Schreiner d4af0ac229 feat: add schema and validate-pyproject support (#1622)
* feat: add schema and validate-pyproject support

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: address review comments, fix bug, add tests

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: add test of examples in docs and fix

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* fix: nicer titles

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-26 11:23:20 -05:00
Joe Rickerby 7da7df1efc Bump version: v2.16.1 2023-09-26 10:52:04 +02:00
Joe Rickerby 9deb1b6794 Merge pull request #1625 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-09-26 09:44:46 +01:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 271c5fe6e4 [pre-commit.ci] pre-commit autoupdate (#1627)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.290 → v0.0.291](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.290...v0.0.291)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-26 08:47:25 +02:00
cibuildwheel-bot[bot] c716cfaeb8 Update dependencies 2023-09-25 06:13:35 +00:00
pre-commit-ci[bot] 28ad6e4b40 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-09-19 19:00:48 +00:00
Robin De Schepper 13599a1a10 Merge branch 'main' into cibw-debug-keep-container 2023-09-19 20:59:22 +02:00
Robin De Schepper a1bebe5362 addressed comments from review 2023-09-19 16:39:23 +02:00
Joe Rickerby 687981060f Improve parse_key_value_string to allow colons in values.
Fix #1600
2023-09-19 14:05:36 +01:00
Joe Rickerby 29cb13893f Merge remote-tracking branch 'origin/main' into env-order 2023-09-19 11:59:12 +01:00
Joe Rickerby 099d397aee Merge pull request #1599 from mayeut/manylinux-entrypoint
fix: do not use `linux32` when unnecessary
2023-09-19 11:56:45 +01:00
Robin De Schepper d7a6d04353 feature: CIBW_DEBUG_KEEP_CONTAINER option. debug container after build 2023-09-19 11:57:03 +02:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 72222654f4 [pre-commit.ci] pre-commit autoupdate (#1619)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.288 → v0.0.290](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.288...v0.0.290)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-19 08:28:07 +02:00
Matthieu DarboisandJoe Rickerby 7a8b8012ff clearer simulate_32_bit initialization
Co-authored-by: Joe Rickerby <joerick@mac.com>
2023-09-18 21:30:22 +02:00
mayeut 0ccf1dc016 remove GHA runner cached docker images
This frees up some space preventing reaching GHA disk space limits.
2023-09-18 21:28:33 +02:00
mayeut ba11212a13 use fixture in oci_container_test.py to clean-up images after tests 2023-09-18 21:28:33 +02:00
mayeut 6d0890e7e0 add tests 2023-09-18 21:28:33 +02:00
mayeut cf7586ce7e check i686 directly 2023-09-18 21:28:33 +02:00
mayeut 137dc1a2cf Rename simulate_32_bit to enforce_32_bit 2023-09-18 21:28:33 +02:00
mayeut 1646b08659 fix: do not use linux32 when unnecessary 2023-09-18 21:28:32 +02:00
Joe Rickerby a873dd9cbf Bump version: v2.16.0 2023-09-18 18:34:53 +01:00
Joe Rickerby e8ba0d49ed Merge pull request #1615 from pypa/dependabot/github_actions/docker/setup-qemu-action-3
chore(deps): bump docker/setup-qemu-action from 2 to 3
2023-09-18 18:19:19 +01:00
Joe Rickerby f0feaffbaa Merge pull request #1613 from henryiii/henryiii/fix/mainif
fix(setup.py): look inside if name == main block
2023-09-18 18:16:04 +01:00
Joe Rickerby 80a54b0226 Merge pull request #1589 from dalcinl/source_date_epoch
feature: Automatically pass SOURCE_DATE_EPOCH to Linux containers
2023-09-18 18:15:13 +01:00
Joe Rickerby 76dba0b9ba Merge pull request #1588 from pypa/frontend-flags
Add the ability to pass extra flags to a build frontend through CIBW_BUILD_FRONTEND
2023-09-18 18:14:42 +01:00
Joe Rickerby 391249a1ca Merge remote-tracking branch 'origin/main' into env-order 2023-09-18 17:39:08 +01:00
Joe Rickerby 0954ffaa65 Merge pull request #1618 from pypa/rtd-update
Update RtD config to include mandatory build.os option
2023-09-18 17:25:54 +01:00
Joe Rickerby 753cbd1ca5 Update RtD config to include mandatory build.os option 2023-09-18 17:20:30 +01:00
Joe Rickerby 825d89818a Merge pull request #1614 from henryiii/henryiii/chore/minor
chore: minor additions
2023-09-18 17:15:21 +01:00
Joe Rickerby 62a06d28b5 Change order of environment-pass, so environment can reference it 2023-09-18 17:08:30 +01:00
Joe Rickerby 647b509c74 Add test for environment and environment_pass references 2023-09-18 17:06:09 +01:00
Henry Schreiner f5e60d647f fix: include examples too
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-18 11:57:32 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> adc991c47b [Bot] Update dependencies (#1604)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-09-18 10:34:09 -04:00
dependabot[bot] cc50337ecd chore(deps): bump docker/setup-qemu-action from 2 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-18 13:11:07 +00:00
Henry Schreiner db6d3095b9 chore: add .gitattributes
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-13 16:09:56 -04:00
Henry Schreiner f6a95d3d0b chore: Ruff ignore for _compat
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-13 16:09:21 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 028455f481 chore(deps): bump tibdex/github-app-token from 1 to 2 (#1606)
Bumps [tibdex/github-app-token](https://github.com/tibdex/github-app-token) from 1 to 2.
- [Release notes](https://github.com/tibdex/github-app-token/releases)
- [Commits](https://github.com/tibdex/github-app-token/compare/v1...v2)

---
updated-dependencies:
- dependency-name: tibdex/github-app-token
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-13 16:07:34 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 05d5c9bada [pre-commit.ci] pre-commit autoupdate (#1607)
updates:
- [github.com/psf/black-pre-commit-mirror: 23.7.0 → 23.9.1](https://github.com/psf/black-pre-commit-mirror/compare/23.7.0...23.9.1)
- [github.com/astral-sh/ruff-pre-commit: v0.0.287 → v0.0.288](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.287...v0.0.288)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-13 16:02:03 -04:00
Henry Schreiner f34ae7731d fix(setup.py): look inside if name == main block
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-13 15:45:40 -04:00
Lisandro DalcinandJoe Rickerby 4f888e27c3 feature: Automatically pass SOURCE_DATE_EPOCH to Linux containers
Co-authored-by: Joe Rickerby <joerick@mac.com>
2023-09-08 18:59:32 +03:00
Joe Rickerby e5d0cc0b0d Merge pull request #1598 from henryiii/henryiii/chore/checkoutv4
chore: use actions/checkout@4 everywhere
2023-09-06 10:13:35 +01:00
Henry Schreiner a449142802 chore: use actions/checkout@4 everywhere
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-09-05 10:09:36 -04:00
Mikail 82a1f99268 docs: fix deprecated option in github-deploy example (#1593)
The `github-deploy.yml` example workflow was using a deprecated argument `repository_url` which is not `repository-url` since v1.7.0 (https://github.com/pypa/gh-action-pypi-publish/releases/tag/v1.7.0 + https://github.com/pypa/gh-action-pypi-publish/blob/b7f401de30cb6434a1e19f805ff006643653240e/action.yml#L15)

Thus fixing the warning in GitHub workflows:

> Warning: Input 'repository_url' has been deprecated with message: The inputs have been normalized to use kebab-case. Use `repository-url` instead.
2023-09-05 10:07:16 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 1280565f7f [Bot] Update dependencies (#1594)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-09-05 10:06:44 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 386d36f5ad chore(deps): bump actions/checkout from 3 to 4 (#1595)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-05 10:06:24 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> be0e07ac31 [pre-commit.ci] pre-commit autoupdate (#1596)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.286 → v0.0.287](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.286...v0.0.287)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-09-05 10:06:12 -04:00
Joe Rickerby 001f11c755 Merge pull request #1591 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-09-01 11:45:01 +01:00
Joe Rickerby 5f37a3bb02 Merge pull request #1590 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-09-01 11:44:39 +01:00
Joe Rickerby 5311f88684 Fix for missing table in option parsing 2023-08-30 09:28:47 +01:00
Joe Rickerby 81ef5fac43 Add a unit test for the TOML form of the option 2023-08-30 09:28:34 +01:00
pre-commit-ci[bot] 53b641caaf [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.285 → v0.0.286](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.285...v0.0.286)
2023-08-28 23:17:35 +00:00
cibuildwheel-bot[bot] ae6b3d40b5 Update dependencies 2023-08-28 06:12:52 +00:00
Joe Rickerby 061ea627e2 Add docs 2023-08-26 19:47:49 +01:00
Joe Rickerby 297e4a6099 Add args param to build-frontend option 2023-08-26 19:37:29 +01:00
pre-commit-ci[bot]Joe Rickerbypre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
e8bb208374 [pre-commit.ci] pre-commit autoupdate (#1583)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.284 → v0.0.285](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.284...v0.0.285)
- [github.com/pre-commit/mirrors-mypy: v1.5.0 → v1.5.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.5.0...v1.5.1)

* chore: add check arguments

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Update bin/bump_version.py

Co-authored-by: Joe Rickerby <joerick@mac.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2023-08-24 11:57:20 -04:00
Mike Taves 18ff2c57c2 docs: Update info for CIBW_TEST_EXTRAS (#1582)
Update setuptools link to new URL, and add `pyproject.toml` as a source file (as already done in the example).
2023-08-22 11:41:51 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 98b83afe63 [Bot] Update dependencies (#1581)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-08-21 17:24:01 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 25428deff2 [pre-commit.ci] pre-commit autoupdate (#1579)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.282 → v0.0.284](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.282...v0.0.284)
- [github.com/pre-commit/mirrors-mypy: v1.4.1 → v1.5.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.4.1...v1.5.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-08-21 17:23:52 -04:00
Henry SchreinerandJoe Rickerby ce71f445de fix: --only shouldn't require prerelease pythons setting (#1564)
* fix: --only shouldn't require prerelease pythons setting

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

* Add test

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2023-08-14 12:15:53 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 12d548865f [Bot] Update dependencies (#1575)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-08-14 12:15:24 -04:00
Ben Darnell 9afd31017a Update Tornado's entry in projects.yml (#1571)
We've moved to github actions and added windows support. Also add a note about our use of the stable ABI which may be the most interesting part of our config.
2023-08-14 08:36:44 +02:00
Mark Barsi-Siminszky 7508943e06 fix: path construction when testing Linux wheels on Windows hosts (#1573)
fix: path construction when testing linux wheels
2023-08-14 08:30:33 +02:00
Henry Schreiner 26c5e18e62 chore: use 2x faster pre-commit mirror (#1569) 2023-08-11 08:43:29 +02:00
Joe Rickerby c655dbdaab Merge pull request #1566 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-08-08 19:06:06 +01:00
Joe Rickerby 39a63b5912 Bump version: v2.15.0 2023-08-08 18:54:48 +01:00
Joe Rickerby 47e5d3c2cd Merge pull request #1565 from henryiii/henryiii/feat/312rc
feat: build using 3.12 RC by default
2023-08-08 18:37:33 +01:00
Henry Schreiner a63e11a1c4 feat: build using 3.12 RC by default
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-08-08 08:29:44 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> df94b5db67 [Bot] Update dependencies (#1553)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-08-08 08:27:23 +02:00
pre-commit-ci[bot] 8946bfb2e8 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.281 → v0.0.282](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.281...v0.0.282)
2023-08-07 23:30:53 +00:00
Matthieu Darboisandpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 36049d86a2 feature: add musllinux_1_2 support (#1561)
* feature: add musllinux_1_2 support

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix[test]: clean-up docker images in test_*linux*_only.py

We are reaching disk space limits (14 GB) when running tests.
Add a fixture to clean-up docker images after tests.
This fixture is applied on tests that pull a specific image for one test only in order not to take too much time pulling that image many times.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-08-07 12:01:10 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 229f8570b4 [pre-commit.ci] pre-commit autoupdate (#1562)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.280 → v0.0.281](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.280...v0.0.281)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-08-01 17:12:16 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 5b32ee7d7b [pre-commit.ci] pre-commit autoupdate (#1559)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.278 → v0.0.280](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.278...v0.0.280)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-07-24 22:34:06 -04:00
Joe Rickerby 3f3bd9cff6 Merge pull request #1554 from pypa/pre-commit-ci-update-config
[pre-commit.ci] pre-commit autoupdate
2023-07-24 18:36:15 +01:00
pre-commit-ci[bot] 8df6d59adf [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/psf/black: 23.3.0 → 23.7.0](https://github.com/psf/black/compare/23.3.0...23.7.0)
2023-07-17 23:27:43 +00:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
4135c0a01d [pre-commit.ci] pre-commit autoupdate (#1546)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.276 → v0.0.277](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.276...v0.0.277)

* Update .pre-commit-config.yaml

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2023-07-16 15:32:55 -05:00
Joe Rickerby 6282bc5a83 Merge pull request #1542 from pypa/ci-exclude-paths
Ignore docs changes on Azure Pipelines and CirrusCI
2023-07-15 10:02:51 +01:00
Joe Rickerby ddbcf561db Correct logic with includes-only
I'm assuming it takes multiple arguments because the Starlark version of the function does 
https://cirrus-ci.org/guide/programming-tasks/#changes_include_only
2023-07-15 09:57:54 +01:00
Joe Rickerby f21bb8376a Bump version: v2.14.1 2023-07-15 09:53:23 +01:00
Joe Rickerby a5b2e543e5 Merge pull request #1550 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-07-15 09:49:24 +01:00
Joe Rickerby bd9675d05b Manually specify 3.12.0b4 on macOS 2023-07-14 22:42:03 +01:00
cibuildwheel-bot[bot] 661ba2d0de Update dependencies 2023-07-14 19:20:18 +00:00
Joe Rickerby 66b46d0868 Bump version: v2.14.0 2023-07-10 11:43:05 +01:00
Joe Rickerby b0a5c951f5 Merge pull request #1543 from pypa/update-dependencies-pr
[Bot] Update dependencies
2023-07-10 11:39:37 +01:00
Joe Rickerby f5960020cd Add .pre-commit-config.yaml to CI ignore rules 2023-07-10 11:34:10 +01:00
cibuildwheel-bot[bot] 8bfc92df50 Update dependencies 2023-07-10 06:15:20 +00:00
pre-commit-ci[bot]Henry Schreinerpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Joe Rickerby
9afee48243 [pre-commit.ci] pre-commit autoupdate (#1541)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.275 → v0.0.276](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.275...v0.0.276)
- [github.com/asottile/setup-cfg-fmt: v2.3.0 → v2.4.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.3.0...v2.4.0)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Apply suggestions from code review

* Update .pre-commit-config.yaml

Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2023-07-09 23:01:17 -04:00
Joe Rickerby 7f6fe8a031 Merge pull request #1416 from Czaki/poerty_problem 2023-07-09 16:41:22 +01:00
Joe Rickerby c824c7e87a Ignore docs changes on more CIs 2023-07-09 15:59:27 +01:00
Joe Rickerby f44d2784f8 Update docs/faq.md 2023-07-09 15:17:51 +01:00
Joe Rickerby 740f081606 Merge pull request #1526 from mayeut/drop-python-3.7
chore: drop python 3.7 for cibuildwheel driver
2023-07-09 14:31:54 +01:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> 8c6ff25315 [Bot] Update dependencies (#1539)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-07-08 09:39:18 -04:00
Henry Schreiner b77cedba39 chore: ruff moved to astral-sh (#1540) 2023-07-03 18:21:29 -04:00
mayeut 6415878631 chore: remove cap on markdown-it-py
Since it's an indirect dependency (of rich), just remove the line altogether.
2023-07-01 14:42:03 +02:00
Henry Schreiner ac34701e98 chore: bump Ruff to 3.8+ too 2023-07-01 14:33:24 +02:00
mayeut 4b19db8454 chore: drop python 3.7 for cibuildwheel driver
This drops python 3.7 for cibuildwheel.
Building python 3.6 / 3.7 packages is still supported.
2023-07-01 14:33:24 +02:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> af42be1f3b [Bot] Update dependencies (#1535)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-06-27 17:31:15 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
aeb0a3ee83 [pre-commit.ci] pre-commit autoupdate (#1536)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/charliermarsh/ruff-pre-commit: v0.0.272 → v0.0.275](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.272...v0.0.275)
- [github.com/pre-commit/mirrors-mypy: v1.3.0 → v1.4.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.3.0...v1.4.1)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* chore: update for better mypy lambdas

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>

---------

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-06-27 17:30:17 -04:00
Joe Rickerby 33f02f2e1d Merge pull request #1532 from pypa/henryiii/docs/trustedpub 2023-06-25 17:36:48 +01:00
Henry SchreinerandJoe Rickerby 062a745fc9 Update examples/github-deploy.yml
Co-authored-by: Joe Rickerby <joerick@mac.com>
2023-06-25 10:21:09 -04:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> b8a3cfa4f9 [Bot] Update dependencies (#1528)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
2023-06-23 12:01:33 -04:00
Henry SchreinerandCosimo Lupo cee0848b49 fix: allow access to {wheel} in more places (#1533)
pass {wheel} path to test command so I can use with tox --installpkg

Co-authored-by: Cosimo Lupo <clupo@google.com>
2023-06-23 08:29:58 -04:00
Joe Rickerby 2b769c9052 Merge pull request #1525 from mayeut/pypy-7.3.12
feature: add PyPy 3.10
2023-06-23 08:49:14 +01:00
Joe Rickerby 8f569c42ec Merge remote-tracking branch 'origin/main' into poerty_problem 2023-06-23 08:46:51 +01:00
Henry Schreiner 28b03782f8 docs: use trusted publisher for GHA docs/example
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2023-06-22 15:08:24 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 5ef9f081bd [pre-commit.ci] pre-commit autoupdate (#1529)
updates:
- [github.com/codespell-project/codespell: v2.2.4 → v2.2.5](https://github.com/codespell-project/codespell/compare/v2.2.4...v2.2.5)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-06-22 10:18:33 -04:00
Joe Rickerby 1ce209198a Copy edit of the whole section, make it a bit easier to follow, add some details about universal2 2023-06-18 19:15:06 +01:00
Joe Rickerby 3192cdcbfa Copy pass on this text 2023-06-18 18:03:06 +01:00
Joe Rickerby 983347f370 Add reference to the new 'wheel tags' command 2023-06-18 17:49:57 +01:00
mayeut b1929b7eaf feature: add PyPy 3.10 2023-06-17 14:21:50 +02:00
cibuildwheel-bot[bot]cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>Joe Rickerby
0a7800c9d9 [Bot] Update dependencies (#1518)
Update dependencies

Co-authored-by: cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>
Co-authored-by: Joe Rickerby <joerick@mac.com>
2023-06-15 09:07:03 -04:00
Joe Rickerby 43cb682c24 Merge pull request #1521 from pypa/pre-commit-ci-update-config 2023-06-15 07:42:38 +01:00
Henry Schreiner c9e0981955 tests: remove testpaths, since we have two incomplatible test suites 2023-06-14 09:14:44 -04:00
Henry Schreiner aae0524f8a chore: fix for Ruff & markdown-it updates 2023-06-14 09:02:39 -04:00
pre-commit-ci[bot] ada476e3c1 [pre-commit.ci] pre-commit autoupdate
updates:
- [github.com/charliermarsh/ruff-pre-commit: v0.0.270 → v0.0.272](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.270...v0.0.272)
2023-06-12 22:20:58 +00:00
Grzegorz Bokota ed320412b0 fix note text 2023-02-16 18:20:37 +00:00
Grzegorz BokotaandHenry Schreiner 567fe2a923 Apply suggestions from code review
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2023-02-15 00:00:22 +01:00
Grzegorz Bokota c7643f08e7 update information about poetry state 2023-02-14 13:31:20 +00:00
Grzegorz BokotaandHenry Schreiner 96cffc2c7c Update docs/faq.md
Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
2023-02-10 22:56:52 +01:00
pre-commit-ci[bot] cc0bb5da34 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-02-10 20:00:17 +00:00
Grzegorz Bokota 5be1d17d5f add information about lack of possibility of cross compile Poetry projects 2023-02-10 19:56:24 +00:00
155 changed files with 8568 additions and 2794 deletions
+8 -7
View File
@@ -1,9 +1,10 @@
version: 2
jobs:
osx-python3.9:
osx-python3.12:
macos:
xcode: 12.5.1
xcode: 15.4.0
resource_class: macos.m1.medium.gen1
environment:
PYTHON: python3
steps:
@@ -17,9 +18,9 @@ jobs:
command: venv/bin/python ./bin/run_tests.py
no_output_timeout: 30m
linux-python3.9:
linux-python3.12:
docker:
- image: circleci/python:3.9
- image: cimg/python:3.12
environment:
PYTHON: python3
# Temporarily restrict the tests that are run on CircleCI to prevent
@@ -39,7 +40,7 @@ jobs:
linux-aarch64:
machine:
image: ubuntu-2004:2022.04.1
image: default
resource_class: arm.medium
environment:
PYTHON: python3
@@ -61,6 +62,6 @@ workflows:
version: 2
all-tests:
jobs:
- osx-python3.9
- linux-python3.9
- osx-python3.12
- linux-python3.12
- linux-aarch64
+9 -3
View File
@@ -2,9 +2,15 @@
set -o errexit
set -o xtrace
if [ "$(uname -s)" == "Darwin" ]; then
sudo softwareupdate --install-rosetta --agree-to-license
else
docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
fi
$PYTHON --version
$PYTHON -m pip --version
$PYTHON -m virtualenv -p "$PYTHON" venv
venv/bin/python -m pip install -e ".[dev]"
$PYTHON -m venv venv
venv/bin/python -m pip install -U pip dependency-groups
venv/bin/python -m dependency_groups test | xargs venv/bin/python -m pip install -e.
venv/bin/python -m pip freeze
venv/bin/python --version
+10 -7
View File
@@ -1,6 +1,9 @@
only_if: changesInclude('.cirrus.yml') || ($CIRRUS_BRANCH == "main" && !changesIncludeOnly('docs/*', '.pre-commit-config.yaml')) || $CIRRUS_BRANCH =~ 'cirrus.*'
run_tests: &RUN_TESTS
install_cibuildwheel_script:
- python -m pip install -e ".[dev]" pytest-custom-exit-code
- python -m pip install dependency-groups
- python -m dependency_groups test | xargs python -m pip install -e.
run_cibuildwheel_tests_script:
- python ./bin/run_tests.py
@@ -15,6 +18,7 @@ linux_x86_task:
memory: 8G
install_pre_requirements_script:
- docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
- apt install -y python3-venv python-is-python3
<<: *RUN_TESTS
@@ -28,6 +32,7 @@ linux_aarch64_task:
memory: 4G
install_pre_requirements_script:
- docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
- apt install -y python3-venv python-is-python3
<<: *RUN_TESTS
@@ -48,25 +53,23 @@ windows_x86_task:
macos_arm64_task:
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode
image: ghcr.io/cirruslabs/macos-runner:sonoma
env:
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
PATH: /opt/homebrew/opt/python@3.10/libexec/bin:$PATH
install_pre_requirements_script:
- brew install python@3.10
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
<<: *RUN_TESTS
macos_arm64_cp38_task:
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode
image: ghcr.io/cirruslabs/macos-runner:sonoma
env:
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
PATH: /opt/homebrew/opt/python@3.10/libexec/bin:$PATH
PYTEST_ADDOPTS: --run-cp38-universal2 -k 'test_cp38_arm64_testing_universal2_installer or test_arch_auto'
install_pre_requirements_script:
- brew install python@3.10
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
- curl -fsSLO https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg
- sudo installer -pkg python-3.8.10-macos11.pkg -target /
- rm python-3.8.10-macos11.pkg
+6
View File
@@ -0,0 +1,6 @@
* text=auto
*.py diff=python
*.md diff=markdown
*.svg -diff
+4
View File
@@ -5,3 +5,7 @@ updates:
directory: "/"
schedule:
interval: "weekly"
groups:
actions:
patterns:
- "*"
-32
View File
@@ -1,32 +0,0 @@
{
"problemMatcher": [
{
"severity": "warning",
"pattern": [
{
"regexp": "^([^:]+):(\\d+):(\\d+): ([A-DF-Z]\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
"file": 1,
"line": 2,
"column": 3,
"code": 4,
"message": 5
}
],
"owner": "pylint-warning"
},
{
"severity": "error",
"pattern": [
{
"regexp": "^([^:]+):(\\d+):(\\d+): (E\\d+): \\033\\[[\\d;]+m([^\\033]+).*$",
"file": 1,
"line": 2,
"column": 3,
"code": 4,
"message": 5
}
],
"owner": "pylint-error"
}
]
}
+15 -13
View File
@@ -11,30 +11,32 @@ jobs:
dist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build SDist and wheel
run: pipx run build
- uses: actions/upload-artifact@v3
with:
path: dist/*
- name: Check metadata
run: pipx run twine check dist/*
- uses: hynek/build-and-inspect-python-package@v2
publish:
needs: [dist]
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'published'
environment: pypi
environment:
name: pypi
url: https://pypi.org/p/cibuildwheel
permissions:
id-token: write
attestations: write
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: artifact
name: Packages
path: dist
- name: Generate artifact attestation for sdist and wheel
uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1.4.4
with:
subject-path: "dist/cibuildwheel-*"
- uses: pypa/gh-action-pypi-publish@release/v1
with:
attestations: true
+134 -39
View File
@@ -4,9 +4,11 @@ on:
push:
branches:
- main
- 2.x
pull_request:
paths-ignore:
- 'docs/**'
- .pre-commit-config.yaml
workflow_dispatch:
# allow manual runs on branches without a PR
@@ -19,55 +21,58 @@ jobs:
name: Linters (mypy, flake8, etc.)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
id: python
with:
python-version: "3.x"
- uses: pre-commit/action@v3.0.0
- uses: pre-commit/action@v3.0.1
- name: Check manifest
run: pipx run nox -s check_manifest
run: pipx run --python "${{ steps.python.outputs.python-path }}" nox -s check_manifest
- name: PyLint checks
run: |
echo "::add-matcher::$GITHUB_WORKSPACE/.github/matchers/pylint.json"
pipx run nox -s pylint
run: pipx run --python "${{ steps.python.outputs.python-path }}" nox -s pylint -- --output-format=github
test:
name: Test cibuildwheel on ${{ matrix.os }}
name: Test on ${{ matrix.os }} (${{ matrix.python_version }})
needs: lint
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-latest, macos-11]
python_version: ['3.11']
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-14]
python_version: ['3.13']
include:
- os: ubuntu-22.04
python_version: '3.7'
- os: ubuntu-latest
python_version: '3.8'
timeout-minutes: 180
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
name: Install Python ${{ matrix.python_version }}
with:
python-version: ${{ matrix.python_version }}
allow-prereleases: true
# Install podman on this CI instance for podman tests on linux
# Snippet from: https://github.com/redhat-actions/podman-login/blob/main/.github/workflows/example.yml
- name: Install latest podman
- uses: astral-sh/setup-uv@v3
# free some space to prevent reaching GHA disk space limits
- name: Clean docker images
if: runner.os == 'Linux'
run: |
. /etc/os-release
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 install podman
docker system prune -a -f
df -h
# for oci_container unit tests
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v3
- name: Install dependencies
run: |
python -m pip install ".[test]"
uv sync --no-dev --group test
- name: Generate a sample project
run: |
python -m test.test_projects test.test_0_basic.basic_project sample_proj
uv run -m test.test_projects test.test_0_basic.basic_project sample_proj
- name: Run a sample build (GitHub Action)
uses: ./
@@ -76,36 +81,126 @@ jobs:
output-dir: wheelhouse
env:
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
CIBW_BUILD_FRONTEND: 'build[uv]'
CIBW_FREE_THREADED_SUPPORT: 1
CIBW_PRERELEASE_PYTHONS: 1
- uses: actions/upload-artifact@v3
- name: Run a sample build (GitHub Action, only)
uses: ./
with:
name: sample_wheels_action
path: wheelhouse
package-dir: sample_proj
output-dir: wheelhouse_only
only: cp312-${{ runner.os == 'Linux' && (runner.arch == 'ARM64' && 'manylinux_aarch64' || 'manylinux_x86_64') || (runner.os == 'Windows' && 'win_amd64' || 'macosx_x86_64') }}
- name: Create custom configuration file
shell: bash
run: |
cat > sample_proj/cibw.toml <<EOF
[tool.cibuildwheel]
# Only build on CPython 3.12 on native arch
archs = ["native"]
build = "cp312-*"
# Skip musllinux
skip = "*-musllinux*"
EOF
- name: Run a sample build (GitHub Action, config-file)
uses: ./
with:
package-dir: sample_proj
output-dir: wheelhouse_config_file
config-file: sample_proj/cibw.toml
- name: Check Action artifacts
shell: bash
run: |
test $(find wheelhouse -name '*.whl' | wc -l) -ge 1
test $(find wheelhouse_only -name '*.whl' | wc -l) -eq 1
test $(find wheelhouse_config_file -name '*.whl' | wc -l) -eq 1
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: wheelhouse/*.whl
- name: Test cibuildwheel
run: |
python ./bin/run_tests.py --run-podman
uv run bin/run_tests.py ${{ (runner.os == 'Linux' && runner.arch == 'X64') && '--run-podman' || '' }}
test-emulated:
name: Test emulated cibuildwheel using qemu
emulated-archs:
name: Get qemu emulated architectures
needs: lint
runs-on: ubuntu-latest
timeout-minutes: 180
outputs:
archs: ${{ steps.archs.outputs.archs }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- uses: astral-sh/setup-uv@v3
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Get qemu emulated architectures
id: archs
run: |
python -m pip install ".[test]"
OUTPUT=$(uv run python -c "from json import dumps; from test.utils import EMULATED_ARCHS; print(dumps(EMULATED_ARCHS))")
echo "${OUTPUT}"
echo "archs=${OUTPUT}" >> "$GITHUB_OUTPUT"
test-emulated:
name: Test Linux ${{ matrix.arch }} using qemu
needs: emulated-archs
runs-on: ubuntu-latest
timeout-minutes: 180
strategy:
matrix:
arch: ${{ fromJSON(needs.emulated-archs.outputs.archs) }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- uses: astral-sh/setup-uv@v3
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Set up QEMU
id: qemu
uses: docker/setup-qemu-action@v2
with:
platforms: all
uses: docker/setup-qemu-action@v3
- name: Run the emulation tests
run: uv run pytest --run-emulation ${{ matrix.arch }} test/test_emulation.py
test-pyodide:
name: Test cibuildwheel building Pyodide wheels
needs: lint
runs-on: ubuntu-24.04
timeout-minutes: 180
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
name: Install Python 3.12
with:
python-version: '3.12'
- uses: astral-sh/setup-uv@v3
- name: Install dependencies
run: uv sync --no-dev --group test
- name: Generate a sample project
run: |
pytest --run-emulation test/test_emulation.py
uv run -m test.test_projects test.test_0_basic.basic_project sample_proj
- name: Run a sample build (GitHub Action)
uses: ./
with:
package-dir: sample_proj
output-dir: wheelhouse
env:
CIBW_PLATFORM: pyodide
- name: Run tests with 'CIBW_PLATFORM' set to 'pyodide'
run: |
uv run ./bin/run_tests.py
env:
CIBW_PLATFORM: pyodide
+14 -16
View File
@@ -18,13 +18,21 @@ jobs:
update-dependencies:
name: Update dependencies
if: github.repository_owner == 'pypa' || github.event_name != 'schedule'
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: wntrblm/nox@2023.04.22
# we use this step to grab a Github App auth token, so that PRs generated by this workflow
# run the GHA tests.
- uses: actions/create-github-app-token@v1
id: generate-token
if: github.ref == 'refs/heads/main' && github.repository == 'pypa/cibuildwheel'
with:
python-versions: "3.7, 3.8, 3.9, 3.10, 3.11, 3.12-dev"
app_id: ${{ secrets.CIBUILDWHEEL_BOT_APP_ID }}
private_key: ${{ secrets.CIBUILDWHEEL_BOT_APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
- uses: wntrblm/nox@2024.10.09
- name: "Run update: dependencies"
run: nox --force-color -s update_constraints
@@ -33,18 +41,9 @@ jobs:
- name: "Run update: docs user projects"
run: nox --force-color -s update_proj -- --auth=${{ secrets.GITHUB_TOKEN }}
# 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
id: generate-token
if: github.ref == 'refs/heads/main' && github.repository == 'pypa/cibuildwheel'
with:
app_id: ${{ secrets.CIBUILDWHEEL_BOT_APP_ID }}
private_key: ${{ secrets.CIBUILDWHEEL_BOT_APP_PRIVATE_KEY }}
- name: Create Pull Request
if: github.ref == 'refs/heads/main' && github.repository == 'pypa/cibuildwheel'
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v7
with:
commit-message: Update dependencies
title: '[Bot] Update dependencies'
@@ -53,7 +52,6 @@ jobs:
PR generated by "Update dependencies" [workflow](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}).
branch: update-dependencies-pr
committer: "cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>"
author: "cibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com>"
sign-commits: true
token: ${{ steps.generate-token.outputs.token }}
delete-branch: true
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-minor-tag
+19 -5
View File
@@ -1,5 +1,5 @@
linux:
image: python:3.8
image: python:3.12
services:
- name: docker:dind
entrypoint: ["env", "-u", "DOCKER_HOST"]
@@ -15,7 +15,9 @@ linux:
PYTEST_ADDOPTS: -k "unit_test or test_0_basic" --suppress-no-test-exit-code
script:
- curl -sSL https://get.docker.com/ | sh
- python -m pip install -e ".[dev]" pytest-custom-exit-code
- docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
- python -m pip install dependency-groups
- python -m dependency_groups test | xargs python -m pip install -e. pytest-custom-exit-code
- python ./bin/run_tests.py
windows:
@@ -23,9 +25,21 @@ windows:
variables:
PYTEST_ADDOPTS: -k "unit_test or test_0_basic" --suppress-no-test-exit-code
before_script:
- choco install python -y --version 3.8.6
- choco install python -y --version 3.12.4
script:
- py -m pip install -e ".[dev]" pytest-custom-exit-code
- py -m pip install dependency-groups
- py -m pip install -e. pytest-custom-exit-code $(py -m dependency_groups test)
- py bin\run_tests.py
tags:
- windows
- saas-windows-medium-amd64
macos:
image: macos-14-xcode-15
variables:
PYTEST_ADDOPTS: -k "unit_test or test_0_basic" --suppress-no-test-exit-code
script:
- python3 -m pip install dependency-groups
- python3 -m dependency_groups test | xargs python3 -m pip install -e. pytest-custom-exit-code
- python3 ./bin/run_tests.py
tags:
- saas-macos-medium-m1
+38 -25
View File
@@ -1,7 +1,7 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v5.0.0
hooks:
- id: check-case-conflict
- id: check-merge-conflict
@@ -13,34 +13,28 @@ repos:
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.270
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.3.0
hooks:
- id: setup-cfg-fmt
args: [--include-version-classifiers, --max-py-version=3.11]
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.3.0
rev: v1.13.0
hooks:
- id: mypy
name: mypy 3.7 on cibuildwheel/
exclude: ^cibuildwheel/resources/.*py$
args: ["--python-version=3.7"]
name: mypy 3.8 on cibuildwheel/
exclude: ^cibuildwheel/resources/.*py|bin/generate_schema.py$
args: ["--python-version=3.8"]
additional_dependencies: &mypy-dependencies
- bracex
- dependency-groups>=1.2
- nox
- packaging~=21.0
- orjson
- packaging
- pygithub
- pytest
- rich
- tomli
- tomli_w
@@ -49,15 +43,17 @@ repos:
- types-jinja2
- types-pyyaml
- types-requests
- bracex
- types-setuptools
- uv
- validate-pyproject
- id: mypy
name: mypy 3.11
name: mypy 3.12
exclude: ^cibuildwheel/resources/.*py$
args: ["--python-version=3.11"]
args: ["--python-version=3.12"]
additional_dependencies: *mypy-dependencies
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.9.0.5
rev: v0.10.0.1
hooks:
- id: shellcheck
@@ -77,8 +73,25 @@ repos:
files: ^docs/changelog.md$
- repo: https://github.com/codespell-project/codespell
rev: v2.2.4
rev: v2.3.0
hooks:
- id: codespell
args: ["-L", "sur"]
args: ["-L", "sur,assertin", "-w"]
exclude: ^docs/working-examples\.md$ # Autogenerated
- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.29.4
hooks:
- id: check-dependabot
- id: check-github-actions
- id: check-github-workflows
- id: check-gitlab-ci
- id: check-readthedocs
- id: check-travis
- id: check-jsonschema
name: Check projects
args: [--schemafile, docs/data/projects.schema.json]
files: '^docs/data/projects.yml$'
- id: check-metaschema
files: '^docs/data/projects.schema.json$'
+9 -10
View File
@@ -2,13 +2,12 @@
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
version: 2
mkdocs:
configuration: mkdocs.yml
python:
version: 3.8
install:
- method: pip
path: .
extra_requirements:
- docs
build:
os: ubuntu-22.04
tools:
python: "3.12"
commands:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- NO_COLOR=1 uv run --no-dev --group docs mkdocs build --strict --site-dir $READTHEDOCS_OUTPUT/html
+26 -14
View File
@@ -8,21 +8,29 @@ 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
# docker is outdated in the arm64-graviton2 vm focal image (19.x)
# we need to upgrade to get >= 24.0
addons:
apt:
sources:
- sourceline: 'deb https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable'
packages:
- docker-ce docker-ce-cli containerd.io
- 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,23 +40,25 @@ 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
- 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
allow_failure: True
env: PYTHON=python
install:
- $PYTHON -m pip install -U pip
- $PYTHON -m pip install -e ".[dev]" pytest-custom-exit-code
- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all; fi
- $PYTHON -m pip install -U pip dependency-groups
- $PYTHON -m dependency_groups test | xargs $PYTHON -m pip install -e.
script: |
# travis_wait disable the output while waiting
@@ -56,5 +66,7 @@ script: |
(while true; do echo "travis_keep_alive"; sleep 300; done) &
SPINNER_PID=$!
disown
$PYTHON ./bin/run_tests.py
result=0
$PYTHON ./bin/run_tests.py --num-processes 2 || result=1
kill -9 ${SPINNER_PID}
test ${result} -eq 0
+7 -7
View File
@@ -1,11 +1,11 @@
This is a summary of the Python versions and platforms covered by the different CI platforms:
This is a summary of the host Python versions and platforms covered by the different CI platforms:
| | 3.7 | 3.8 | 3.9 | 3.10 | 3.11 |
|---------|-----------|---------------------------------------|-----------|-----------|----------------|
| Linux | Travis CI | AppVeyor¹ / Azure Pipelines / GitLab¹ | CircleCI¹ | Cirrus CI | GitHub Actions |
| macOS | Travis CI | AppVeyor¹ / Azure Pipelines | CircleCI¹ | Cirrus CI | GitHub Actions |
| Windows | Travis CI | AppVeyor¹ / Azure Pipelines / GitLab¹ | | Cirrus CI | GitHub Actions |
| | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 |
|---------|----------------------------------|-----------|-----------|---------|--------------------------------------------------|
| Linux | Azure Pipelines / GitHub Actions | Travis CI | Cirrus CI | | AppVeyor¹ / CircleCI¹ / GitHub Actions / GitLab¹ |
| macOS | Azure Pipelines | | Cirrus CI | GitLab¹ | AppVeyor¹ /CircleCI¹ / GitHub Actions |
| Windows | Azure Pipelines | Travis CI | Cirrus CI | | AppVeyor¹ / GitHub Actions / GitLab¹ |
> ¹ 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.
+1 -1
View File
@@ -1,6 +1,6 @@
This project is licensed under the 'BSD 2-clause license'.
Copyright (c) 2017-2019, Joe Rickerby and contributors. All rights reserved.
Copyright (c) 2017-2023, Joe Rickerby and contributors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
-6
View File
@@ -1,6 +0,0 @@
recursive-include cibuildwheel *.cfg
recursive-include cibuildwheel *.in
recursive-include cibuildwheel *.py
recursive-include cibuildwheel *.toml
recursive-include cibuildwheel *.txt
recursive-include cibuildwheel *.typed
+107 -92
View File
@@ -2,16 +2,15 @@ cibuildwheel
============
[![PyPI](https://img.shields.io/pypi/v/cibuildwheel.svg)](https://pypi.python.org/pypi/cibuildwheel)
[![Documentation Status](https://readthedocs.org/projects/cibuildwheel/badge/?version=stable)](https://cibuildwheel.readthedocs.io/en/stable/?badge=stable)
[![Documentation Status](https://readthedocs.org/projects/cibuildwheel/badge/?version=stable)](https://cibuildwheel.pypa.io/en/stable/?badge=stable)
[![Actions Status](https://github.com/pypa/cibuildwheel/workflows/Test/badge.svg)](https://github.com/pypa/cibuildwheel/actions)
[![Travis Status](https://img.shields.io/travis/com/pypa/cibuildwheel/main?logo=travis)](https://travis-ci.com/pypa/cibuildwheel)
[![Travis Status](https://img.shields.io/travis/com/pypa/cibuildwheel/main?logo=travis)](https://travis-ci.com/github/pypa/cibuildwheel)
[![Appveyor status](https://ci.appveyor.com/api/projects/status/gt3vwl88yt0y3hur/branch/main?svg=true)](https://ci.appveyor.com/project/joerick/cibuildwheel/branch/main)
[![CircleCI Status](https://img.shields.io/circleci/build/gh/pypa/cibuildwheel/main?logo=circleci)](https://circleci.com/gh/pypa/cibuildwheel)
[![Azure Status](https://dev.azure.com/joerick0429/cibuildwheel/_apis/build/status/pypa.cibuildwheel?branchName=main)](https://dev.azure.com/joerick0429/cibuildwheel/_build/latest?definitionId=4&branchName=main)
[![Cirrus CI Status](https://img.shields.io/cirrus/github/pypa/cibuildwheel/main?logo=cirrusci)](https://cirrus-ci.com/github/pypa/cibuildwheel)
[Documentation](https://cibuildwheel.readthedocs.org)
[Documentation](https://cibuildwheel.pypa.io)
<!--intro-start-->
@@ -23,31 +22,36 @@ Python wheels are great. Building them across **Mac, Linux, Windows**, on **mult
What does it do?
----------------
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x |
|---------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|
| CPython 3.6 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.7 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.8 | ✅ | | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.9 | ✅ | | ✅ | ✅ | ✅² | ✅³ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.11 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.12⁵ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ |
| PyPy 3.7 v7.3 | ✅ | N/A | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
| PyPy 3.9 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A |
While cibuildwheel itself requires a recent Python version to run (we support the last three releases), it can target the following versions to build wheels:
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | Windows Arm64 | manylinux<br/>musllinux x86_64 | manylinux<br/>musllinux i686 | manylinux<br/>musllinux aarch64 | manylinux<br/>musllinux ppc64le | manylinux<br/>musllinux s390x | manylinux<br/>musllinux armv7l | Pyodide |
|----------------|----|-----|-----|-----|-----|----|-----|----|-----|-----|---|-----|
| CPython 3.6 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A |
| CPython 3.7 | ✅ | N/A | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A |
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A |
| CPython 3.9 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A |
| CPython 3.10 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A |
| CPython 3.11 | ✅ | | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A |
| CPython 3.12 | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | ✅⁴ |
| CPython 3.13³ | ✅ | ✅ | ✅ | ✅ | ✅² | ✅ | ✅ | ✅ | ✅ | ✅ | ✅⁵ | N/A |
| PyPy 3.7 v7.3 | ✅ | N/A | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A |
| PyPy 3.8 v7.3 | ✅ | ✅ | ✅ | N/A | 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 | N/A |
| PyPy 3.10 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A |
| PyPy 3.11 v7.3 | ✅ | ✅ | ✅ | N/A | N/A | ✅¹ | ✅¹ | ✅¹ | N/A | N/A | N/A | N/A |
<sup>¹ PyPy is only supported for manylinux wheels.</sup><br>
<sup>² Windows arm64 support is experimental.</sup><br>
<sup>³ Alpine 3.14 and very briefly 3.15's default python3 [was not able to load](https://github.com/pypa/cibuildwheel/issues/934) musllinux wheels. This has been fixed; please upgrade the python package if using Alpine from before the fix.</sup><br>
<sup>⁴ Cross-compilation not supported with PyPy - to build these wheels you need to run cibuildwheel on an Apple Silicon machine.</sup><br>
<sup>⁵ CPython 3.12 is available using the [CIBW_PRERELEASE_PYTHONS](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons) option.</sup><br>
<sup>³ Free-threaded mode requires opt-in using [`CIBW_FREE_THREADED_SUPPORT`](https://cibuildwheel.pypa.io/en/stable/options/#free-threaded-support).</sup><br>
<sup>⁴ Experimental, not yet supported on PyPI, but can be used directly in web deployment. Use `--platform pyodide` to build.</sup><br>
<sup>⁵ manylinux armv7l support is experimental. As there are no RHEL based image for this architecture, it's using an Ubuntu based image instead.</sup><br>
- Builds manylinux, musllinux, macOS 10.9+, and Windows wheels for CPython and PyPy
- Builds manylinux, musllinux, macOS 10.9+ (10.13+ for Python 3.12+), and Windows wheels for CPython and PyPy
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, GitLab CI, and Cirrus CI
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
- Runs your library's tests against the wheel-installed version of your library
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) if you need to build unsupported versions of Python, such as Python 2.
See the [cibuildwheel 1 documentation](https://cibuildwheel.pypa.io/en/1.x/) if you need to build unsupported versions of Python, such as Python 2.
Usage
-----
@@ -56,18 +60,16 @@ Usage
| | Linux | macOS | Windows | Linux ARM | macOS ARM | Windows ARM |
|-----------------|-------|-------|---------|-----------|-----------|-------------|
| GitHub Actions | ✅ | ✅ | ✅ | ✅¹ | ✅² | ✅ |
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅² | ✅ |
| GitHub Actions | ✅ | ✅ | ✅ | ✅ | ✅ | ✅² |
| Azure Pipelines | ✅ | ✅ | ✅ | | ✅ | ✅² |
| Travis CI | ✅ | | ✅ | ✅ | | |
| AppVeyor | ✅ | ✅ | ✅ | | ✅² | ✅ |
| CircleCI | ✅ | ✅ | | ✅ | ✅² | |
| Gitlab CI | ✅ | | ✅ | ✅¹ | | |
| Cirrus CI | ✅ | ✅³ | ✅ | ✅ | ✅ | |
| AppVeyor | ✅ | ✅ | ✅ | | ✅ | ✅² |
| CircleCI | ✅ | ✅ | | ✅ | ✅ | |
| Gitlab CI | ✅ | | ✅ | ✅¹ | | |
| Cirrus CI | ✅ | ✅ | ✅ | ✅ | ✅ | |
<sup>¹ [Requires emulation](https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation), distributed separately. Other services may also support Linux ARM through emulation or third-party build hosts, but these are not tested in our CI.</sup><br>
<sup>² [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). It is not possible to test `arm64` and the `arm64` part of a `universal2` wheel on this CI platform.</sup><br>
<sup>³ [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#universal2). Thanks to Rosetta 2 emulation, it is possible to test `x86_64` and both parts of a `universal2` wheel on this CI platform.</sup><br>
<sup>⁴ [Uses cross-compilation](https://cibuildwheel.readthedocs.io/en/stable/faq/#windows-arm64). It is not possible to test `arm64` on this CI platform.</sup>
<sup>¹ [Requires emulation](https://cibuildwheel.pypa.io/en/stable/faq/#emulation), distributed separately. Other services may also support Linux ARM through emulation or third-party build hosts, but these are not tested in our CI.</sup><br>
<sup>² [Uses cross-compilation](https://cibuildwheel.pypa.io/en/stable/faq/#windows-arm64). It is not possible to test `arm64` on this CI platform.</sup>
<!--intro-end-->
@@ -87,16 +89,16 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macOS-11]
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-latest]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Used to host cibuildwheel
- uses: actions/setup-python@v3
- uses: actions/setup-python@v5
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.13.1
run: python -m pip install cibuildwheel==2.23.2
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
@@ -104,12 +106,13 @@ jobs:
# env:
# CIBW_SOME_OPTION: value
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
```
For more information, including PyPI deployment, and the use of other CI services or the dedicated GitHub Action, check out the [documentation](https://cibuildwheel.readthedocs.org) and the [examples](https://github.com/pypa/cibuildwheel/tree/main/examples).
For more information, including PyPI deployment, and the use of other CI services or the dedicated GitHub Action, check out the [documentation](https://cibuildwheel.pypa.io) and the [examples](https://github.com/pypa/cibuildwheel/tree/main/examples).
How it works
------------
@@ -118,35 +121,35 @@ The following diagram summarises the steps that cibuildwheel takes on each platf
![](docs/data/how-it-works.png)
<sup>Explore an interactive version of this diagram [in the docs](https://cibuildwheel.readthedocs.io/en/stable/#how-it-works).</sup>
<sup>Explore an interactive version of this diagram [in the docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works).</sup>
Options
-------
| | Option | Description |
|---|--------|-------------|
| **Build selection** | [`CIBW_PLATFORM`](https://cibuildwheel.readthedocs.io/en/stable/options/#platform) | Override the auto-detected target platform |
| | [`CIBW_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) <br> [`CIBW_SKIP`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) | Choose the Python versions to build |
| | [`CIBW_ARCHS`](https://cibuildwheel.readthedocs.io/en/stable/options/#archs) | Change the architectures built on your machine by default. |
| | [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.readthedocs.io/en/stable/options/#requires-python) | Manually set the Python compatibility of your project |
| | [`CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons) | Enable building with pre-release versions of Python if available |
| **Build customization** | [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-frontend) | Set the tool to use to build, either "pip" (default for now) or "build" |
| | [`CIBW_ENVIRONMENT`](https://cibuildwheel.readthedocs.io/en/stable/options/#environment) | Set environment variables needed during the build |
| | [`CIBW_ENVIRONMENT_PASS_LINUX`](https://cibuildwheel.readthedocs.io/en/stable/options/#environment-pass) | Set environment variables on the host to pass-through to the container during the build. |
| | [`CIBW_BEFORE_ALL`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. |
| | [`CIBW_BEFORE_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build |
| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each built wheel |
| | [`CIBW_MANYLINUX_*_IMAGE`<br/>`CIBW_MUSLLINUX_*_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image) | Specify alternative manylinux / musllinux Docker images |
| | [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.readthedocs.io/en/stable/options/#container-engine) | Specify which container engine to use when building Linux wheels |
| | [`CIBW_DEPENDENCY_VERSIONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#dependency-versions) | Specify how cibuildwheel controls the versions of the tools it uses |
| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel |
| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel |
| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests |
| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require |
| | [`CIBW_TEST_SKIP`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-skip) | Skip running tests on some builds |
| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel |
| **Build selection** | [`CIBW_PLATFORM`](https://cibuildwheel.pypa.io/en/stable/options/#platform) | Override the auto-detected target platform |
| | [`CIBW_BUILD`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) <br> [`CIBW_SKIP`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) | Choose the Python versions to build |
| | [`CIBW_ARCHS`](https://cibuildwheel.pypa.io/en/stable/options/#archs) | Change the architectures built on your machine by default. |
| | [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.pypa.io/en/stable/options/#requires-python) | Manually set the Python compatibility of your project |
| | [`CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons) | Enable building with pre-release versions of Python if available |
| **Build customization** | [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) | Set the tool to use to build, either "pip" (default for now) or "build" |
| | [`CIBW_ENVIRONMENT`](https://cibuildwheel.pypa.io/en/stable/options/#environment) | Set environment variables needed during the build |
| | [`CIBW_ENVIRONMENT_PASS_LINUX`](https://cibuildwheel.pypa.io/en/stable/options/#environment-pass) | Set environment variables on the host to pass-through to the container during the build. |
| | [`CIBW_BEFORE_ALL`](https://cibuildwheel.pypa.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. |
| | [`CIBW_BEFORE_BUILD`](https://cibuildwheel.pypa.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build |
| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each built wheel |
| | [`CIBW_MANYLINUX_*_IMAGE`<br/>`CIBW_MUSLLINUX_*_IMAGE`](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) | Specify alternative manylinux / musllinux Docker images |
| | [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) | Specify which container engine to use when building Linux wheels |
| | [`CIBW_DEPENDENCY_VERSIONS`](https://cibuildwheel.pypa.io/en/stable/options/#dependency-versions) | Specify how cibuildwheel controls the versions of the tools it uses |
| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.pypa.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel |
| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.pypa.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel |
| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.pypa.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests |
| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.pypa.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require |
| | [`CIBW_TEST_SKIP`](https://cibuildwheel.pypa.io/en/stable/options/#test-skip) | Skip running tests on some builds |
| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.pypa.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel |
These options can be specified in a pyproject.toml file, as well; see [configuration](https://cibuildwheel.readthedocs.io/en/stable/options/#configuration).
These options can be specified in a pyproject.toml file, as well; see [configuration](https://cibuildwheel.pypa.io/en/stable/options/#configuration).
Working examples
----------------
@@ -162,24 +165,24 @@ Here are some repos that use cibuildwheel.
| [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. |
| [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][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
| [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. |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
| [MemRay][] | ![github icon][] | ![linux icon][] | Memray is a memory profiler for Python |
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
[pytorch-fairseq]: https://github.com/pytorch/fairseq
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy
[duckdb]: https://github.com/duckdb/duckdb
[Tornado]: https://github.com/tornadoweb/tornado
[Matplotlib]: https://github.com/matplotlib/matplotlib
[NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib
[Prophet]: https://github.com/facebook/prophet
[Kivy]: https://github.com/kivy/kivy
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
[MemRay]: https://github.com/bloomberg/memray
[Kivy]: https://github.com/kivy/kivy
[appveyor icon]: docs/data/readme_icons/appveyor.svg
[github icon]: docs/data/readme_icons/github.svg
@@ -194,7 +197,7 @@ Here are some repos that use cibuildwheel.
<!-- END bin/projects.py -->
> ️ That's just a handful, there are many more! Check out the [Working Examples](https://cibuildwheel.readthedocs.io/en/stable/working-examples) page in the docs.
> ️ That's just a handful, there are many more! Check out the [Working Examples](https://cibuildwheel.pypa.io/en/stable/working-examples) page in the docs.
Legal note
----------
@@ -212,42 +215,54 @@ Changelog
<!-- this section was generated by bin/update_readme_changelog.py -- do not edit manually -->
### v2.13.1
### v2.23.2
_10 June 2023_
_24 March 2025_
- 🛠 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)
- 🐛 Workaround an issue with pyodide builds when running cibuildwheel with a Python that was installed via UV (#2328 via #2331)
- 🛠 Dependency updates, including a manylinux update that fixes an ['undefined symbol' error](https://github.com/pypa/manylinux/issues/1760) in gcc-toolset (#2334)
### v2.13.0
### v2.23.1
_28 May 2023_
_15 March 2025_
- 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.
- ⚠️ Added warnings when the shorthand values `manylinux1`, `manylinux2010`, `manylinux_2_24`, and `musllinux_1_1` are used to specify the images in linux builds. The shorthand to these (unmaintainted) images will be removed in v3.0. If you want to keep using these images, explicitly opt-in using the full image URL, which can be found in [this file](https://github.com/pypa/cibuildwheel/blob/v2.23.1/cibuildwheel/resources/pinned_docker_images.cfg). (#2312)
- 🛠 Dependency updates, including a manylinux update which fixes an [issue with rustup](https://github.com/pypa/cibuildwheel/issues/2303). (#2315)
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)
### v2.23.0
- ✨ 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)
_1 March 2025_
### v2.12.3
- ✨ Adds official support for the new GitHub Actions Arm runners. In fact these worked out-of-the-box, now we include them in our tests and example configs. (#2135 via #2281)
- ✨ Adds support for building PyPy 3.11 wheels (#2268 via #2281)
- 🛠 Adopts the beta pypa/manylinux image for armv7l builds (#2269 via #2281)
- 🛠 Dependency updates, including Pyodide 0.27 (#2117 and #2281)
_19 April 2023_
### v2.22.0
- 🐛 Fix an import error when running on Python 3.7. (#1479)
_23 November 2024_
### v2.12.2
- 🌟 Added a new `CIBW_ENABLE`/`enable` feature that replaces `CIBW_FREETHREADED_SUPPORT`/`free-threaded-support` and `CIBW_PRERELEASE_PYTHONS` with a system that supports both. In cibuildwheel 3, this will also include a PyPy setting and the deprecated options will be removed. (#2048)
- 🌟 [Dependency groups](https://peps.python.org/pep-0735/) are now supported for tests. Use `CIBW_TEST_GROUPS`/`test-groups` to specify groups in `[dependency-groups]` for testing. (#2063)
- 🌟 Support for the experimental Ubuntu-based ARMv7l manylinux image (#2052)
- ✨ Show a warning when cibuildwheel is run from Python 3.10 or older; cibuildwheel 3.0 will require Python 3.11 or newer as host (#2050)
- 🐛 Fix issue with stderr interfering with checking the docker version (#2074)
- 🛠 Python 3.9 is now used in `CIBW_BEFORE_ALL`/`before-all` on linux, replacing 3.8, which is now EoL (#2043)
- 🛠 Error messages for producing a pure-Python wheel are slightly more informative (#2044)
- 🛠 Better error when `uname -m` fails on ARM (#2049)
- 🛠 Better error when repair fails and docs for abi3audit on Windows (#2058)
- 🛠 Better error when `manylinux-interpreters ensure` fails (#2066)
- 🛠 Update Pyodide to 0.26.4, and adapt to the unbundled pyodide-build (now 0.29) (#2090)
- 🛠 Now cibuildwheel uses dependency-groups for development dependencies (#2064, #2085)
- 📚 Docs updates and tidy ups (#2061, #2067, #2072)
_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.21.3
### v2.12.1
_9 October 2024_
_11 March 2023_
- 🐛 Fix a bug that prevented the use of CIBW_CONFIG_SETTINGS with the 'pip' build backend. (#1430)
- 🛠 Update CPython 3.13 to 3.13.0 final release (#2032)
- 📚 Docs updates and tidy ups (#2035)
<!-- END bin/update_readme_changelog.py -->
@@ -255,14 +270,14 @@ _11 March 2023_
That's the last few versions.
️ **Want more changelog? Head over to [the changelog page in the docs](https://cibuildwheel.readthedocs.io/en/stable/changelog/).**
️ **Want more changelog? Head over to [the changelog page in the docs](https://cibuildwheel.pypa.io/en/stable/changelog/).**
---
Contributing
============
For more info on how to contribute to cibuildwheel, see the [docs](https://cibuildwheel.readthedocs.io/en/latest/contributing/).
For more info on how to contribute to cibuildwheel, see the [docs](https://cibuildwheel.pypa.io/en/latest/contributing/).
Everyone interacting with the cibuildwheel project via codebase, issue tracker, chat rooms, or otherwise is expected to follow the [PSF Code of Conduct](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md).
@@ -297,4 +312,4 @@ See also
Another very similar tool to consider is [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild). `multibuild` is a shell script toolbox for building a wheel on various platforms. It is used as a basis to build some of the big data science tools, like SciPy.
If you are building Rust wheels, you can get by without some of the tricks required to make GLIBC work via manylinux; this is especially relevant for cross-compiling, which is easy with Rust. See [maturin-action](https://github.com/messense/maturin-action) for a tool that is optimized for building Rust wheels and cross-compiling.
If you are building Rust wheels, you can get by without some of the tricks required to make GLIBC work via manylinux; this is especially relevant for cross-compiling, which is easy with Rust. See [maturin-action](https://github.com/PyO3/maturin-action) for a tool that is optimized for building Rust wheels and cross-compiling.
+50 -17
View File
@@ -24,36 +24,69 @@ branding:
runs:
using: composite
steps:
# Set up a non-EOL, cibuildwheel & pipx supported Python version
- uses: actions/setup-python@v4
# Set up the version of Python that supports pyodide
- uses: actions/setup-python@v5
id: python
with:
python-version: "3.7 - 3.11"
python-version: "3.12"
update-environment: false
- id: cibw
run: |
# Install cibuildwheel
"${{ steps.python.outputs.python-path }}" -u << "EOF"
import os
import shutil
import sys
import venv
from pathlib import Path
from subprocess import run
class EnvBuilder(venv.EnvBuilder):
def __init__(self):
super().__init__()
def setup_scripts(self, context):
pass
def post_setup(self, context):
super().post_setup(context)
self.bin_path = Path(context.env_exe).parent
run([sys.executable, "-m", "pip", "--python", context.env_exe, "install", r"${{ github.action_path }}"], check=True)
print("::group::Install cibuildwheel")
venv_path = Path(r"${{ runner.temp }}") / "cibw"
if venv_path.exists():
shutil.rmtree(venv_path)
builder = EnvBuilder()
builder.create(venv_path)
cibw_path = [path for path in builder.bin_path.glob("cibuildwheel*") if path.stem == "cibuildwheel"][0]
with open(os.environ["GITHUB_OUTPUT"], "at") as f:
f.write(f"cibw-path={cibw_path}\n")
print("::endgroup::")
EOF
shell: bash
# Redirecting stderr to stdout to fix interleaving issue in Actions.
- run: >
pipx run
--python '${{ steps.python.outputs.python-path }}'
--spec '${{ github.action_path }}'
cibuildwheel
"${{ steps.cibw.outputs.cibw-path }}"
"${{ inputs.package-dir }}"
--output-dir "${{ inputs.output-dir }}"
--config-file "${{ inputs.config-file }}"
--only "${{ inputs.only }}"
${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}}
${{ inputs.config-file != '' && format('--config-file "{0}"', inputs.config-file) || ''}}
${{ inputs.only != '' && format('--only "{0}"', inputs.only) || ''}}
2>&1
shell: bash
if: runner.os != 'Windows'
# Windows needs powershell to interact nicely with Meson
- run: >
pipx run
--python "${{ steps.python.outputs.python-path }}"
--spec "${{ github.action_path }}"
cibuildwheel
& "${{ steps.cibw.outputs.cibw-path }}"
"${{ inputs.package-dir }}"
--output-dir '"${{ inputs.output-dir }}"'
--config-file '"${{ inputs.config-file }}"'
--only '"${{ inputs.only }}"'
${{ inputs.output-dir != '' && format('--output-dir "{0}"', inputs.output-dir) || ''}}
${{ inputs.config-file != '' && format('--config-file "{0}"', inputs.config-file) || ''}}
${{ inputs.only != '' && format('--only "{0}"', inputs.only) || ''}}
shell: pwsh
if: runner.os == 'Windows'
+14 -11
View File
@@ -1,26 +1,29 @@
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu
APPVEYOR_JOB_NAME: "python38-x64-ubuntu"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
APPVEYOR_JOB_NAME: "python38-x64-vs2015"
- APPVEYOR_BUILD_WORKER_IMAGE: macos
APPVEYOR_JOB_NAME: "python38-x64-macos"
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204
APPVEYOR_JOB_NAME: "python312-x64-ubuntu"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: "python312-x64-vs2022"
- APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
APPVEYOR_JOB_NAME: "python312-x64-macos"
stack: python 3.8
stack: python 3.12
build: off
init:
- 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-'))) {
$env:PYTEST_ADDOPTS='-k "unit_test or test_0_basic" --suppress-no-test-exit-code'
$env:PYTEST_ADDOPTS = '-k "unit_test or test_0_basic" --suppress-no-test-exit-code'
}
if ($IsLinux) {
docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
}
python -m pip install -U pip
install: python -m pip install -e ".[dev]" pytest-custom-exit-code
install:
- python -m pip install -U pip
- python -m pip install -e ".[dev]" pytest-custom-exit-code
# the '-u' flag is required so the output is in the correct order.
# See https://github.com/pypa/cibuildwheel/pull/24 for more info.
+15 -5
View File
@@ -1,3 +1,9 @@
pr:
paths:
exclude:
- docs/*
- .pre-commit-config.yaml
jobs:
- job: linux_38
timeoutInMinutes: 120
@@ -7,18 +13,21 @@ jobs:
inputs:
versionSpec: '3.8'
- bash: |
python -m pip install -e ".[dev]"
docker run --rm --privileged docker.io/tonistiigi/binfmt:latest --install all
python -m pip install dependency-groups
python -m dependency_groups test | xargs python -m pip install -e.
python ./bin/run_tests.py
- job: macos_38
pool: {vmImage: 'macOS-11'}
pool: {vmImage: 'macOS-13'}
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.8'
- bash: |
python -m pip install -e ".[dev]"
python ./bin/run_tests.py
python -m pip install dependency-groups
python -m dependency_groups test | xargs python -m pip install -e.
python ./bin/run_tests.py --num-processes 2
- job: windows_38
pool: {vmImage: 'windows-2019'}
@@ -28,5 +37,6 @@ jobs:
inputs:
versionSpec: '3.8'
- bash: |
python -m pip install -e ".[dev]"
python -m pip install dependency-groups
python -m dependency_groups test | xargs python -m pip install -e.
python ./bin/run_tests.py
+15 -6
View File
@@ -1,5 +1,9 @@
#!/usr/bin/env python3
# /// script
# dependencies = ["click", "packaging", "tomli; python_version<'3.11'"]
# ///
from __future__ import annotations
@@ -13,10 +17,14 @@ from pathlib import Path
import click
from packaging.version import InvalidVersion, Version
import cibuildwheel
if sys.version_info < (3, 11):
import tomli as tomllib
else:
import tomllib
config = [
# file path, version find/replace format
("pyproject.toml", 'version = "{}"'),
("README.md", "cibuildwheel=={}"),
("cibuildwheel/__init__.py", '__version__ = "{}"'),
("docs/faq.md", "cibuildwheel=={}"),
@@ -24,7 +32,6 @@ config = [
("docs/setup.md", "cibuildwheel=={}"),
("examples/*", "cibuildwheel=={}"),
("examples/*", "cibuildwheel@v{}"),
("setup.cfg", "version = {}"),
]
RED = "\u001b[31m"
@@ -34,7 +41,8 @@ OFF = "\u001b[0m"
@click.command()
def bump_version() -> None:
current_version = cibuildwheel.__version__
with open("pyproject.toml", "rb") as f:
current_version = tomllib.load(f)["project"]["version"]
try:
commit_date_str = subprocess.run(
@@ -60,7 +68,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:
@@ -142,7 +150,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
@@ -180,7 +189,7 @@ def bump_version() -> None:
print()
print("Push the new version to GitHub with:")
print(" git push && git push --tags")
print(f" git push && git push origin v{new_version}")
print()
release_url = "https://github.com/pypa/cibuildwheel/releases/new?" + urllib.parse.urlencode(
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
CIBW_PLATFORM=linux pytest "$@"
+333
View File
@@ -0,0 +1,333 @@
#!/usr/bin/env python
# /// script
# dependencies = ["pyyaml"]
# ///
import argparse
import copy
import json
from typing import Any
import yaml
parser = argparse.ArgumentParser()
parser.add_argument("--schemastore", action="store_true", help="Generate schema_store version")
args = parser.parse_args()
starter = """
$schema: http://json-schema.org/draft-07/schema
$id: https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/resources/cibuildwheel.schema.json
$defs:
inherit:
enum:
- none
- prepend
- append
default: none
description: How to inherit the parent's value.
enable:
enum:
- cpython-freethreading
- cpython-prerelease
- pypy
description: A Python version or flavor to enable.
additionalProperties: false
description: cibuildwheel's settings.
type: object
properties:
archs:
description: Change the architectures built on your machine by default.
type: string_array
before-all:
description: Execute a shell command on the build system before any wheels are built.
type: string_array
before-build:
description: Execute a shell command preparing each wheel's build.
type: string_array
before-test:
description: Execute a shell command before testing each wheel.
type: string_array
build:
default: ['*']
description: Choose the Python versions to build.
type: string_array
build-frontend:
default: default
description: Set the tool to use to build, either "pip" (default for now), "build", or "build[uv]"
oneOf:
- enum: [pip, build, "build[uv]", default]
- type: string
pattern: '^pip; ?args:'
- type: string
pattern: '^build; ?args:'
- type: string
pattern: '^build\\[uv\\]; ?args:'
- type: object
additionalProperties: false
required: [name]
properties:
name:
enum: [pip, build, "build[uv]"]
args:
type: array
items:
type: string
build-verbosity:
type: integer
minimum: -3
maximum: 3
default: 0
description: Increase/decrease the output of pip wheel.
config-settings:
description: Specify config-settings for the build backend.
type: string_table_array
container-engine:
oneOf:
- enum: [docker, podman]
- type: string
pattern: '^docker; ?(create_args|disable_host_mount):'
- type: string
pattern: '^podman; ?(create_args|disable_host_mount):'
- type: object
additionalProperties: false
required: [name]
properties:
name:
enum: [docker, podman]
create-args:
type: array
items:
type: string
disable-host-mount:
type: boolean
dependency-versions:
default: pinned
description: Specify how cibuildwheel controls the versions of the tools it uses
type: string
enable:
description: Enable or disable certain builds.
oneOf:
- $ref: "#/$defs/enable"
- type: array
items:
$ref: "#/$defs/enable"
environment:
description: Set environment variables needed during the build.
type: string_table
environment-pass:
description: Set environment variables on the host to pass-through to the container
during the build.
type: string_array
free-threaded-support:
type: boolean
default: false
description: The project supports free-threaded builds of Python (PEP703)
deprecated: Use the `enable` option instead.
manylinux-aarch64-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-armv7l-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-i686-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-ppc64le-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-pypy_aarch64-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-pypy_i686-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-pypy_x86_64-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-s390x-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-x86_64-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-aarch64-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-armv7l-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-i686-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-ppc64le-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-s390x-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-x86_64-image:
type: string
description: Specify alternative manylinux / musllinux container images
repair-wheel-command:
type: string_array
description: Execute a shell command to repair each built wheel.
skip:
description: Choose the Python versions to skip.
type: string_array
test-command:
description: Execute a shell command to test each built wheel.
type: string_array
test-extras:
description: Install your wheel for testing using `extras_require`
type: string_array
test-groups:
description: Install extra groups when testing
type: string_array
test-requires:
description: Install Python dependencies before running the tests
type: string_array
test-skip:
description: Skip running tests on some builds.
type: string_array
"""
schema = yaml.safe_load(starter)
string_array = yaml.safe_load(
"""
- type: string
- type: array
items:
type: string
"""
)
string_table_array = yaml.safe_load(
"""
- type: string
- type: object
additionalProperties: false
patternProperties:
.+:
oneOf:
- type: string
- type: array
items:
type: string
"""
)
string_table = yaml.safe_load(
"""
- type: string
- type: object
additionalProperties: false
patternProperties:
.+:
type: string
"""
)
for value in schema["properties"].values():
match value:
case {"type": "string_array"}:
del value["type"]
value["oneOf"] = string_array
case {"type": "string_table"}:
del value["type"]
value["oneOf"] = string_table
case {"type": "string_table_array"}:
del value["type"]
value["oneOf"] = string_table_array
overrides = yaml.safe_load(
"""
type: array
description: An overrides array
items:
type: object
required: ["select"]
minProperties: 2
additionalProperties: false
properties:
select: {}
inherit:
type: object
additionalProperties: false
properties:
before-all: {"$ref": "#/$defs/inherit"}
before-build: {"$ref": "#/$defs/inherit"}
before-test: {"$ref": "#/$defs/inherit"}
config-settings: {"$ref": "#/$defs/inherit"}
container-engine: {"$ref": "#/$defs/inherit"}
environment: {"$ref": "#/$defs/inherit"}
environment-pass: {"$ref": "#/$defs/inherit"}
repair-wheel-command: {"$ref": "#/$defs/inherit"}
test-command: {"$ref": "#/$defs/inherit"}
test-extras: {"$ref": "#/$defs/inherit"}
test-requires: {"$ref": "#/$defs/inherit"}
"""
)
for key, value in schema["properties"].items():
value["title"] = f'CIBW_{key.replace("-", "_").upper()}'
non_global_options = {k: {"$ref": f"#/properties/{k}"} for k in schema["properties"]}
del non_global_options["build"]
del non_global_options["skip"]
del non_global_options["test-skip"]
del non_global_options["free-threaded-support"]
del non_global_options["enable"]
overrides["items"]["properties"]["select"]["oneOf"] = string_array
overrides["items"]["properties"] |= non_global_options.copy()
del overrides["items"]["properties"]["archs"]
not_linux = non_global_options.copy()
del not_linux["environment-pass"]
del not_linux["container-engine"]
for key in list(not_linux):
if "linux-" in key:
del not_linux[key]
def as_object(d: dict[str, Any]) -> dict[str, Any]:
return {
"type": "object",
"additionalProperties": False,
"properties": copy.deepcopy(d),
}
oses = {
"linux": as_object(non_global_options),
"windows": as_object(not_linux),
"macos": as_object(not_linux),
"pyodide": as_object(not_linux),
}
oses["linux"]["properties"]["repair-wheel-command"] = {
**schema["properties"]["repair-wheel-command"],
"default": "auditwheel repair -w {dest_dir} {wheel}",
}
oses["macos"]["properties"]["repair-wheel-command"] = {
**schema["properties"]["repair-wheel-command"],
"default": "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}",
}
del oses["linux"]["properties"]["dependency-versions"]
schema["properties"]["overrides"] = overrides
schema["properties"] |= oses
if args.schemastore:
schema["$id"] = "https://json.schemastore.org/partial-cibuildwheel.json"
schema["$schema"] = "http://json-schema.org/draft-07/schema#"
schema["description"] = (
"cibuildwheel's toml file, generated with ./bin/generate_schema.py --schemastore from cibuildwheel."
)
print(json.dumps(schema, indent=2))
-1
View File
@@ -11,7 +11,6 @@ This will cache the results to all_known_setup.yaml; you can reprint
the results without the `--online` setting.
"""
from __future__ import annotations
import ast
+11 -9
View File
@@ -3,27 +3,29 @@
from __future__ import annotations
import os
import subprocess
import sys
import textwrap
import time
from pathlib import Path
from subprocess import run
import click
def shell(cmd, **kwargs):
return run([cmd], shell=True, **kwargs)
def shell(cmd: str, *, check: bool, **kwargs: object) -> subprocess.CompletedProcess[str]:
return subprocess.run([cmd], shell=True, check=check, **kwargs) # type: ignore[call-overload, no-any-return]
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
def git_repo_has_changes() -> bool:
unstaged_changes: bool = shell("git diff-index --quiet HEAD --", check=False).returncode != 0
staged_changes: bool = (
shell("git diff-index --quiet --cached HEAD --", check=False).returncode != 0
)
return unstaged_changes or staged_changes
@click.command()
def main():
def main() -> None:
project_root = Path(__file__).parent / ".."
os.chdir(project_root)
@@ -57,7 +59,7 @@ def main():
PR generated by `{os.path.basename(__file__)}`.
"""
)
run(
subprocess.run(
[
"gh",
"pr",
@@ -73,7 +75,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)
+12 -2
View File
@@ -1,5 +1,13 @@
#!/usr/bin/env python3
# /// script
# dependencies = [
# "click",
# "pyyaml",
# "pygithub",
# ]
# ///
"""
Convert a yaml project list into a nice table.
@@ -164,7 +172,9 @@ def get_projects(
return sorted((Project(item, github) for item in config), reverse=online)
def render_projects(projects: Sequence[Project], *, dest_path: Path, include_info: bool = True):
def render_projects(
projects: Sequence[Project], *, dest_path: Path, include_info: bool = True
) -> str:
io = StringIO()
print = functools.partial(builtins.print, file=io)
@@ -195,7 +205,7 @@ def insert_projects_table(
projects: Sequence[Project],
input_filename: str,
include_info: bool = True,
):
) -> None:
text = file.read_text()
projects_table = render_projects(projects, include_info=include_info, dest_path=file)
+18 -13
View File
@@ -4,29 +4,29 @@ from __future__ import annotations
import os
import shutil
import subprocess
import sys
import textwrap
import time
from collections import namedtuple
import typing
from glob import glob
from pathlib import Path
from subprocess import run
from urllib.parse import quote
import click
def shell(cmd, **kwargs):
return run([cmd], shell=True, **kwargs)
def shell(cmd: str, *, check: bool, **kwargs: object) -> subprocess.CompletedProcess[str]:
return subprocess.run([cmd], shell=True, check=check, **kwargs) # type: ignore[call-overload, no-any-return]
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
def git_repo_has_changes() -> bool:
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
def generate_basic_project(path):
def generate_basic_project(path: Path) -> None:
sys.path.insert(0, "")
from test.test_projects.c import new_c_project
@@ -34,7 +34,12 @@ def generate_basic_project(path):
project.generate(path)
CIService = namedtuple("CIService", "name dst_config_path badge_md")
class CIService(typing.NamedTuple):
name: str
dst_config_path: str
badge_md: str
services = [
CIService(
name="appveyor",
@@ -74,7 +79,7 @@ services = [
]
def ci_service_for_config_file(config_file):
def ci_service_for_config_file(config_file: str) -> CIService:
filename = Path(config_file).name
try:
@@ -129,7 +134,7 @@ def run_example_ci_configs(config_files=None):
dst_config_file.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(src_config_file, dst_config_file)
run(["git", "add", example_project], check=True)
subprocess.run(["git", "add", example_project], check=True)
message = textwrap.dedent(
f"""\
Test example minimal configs
@@ -139,7 +144,7 @@ def run_example_ci_configs(config_files=None):
Time: {timestamp}
"""
)
run(["git", "commit", "--no-verify", "--message", message], check=True)
subprocess.run(["git", "commit", "--no-verify", "--message", message], check=True)
shell(f"git subtree --prefix={example_project} push origin {branch_name}", check=True)
print("---")
@@ -163,7 +168,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)
+9 -2
View File
@@ -9,10 +9,17 @@ import sys
from pathlib import Path
if __name__ == "__main__":
default_cpu_count = os.cpu_count() or 2
parser = argparse.ArgumentParser()
parser.add_argument(
"--run-podman", action="store_true", default=False, help="run podman tests (linux only)"
)
parser.add_argument(
"--num-processes",
action="store",
default=default_cpu_count,
help="number of processes to use for testing",
)
args = parser.parse_args()
# move cwd to the project root
@@ -21,7 +28,7 @@ if __name__ == "__main__":
# unit tests
unit_test_args = [sys.executable, "-m", "pytest", "unit_test"]
if sys.platform.startswith("linux"):
if sys.platform.startswith("linux") and os.environ.get("CIBW_PLATFORM", "linux") == "linux":
# run the docker unit tests only on Linux
unit_test_args += ["--run-docker"]
@@ -35,7 +42,7 @@ if __name__ == "__main__":
sys.executable,
"-m",
"pytest",
"--numprocesses=2",
f"--numprocesses={args.num_processes}",
"-x",
"--durations",
"0",
+5 -1
View File
@@ -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
)
+25
View File
@@ -6,6 +6,7 @@ from dataclasses import dataclass
from pathlib import Path
import requests
from packaging.version import Version
DIR = Path(__file__).parent.resolve()
RESOURCES = DIR.parent / "cibuildwheel/resources"
@@ -53,12 +54,21 @@ images = [
Image("manylinux_2_28", "s390x", "quay.io/pypa/manylinux_2_28_s390x", None),
Image("manylinux_2_28", "pypy_x86_64", "quay.io/pypa/manylinux_2_28_x86_64", None),
Image("manylinux_2_28", "pypy_aarch64", "quay.io/pypa/manylinux_2_28_aarch64", None),
# manylinux_2_31 images
Image("manylinux_2_31", "armv7l", "quay.io/pypa/manylinux_2_31_armv7l", None),
# musllinux_1_1 images
Image("musllinux_1_1", "x86_64", "quay.io/pypa/musllinux_1_1_x86_64", None),
Image("musllinux_1_1", "i686", "quay.io/pypa/musllinux_1_1_i686", None),
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),
Image("musllinux_1_2", "armv7l", "quay.io/pypa/musllinux_1_2_armv7l", None),
]
config = configparser.ConfigParser()
@@ -84,6 +94,21 @@ for image in images:
for (name, info) in tags_dict.items()
if info["manifest_digest"] == latest_tag["manifest_digest"]
)
elif image.image_name.startswith("ghcr.io/"):
repository = image.image_name[8:]
response = requests.get(
"https://ghcr.io/token", params={"scope": f"repository:{repository}:pull"}
)
response.raise_for_status()
token = response.json()["token"]
response = requests.get(
f"https://ghcr.io/v2/{repository}/tags/list",
headers={"Authorization": f"Bearer {token}"},
)
response.raise_for_status()
ghcr_tags = [(Version(tag), tag) for tag in response.json()["tags"] if tag != "latest"]
ghcr_tags.sort(reverse=True)
tag_name = ghcr_tags[0][1]
else:
response = requests.get(f"https://hub.docker.com/v2/repositories/{image.image_name}/tags")
response.raise_for_status()
+3 -3
View File
@@ -7,7 +7,7 @@ import sys
from pathlib import Path
try:
from html2image import Html2Image # type: ignore[import]
from html2image import Html2Image # type: ignore[import-not-found]
except ImportError:
sys.exit(
"""
@@ -18,8 +18,8 @@ except ImportError:
)
def main():
subprocess.run(["mkdocs", "build"])
def main() -> None:
subprocess.run(["mkdocs", "build"], check=True)
hti = Html2Image(custom_flags=["--force-device-scale-factor=2"])
+148
View File
@@ -0,0 +1,148 @@
#!/usr/bin/env python3
from __future__ import annotations
import difflib
import logging
from dataclasses import dataclass
from pathlib import Path
from typing import Final
import click
import packaging.specifiers
import requests
import rich
from packaging.version import InvalidVersion, Version
from rich.logging import RichHandler
from rich.syntax import Syntax
from cibuildwheel._compat import tomllib
log = logging.getLogger("cibw")
# Looking up the dir instead of using utils.resources_dir
# since we want to write to it.
DIR: Final[Path] = Path(__file__).parent.parent.resolve()
RESOURCES_DIR: Final[Path] = DIR / "cibuildwheel/resources"
NODEJS_DIST: Final[str] = "https://nodejs.org/dist/"
NODEJS_INDEX: Final[str] = f"{NODEJS_DIST}index.json"
@dataclass(frozen=True, order=True)
class VersionTuple:
version: Version
version_string: str
def parse_nodejs_index() -> list[VersionTuple]:
versions: list[VersionTuple] = []
response = requests.get(NODEJS_INDEX)
response.raise_for_status()
versions_info = response.json()
for version_info in versions_info:
version_string = version_info.get("version", "???")
if not version_info.get("lts", False):
log.debug("Ignoring non LTS release %r", version_string)
continue
if "linux-x64" not in version_info.get("files", []):
log.warning(
"Ignoring release %r which does not include a linux-x64 binary", version_string
)
continue
try:
version = Version(version_string)
if version.is_devrelease:
log.info("Ignoring development release %r", str(version))
continue
if version.is_prerelease:
log.info("Ignoring pre-release %r", str(version))
continue
versions.append(VersionTuple(version, version_string))
except InvalidVersion:
log.warning("Ignoring release %r", version_string)
versions.sort(reverse=True)
return versions
@click.command()
@click.option("--force", is_flag=True)
@click.option(
"--level", default="INFO", type=click.Choice(["WARNING", "INFO", "DEBUG"], case_sensitive=False)
)
def update_nodejs(force: bool, level: str) -> None:
logging.basicConfig(
level="INFO",
format="%(message)s",
datefmt="[%X]",
handlers=[RichHandler(rich_tracebacks=True, markup=True)],
)
log.setLevel(level)
toml_file_path = RESOURCES_DIR / "nodejs.toml"
original_toml = toml_file_path.read_text()
with toml_file_path.open("rb") as f:
nodejs_data = tomllib.load(f)
nodejs_data.pop("url")
major_versions = [VersionTuple(Version(key), key) for key in nodejs_data]
major_versions.sort(reverse=True)
versions = parse_nodejs_index()
# update existing versions, 1 per LTS
for major_version in major_versions:
current = Version(nodejs_data[major_version.version_string])
specifier = packaging.specifiers.SpecifierSet(
specifiers=f"=={major_version.version.major}.*"
)
for version in versions:
if specifier.contains(version.version) and version.version > current:
nodejs_data[major_version.version_string] = version.version_string
break
# check for a new major LTS to insert
if versions and versions[0].version.major > major_versions[0].version.major:
major_versions.insert(
0,
VersionTuple(Version(str(versions[0].version.major)), f"v{versions[0].version.major}"),
)
nodejs_data[major_versions[0].version_string] = versions[0].version_string
versions_toml = "\n".join(
f'{major_version.version_string} = "{nodejs_data[major_version.version_string]}"'
for major_version in major_versions
)
result_toml = f'url = "{NODEJS_DIST}"\n{versions_toml}\n'
rich.print() # spacer
if original_toml == result_toml:
rich.print("[green]Check complete, nodejs version unchanged.")
return
rich.print("nodejs version updated.")
rich.print("Changes:")
rich.print()
toml_relpath = toml_file_path.relative_to(DIR).as_posix()
diff_lines = difflib.unified_diff(
original_toml.splitlines(keepends=True),
result_toml.splitlines(keepends=True),
fromfile=toml_relpath,
tofile=toml_relpath,
)
rich.print(Syntax("".join(diff_lines), "diff", theme="ansi_light"))
rich.print()
if force:
toml_file_path.write_text(result_toml)
rich.print("[green]TOML file updated.")
else:
rich.print("[yellow]File left unchanged. Use --force flag to update.")
if __name__ == "__main__":
update_nodejs()
+26 -16
View File
@@ -7,7 +7,7 @@ import difflib
import logging
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
@@ -18,7 +18,6 @@ from rich.logging import RichHandler
from rich.syntax import Syntax
from cibuildwheel._compat import tomllib
from cibuildwheel._compat.typing import Final, Literal, TypedDict
from cibuildwheel.extra import dump_python_configurations
log = logging.getLogger("cibw")
@@ -59,7 +58,7 @@ AnyConfig = Union[ConfigWinCP, ConfigWinPP, ConfigMacOS]
class WindowsVersions:
def __init__(self, arch_str: ArchStr) -> None:
def __init__(self, arch_str: ArchStr, free_threaded: bool) -> None:
response = requests.get("https://api.nuget.org/v3/index.json")
response.raise_for_status()
api_info = response.json()
@@ -73,7 +72,11 @@ class WindowsVersions:
self.arch_str = arch_str
self.arch = ARCH_DICT[arch_str]
self.free_threaded = free_threaded
package = PACKAGE_DICT[arch_str]
if free_threaded:
package = f"{package}-freethreaded"
response = requests.get(f"{endpoint}{package}/index.json")
response.raise_for_status()
@@ -93,8 +96,9 @@ class WindowsVersions:
if not versions:
return None
flags = "t" if self.free_threaded else ""
version = versions[0]
identifier = f"cp{version.major}{version.minor}-{self.arch}"
identifier = f"cp{version.major}{version.minor}{flags}-{self.arch}"
return ConfigWinCP(
identifier=identifier,
version=self.version_dict[version],
@@ -129,7 +133,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:
@@ -156,7 +160,7 @@ class PyPyVersions:
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}!"
@@ -205,10 +209,8 @@ class CPythonVersions:
unsorted_versions = spec.filter(self.versions_dict)
sorted_versions = sorted(unsorted_versions, reverse=True)
if version <= Version("3.8.9999"):
file_ident = "macosx10.9.pkg"
else:
file_ident = "macos11.pkg"
macver = "x10.9" if version <= Version("3.8.9999") else "11"
file_ident = f"macos{macver}.pkg"
for new_version in sorted_versions:
# Find the first patch version that contains the requested file
@@ -236,9 +238,12 @@ class CPythonVersions:
class AllVersions:
def __init__(self) -> None:
self.windows_32 = WindowsVersions("32")
self.windows_64 = WindowsVersions("64")
self.windows_arm64 = WindowsVersions("ARM64")
self.windows_32 = WindowsVersions("32", False)
self.windows_t_32 = WindowsVersions("32", True)
self.windows_64 = WindowsVersions("64", False)
self.windows_t_64 = WindowsVersions("64", True)
self.windows_arm64 = WindowsVersions("ARM64", False)
self.windows_t_arm64 = WindowsVersions("ARM64", True)
self.windows_pypy_64 = PyPyVersions("64")
self.macos_cpython = CPythonVersions()
@@ -262,14 +267,19 @@ class AllVersions:
config_update = self.macos_pypy.update_version_macos(spec)
elif "macosx_arm64" in identifier:
config_update = self.macos_pypy_arm64.update_version_macos(spec)
elif "win32" in identifier:
if identifier.startswith("cp"):
config_update = self.windows_32.update_version_windows(spec)
elif "t-win32" in identifier and identifier.startswith("cp"):
config_update = self.windows_t_32.update_version_windows(spec)
elif "win32" in identifier and identifier.startswith("cp"):
config_update = self.windows_32.update_version_windows(spec)
elif "t-win_amd64" in identifier and identifier.startswith("cp"):
config_update = self.windows_t_64.update_version_windows(spec)
elif "win_amd64" in identifier:
if identifier.startswith("cp"):
config_update = self.windows_64.update_version_windows(spec)
elif identifier.startswith("pp"):
config_update = self.windows_pypy_64.update_version_windows(spec)
elif "t-win_arm64" in identifier and identifier.startswith("cp"):
config_update = self.windows_t_arm64.update_version_windows(spec)
elif "win_arm64" in identifier and identifier.startswith("cp"):
config_update = self.windows_arm64.update_version_windows(spec)
+1 -1
View File
@@ -20,7 +20,7 @@ README_CHANGELOG_SECTION = re.compile(
)
def main():
def main() -> None:
changelog_text = CHANGELOG_FILE.read_text()
readme_text = README_FILE.read_text()
+15 -14
View File
@@ -7,6 +7,7 @@ import logging
import subprocess
from dataclasses import dataclass
from pathlib import Path
from typing import Final
import click
import rich
@@ -15,7 +16,6 @@ from rich.logging import RichHandler
from rich.syntax import Syntax
from cibuildwheel._compat import tomllib
from cibuildwheel._compat.typing import Final
log = logging.getLogger("cibw")
@@ -25,9 +25,9 @@ DIR: Final[Path] = Path(__file__).parent.parent.resolve()
RESOURCES_DIR: Final[Path] = DIR / "cibuildwheel/resources"
GET_VIRTUALENV_GITHUB: Final[str] = "https://github.com/pypa/get-virtualenv"
GET_VIRTUALENV_URL_TEMPLATE: Final[
str
] = f"{GET_VIRTUALENV_GITHUB}/blob/{{version}}/public/virtualenv.pyz?raw=true"
GET_VIRTUALENV_URL_TEMPLATE: Final[str] = (
f"{GET_VIRTUALENV_GITHUB}/blob/{{version}}/public/virtualenv.pyz?raw=true"
)
@dataclass(frozen=True, order=True)
@@ -36,7 +36,7 @@ class VersionTuple:
version_string: str
def git_ls_remote_versions(url) -> list[VersionTuple]:
def git_ls_remote_versions(url: str) -> list[VersionTuple]:
versions: list[VersionTuple] = []
tags = subprocess.run(
["git", "ls-remote", "--tags", url], check=True, text=True, capture_output=True
@@ -53,10 +53,6 @@ def git_ls_remote_versions(url) -> list[VersionTuple]:
if version.is_prerelease:
log.info("Ignoring pre-release %r", str(version))
continue
# Do not upgrade past 20.22.0 to keep python 3.6 compat
if version >= Version("20.22.0"):
log.info("Ignoring %r which is not compatible with python 3.6", str(version))
continue
versions.append(VersionTuple(version, version_string))
except InvalidVersion:
log.warning("Ignoring ref %r", ref)
@@ -82,15 +78,20 @@ def update_virtualenv(force: bool, level: str) -> None:
original_toml = toml_file_path.read_text()
with toml_file_path.open("rb") as f:
loaded_file = tomllib.load(f)
version = str(loaded_file["version"])
configurations = tomllib.load(f)
default = configurations.pop("default")
version = str(default["version"])
versions = git_ls_remote_versions(GET_VIRTUALENV_GITHUB)
if versions[0].version > Version(version):
version = versions[0].version_string
result_toml = (
f'version = "{version}"\n'
f'url = "{GET_VIRTUALENV_URL_TEMPLATE.format(version=version)}"\n'
configurations["default"] = {
"version": version,
"url": GET_VIRTUALENV_URL_TEMPLATE.format(version=version),
}
result_toml = "".join(
f'{key} = {{ version = "{value["version"]}", url = "{value["url"]}" }}\n'
for key, value in configurations.items()
)
rich.print() # spacer
+1 -1
View File
@@ -1,3 +1,3 @@
from __future__ import annotations
__version__ = "2.13.1"
__version__ = "2.23.2"
+105 -70
View File
@@ -1,22 +1,27 @@
from __future__ import annotations
import argparse
import dataclasses
import os
import shutil
import sys
import tarfile
import textwrap
import traceback
import typing
from collections.abc import Iterable, Sequence, Set
from pathlib import Path
from tempfile import mkdtemp
from typing import Protocol
import cibuildwheel
import cibuildwheel.linux
import cibuildwheel.macos
import cibuildwheel.pyodide
import cibuildwheel.util
import cibuildwheel.windows
from cibuildwheel._compat.typing import Protocol, assert_never
from cibuildwheel import errors
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
@@ -29,10 +34,38 @@ from cibuildwheel.util import (
chdir,
detect_ci_provider,
fix_ansi_codes_for_github_actions,
strtobool,
)
@dataclasses.dataclass
class GlobalOptions:
print_traceback_on_error: bool = True # decides what happens when errors are hit.
def main() -> None:
global_options = GlobalOptions()
try:
main_inner(global_options)
except errors.FatalError as e:
message = e.args[0]
if log.step_active:
log.step_end_with_error(message)
else:
print(f"cibuildwheel: {message}", file=sys.stderr)
if global_options.print_traceback_on_error:
traceback.print_exc(file=sys.stderr)
sys.exit(e.return_code)
def main_inner(global_options: GlobalOptions) -> None:
"""
`main_inner` is the same as `main`, but it raises FatalError exceptions
rather than exiting directly.
"""
parser = argparse.ArgumentParser(
description="Build wheels for all the platforms.",
epilog="""
@@ -44,14 +77,13 @@ def main() -> None:
parser.add_argument(
"--platform",
choices=["auto", "linux", "macos", "windows"],
choices=["auto", "linux", "macos", "windows", "pyodide"],
default=None,
help="""
Platform to build for. Use this option to override the
auto-detected platform or to run cibuildwheel on your development
machine. Specifying "macos" or "windows" only works on that
operating system, but "linux" works on all three, as long as
Docker/Podman is installed. Default: auto.
auto-detected platform. Specifying "macos" or "windows" only works
on that operating system, but "linux" works on all three, as long
as Docker/Podman is installed. Default: auto.
""",
)
@@ -131,8 +163,17 @@ def main() -> None:
help="Enable pre-release Python versions if available.",
)
parser.add_argument(
"--debug-traceback",
action="store_true",
default=strtobool(os.environ.get("CIBW_DEBUG_TRACEBACK", "0")),
help="Print a full traceback for all errors",
)
args = CommandLineArguments(**vars(parser.parse_args()))
global_options.print_traceback_on_error = args.debug_traceback
args.package_dir = args.package_dir.resolve()
# This are always relative to the base directory, even in SDist builds
@@ -159,7 +200,7 @@ def main() -> None:
# This is now the new package dir
args.package_dir = project_dir.resolve()
with chdir(temp_dir):
with chdir(project_dir):
build_in_directory(args)
finally:
# avoid https://github.com/python/cpython/issues/86962 by performing
@@ -176,27 +217,13 @@ def _compute_platform_only(only: str) -> PlatformName:
return "macos"
if "win_" in only or "win32" in only:
return "windows"
print(
f"Invalid --only='{only}', must be a build selector with a known platform",
file=sys.stderr,
)
sys.exit(2)
if "pyodide_" in only:
return "pyodide"
msg = f"Invalid --only='{only}', must be a build selector with a known platform"
raise errors.ConfigurationError(msg)
def _compute_platform_ci() -> PlatformName:
if detect_ci_provider() is None:
print(
textwrap.dedent(
"""
cibuildwheel: Unable to detect platform. cibuildwheel should run on your CI server;
Travis CI, AppVeyor, Azure Pipelines, GitHub Actions, CircleCI, Gitlab, and Cirrus CI
are supported. You can run on your development machine or other CI providers
using the --platform argument. Check --help output for more information.
"""
),
file=sys.stderr,
)
sys.exit(2)
def _compute_platform_auto() -> PlatformName:
if sys.platform.startswith("linux"):
return "linux"
elif sys.platform == "darwin":
@@ -204,40 +231,34 @@ def _compute_platform_ci() -> PlatformName:
elif sys.platform == "win32":
return "windows"
else:
print(
'cibuildwheel: Unable to detect platform from "sys.platform" in a CI environment. You can run '
"cibuildwheel using the --platform argument. Check --help output for more information.",
file=sys.stderr,
msg = (
'cibuildwheel: Unable to detect platform from "sys.platform". cibuildwheel doesn\'t '
"support building wheels for this platform. You might be able to build for a different "
"platform using the --platform argument. Check --help output for more information."
)
sys.exit(2)
raise errors.ConfigurationError(msg)
def _compute_platform(args: CommandLineArguments) -> PlatformName:
platform_option_value = args.platform or os.environ.get("CIBW_PLATFORM", "auto")
platform_option_value = args.platform or os.environ.get("CIBW_PLATFORM", "") or "auto"
if args.only and args.platform is not None:
print(
"--platform cannot be specified with --only, it is computed from --only",
file=sys.stderr,
)
sys.exit(2)
msg = "--platform cannot be specified with --only, it is computed from --only"
raise errors.ConfigurationError(msg)
if args.only and args.archs is not None:
print(
"--arch cannot be specified with --only, it is computed from --only",
file=sys.stderr,
)
sys.exit(2)
msg = "--arch cannot be specified with --only, it is computed from --only"
raise errors.ConfigurationError(msg)
if platform_option_value not in PLATFORMS | {"auto"}:
print(f"cibuildwheel: Unsupported platform: {platform_option_value}", file=sys.stderr)
sys.exit(2)
msg = f"Unsupported platform: {platform_option_value}"
raise errors.ConfigurationError(msg)
if args.only:
return _compute_platform_only(args.only)
elif platform_option_value != "auto":
return typing.cast(PlatformName, platform_option_value)
return _compute_platform_ci()
return _compute_platform_auto()
class PlatformModule(Protocol):
@@ -245,14 +266,11 @@ class PlatformModule(Protocol):
# is applied to a module
def get_python_configurations(
self, build_selector: BuildSelector, architectures: Set[Architecture]
) -> Sequence[GenericPythonConfiguration]:
...
) -> Sequence[GenericPythonConfiguration]: ...
def build(self, options: Options, tmp_path: Path) -> None:
...
def build(self, options: Options, tmp_path: Path) -> None: ...
# pylint: disable-next=inconsistent-return-statements
def get_platform_module(platform: PlatformName) -> PlatformModule:
if platform == "linux":
return cibuildwheel.linux
@@ -260,11 +278,18 @@ def get_platform_module(platform: PlatformName) -> PlatformModule:
return cibuildwheel.windows
if platform == "macos":
return cibuildwheel.macos
if platform == "pyodide":
return cibuildwheel.pyodide
assert_never(platform)
def build_in_directory(args: CommandLineArguments) -> None:
platform: PlatformName = _compute_platform(args)
if platform == "pyodide" and sys.platform == "win32":
msg = "cibuildwheel: Building for pyodide is not supported on Windows"
print(msg, file=sys.stderr)
sys.exit(2)
options = compute_options(platform=platform, command_line_arguments=args, env=os.environ)
package_dir = options.globals.package_dir
@@ -272,9 +297,8 @@ def build_in_directory(args: CommandLineArguments) -> None:
if not any(package_dir.joinpath(name).exists() for name in package_files):
names = ", ".join(sorted(package_files, reverse=True))
msg = f"cibuildwheel: Could not find any of {{{names}}} at root of package"
print(msg, file=sys.stderr)
sys.exit(2)
msg = f"Could not find any of {{{names}}} at root of package"
raise errors.ConfigurationError(msg)
platform_module = get_platform_module(platform)
identifiers = get_build_identifiers(
@@ -291,8 +315,10 @@ def build_in_directory(args: CommandLineArguments) -> None:
# Add CIBUILDWHEEL environment variable
os.environ["CIBUILDWHEEL"] = "1"
# Python is buffering by default when running on the CI platforms, giving problems interleaving subprocess call output with unflushed calls to 'print'
sys.stdout = Unbuffered(sys.stdout) # type: ignore[assignment]
# Python is buffering by default when running on the CI platforms, giving
# problems interleaving subprocess call output with unflushed calls to
# 'print'
sys.stdout = Unbuffered(sys.stdout)
# create the cache dir before it gets printed & builds performed
CIBW_CACHE_PATH.mkdir(parents=True, exist_ok=True)
@@ -303,16 +329,14 @@ def build_in_directory(args: CommandLineArguments) -> None:
options.check_for_invalid_configuration(identifiers)
allowed_architectures_check(platform, options.globals.architectures)
except ValueError as err:
print("cibuildwheel:", *err.args, file=sys.stderr)
sys.exit(4)
raise errors.DeprecationError(*err.args) from err
if not identifiers:
print(
f"cibuildwheel: No build identifiers selected: {options.globals.build_selector}",
file=sys.stderr,
)
if not args.allow_empty:
sys.exit(3)
message = f"No build identifiers selected: {options.globals.build_selector}"
if options.globals.allow_empty:
print(f"cibuildwheel: {message}", file=sys.stderr)
else:
raise errors.NothingToDoError(message)
output_dir = options.globals.output_dir
@@ -356,18 +380,19 @@ def print_preamble(platform: str, options: Options, identifiers: Sequence[str])
print()
print(f"Cache folder: {CIBW_CACHE_PATH}")
print()
warnings = detect_warnings(options=options, identifiers=identifiers)
if warnings:
print("\nWarnings:")
for warning in warnings:
print(" " + warning)
for warning in warnings:
log.warning(warning)
print("\nHere we go!\n")
print("Here we go!\n")
def get_build_identifiers(
platform_module: PlatformModule, build_selector: BuildSelector, architectures: Set[Architecture]
platform_module: PlatformModule,
build_selector: BuildSelector,
architectures: Set[Architecture],
) -> list[str]:
python_configurations = platform_module.get_python_configurations(build_selector, architectures)
return [config.identifier for config in python_configurations]
@@ -376,6 +401,16 @@ def get_build_identifiers(
def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str]:
warnings = []
python_version_deprecation = ((3, 11), 3)
if sys.version_info[:2] < python_version_deprecation[0]:
python_version = ".".join(map(str, python_version_deprecation[0]))
msg = (
f"cibuildwheel {python_version_deprecation[1]} will require Python {python_version}+, "
"please upgrade the Python version used to run cibuildwheel. "
"This does not affect the versions you can target when building wheels. See: https://cibuildwheel.pypa.io/en/stable/#what-does-it-do"
)
warnings.append(msg)
# warn about deprecated {python} and {pip}
for option_name in ["test_command", "before_build"]:
option_values = [getattr(options.build_options(i), option_name) for i in identifiers]
@@ -384,7 +419,7 @@ def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str
# Reminder: in an f-string, double braces means literal single brace
msg = (
f"{option_name}: '{{python}}' and '{{pip}}' are no longer needed, "
"and will be removed in a future release. Simply use 'python' or 'pip' instead."
"and will be removed in cibuildwheel 3. Simply use 'python' or 'pip' instead."
)
warnings.append(msg)
@@ -1,66 +0,0 @@
from __future__ import annotations
import typing
from collections.abc import Callable
from threading import RLock
from typing import Any, Generic, TypeVar
__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)
@typing.overload
def __get__(self, instance: None, owner: type[Any] | None = ...) -> cached_property[_T]:
...
@typing.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
-10
View File
@@ -1,10 +0,0 @@
from __future__ import annotations
import sys
if sys.version_info >= (3, 8):
from functools import cached_property
else:
from ._functools_cached_property_38 import cached_property
__all__ = ("cached_property",)
+3 -3
View File
@@ -3,8 +3,8 @@ from __future__ import annotations
import sys
if sys.version_info >= (3, 11):
from tomllib import load # noqa: TID251
from tomllib import load, loads
else:
from tomli import load # noqa: TID251
from tomli import load, loads
__all__ = ("load",)
__all__ = ["load", "loads"]
+4 -14
View File
@@ -2,23 +2,13 @@ from __future__ import annotations
import sys
if sys.version_info < (3, 8):
from typing_extensions import Final, Literal, OrderedDict, Protocol, TypedDict
else:
from typing import Final, Literal, OrderedDict, Protocol, TypedDict # noqa: TID251
if sys.version_info < (3, 11):
from typing_extensions import NotRequired, assert_never
from typing_extensions import NotRequired, Self, assert_never
else:
from typing import NotRequired, assert_never # noqa: TID251
from typing import NotRequired, Self, assert_never
__all__ = (
"Final",
"Literal",
"Protocol",
"Protocol",
"TypedDict",
"OrderedDict",
"assert_never",
"NotRequired",
"Self",
"assert_never",
)
+28 -11
View File
@@ -6,14 +6,16 @@ import re
import sys
from collections.abc import Set
from enum import Enum
from typing import Final, Literal
from ._compat.typing import Final, Literal, assert_never
from ._compat.typing import assert_never
from .typing import PlatformName
PRETTY_NAMES: Final[dict[PlatformName, str]] = {
"linux": "Linux",
"macos": "macOS",
"windows": "Windows",
"pyodide": "Pyodide",
}
ARCH_SYNONYMS: Final[list[dict[PlatformName, str | None]]] = [
@@ -35,6 +37,7 @@ class Architecture(Enum):
aarch64 = "aarch64"
ppc64le = "ppc64le"
s390x = "s390x"
armv7l = "armv7l"
# mac archs
universal2 = "universal2"
@@ -45,6 +48,9 @@ class Architecture(Enum):
AMD64 = "AMD64"
ARM64 = "ARM64"
# WebAssembly
wasm32 = "wasm32"
# Allow this to be sorted
def __lt__(self, other: Architecture) -> bool:
return self.value < other.value
@@ -59,7 +65,9 @@ class Architecture(Enum):
if arch_str == "auto":
result |= Architecture.auto_archs(platform=platform)
elif arch_str == "native":
result.add(Architecture(platform_module.machine()))
native_arch = Architecture.native_arch(platform=platform)
if native_arch:
result.add(native_arch)
elif arch_str == "all":
result |= Architecture.all_archs(platform=platform)
elif arch_str == "auto64":
@@ -71,8 +79,9 @@ class Architecture(Enum):
return result
@staticmethod
def auto_archs(platform: PlatformName) -> set[Architecture]:
native_machine = platform_module.machine()
def native_arch(platform: PlatformName) -> Architecture | None:
if platform == "pyodide":
return Architecture.wasm32
# Cross-platform support. Used for --print-build-identifiers or docker builds.
host_platform: PlatformName = (
@@ -81,6 +90,7 @@ class Architecture(Enum):
else ("macos" if sys.platform.startswith("darwin") else "linux")
)
native_machine = platform_module.machine()
native_architecture = Architecture(native_machine)
# we might need to rename the native arch to the machine we're running
@@ -92,11 +102,18 @@ class Architecture(Enum):
if synonym is None:
# can't build anything on this platform
return set()
return None
native_architecture = Architecture(synonym)
result = {native_architecture}
return native_architecture
@staticmethod
def auto_archs(platform: PlatformName) -> set[Architecture]:
native_arch = Architecture.native_arch(platform)
if native_arch is None:
return set() # can't build anything on this platform
result = {native_arch}
if platform == "linux" and Architecture.x86_64 in result:
# x86_64 machines can run i686 containers
@@ -116,24 +133,24 @@ class Architecture(Enum):
Architecture.aarch64,
Architecture.ppc64le,
Architecture.s390x,
Architecture.armv7l,
},
"macos": {Architecture.x86_64, Architecture.arm64, Architecture.universal2},
"windows": {Architecture.x86, Architecture.AMD64, Architecture.ARM64},
"pyodide": {Architecture.wasm32},
}
return all_archs_map[platform]
@staticmethod
# pylint: disable-next=inconsistent-return-statements
def bitness_archs(platform: PlatformName, bitness: Literal["64", "32"]) -> set[Architecture]:
archs_32 = {Architecture.i686, Architecture.x86}
archs_32 = {Architecture.i686, Architecture.x86, Architecture.armv7l}
auto_archs = Architecture.auto_archs(platform)
if bitness == "64":
return auto_archs - archs_32
elif bitness == "32":
if bitness == "32":
return auto_archs & archs_32
else:
assert_never(bitness)
assert_never(bitness)
def allowed_architectures_check(
+7 -4
View File
@@ -2,13 +2,12 @@ from __future__ import annotations
import dataclasses
from collections.abc import Mapping, Sequence
from typing import Any
from typing import Any, Protocol
import bashlex
import bashlex.errors
from . import bashlex_eval
from ._compat.typing import Protocol
class EnvironmentParseError(Exception):
@@ -125,8 +124,12 @@ class ParsedEnvironment:
return environment
def add(self, name: str, value: str) -> None:
self.assignments.append(EnvironmentAssignmentRaw(name=name, value=value))
def add(self, name: str, value: str, prepend: bool = False) -> None:
assignment = EnvironmentAssignmentRaw(name=name, value=value)
if prepend:
self.assignments.insert(0, assignment)
else:
self.assignments.append(assignment)
def __repr__(self) -> str:
return f"{self.__class__.__name__}({[repr(a) for a in self.assignments]!r})"
+87
View File
@@ -0,0 +1,87 @@
"""
Errors that can cause the build to fail. Each subclass of FatalError has
a different return code, by defining them all here, we can ensure that they're
semantically clear and unique.
"""
import textwrap
class FatalError(BaseException):
"""
Raising an error of this type will cause the message to be printed to
stderr and the process to be terminated. Within cibuildwheel, raising this
exception produces a better error message, and optional traceback.
"""
return_code: int = 1
class ConfigurationError(FatalError):
return_code = 2
class NothingToDoError(FatalError):
return_code = 3
class DeprecationError(FatalError):
return_code = 4
class NonPlatformWheelError(FatalError):
def __init__(self) -> None:
message = textwrap.dedent(
"""
Build failed because a pure Python wheel was generated.
If you intend to build a pure-Python wheel, you don't need
cibuildwheel - use `pip wheel .`, `pipx run build --wheel`, `uv
build --wheel`, etc. instead. You only need cibuildwheel if you
have compiled (not Python) code in your wheels making them depend
on the platform.
If you expected a platform wheel, check your project configuration,
or run cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
"""
)
super().__init__(message)
self.return_code = 5
class AlreadyBuiltWheelError(FatalError):
def __init__(self, wheel_name: str) -> None:
message = textwrap.dedent(
f"""
Build failed because a wheel named {wheel_name} was already generated in the current run.
If you expected another wheel to be generated, check your project configuration, or run
cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
"""
)
super().__init__(message)
self.return_code = 6
class OCIEngineTooOldError(FatalError):
def __init__(self, message: str) -> None:
super().__init__(message)
self.return_code = 7
class RepairStepProducedNoWheelError(FatalError):
def __init__(self) -> None:
message = textwrap.dedent(
"""
Build failed because the repair step completed successfully but
did not produce a wheel.
Your `repair-wheel-command` is expected to place the repaired
wheel in the {dest_dir} directory. See the documentation for
example configurations:
https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command
"""
)
super().__init__(message)
self.return_code = 8
+3 -5
View File
@@ -6,19 +6,17 @@ from __future__ import annotations
from collections.abc import Mapping, Sequence
from io import StringIO
from ._compat.typing import Protocol
from typing import Protocol
__all__ = ("Printable", "dump_python_configurations")
class Printable(Protocol):
def __str__(self) -> str:
...
def __str__(self) -> str: ...
def dump_python_configurations(
inp: Mapping[str, Mapping[str, Sequence[Mapping[str, Printable]]]]
inp: Mapping[str, Mapping[str, Sequence[Mapping[str, Printable]]]],
) -> str:
output = StringIO()
for header, values in inp.items():
+127 -81
View File
@@ -1,24 +1,26 @@
from __future__ import annotations
import contextlib
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 Tuple
from typing import OrderedDict, Tuple
from ._compat.typing import OrderedDict, assert_never
from packaging.version import Version
from . import errors
from ._compat.typing import assert_never
from .architecture import Architecture
from .logger import log
from .oci_container import OCIContainer
from .options import Options
from .oci_container import OCIContainer, OCIContainerEngineConfig, OCIPlatform
from .options import BuildOptions, Options
from .typing import PathOrStr
from .util import (
AlreadyBuiltWheelError,
BuildFrontendConfig,
BuildSelector,
NonPlatformWheelError,
build_frontend_or_default,
find_compatible_wheel,
get_build_verbosity_extra_flags,
prepare_command,
@@ -28,6 +30,15 @@ from .util import (
unwrap,
)
ARCHITECTURE_OCI_PLATFORM_MAP = {
Architecture.x86_64: OCIPlatform.AMD64,
Architecture.i686: OCIPlatform.i386,
Architecture.aarch64: OCIPlatform.ARM64,
Architecture.ppc64le: OCIPlatform.PPC64LE,
Architecture.s390x: OCIPlatform.S390X,
Architecture.armv7l: OCIPlatform.ARMV7,
}
@dataclass(frozen=True)
class PythonConfiguration:
@@ -44,6 +55,7 @@ class PythonConfiguration:
class BuildStep:
platform_configs: list[PythonConfiguration]
platform_tag: str
container_engine: OCIContainerEngineConfig
container_image: str
@@ -65,8 +77,9 @@ def get_python_configurations(
]
def container_image_for_python_configuration(config: PythonConfiguration, options: Options) -> str:
build_options = options.build_options(config.identifier)
def container_image_for_python_configuration(
config: PythonConfiguration, build_options: BuildOptions
) -> str:
# e.g
# identifier is 'cp310-manylinux_x86_64'
# platform_tag is 'manylinux_x86_64'
@@ -91,15 +104,18 @@ def get_build_steps(
Groups PythonConfigurations into BuildSteps. Each BuildStep represents a
separate container instance.
"""
steps = OrderedDict[Tuple[str, str, str], BuildStep]()
steps = OrderedDict[Tuple[str, str, str, OCIContainerEngineConfig], BuildStep]()
for config in python_configurations:
_, platform_tag = config.identifier.split("-", 1)
before_all = options.build_options(config.identifier).before_all
container_image = container_image_for_python_configuration(config, options)
build_options = options.build_options(config.identifier)
step_key = (platform_tag, container_image, before_all)
before_all = build_options.before_all
container_image = container_image_for_python_configuration(config, build_options)
container_engine = build_options.container_engine
step_key = (platform_tag, container_image, before_all, container_engine)
if step_key in steps:
steps[step_key].platform_configs.append(config)
@@ -107,6 +123,7 @@ def get_build_steps(
steps[step_key] = BuildStep(
platform_configs=[config],
platform_tag=platform_tag,
container_engine=container_engine,
container_image=container_image,
)
@@ -117,23 +134,36 @@ def check_all_python_exist(
*, platform_configs: Iterable[PythonConfiguration], container: OCIContainer
) -> None:
exist = True
has_manylinux_interpreters = False
messages = []
with contextlib.suppress(subprocess.CalledProcessError):
# use capture_output to keep quiet
container.call(["manylinux-interpreters", "--help"], capture_output=True)
has_manylinux_interpreters = True
for config in platform_configs:
python_path = config.path / "bin" / "python"
try:
container.call(["test", "-x", python_path])
except subprocess.CalledProcessError:
messages.append(
f" '{python_path}' executable doesn't exist in image '{container.image}' to build '{config.identifier}'."
)
exist = False
if has_manylinux_interpreters:
try:
container.call(["manylinux-interpreters", "ensure", config.path.name])
except subprocess.CalledProcessError:
messages.append(
f" 'manylinux-interpreters ensure {config.path.name}' needed to build '{config.identifier}' failed in container running image '{container.image}'."
" Either the installation failed or this interpreter is not available in that image. Please check the logs."
)
exist = False
else:
try:
container.call(["test", "-x", python_path])
except subprocess.CalledProcessError:
messages.append(
f" '{python_path}' executable doesn't exist in image '{container.image}' to build '{config.identifier}'."
)
exist = False
if not exist:
message = "\n".join(messages)
print(
f"cibuildwheel:\n{message}",
file=sys.stderr,
)
sys.exit(1)
raise errors.FatalError(message)
def build_in_container(
@@ -158,7 +188,7 @@ def build_in_container(
log.step("Running before_all...")
env = container.get_environment()
env["PATH"] = f'/opt/python/cp38-cp38/bin:{env["PATH"]}'
env["PATH"] = f'/opt/python/cp39-cp39/bin:{env["PATH"]}'
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
env["PIP_ROOT_USER_ACTION"] = "ignore"
env = before_all_options.environment.as_dictionary(
@@ -177,21 +207,23 @@ def build_in_container(
for config in platform_configs:
log.build_start(config.identifier)
build_options = options.build_options(config.identifier)
build_frontend = build_frontend_or_default(build_options.build_frontend)
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
use_uv = build_frontend.name == "build[uv]" and Version(config.version) >= Version("3.8")
pip = ["uv", "pip"] if use_uv else ["pip"]
dependency_constraint_flags: list[PathOrStr] = []
log.step("Setting up build environment...")
if build_options.dependency_constraints:
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]
log.step("Setting up build environment...")
env = container.get_environment()
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
env["PIP_ROOT_USER_ACTION"] = "ignore"
@@ -205,19 +237,19 @@ def build_in_container(
# check config python is still on PATH
which_python = container.call(["which", "python"], env=env, capture_output=True).strip()
if PurePosixPath(which_python) != python_bin / "python":
print(
"cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
file=sys.stderr,
)
sys.exit(1)
msg = "python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
raise errors.FatalError(msg)
which_pip = container.call(["which", "pip"], env=env, capture_output=True).strip()
if PurePosixPath(which_pip) != python_bin / "pip":
print(
"cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.",
file=sys.stderr,
)
sys.exit(1)
if use_uv:
which_uv = container.call(["which", "uv"], env=env, capture_output=True).strip()
if not which_uv:
msg = "uv not found on PATH. You must use a supported manylinux or musllinux environment with uv."
raise errors.FatalError(msg)
else:
which_pip = container.call(["which", "pip"], env=env, capture_output=True).strip()
if PurePosixPath(which_pip) != python_bin / "pip":
msg = "pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
raise errors.FatalError(msg)
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
if compatible_wheel:
@@ -243,9 +275,10 @@ def build_in_container(
container.call(["rm", "-rf", built_wheel_dir])
container.call(["mkdir", "-p", built_wheel_dir])
extra_flags = split_config_settings(build_options.config_settings, build_frontend)
extra_flags = split_config_settings(build_options.config_settings, build_frontend.name)
extra_flags += build_frontend.args
if build_frontend == "pip":
if build_frontend.name == "pip":
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
container.call(
[
@@ -260,10 +293,12 @@ def build_in_container(
],
env=env,
)
elif build_frontend == "build":
elif build_frontend.name == "build" or build_frontend.name == "build[uv]":
if not 0 <= build_options.build_verbosity < 2:
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
log.warning(msg)
if use_uv and "--no-isolation" not in extra_flags and "-n" not in extra_flags:
extra_flags += ["--installer=uv"]
container.call(
[
"python",
@@ -286,7 +321,7 @@ def build_in_container(
container.call(["mkdir", "-p", repaired_wheel_dir])
if built_wheel.name.endswith("none-any.whl"):
raise NonPlatformWheelError()
raise errors.NonPlatformWheelError()
if build_options.repair_command:
log.step("Repairing wheel...")
@@ -299,26 +334,41 @@ def build_in_container(
repaired_wheels = container.glob(repaired_wheel_dir, "*.whl")
if not repaired_wheels:
raise errors.RepairStepProducedNoWheelError()
for repaired_wheel in repaired_wheels:
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
raise AlreadyBuiltWheelError(repaired_wheel.name)
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
if build_options.test_command and build_options.test_selector(config.identifier):
log.step("Testing wheel...")
# set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time.
container.call(["pip", "install", "virtualenv", *dependency_constraint_flags], env=env)
if not use_uv:
container.call(
["pip", "install", "virtualenv", *dependency_constraint_flags], env=env
)
testing_temp_dir = PurePosixPath(
container.call(["mktemp", "-d"], capture_output=True).strip()
)
venv_dir = testing_temp_dir / "venv"
container.call(["python", "-m", "virtualenv", "--no-download", venv_dir], env=env)
if use_uv:
container.call(["uv", "venv", venv_dir, "--python", python_bin / "python"], env=env)
else:
# Use embedded dependencies from virtualenv to ensure determinism
venv_args = ["--no-periodic-update", "--pip=embed"]
# In Python<3.12, setuptools & wheel are installed as well
if Version(config.version) < Version("3.12"):
venv_args.extend(("--setuptools=embed", "--wheel=embed"))
container.call(["python", "-m", "virtualenv", *venv_args, venv_dir], env=env)
virtualenv_env = env.copy()
virtualenv_env["PATH"] = f"{venv_dir / 'bin'}:{virtualenv_env['PATH']}"
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
if build_options.before_test:
before_test_prepared = prepare_command(
@@ -336,19 +386,20 @@ def build_in_container(
# Let's just pick the first one.
wheel_to_test = repaired_wheels[0]
container.call(
["pip", "install", str(wheel_to_test) + build_options.test_extras],
[*pip, "install", str(wheel_to_test) + build_options.test_extras],
env=virtualenv_env,
)
# Install any requirements to run the tests
if build_options.test_requires:
container.call(["pip", "install", *build_options.test_requires], env=virtualenv_env)
container.call([*pip, "install", *build_options.test_requires], env=virtualenv_env)
# Run the tests from a different directory
test_command_prepared = prepare_command(
build_options.test_command,
project=container_project_path,
package=container_package_dir,
wheel=wheel_to_test,
)
test_cwd = testing_temp_dir / "test_cwd"
container.call(["mkdir", "-p", test_cwd])
@@ -376,29 +427,6 @@ def build_in_container(
def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
try:
# check the container engine is installed
subprocess.run(
[options.globals.container_engine.name, "--version"],
check=True,
stdout=subprocess.DEVNULL,
)
except subprocess.CalledProcessError:
print(
unwrap(
f"""
cibuildwheel: {options.globals.container_engine} not found. An
OCI exe like Docker or Podman is required to run Linux builds.
If you're building on Travis CI, add `services: [docker]` to
your .travis.yml. If you're building on Circle CI in Linux,
add a `setup_remote_docker` step to your .circleci/config.yml.
If you're building on Cirrus CI, use `docker_builder` task.
"""
),
file=sys.stderr,
)
sys.exit(2)
python_configurations = get_python_configurations(
options.globals.build_selector, options.globals.architectures
)
@@ -413,17 +441,38 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
container_package_dir = container_project_path / abs_package_dir.relative_to(cwd)
for build_step in get_build_steps(options, python_configurations):
try:
# check the container engine is installed
subprocess.run(
[build_step.container_engine.name, "--version"],
check=True,
stdout=subprocess.DEVNULL,
)
except subprocess.CalledProcessError as error:
msg = unwrap(
f"""
cibuildwheel: {build_step.container_engine.name} not found. An
OCI exe like Docker or Podman is required to run Linux builds.
If you're building on Travis CI, add `services: [docker]` to
your .travis.yml. If you're building on Circle CI in Linux,
add a `setup_remote_docker` step to your .circleci/config.yml.
If you're building on Cirrus CI, use `docker_builder` task.
"""
)
raise errors.ConfigurationError(msg) from error
try:
ids_to_build = [x.identifier for x in build_step.platform_configs]
log.step(f"Starting container image {build_step.container_image}...")
print(f"info: This container will host the build for {', '.join(ids_to_build)}...")
architecture = Architecture(build_step.platform_tag.split("_", 1)[1])
with OCIContainer(
image=build_step.container_image,
simulate_32_bit=build_step.platform_tag.endswith("i686"),
oci_platform=ARCHITECTURE_OCI_PLATFORM_MAP[architecture],
cwd=container_project_path,
engine=options.globals.container_engine,
engine=build_step.container_engine,
) as container:
build_in_container(
options=options,
@@ -434,11 +483,9 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
)
except subprocess.CalledProcessError as error:
log.step_end_with_error(
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
)
troubleshoot(options, error)
sys.exit(1)
msg = f"Command {error.cmd} failed with code {error.returncode}. {error.stdout or ''}"
raise errors.FatalError(msg) from error
def _matches_prepared_command(error_cmd: Sequence[str], command_template: str) -> bool:
@@ -457,7 +504,6 @@ def troubleshoot(options: Options, error: Exception) -> None:
) # TODO allow matching of overrides too?
):
# the wheel build step or the repair step failed
print("Checking for common errors...")
so_files = list(options.globals.package_dir.glob("**/*.so"))
if so_files:
+9 -3
View File
@@ -5,9 +5,8 @@ import os
import re
import sys
import time
from typing import IO, AnyStr, Tuple
from typing import IO, AnyStr, Final, Tuple
from ._compat.typing import Final
from .util import CIProvider, detect_ci_provider
FoldPattern = Tuple[str, str]
@@ -24,17 +23,20 @@ PLATFORM_IDENTIFIER_DESCRIPTIONS: Final[dict[str, str]] = {
"manylinux_aarch64": "manylinux aarch64",
"manylinux_ppc64le": "manylinux ppc64le",
"manylinux_s390x": "manylinux s390x",
"manylinux_armv7l": "manylinux armv7l",
"musllinux_x86_64": "musllinux x86_64",
"musllinux_i686": "musllinux i686",
"musllinux_aarch64": "musllinux aarch64",
"musllinux_ppc64le": "musllinux ppc64le",
"musllinux_s390x": "manylinux s390x",
"musllinux_s390x": "musllinux s390x",
"musllinux_armv7l": "musllinux armv7l",
"win32": "Windows 32bit",
"win_amd64": "Windows 64bit",
"win_arm64": "Windows on ARM 64bit",
"macosx_x86_64": "macOS x86_64",
"macosx_universal2": "macOS Universal 2 - x86_64 and arm64",
"macosx_arm64": "macOS arm64 - Apple Silicon",
"pyodide_wasm32": "Pyodide",
}
@@ -152,6 +154,10 @@ class Logger:
c = self.colors
print(f"{c.bright_red}Error{c.end}: {error}\n", file=sys.stderr)
@property
def step_active(self) -> bool:
return self.step_start_time is not None
def _start_fold_group(self, name: str) -> None:
self._end_fold_group()
self.active_fold_group_name = name
+244 -109
View File
@@ -1,7 +1,7 @@
from __future__ import annotations
import contextlib
import functools
import inspect
import os
import platform
import re
@@ -12,11 +12,13 @@ import typing
from collections.abc import Sequence, Set
from dataclasses import dataclass
from pathlib import Path
from typing import Tuple
from typing import Literal, Tuple
from filelock import FileLock
from packaging.version import Version
from ._compat.typing import Literal, assert_never
from . import errors
from ._compat.typing import assert_never
from .architecture import Architecture
from .environment import ParsedEnvironment
from .logger import log
@@ -24,18 +26,20 @@ from .options import Options
from .typing import PathOrStr
from .util import (
CIBW_CACHE_PATH,
AlreadyBuiltWheelError,
BuildFrontend,
BuildFrontendConfig,
BuildFrontendName,
BuildSelector,
NonPlatformWheelError,
build_frontend_or_default,
call,
combine_constraints,
detect_ci_provider,
download,
find_compatible_wheel,
find_uv,
free_thread_enable_313,
get_build_verbosity_extra_flags,
get_pip_version,
install_certifi_script,
move_file,
prepare_command,
read_python_configs,
shell,
@@ -46,6 +50,7 @@ from .util import (
)
@functools.lru_cache(maxsize=None)
def get_macos_version() -> tuple[int, int]:
"""
Returns the macOS major/minor version, as a tuple, e.g. (10, 15) or (11, 0)
@@ -57,9 +62,29 @@ def get_macos_version() -> tuple[int, int]:
"""
version_str, _, _ = platform.mac_ver()
version = tuple(map(int, version_str.split(".")[:2]))
if (10, 15) < version < (11, 0):
# When built against an older macOS SDK, Python will report macOS 10.16
# instead of the real version.
version_str = call(
sys.executable,
"-sS",
"-c",
"import platform; print(platform.mac_ver()[0])",
env={"SYSTEM_VERSION_COMPAT": "0"},
capture_stdout=True,
)
version = tuple(map(int, version_str.split(".")[:2]))
return typing.cast(Tuple[int, int], version)
@functools.lru_cache(maxsize=None)
def get_test_macosx_deployment_target() -> str:
version = get_macos_version()
if version >= (11, 0):
return f"{version[0]}.0"
return f"{version[0]}.{version[1]}"
def get_macos_sdks() -> list[str]:
output = call("xcodebuild", "-showsdks", capture_stdout=True)
return [m.group(1) for m in re.finditer(r"-sdk (macosx\S+)", output)]
@@ -114,35 +139,48 @@ def get_python_configurations(
return python_configurations
def install_cpython(tmp: Path, version: str, url: str) -> Path:
installation_path = Path(f"/Library/Frameworks/Python.framework/Versions/{version}")
def install_cpython(tmp: Path, version: str, url: str, free_threading: bool) -> Path:
ft = "T" if free_threading else ""
installation_path = Path(f"/Library/Frameworks/Python{ft}.framework/Versions/{version}")
with FileLock(CIBW_CACHE_PATH / f"cpython{version}.lock"):
installed_system_packages = call("pkgutil", "--pkgs", capture_stdout=True).splitlines()
# if this version of python isn't installed, get it from python.org and install
python_package_identifier = f"org.python.Python.PythonFramework-{version}"
python_package_identifier = f"org.python.Python.Python{ft}Framework-{version}"
if python_package_identifier not in installed_system_packages:
if detect_ci_provider() is None:
# if running locally, we don't want to install CPython with sudo
# let the user know & provide a link to the installer
print(
f"Error: CPython {version} is not installed.\n"
"cibuildwheel will not perform system-wide installs when running outside of CI.\n"
f"To build locally, install CPython {version} on this machine, or, disable this version of Python using CIBW_SKIP=cp{version.replace('.', '')}-macosx_*\n"
f"\nDownload link: {url}",
file=sys.stderr,
msg = inspect.cleandoc(
f"""
Error: CPython {version} is not installed.
cibuildwheel will not perform system-wide installs when running outside of CI.
To build locally, install CPython {version} on this machine, or, disable this
version of Python using CIBW_SKIP=cp{version.replace('.', '')}-macosx_*
For portable builds, cibuildwheel needs the official builds from python.org.
Download link: {url}
"""
)
raise SystemExit(1)
raise errors.FatalError(msg)
pkg_path = tmp / "Python.pkg"
# download the pkg
download(url, pkg_path)
# install
call("sudo", "installer", "-pkg", pkg_path, "-target", "/")
args = []
if version.startswith("3.13"):
# Python 3.13 is the first version to have a free-threading option
args += ["-applyChoiceChangesXML", str(free_thread_enable_313.resolve())]
call("sudo", "installer", "-pkg", pkg_path, *args, "-target", "/")
pkg_path.unlink()
env = os.environ.copy()
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
call(installation_path / "bin" / "python3", install_certifi_script, env=env)
return installation_path / "bin" / "python3"
if free_threading:
call(installation_path / f"bin/python{version}t", "-m", "ensurepip", env=env)
call(installation_path / f"bin/python{version}t", install_certifi_script, env=env)
else:
call(installation_path / "bin/python3", install_certifi_script, env=env)
return installation_path / "bin" / (f"python{version}t" if free_threading else "python3")
def install_pypy(tmp: Path, url: str) -> Path:
@@ -160,28 +198,51 @@ def install_pypy(tmp: Path, url: str) -> Path:
return installation_path / "bin" / "pypy3"
def can_use_uv(python_configuration: PythonConfiguration) -> bool:
conditions = (Version(python_configuration.version) >= Version("3.8"),)
return all(conditions)
def setup_python(
tmp: Path,
python_configuration: PythonConfiguration,
dependency_constraint_flags: Sequence[PathOrStr],
environment: ParsedEnvironment,
build_frontend: BuildFrontend,
) -> dict[str, str]:
build_frontend: BuildFrontendName,
) -> tuple[Path, dict[str, str]]:
if build_frontend == "build[uv]" and not can_use_uv(python_configuration):
build_frontend = "build"
uv_path = find_uv()
use_uv = build_frontend == "build[uv]"
tmp.mkdir()
implementation_id = python_configuration.identifier.split("-")[0]
log.step(f"Installing Python {implementation_id}...")
if implementation_id.startswith("cp"):
base_python = install_cpython(tmp, python_configuration.version, python_configuration.url)
free_threading = "t-macos" in python_configuration.identifier
base_python = install_cpython(
tmp, python_configuration.version, python_configuration.url, free_threading
)
elif implementation_id.startswith("pp"):
base_python = install_pypy(tmp, python_configuration.url)
else:
msg = "Unknown Python implementation"
raise ValueError(msg)
assert base_python.exists()
assert (
base_python.exists()
), f"{base_python.name} not found, has {list(base_python.parent.iterdir())}"
log.step("Setting up build environment...")
venv_path = tmp / "venv"
env = virtualenv(base_python, venv_path, dependency_constraint_flags)
env = virtualenv(
python_configuration.version,
base_python,
venv_path,
dependency_constraint_flags,
use_uv=use_uv,
)
venv_bin_path = venv_path / "bin"
assert venv_bin_path.exists()
# Fix issue with site.py setting the wrong `sys.prefix`, `sys.exec_prefix`,
@@ -197,43 +258,43 @@ def setup_python(
# upgrade pip to the version matching our constraints
# if necessary, reinstall it to ensure that it's available on PATH as 'pip'
call(
"python",
"-m",
"pip",
"install",
"--upgrade",
"pip",
*dependency_constraint_flags,
env=env,
cwd=venv_path,
)
if build_frontend == "build[uv]":
assert uv_path is not None
pip = [str(uv_path), "pip"]
else:
pip = ["python", "-m", "pip"]
if not use_uv:
call(
*pip,
"install",
"--upgrade",
"pip",
*dependency_constraint_flags,
env=env,
cwd=venv_path,
)
# Apply our environment after pip is ready
env = environment.as_dictionary(prev_environment=env)
# check what pip version we're on
assert (venv_bin_path / "pip").exists()
call("which", "pip", env=env)
call("pip", "--version", env=env)
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
if which_pip != str(venv_bin_path / "pip"):
print(
"cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.",
file=sys.stderr,
)
sys.exit(1)
# check what Python version we're on
call("which", "python", env=env)
call("python", "--version", env=env)
which_python = call("which", "python", env=env, capture_stdout=True).strip()
print(which_python)
if which_python != str(venv_bin_path / "python"):
print(
"cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
file=sys.stderr,
)
sys.exit(1)
msg = "cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
raise errors.FatalError(msg)
call("python", "--version", env=env)
# check what pip version we're on
if not use_uv:
assert (venv_bin_path / "pip").exists()
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
print(which_pip)
if which_pip != str(venv_bin_path / "pip"):
msg = "cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
raise errors.FatalError(msg)
call("pip", "--version", env=env)
config_is_arm64 = python_configuration.identifier.endswith("arm64")
config_is_universal2 = python_configuration.identifier.endswith("universal2")
@@ -241,8 +302,25 @@ def setup_python(
# Set MACOSX_DEPLOYMENT_TARGET, if the user didn't set it.
# For arm64, the minimal deployment target is 11.0.
# On x86_64 (or universal2), use 10.9 as a default.
# PyPy defaults to 10.7, causing inconsistencies if it's left unset.
env.setdefault("MACOSX_DEPLOYMENT_TARGET", "11.0" if config_is_arm64 else "10.9")
# CPython 3.12.6+ needs 10.13.
if config_is_arm64:
default_target = "11.0"
elif Version(python_configuration.version) >= Version("3.12"):
default_target = "10.13"
elif python_configuration.identifier.startswith("pp") and Version(
python_configuration.version
) >= Version("3.9"):
default_target = "10.15"
else:
default_target = "10.9"
env.setdefault("MACOSX_DEPLOYMENT_TARGET", default_target)
# This is a floor, it can't be set lower than the default_target.
if Version(env["MACOSX_DEPLOYMENT_TARGET"]) < Version(default_target):
log.warning(
f"Bumping MACOSX_DEPLOYMENT_TARGET ({env['MACOSX_DEPLOYMENT_TARGET']}) to the minimum required ({default_target})."
)
env["MACOSX_DEPLOYMENT_TARGET"] = default_target
if python_configuration.version not in {"3.6", "3.7"}:
if config_is_arm64:
@@ -287,8 +365,6 @@ def setup_python(
"pip",
"install",
"--upgrade",
"setuptools",
"wheel",
"delocate",
*dependency_constraint_flags,
env=env,
@@ -303,10 +379,22 @@ def setup_python(
*dependency_constraint_flags,
env=env,
)
elif build_frontend == "build[uv]":
assert uv_path is not None
call(
uv_path,
"pip",
"install",
"--upgrade",
"delocate",
"build[virtualenv, uv]",
*dependency_constraint_flags,
env=env,
)
else:
assert_never(build_frontend)
return env
return base_python, env
def build(options: Options, tmp_path: Path) -> None:
@@ -334,7 +422,13 @@ def build(options: Options, tmp_path: Path) -> None:
for config in python_configurations:
build_options = options.build_options(config.identifier)
build_frontend = build_frontend_or_default(build_options.build_frontend)
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
use_uv = build_frontend.name == "build[uv]" and can_use_uv(config)
uv_path = find_uv()
if use_uv and uv_path is None:
msg = "uv not found"
raise AssertionError(msg)
pip = ["pip"] if not use_uv else [str(uv_path), "pip"]
log.build_start(config.identifier)
identifier_tmp_dir = tmp_path / config.identifier
@@ -352,13 +446,15 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.dependency_constraints.get_for_python_version(config.version),
]
env = setup_python(
base_python, env = setup_python(
identifier_tmp_dir / "build",
config,
dependency_constraint_flags,
build_options.environment,
build_frontend,
build_frontend.name,
)
if not use_uv:
pip_version = get_pip_version(env)
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
if compatible_wheel:
@@ -378,9 +474,23 @@ def build(options: Options, tmp_path: Path) -> None:
log.step("Building wheel...")
built_wheel_dir.mkdir()
extra_flags = split_config_settings(build_options.config_settings, build_frontend)
extra_flags = split_config_settings(
build_options.config_settings, build_frontend.name
)
extra_flags += build_frontend.args
if build_frontend == "pip":
build_env = env.copy()
if not use_uv:
build_env["VIRTUALENV_PIP"] = pip_version
if build_options.dependency_constraints:
constraint_path = build_options.dependency_constraints.get_for_python_version(
config.version
)
combine_constraints(
build_env, constraint_path, identifier_tmp_dir if use_uv else None
)
if build_frontend.name == "pip":
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/pypa/cibuildwheel/pull/369
@@ -393,21 +503,14 @@ def build(options: Options, tmp_path: Path) -> None:
f"--wheel-dir={built_wheel_dir}",
"--no-deps",
*extra_flags,
env=env,
env=build_env,
)
elif build_frontend == "build":
elif build_frontend.name == "build" or build_frontend.name == "build[uv]":
if not 0 <= build_options.build_verbosity < 2:
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
log.warning(msg)
build_env = env.copy()
if build_options.dependency_constraints:
constraint_path = (
build_options.dependency_constraints.get_for_python_version(
config.version
)
)
build_env["PIP_CONSTRAINT"] = constraint_path.as_uri()
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
if use_uv and "--no-isolation" not in extra_flags and "-n" not in extra_flags:
extra_flags.append("--installer=uv")
call(
"python",
"-m",
@@ -426,7 +529,7 @@ def build(options: Options, tmp_path: Path) -> None:
repaired_wheel_dir.mkdir()
if built_wheel.name.endswith("none-any.whl"):
raise NonPlatformWheelError()
raise errors.NonPlatformWheelError()
if build_options.repair_command:
log.step("Repairing wheel...")
@@ -448,10 +551,13 @@ def build(options: Options, tmp_path: Path) -> None:
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
try:
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.RepairStepProducedNoWheelError() from None
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
raise AlreadyBuiltWheelError(repaired_wheel.name)
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
log.step_end()
@@ -485,10 +591,9 @@ def build(options: Options, tmp_path: Path) -> None:
unwrap(
"""
While arm64 wheels can be built on x86_64, they cannot be
tested. The ability to test the arm64 wheels will be added in a
future release of cibuildwheel, once Apple Silicon CI runners
are widely available. To silence this warning, set
`CIBW_TEST_SKIP: *-macosx_arm64`.
tested. Consider building arm64 wheels natively, if your CI
provider offers this. To silence this warning, set
`CIBW_TEST_SKIP: "*-macosx_arm64"`.
"""
)
)
@@ -497,11 +602,11 @@ def build(options: Options, tmp_path: Path) -> None:
unwrap(
"""
While universal2 wheels can be built on x86_64, the arm64 part
of them cannot currently be tested. The ability to test the
arm64 part of a universal2 wheel will be added in a future
release of cibuildwheel, once Apple Silicon CI runners are
widely available. To silence this warning, set
`CIBW_TEST_SKIP: *-macosx_universal2:arm64`.
of the wheel cannot be tested on x86_64. Consider building
universal2 wheels on an arm64 runner, if your CI provider offers
this. Notably, an arm64 runner can also test the x86_64 part of
the wheel, through Rosetta emulation. To silence this warning,
set `CIBW_TEST_SKIP: "*-macosx_universal2:arm64"`.
"""
)
)
@@ -522,7 +627,7 @@ def build(options: Options, tmp_path: Path) -> None:
Silicon machine. This is because we use the x86_64 installer of
CPython 3.8. See the discussion in
https://github.com/pypa/cibuildwheel/pull/1169 for the details. To
silence this warning, set `CIBW_TEST_SKIP: cp38-macosx_*:arm64`.
silence this warning, set `CIBW_TEST_SKIP: "cp38-macosx_*:arm64"`.
"""
)
)
@@ -538,15 +643,18 @@ def build(options: Options, tmp_path: Path) -> None:
# set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time.
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
if not use_uv:
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
venv_dir = identifier_tmp_dir / "venv-test"
venv_dir = identifier_tmp_dir / f"venv-test-{testing_arch}"
arch_prefix = []
uv_arch_args = []
if testing_arch != machine_arch:
if machine_arch == "arm64" and testing_arch == "x86_64":
# rosetta2 will provide the emulation with just the arch prefix.
arch_prefix = ["arch", "-x86_64"]
uv_arch_args = ["--python-platform", "x86_64-apple-darwin"]
else:
msg = f"don't know how to emulate {testing_arch} on {machine_arch}"
raise RuntimeError(msg)
@@ -555,17 +663,27 @@ def build(options: Options, tmp_path: Path) -> None:
call_with_arch = functools.partial(call, *arch_prefix)
shell_with_arch = functools.partial(call, *arch_prefix, "/bin/sh", "-c")
# Use --no-download to ensure determinism by using seed libraries
# built into virtualenv
call_with_arch("python", "-m", "virtualenv", "--no-download", venv_dir, env=env)
if use_uv:
pip_install = functools.partial(call, *pip, "install", *uv_arch_args)
call("uv", "venv", venv_dir, f"--python={base_python}", env=env)
else:
pip_install = functools.partial(call_with_arch, *pip, "install")
# Use pip version from the initial env to ensure determinism
venv_args = ["--no-periodic-update", f"--pip={pip_version}"]
# In Python<3.12, setuptools & wheel are installed as well, use virtualenv embedded ones
if Version(config.version) < Version("3.12"):
venv_args.extend(("--setuptools=embed", "--wheel=embed"))
call_with_arch("python", "-m", "virtualenv", *venv_args, venv_dir, env=env)
virtualenv_env = env.copy()
virtualenv_env["MACOSX_DEPLOYMENT_TARGET"] = get_test_macosx_deployment_target()
virtualenv_env["PATH"] = os.pathsep.join(
[
str(venv_dir / "bin"),
virtualenv_env["PATH"],
]
)
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
# check that we are using the Python from the virtual environment
call_with_arch("which", "python", env=virtualenv_env)
@@ -579,17 +697,33 @@ def build(options: Options, tmp_path: Path) -> None:
shell_with_arch(before_test_prepared, env=virtualenv_env)
# install the wheel
call_with_arch(
"pip",
"install",
if is_cp38 and python_arch == "x86_64":
virtualenv_env_install_wheel = virtualenv_env.copy()
virtualenv_env_install_wheel["SYSTEM_VERSION_COMPAT"] = "0"
log.notice(
unwrap(
"""
Setting SYSTEM_VERSION_COMPAT=0 to ensure CPython 3.8 can get
correct macOS version and allow installation of wheels with
MACOSX_DEPLOYMENT_TARGET >= 11.0.
See https://github.com/pypa/cibuildwheel/issues/1767 for the
details.
"""
)
)
else:
virtualenv_env_install_wheel = virtualenv_env
pip_install(
f"{repaired_wheel}{build_options.test_extras}",
env=virtualenv_env,
env=virtualenv_env_install_wheel,
)
# test the wheel
if build_options.test_requires:
call_with_arch(
"pip", "install", *build_options.test_requires, env=virtualenv_env
pip_install(
*build_options.test_requires,
env=virtualenv_env_install_wheel,
)
# run the tests from a temp dir, with an absolute path in the command
@@ -599,6 +733,7 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.test_command,
project=Path(".").resolve(),
package=build_options.package_dir.resolve(),
wheel=repaired_wheel,
)
test_cwd = identifier_tmp_dir / "test_cwd"
@@ -609,18 +744,18 @@ def build(options: Options, tmp_path: Path) -> None:
# we're all done here; move it to output (overwrite existing)
if compatible_wheel is None:
with contextlib.suppress(FileNotFoundError):
(build_options.output_dir / repaired_wheel.name).unlink()
shutil.move(str(repaired_wheel), build_options.output_dir)
built_wheels.append(build_options.output_dir / repaired_wheel.name)
output_wheel = build_options.output_dir.joinpath(repaired_wheel.name)
moved_wheel = move_file(repaired_wheel, output_wheel)
if moved_wheel != output_wheel.resolve():
log.warning(
"{repaired_wheel} was moved to {moved_wheel} instead of {output_wheel}"
)
built_wheels.append(output_wheel)
# clean up
shutil.rmtree(identifier_tmp_dir)
log.build_end()
except subprocess.CalledProcessError as error:
log.step_end_with_error(
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
)
sys.exit(1)
msg = f"Command {error.cmd} failed with code {error.returncode}. {error.stdout or ''}"
raise errors.FatalError(msg) from error
+181 -53
View File
@@ -8,49 +8,143 @@ import shlex
import shutil
import subprocess
import sys
import textwrap
import typing
import uuid
from collections.abc import Mapping, Sequence
from dataclasses import dataclass
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path, PurePath, PurePosixPath
from types import TracebackType
from typing import IO, Dict
from typing import IO, Dict, Literal
from ._compat.typing import Literal
from ._compat.typing import Self, assert_never
from .errors import OCIEngineTooOldError
from .logger import log
from .typing import PathOrStr, PopenBytes
from .util import CIProvider, detect_ci_provider, parse_key_value_string
from .util import (
CIProvider,
FlexibleVersion,
call,
detect_ci_provider,
parse_key_value_string,
strtobool,
)
ContainerEngineName = Literal["docker", "podman"]
# Order of the enum matters for tests. 386 shall appear before amd64.
class OCIPlatform(Enum):
i386 = "linux/386"
AMD64 = "linux/amd64"
ARMV7 = "linux/arm/v7"
ARM64 = "linux/arm64"
PPC64LE = "linux/ppc64le"
S390X = "linux/s390x"
@dataclass(frozen=True)
class OCIContainerEngineConfig:
name: ContainerEngineName
create_args: Sequence[str] = ()
create_args: tuple[str, ...] = field(default_factory=tuple)
disable_host_mount: bool = False
@staticmethod
def from_config_string(config_string: str) -> OCIContainerEngineConfig:
config_dict = parse_key_value_string(config_string, ["name"])
config_dict = parse_key_value_string(
config_string,
["name"],
["create_args", "create-args", "disable_host_mount", "disable-host-mount"],
)
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
# some flexibility in the option names to cope with TOML conventions
create_args = config_dict.get("create_args") or config_dict.get("create-args") or []
return OCIContainerEngineConfig(name=name, create_args=create_args)
disable_host_mount_options = (
config_dict.get("disable_host_mount") or config_dict.get("disable-host-mount") or []
)
disable_host_mount = (
strtobool(disable_host_mount_options[-1]) if disable_host_mount_options else False
)
if "--platform" in create_args or any(arg.startswith("--platform=") for arg in create_args):
msg = "Using '--platform' in 'container-engine::create_args' is deprecated. It will be ignored."
log.warning(msg)
if "--platform" in create_args:
index = create_args.index("--platform")
create_args.pop(index)
create_args.pop(index)
else:
create_args = [arg for arg in create_args if not arg.startswith("--platform=")]
return OCIContainerEngineConfig(
name=name, create_args=tuple(create_args), disable_host_mount=disable_host_mount
)
def options_summary(self) -> str | dict[str, str]:
if not self.create_args:
return self.name
else:
return {"name": self.name, "create_args": repr(self.create_args)}
return {
"name": self.name,
"create_args": repr(self.create_args),
"disable_host_mount": str(self.disable_host_mount),
}
DEFAULT_ENGINE = OCIContainerEngineConfig("docker")
def _check_engine_version(engine: OCIContainerEngineConfig) -> None:
try:
version_string = call(engine.name, "version", "-f", "{{json .}}", capture_stdout=True)
version_info = json.loads(version_string.strip())
if engine.name == "docker":
client_api_version = FlexibleVersion(version_info["Client"]["ApiVersion"])
server_api_version = FlexibleVersion(version_info["Server"]["ApiVersion"])
# --platform support was introduced in 1.32 as experimental, 1.41 removed the experimental flag
version = min(client_api_version, server_api_version)
minimum_version = FlexibleVersion("1.41")
minimum_version_str = "20.10.0" # docker version
error_msg = textwrap.dedent(
f"""
Build failed because {engine.name} is too old.
cibuildwheel requires {engine.name}>={minimum_version_str} running API version {minimum_version}.
The API version found by cibuildwheel is {version}.
"""
)
elif engine.name == "podman":
# podman uses the same version string for "Version" & "ApiVersion"
client_version = FlexibleVersion(version_info["Client"]["Version"])
if "Server" in version_info:
server_version = FlexibleVersion(version_info["Server"]["Version"])
else:
server_version = client_version
# --platform support was introduced in v3
version = min(client_version, server_version)
minimum_version = FlexibleVersion("3")
error_msg = textwrap.dedent(
f"""
Build failed because {engine.name} is too old.
cibuildwheel requires {engine.name}>={minimum_version}.
The version found by cibuildwheel is {version}.
"""
)
else:
assert_never(engine.name)
if version < minimum_version:
raise OCIEngineTooOldError(error_msg) from None
except (subprocess.CalledProcessError, KeyError, ValueError) as e:
msg = f"Build failed because {engine.name} is too old or is not working properly."
raise OCIEngineTooOldError(msg) from e
class OCIContainer:
"""
An object that represents a running OCI (e.g. Docker) container.
@@ -74,7 +168,7 @@ class OCIContainer:
... print(self.debug_info())
"""
UTILITY_PYTHON = "/opt/python/cp38-cp38/bin/python"
UTILITY_PYTHON = "/opt/python/cp39-cp39/bin/python"
process: PopenBytes
bash_stdin: IO[bytes]
@@ -84,7 +178,7 @@ class OCIContainer:
self,
*,
image: str,
simulate_32_bit: bool = False,
oci_platform: OCIPlatform,
cwd: PathOrStr | None = None,
engine: OCIContainerEngineConfig = DEFAULT_ENGINE,
):
@@ -93,14 +187,48 @@ class OCIContainer:
raise ValueError(msg)
self.image = image
self.simulate_32_bit = simulate_32_bit
self.oci_platform = oci_platform
self.cwd = cwd
self.name: str | None = None
self.engine = engine
self.host_tar_format = ""
if sys.platform.startswith("darwin"):
self.host_tar_format = "--format gnutar"
def __enter__(self) -> OCIContainer:
def _get_platform_args(self, *, oci_platform: OCIPlatform | None = None) -> tuple[str, str]:
if oci_platform is None:
oci_platform = self.oci_platform
# we need '--pull=always' otherwise some images with the wrong platform get re-used (e.g. 386 image for amd64)
# c.f. https://github.com/moby/moby/issues/48197#issuecomment-2282802313
pull = "always"
try:
image_platform = call(
self.engine.name,
"image",
"inspect",
self.image,
"--format",
(
"{{.Os}}/{{.Architecture}}/{{.Variant}}"
if len(oci_platform.value.split("/")) == 3
else "{{.Os}}/{{.Architecture}}"
),
capture_stdout=True,
).strip()
if image_platform == oci_platform.value:
# in case the correct image is already present, don't pull
# this allows to run local only images
pull = "never"
except subprocess.CalledProcessError:
pass
return f"--platform={oci_platform.value}", f"--pull={pull}"
def __enter__(self) -> Self:
self.name = f"cibuildwheel-{uuid.uuid4()}"
_check_engine_version(self.engine)
# work-around for Travis-CI PPC64le Docker runs since 2021:
# this avoids network splits
# https://github.com/pypa/cibuildwheel/issues/904
@@ -109,17 +237,44 @@ 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"]
platform_args = self._get_platform_args()
simulate_32_bit = False
if self.oci_platform in {OCIPlatform.i386, OCIPlatform.ARMV7}:
# 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
run_cmd = [self.engine.name, "run", "--rm"]
ctr_cmd = ["uname", "-m"]
try:
container_machine = call(
*run_cmd, *platform_args, self.image, *ctr_cmd, capture_stdout=True
).strip()
except subprocess.CalledProcessError:
if self.oci_platform == OCIPlatform.i386:
# The image might have been built with amd64 architecture
# Let's try that
platform_args = self._get_platform_args(oci_platform=OCIPlatform.AMD64)
container_machine = call(
*run_cmd, *platform_args, self.image, *ctr_cmd, capture_stdout=True
).strip()
else:
raise
simulate_32_bit = container_machine not in {"i686", "armv7l", "armv8l"}
shell_args = ["linux32", "/bin/bash"] if simulate_32_bit else ["/bin/bash"]
subprocess.run(
[
self.engine.name,
"create",
"--env=CIBUILDWHEEL",
"--env=SOURCE_DATE_EPOCH",
f"--name={self.name}",
"--interactive",
"--volume=/:/host", # ignored on CircleCI
*(["--volume=/:/host"] if not self.engine.disable_host_mount else []),
*network_args,
*platform_args,
*self.engine.create_args,
self.image,
*shell_args,
@@ -176,23 +331,20 @@ class OCIContainer:
assert isinstance(self.name, str)
subprocess.run(
[self.engine.name, "rm", "--force", "-v", self.name],
stdout=subprocess.DEVNULL,
check=False,
)
self.name = None
keep_container = strtobool(os.environ.get("CIBW_DEBUG_KEEP_CONTAINER", ""))
if not keep_container:
subprocess.run(
[self.engine.name, "rm", "--force", "-v", self.name],
stdout=subprocess.DEVNULL,
check=False,
)
self.name = None
def copy_into(self, from_path: Path, to_path: PurePath) -> None:
# `docker cp` causes 'no space left on device' error when
# a container is running and the host filesystem is
# mounted. https://github.com/moby/moby/issues/38995
# Use `docker exec` instead.
if from_path.is_dir():
self.call(["mkdir", "-p", to_path])
subprocess.run(
f"tar cf - . | {self.engine.name} exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -",
f"tar -c {self.host_tar_format} -f - . | {self.engine.name} exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -",
shell=True,
check=True,
cwd=from_path,
@@ -213,8 +365,7 @@ class OCIContainer:
) as exec_process:
assert exec_process.stdin
with open(from_path, "rb") as from_file:
# Bug in mypy, https://github.com/python/mypy/issues/15031
shutil.copyfileobj(from_file, exec_process.stdin) # type: ignore[misc]
shutil.copyfileobj(from_file, exec_process.stdin)
exec_process.stdin.close()
exec_process.wait()
@@ -227,30 +378,7 @@ class OCIContainer:
def copy_out(self, from_path: PurePath, to_path: Path) -> None:
# note: we assume from_path is a dir
to_path.mkdir(parents=True, exist_ok=True)
if self.engine.name == "podman":
subprocess.run(
[
self.engine.name,
"cp",
f"{self.name}:{from_path}/.",
str(to_path),
],
check=True,
cwd=to_path,
)
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.name} exec -i {self.name} tar -cC {shell_quote(from_path)} -f - . | tar -xf -"
subprocess.run(
command,
shell=True,
check=True,
cwd=to_path,
)
else:
raise KeyError(self.engine.name)
call(self.engine.name, "cp", f"{self.name}:{from_path}/.", to_path)
def glob(self, path: PurePosixPath, pattern: str) -> list[PurePosixPath]:
glob_pattern = path.joinpath(pattern)
+397 -149
View File
@@ -5,34 +5,35 @@ import configparser
import contextlib
import dataclasses
import difflib
import enum
import functools
import shlex
import sys
import textwrap
import traceback
from collections.abc import Callable, Generator, Iterable, Iterator, Mapping, Set
from collections.abc import Generator, Iterable, Set
from pathlib import Path
from typing import Any, Dict, List, Union
from typing import Any, Literal, Mapping, Sequence, Union # noqa: TID251
from packaging.specifiers import SpecifierSet
from . import errors
from ._compat import tomllib
from ._compat.typing import Literal, NotRequired, TypedDict
from ._compat.typing import assert_never
from .architecture import Architecture
from .environment import EnvironmentParseError, ParsedEnvironment, parse_environment
from .logger import log
from .oci_container import OCIContainerEngineConfig
from .projectfiles import get_requires_python_str
from .projectfiles import get_requires_python_str, resolve_dependency_groups
from .typing import PLATFORMS, PlatformName
from .util import (
MANYLINUX_ARCHS,
MUSLLINUX_ARCHS,
BuildFrontend,
BuildFrontendConfig,
BuildSelector,
DependencyConstraints,
EnableGroups,
TestSelector,
cached_property,
format_safe,
read_python_configs,
resources_dir,
selector_matches,
strtobool,
@@ -51,6 +52,7 @@ class CommandLineArguments:
print_build_identifiers: bool
allow_empty: bool
prerelease_pythons: bool
debug_traceback: bool
@staticmethod
def defaults() -> CommandLineArguments:
@@ -64,6 +66,7 @@ class CommandLineArguments:
package_dir=Path("."),
prerelease_pythons=False,
print_build_identifiers=False,
debug_traceback=False,
)
@@ -74,7 +77,7 @@ class GlobalOptions:
build_selector: BuildSelector
test_selector: TestSelector
architectures: set[Architecture]
container_engine: OCIContainerEngineConfig
allow_empty: bool
@dataclasses.dataclass(frozen=True)
@@ -91,9 +94,11 @@ class BuildOptions:
before_test: str | None
test_requires: list[str]
test_extras: str
test_groups: list[str]
build_verbosity: int
build_frontend: BuildFrontend | Literal["default"]
build_frontend: BuildFrontendConfig | None
config_settings: str
container_engine: OCIContainerEngineConfig
@property
def package_dir(self) -> Path:
@@ -116,13 +121,17 @@ class BuildOptions:
return self.globals.architectures
Setting = Union[Dict[str, str], List[str], str, int]
SettingLeaf = Union[str, int, bool]
SettingList = Sequence[SettingLeaf]
SettingTable = Mapping[str, Union[SettingLeaf, SettingList]]
SettingValue = Union[SettingTable, SettingList, SettingLeaf]
@dataclasses.dataclass(frozen=True)
class Override:
select_pattern: str
options: dict[str, Setting]
options: dict[str, SettingValue]
inherit: dict[str, InheritRule]
MANYLINUX_OPTIONS = {f"manylinux-{build_platform}-image" for build_platform in MANYLINUX_ARCHS}
@@ -134,44 +143,226 @@ 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]]
class ConfigOptionError(KeyError):
class OptionsReaderError(errors.ConfigurationError):
pass
def _dig_first(*pairs: tuple[Mapping[str, Setting], str], ignore_empty: bool = False) -> Setting:
class OptionFormat:
"""
Base class for option format specifiers. These objects describe how values
can be parsed from rich TOML values and how they're merged together.
"""
Return the first dict item that matches from pairs of dicts and keys.
Will throw a KeyError if missing.
_dig_first((dict1, "key1"), (dict2, "key2"), ...)
class NotSupported(Exception):
pass
def format_list(self, value: SettingList) -> str: # noqa: ARG002
raise OptionFormat.NotSupported
def format_table(self, table: SettingTable) -> str: # noqa: ARG002
raise OptionFormat.NotSupported
def merge_values(self, before: str, after: str) -> str: # noqa: ARG002
raise OptionFormat.NotSupported
class ListFormat(OptionFormat):
"""
A format that joins lists with a separator.
"""
def __init__(self, sep: str) -> None:
self.sep = sep
def format_list(self, value: SettingList) -> str:
return self.sep.join(str(v) for v in value)
def merge_values(self, before: str, after: str) -> str:
return f"{before}{self.sep}{after}"
class ShlexTableFormat(OptionFormat):
"""
The standard table format uses shlex.quote to quote values and shlex.split
to unquote and split them. When merging values, keys in before are
replaced by keys in after.
"""
def __init__(self, sep: str = " ", pair_sep: str = "=", allow_merge: bool = True) -> None:
self.sep = sep
self.pair_sep = pair_sep
self.allow_merge = allow_merge
def format_table(self, table: SettingTable) -> str:
assignments: list[tuple[str, str]] = []
for k, v in table.items():
if shlex.split(k) != [k]:
msg = f"Invalid table key: {k}"
raise OptionsReaderError(msg)
if isinstance(v, str):
assignments.append((k, v))
elif isinstance(v, Sequence):
for inner_v in v:
assignments.append((k, str(inner_v)))
else:
assignments.append((k, str(v)))
return self.sep.join(f"{k}{self.pair_sep}{shlex.quote(v)}" for k, v in assignments)
def merge_values(self, before: str, after: str) -> str:
if not self.allow_merge:
raise OptionFormat.NotSupported
before_dict = self.parse_table(before)
after_dict = self.parse_table(after)
return self.format_table({**before_dict, **after_dict})
def parse_table(self, table: str) -> Mapping[str, str | Sequence[str]]:
assignments: list[tuple[str, str]] = []
for assignment_str in shlex.split(table):
key, sep, value = assignment_str.partition(self.pair_sep)
if not sep:
msg = f"malformed option with value {assignment_str!r}"
raise OptionsReaderError(msg)
assignments.append((key, value))
result: dict[str, str | list[str]] = {}
for key, value in assignments:
if key in result:
existing_value = result[key]
if isinstance(existing_value, list):
result[key] = [*existing_value, value]
else:
result[key] = [existing_value, value]
else:
result[key] = value
return result
class EnvironmentFormat(OptionFormat):
"""
The environment format accepts a table of environment variables, where the
values may contain variables or command substitutions.
"""
def format_table(self, table: SettingTable) -> str:
return " ".join(f'{k}="{v}"' for k, v in table.items())
def merge_values(self, before: str, after: str) -> str:
return f"{before} {after}"
class InheritRule(enum.Enum):
NONE = enum.auto()
APPEND = enum.auto()
PREPEND = enum.auto()
def _resolve_cascade(
*pairs: tuple[SettingValue | None, InheritRule],
ignore_empty: bool = False,
option_format: OptionFormat | None = None,
) -> str:
"""
Given a cascade of values with inherit rules, resolve them into a single
value.
'None' values mean that the option was not set at that level, and are
ignored. If `ignore_empty` is True, empty values are ignored too.
Values start with defaults, followed by more specific rules. If rules are
NONE, the last non-null value is returned. If a rule is APPEND or PREPEND,
the value is concatenated with the previous value.
The following idiom can be used to get the first matching value:
_resolve_cascade(("value1", Inherit.NONE), ("value2", Inherit.NONE), ...)))
"""
if not pairs:
msg = "pairs cannot be empty"
raise ValueError(msg)
for dict_like, key in pairs:
if key in dict_like:
value = dict_like[key]
result: str | None = None
if ignore_empty and value == "": # noqa: PLC1901
continue
for value, rule in pairs:
if value is None:
continue
return value
if ignore_empty and not value and value is not False:
continue
last_key = pairs[-1][1]
raise KeyError(last_key)
value_string = _stringify_setting(value, option_format=option_format)
result = _apply_inherit_rule(result, value_string, rule=rule, option_format=option_format)
if result is None:
msg = "a setting should at least have a default value"
raise ValueError(msg)
return result
def _apply_inherit_rule(
before: str | None, after: str, rule: InheritRule, option_format: OptionFormat | None
) -> str:
if rule == InheritRule.NONE:
return after
if not before:
# if before is None, we can just return after
# if before is an empty string, we shouldn't add any separator
return after
if not after:
# if after is an empty string, we shouldn't add any separator
return before
if not option_format:
msg = f"Don't know how to merge {before!r} and {after!r} with {rule}"
raise OptionsReaderError(msg)
if rule == InheritRule.APPEND:
return option_format.merge_values(before, after)
if rule == InheritRule.PREPEND:
return option_format.merge_values(after, before)
assert_never(rule)
def _stringify_setting(
setting: SettingValue,
option_format: OptionFormat | None,
) -> str:
if isinstance(setting, Mapping):
try:
if option_format is None:
raise OptionFormat.NotSupported
return option_format.format_table(setting)
except OptionFormat.NotSupported:
msg = f"Error converting {setting!r} to a string: this setting doesn't accept a table"
raise OptionsReaderError(msg) from None
if not isinstance(setting, str) and isinstance(setting, Sequence):
try:
if option_format is None:
raise OptionFormat.NotSupported
return option_format.format_list(setting)
except OptionFormat.NotSupported:
msg = f"Error converting {setting!r} to a string: this setting doesn't accept a list"
raise OptionsReaderError(msg) from None
if isinstance(setting, (bool, int)):
return str(setting)
return setting
class OptionsReader:
@@ -232,19 +423,28 @@ class OptionsReader:
if config_overrides is not None:
if not isinstance(config_overrides, list):
msg = "'tool.cibuildwheel.overrides' must be a list"
raise ConfigOptionError(msg)
raise OptionsReaderError(msg)
for config_override in config_overrides:
select = config_override.pop("select", None)
if not select:
msg = "'select' must be set in an override"
raise ConfigOptionError(msg)
raise OptionsReaderError(msg)
if isinstance(select, list):
select = " ".join(select)
self.overrides.append(Override(select, config_override))
inherit = config_override.pop("inherit", {})
if not isinstance(inherit, dict) or not all(
i in {"none", "append", "prepend"} for i in inherit.values()
):
msg = "'inherit' must be a dict containing only {'none', 'append', 'prepend'} values"
raise OptionsReaderError(msg)
inherit_enum = {k: InheritRule[v.upper()] for k, v in inherit.items()}
self.overrides.append(Override(select, config_override, inherit_enum))
def _validate_global_option(self, name: str) -> None:
"""
@@ -258,7 +458,7 @@ class OptionsReader:
matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7)
if matches:
msg += f" Perhaps you meant {matches[0]!r}?"
raise ConfigOptionError(msg)
raise OptionsReaderError(msg)
def _validate_platform_option(self, name: str) -> None:
"""
@@ -268,7 +468,7 @@ class OptionsReader:
disallowed_platform_options = self.disallow.get(self.platform, set())
if name in disallowed_platform_options:
msg = f"{name!r} is not allowed in {disallowed_platform_options}"
raise ConfigOptionError(msg)
raise OptionsReaderError(msg)
allowed_option_names = self.default_options.keys() | self.default_platform_options.keys()
@@ -277,7 +477,7 @@ class OptionsReader:
matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7)
if matches:
msg += f" Perhaps you meant {matches[0]!r}?"
raise ConfigOptionError(msg)
raise OptionsReaderError(msg)
def _load_file(self, filename: Path) -> tuple[dict[str, Any], dict[str, Any]]:
"""
@@ -312,9 +512,9 @@ class OptionsReader:
name: str,
*,
env_plat: bool = True,
sep: str | None = None,
table: TableFmt | None = None,
option_format: OptionFormat | None = None,
ignore_empty: bool = False,
env_rule: InheritRule = InheritRule.NONE,
) -> str:
"""
Get and return the value for the named option from environment,
@@ -329,80 +529,61 @@ class OptionsReader:
if name not in self.default_options and name not in self.default_platform_options:
msg = f"{name!r} must be in cibuildwheel/resources/defaults.toml file to be accessed."
raise ConfigOptionError(msg)
raise OptionsReaderError(msg)
# Environment variable form
envvar = f"CIBW_{name.upper().replace('-', '_')}"
plat_envvar = f"{envvar}_{self.platform.upper()}"
# later overrides take precedence over earlier ones, so reverse the list
active_config_overrides = reversed(self.active_config_overrides)
# get the option from the environment, then the config file, then finally the default.
# get the option from the default, then the config file, then finally the environment.
# platform-specific options are preferred, if they're allowed.
result = _dig_first(
(self.env if env_plat else {}, plat_envvar),
(self.env, envvar),
*[(o.options, name) for o in active_config_overrides],
(self.config_platform_options, name),
(self.config_options, name),
(self.default_platform_options, name),
(self.default_options, name),
return _resolve_cascade(
(self.default_options.get(name), InheritRule.NONE),
(self.default_platform_options.get(name), InheritRule.NONE),
(self.config_options.get(name), InheritRule.NONE),
(self.config_platform_options.get(name), InheritRule.NONE),
*[
(o.options.get(name), o.inherit.get(name, InheritRule.NONE))
for o in self.active_config_overrides
],
(self.env.get(envvar), env_rule),
(self.env.get(plat_envvar) if env_plat else None, env_rule),
ignore_empty=ignore_empty,
option_format=option_format,
)
if isinstance(result, dict):
if table is None:
msg = f"{name!r} does not accept a table"
raise ConfigOptionError(msg)
return table["sep"].join(
item for k, v in result.items() for item in _inner_fmt(k, v, table)
)
if isinstance(result, list):
if sep is None:
msg = f"{name!r} does not accept a list"
raise ConfigOptionError(msg)
return sep.join(result)
if isinstance(result, int):
return str(result)
return result
def _inner_fmt(k: str, v: Any, table: TableFmt) -> Iterator[str]:
quote_function = table.get("quote", lambda a: a)
if isinstance(v, list):
for inner_v in v:
qv = quote_function(inner_v)
yield table["item"].format(k=k, v=qv)
else:
qv = quote_function(v)
yield table["item"].format(k=k, v=qv)
class Options:
pyproject_toml: dict[str, Any] | None
def __init__(
self,
platform: PlatformName,
command_line_arguments: CommandLineArguments,
env: Mapping[str, str],
read_config_file: bool = True,
defaults: bool = False,
):
self.platform = platform
self.command_line_arguments = command_line_arguments
self.env = env
self._defaults = defaults
self._image_warnings: set[str] = set()
self.reader = OptionsReader(
self.config_file_path if read_config_file else None,
None if defaults else self.config_file_path,
platform=platform,
env=env,
disallow=DISALLOWED_OPTIONS,
)
@property
self.package_dir = Path(command_line_arguments.package_dir)
try:
with self.package_dir.joinpath("pyproject.toml").open("rb") as f:
self.pyproject_toml = tomllib.load(f)
except FileNotFoundError:
self.pyproject_toml = None
@functools.cached_property
def config_file_path(self) -> Path | None:
args = self.command_line_arguments
@@ -416,25 +597,50 @@ class Options:
return None
@cached_property
@functools.cached_property
def package_requires_python_str(self) -> str | None:
args = self.command_line_arguments
return get_requires_python_str(Path(args.package_dir))
return get_requires_python_str(self.package_dir, self.pyproject_toml)
@property
@functools.cached_property
def globals(self) -> GlobalOptions:
args = self.command_line_arguments
package_dir = args.package_dir
output_dir = args.output_dir
build_config = self.reader.get("build", env_plat=False, sep=" ") or "*"
skip_config = self.reader.get("skip", env_plat=False, sep=" ")
test_skip = self.reader.get("test-skip", env_plat=False, sep=" ")
build_config = (
self.reader.get("build", env_plat=False, option_format=ListFormat(sep=" ")) or "*"
)
skip_config = self.reader.get("skip", env_plat=False, option_format=ListFormat(sep=" "))
test_skip = self.reader.get("test-skip", env_plat=False, option_format=ListFormat(sep=" "))
allow_empty = args.allow_empty or strtobool(self.env.get("CIBW_ALLOW_EMPTY", "0"))
enable_groups = self.reader.get(
"enable", env_plat=False, option_format=ListFormat(sep=" "), env_rule=InheritRule.APPEND
)
enable = {EnableGroups(group) for group in enable_groups.split()}
free_threaded_support = strtobool(
self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True)
)
prerelease_pythons = args.prerelease_pythons or strtobool(
self.env.get("CIBW_PRERELEASE_PYTHONS", "0")
)
if free_threaded_support or prerelease_pythons:
msg = (
"free-threaded-support and prerelease-pythons should be specified by enable instead"
)
if enable:
raise OptionsReaderError(msg)
log.warning(msg)
if free_threaded_support:
enable.add(EnableGroups.CPythonFreeThreading)
if prerelease_pythons:
enable.add(EnableGroups.CPythonPrerelease)
# 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 = (
@@ -442,7 +648,7 @@ class Options:
)
requires_python = None if requires_python_str is None else SpecifierSet(requires_python_str)
archs_config_str = args.archs or self.reader.get("archs", sep=" ")
archs_config_str = args.archs or self.reader.get("archs", option_format=ListFormat(sep=" "))
architectures = Architecture.parse_config(archs_config_str, platform=self.platform)
# Process `--only`
@@ -450,25 +656,29 @@ class Options:
build_config = args.only
skip_config = ""
architectures = Architecture.all_archs(self.platform)
enable = set(EnableGroups)
build_selector = BuildSelector(
build_config=build_config,
skip_config=skip_config,
requires_python=requires_python,
prerelease_pythons=prerelease_pythons,
enable=frozenset(
enable | {EnableGroups.PyPy}
), # For backwards compatibility, we are adding PyPy for now
)
test_selector = TestSelector(skip_config=test_skip)
container_engine_str = self.reader.get(
"container-engine", table={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote}
)
try:
container_engine = OCIContainerEngineConfig.from_config_string(container_engine_str)
except ValueError as e:
msg = f"cibuildwheel: Failed to parse container config. {e}"
print(msg, file=sys.stderr)
sys.exit(2)
all_configs = read_python_configs(self.platform)
all_pypy_ids = {
config["identifier"] for config in all_configs if config["identifier"].startswith("pp")
}
if (
not self._defaults
and EnableGroups.PyPy not in enable
and any(build_selector(build_id) for build_id in all_pypy_ids)
):
msg = "PyPy builds will be disabled by default in version 3. Enabling PyPy builds should be specified by enable"
log.warning(msg)
return GlobalOptions(
package_dir=package_dir,
@@ -476,62 +686,83 @@ class Options:
build_selector=build_selector,
test_selector=test_selector,
architectures=architectures,
container_engine=container_engine,
allow_empty=allow_empty,
)
def _check_pinned_image(self, value: str, pinned_images: Mapping[str, str]) -> None:
if (
value in {"manylinux1", "manylinux2010", "manylinux_2_24", "musllinux_1_1"}
and value not in self._image_warnings
):
self._image_warnings.add(value)
msg = (
f"Deprecated image {value!r}. This value will not work"
" in a future version of cibuildwheel. Either upgrade to a supported"
" image or continue using the deprecated image by pinning directly"
f" to {pinned_images[value]!r}."
)
log.warning(msg)
def build_options(self, identifier: str | None) -> BuildOptions:
"""
Compute BuildOptions for a single run configuration.
"""
with self.reader.identifier(identifier):
before_all = self.reader.get("before-all", sep=" && ")
before_all = self.reader.get("before-all", option_format=ListFormat(sep=" && "))
build_frontend_str = self.reader.get("build-frontend", env_plat=False)
environment_config = self.reader.get(
"environment", table={"item": '{k}="{v}"', "sep": " "}
environment_config = self.reader.get("environment", option_format=EnvironmentFormat())
environment_pass = self.reader.get(
"environment-pass", option_format=ListFormat(sep=" ")
).split()
before_build = self.reader.get("before-build", option_format=ListFormat(sep=" && "))
repair_command = self.reader.get(
"repair-wheel-command", option_format=ListFormat(sep=" && ")
)
environment_pass = self.reader.get("environment-pass", sep=" ").split()
before_build = self.reader.get("before-build", sep=" && ")
repair_command = self.reader.get("repair-wheel-command", sep=" && ")
config_settings = self.reader.get(
"config-settings", table={"item": "{k}={v}", "sep": " ", "quote": shlex.quote}
"config-settings", option_format=ShlexTableFormat(sep=" ", pair_sep="=")
)
dependency_versions = self.reader.get("dependency-versions")
test_command = self.reader.get("test-command", sep=" && ")
before_test = self.reader.get("before-test", sep=" && ")
test_requires = self.reader.get("test-requires", sep=" ").split()
test_extras = self.reader.get("test-extras", sep=",")
test_command = self.reader.get("test-command", option_format=ListFormat(sep=" && "))
before_test = self.reader.get("before-test", option_format=ListFormat(sep=" && "))
test_requires = self.reader.get(
"test-requires", option_format=ListFormat(sep=" ")
).split()
test_extras = self.reader.get("test-extras", option_format=ListFormat(sep=","))
test_groups_str = self.reader.get("test-groups", option_format=ListFormat(sep=" "))
test_groups = [x for x in test_groups_str.split() if x]
test_requirements_from_groups = resolve_dependency_groups(
self.pyproject_toml, *test_groups
)
build_verbosity_str = self.reader.get("build-verbosity")
build_frontend: BuildFrontend | Literal["default"]
if build_frontend_str == "build":
build_frontend = "build"
elif build_frontend_str == "pip":
build_frontend = "pip"
elif build_frontend_str == "default":
build_frontend = "default"
build_frontend_str = self.reader.get(
"build-frontend",
env_plat=False,
option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
)
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:
msg = f"Failed to parse build frontend. {e}"
raise errors.ConfigurationError(msg) from e
try:
environment = parse_environment(environment_config)
except (EnvironmentParseError, ValueError):
print(
f"cibuildwheel: Malformed environment option {environment_config!r}",
file=sys.stderr,
)
traceback.print_exc(None, sys.stderr)
sys.exit(2)
except (EnvironmentParseError, ValueError) as e:
msg = f"Malformed environment option {environment_config!r}"
raise errors.ConfigurationError(msg) from e
# Pass through environment variables
if self.platform == "linux":
for env_var_name in environment_pass:
for env_var_name in reversed(environment_pass):
with contextlib.suppress(KeyError):
environment.add(env_var_name, self.env[env_var_name])
environment.add(env_var_name, self.env[env_var_name], prepend=True)
if dependency_versions == "pinned":
dependency_constraints: None | (
@@ -553,6 +784,8 @@ class Options:
manylinux_images: dict[str, str] = {}
musllinux_images: dict[str, str] = {}
container_engine: OCIContainerEngineConfig | None = None
if self.platform == "linux":
all_pinned_container_images = _get_pinned_container_images()
@@ -567,6 +800,7 @@ class Options:
# default to manylinux2014
image = pinned_images["manylinux2014"]
elif config_value in pinned_images:
self._check_pinned_image(config_value, pinned_images)
image = pinned_images[config_value]
else:
image = config_value
@@ -579,19 +813,32 @@ class Options:
config_value = self.reader.get(f"musllinux-{build_platform}-image")
if not config_value:
image = pinned_images["musllinux_1_1"]
image = pinned_images["musllinux_1_2"]
elif config_value in pinned_images:
self._check_pinned_image(config_value, pinned_images)
image = pinned_images[config_value]
else:
image = config_value
musllinux_images[build_platform] = image
container_engine_str = self.reader.get(
"container-engine",
option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
)
try:
container_engine = OCIContainerEngineConfig.from_config_string(container_engine_str)
except ValueError as e:
msg = f"Failed to parse container config. {e}"
raise errors.ConfigurationError(msg) from e
return BuildOptions(
globals=self.globals,
test_command=test_command,
test_requires=test_requires,
test_requires=[*test_requires, *test_requirements_from_groups],
test_extras=test_extras,
test_groups=test_groups,
before_test=before_test,
before_build=before_build,
before_all=before_all,
@@ -603,6 +850,7 @@ class Options:
musllinux_images=musllinux_images or None,
build_frontend=build_frontend,
config_settings=config_settings,
container_engine=container_engine,
)
def check_for_invalid_configuration(self, identifiers: Iterable[str]) -> None:
@@ -628,13 +876,13 @@ class Options:
deprecated_selectors("CIBW_SKIP", build_selector.skip_config)
deprecated_selectors("CIBW_TEST_SKIP", test_selector.skip_config)
@cached_property
@functools.cached_property
def defaults(self) -> Options:
return Options(
platform=self.platform,
command_line_arguments=CommandLineArguments.defaults(),
env={},
read_config_file=False,
defaults=True,
)
def summary(self, identifiers: Iterable[str]) -> str:
@@ -764,6 +1012,6 @@ def _get_pinned_container_images() -> Mapping[str, Mapping[str, str]]:
def deprecated_selectors(name: str, selector: str, *, error: bool = False) -> None:
if "p2" in selector or "p35" in selector:
msg = f"cibuildwheel 2.x no longer supports Python < 3.6. Please use the 1.x series or update {name}"
print(msg, file=sys.stderr)
if error:
sys.exit(4)
raise errors.DeprecationError(msg)
log.warning(msg)
+71 -20
View File
@@ -3,23 +3,45 @@ from __future__ import annotations
import ast
import configparser
import contextlib
import sys
from pathlib import Path
from typing import Any
from ._compat import tomllib
import dependency_groups
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__"}
return len(consts) == 1
class Analyzer(ast.NodeVisitor):
@@ -33,15 +55,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)
# Must not be nested in an if or other structure
# 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 not hasattr(node.parent.parent.parent, "parent") # type: ignore[attr-defined]
and isinstance(node.value, Constant)
and isinstance(node.value, ast.Constant)
and (unnested or name_main_unnested)
):
self.requires_python = get_constant(node.value)
self.requires_python = node.value.value
def setup_py_python_requires(content: str) -> str | None:
@@ -54,15 +85,12 @@ def setup_py_python_requires(content: str) -> str | None:
return None
def get_requires_python_str(package_dir: Path) -> str | None:
def get_requires_python_str(package_dir: Path, pyproject_toml: dict[str, Any] | None) -> str | None:
"""Return the python requires string from the most canonical source available, or None"""
# Read in from pyproject.toml:project.requires-python
with contextlib.suppress(FileNotFoundError):
with (package_dir / "pyproject.toml").open("rb") as f1:
info = tomllib.load(f1)
with contextlib.suppress(KeyError, IndexError, TypeError):
return str(info["project"]["requires-python"])
with contextlib.suppress(KeyError, IndexError, TypeError):
return str((pyproject_toml or {})["project"]["requires-python"])
# Read in from setup.cfg:options.python_requires
config = configparser.ConfigParser()
@@ -76,3 +104,26 @@ def get_requires_python_str(package_dir: Path) -> str | None:
return setup_py_python_requires(f2.read())
return None
def resolve_dependency_groups(
pyproject_toml: dict[str, Any] | None, *groups: str
) -> tuple[str, ...]:
"""
Get the packages in dependency-groups for a package.
"""
if not groups:
return ()
if pyproject_toml is None:
msg = f"Didn't find a pyproject.toml, so can't read [dependency-groups] {groups!r} from it!"
raise FileNotFoundError(msg)
try:
dependency_groups_toml = pyproject_toml["dependency-groups"]
except KeyError:
msg = f"Didn't find [dependency-groups] in pyproject.toml, which is needed to resolve {groups!r}."
raise KeyError(msg) from None
return dependency_groups.resolve(dependency_groups_toml, *groups)
+407
View File
@@ -0,0 +1,407 @@
from __future__ import annotations
import os
import shutil
import sys
from collections.abc import Sequence, Set
from dataclasses import dataclass
from pathlib import Path
from filelock import FileLock
from . import errors
from .architecture import Architecture
from .environment import ParsedEnvironment
from .logger import log
from .options import Options
from .typing import PathOrStr
from .util import (
CIBW_CACHE_PATH,
BuildFrontendConfig,
BuildSelector,
call,
combine_constraints,
download,
ensure_node,
extract_zip,
find_compatible_wheel,
get_pip_version,
move_file,
prepare_command,
read_python_configs,
shell,
split_config_settings,
test_fail_cwd_file,
virtualenv,
)
@dataclass(frozen=True)
class PythonConfiguration:
version: str
identifier: str
pyodide_version: str
pyodide_build_version: str
emscripten_version: str
node_version: str
def install_emscripten(tmp: Path, version: str) -> Path:
# We don't need to match the emsdk version to the version we install, but
# we do for stability
url = f"https://github.com/emscripten-core/emsdk/archive/refs/tags/{version}.zip"
installation_path = CIBW_CACHE_PATH / f"emsdk-{version}"
emsdk_path = installation_path / f"emsdk-{version}/emsdk"
emcc_path = installation_path / f"emsdk-{version}/upstream/emscripten/emcc"
with FileLock(f"{installation_path}.lock"):
if installation_path.exists():
return emcc_path
emsdk_zip = tmp / "emsdk.zip"
download(url, emsdk_zip)
installation_path.mkdir()
extract_zip(emsdk_zip, installation_path)
call(emsdk_path, "install", version)
call(emsdk_path, "activate", version)
return emcc_path
def install_xbuildenv(env: dict[str, str], pyodide_build_version: str, pyodide_version: str) -> str:
"""Install a particular Pyodide xbuildenv version and set a path to the Pyodide root."""
# Since pyodide-build was unvendored from Pyodide v0.27.0, the versions of pyodide-build are
# not guaranteed to match the versions of Pyodide or be in sync with them. Hence, we shall
# specify the pyodide-build version in the root path, which will set up the xbuildenv for
# the requested Pyodide version.
pyodide_root = (
CIBW_CACHE_PATH
/ f".pyodide-xbuildenv-{pyodide_build_version}/{pyodide_version}/xbuildenv/pyodide-root"
)
with FileLock(CIBW_CACHE_PATH / "xbuildenv.lock"):
if pyodide_root.exists():
return str(pyodide_root)
# We don't want to mutate env but we need to delete any existing
# PYODIDE_ROOT so copy it first.
env = dict(env)
env.pop("PYODIDE_ROOT", None)
call(
"pyodide",
"xbuildenv",
"install",
pyodide_version,
env=env,
cwd=CIBW_CACHE_PATH,
)
return str(pyodide_root)
def get_base_python(identifier: str) -> Path:
implementation_id = identifier.split("-")[0]
majorminor = implementation_id[len("cp") :]
version_info = (int(majorminor[0]), int(majorminor[1:]))
if version_info == sys.version_info[:2]:
return Path(sys.executable)
major_minor = ".".join(str(v) for v in version_info)
python_name = f"python{major_minor}"
which_python = shutil.which(python_name)
if which_python is None:
msg = f"CPython {major_minor} is not installed."
raise errors.FatalError(msg)
return Path(which_python)
def setup_python(
tmp: Path,
python_configuration: PythonConfiguration,
dependency_constraint_flags: Sequence[PathOrStr],
environment: ParsedEnvironment,
) -> dict[str, str]:
base_python = get_base_python(python_configuration.identifier)
log.step("Setting up build environment...")
venv_path = tmp / "venv"
env = virtualenv(python_configuration.version, base_python, venv_path, [], use_uv=False)
venv_bin_path = venv_path / "bin"
assert venv_bin_path.exists()
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
# upgrade pip to the version matching our constraints
# if necessary, reinstall it to ensure that it's available on PATH as 'pip'
call(
"python",
"-m",
"pip",
"install",
"--upgrade",
"pip",
*dependency_constraint_flags,
env=env,
cwd=venv_path,
)
env = environment.as_dictionary(prev_environment=env)
# check what Python version we're on
which_python = call("which", "python", env=env, capture_stdout=True).strip()
print(which_python)
if which_python != str(venv_bin_path / "python"):
msg = "python available on PATH doesn't match our venv instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
raise errors.FatalError(msg)
call("python", "--version", env=env)
# check what pip version we're on
assert (venv_bin_path / "pip").exists()
which_pip = call("which", "pip", env=env, capture_stdout=True).strip()
print(which_pip)
if which_pip != str(venv_bin_path / "pip"):
msg = "pip available on PATH doesn't match our venv instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
raise errors.FatalError(msg)
call("pip", "--version", env=env)
log.step("Installing build tools...")
call(
"pip",
"install",
"--upgrade",
"auditwheel-emscripten",
"build[virtualenv]",
"pyodide-build",
*dependency_constraint_flags,
env=env,
)
log.step(f"Installing Emscripten version: {python_configuration.emscripten_version} ...")
emcc_path = install_emscripten(tmp, python_configuration.emscripten_version)
env["PATH"] = os.pathsep.join([str(emcc_path.parent), env["PATH"]])
log.step(f"Installing Pyodide xbuildenv version: {python_configuration.pyodide_version} ...")
env["PYODIDE_ROOT"] = install_xbuildenv(
env, python_configuration.pyodide_build_version, python_configuration.pyodide_version
)
return env
def get_python_configurations(
build_selector: BuildSelector,
architectures: Set[Architecture], # noqa: ARG001
) -> list[PythonConfiguration]:
full_python_configs = read_python_configs("pyodide")
python_configurations = [PythonConfiguration(**item) for item in full_python_configs]
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
return python_configurations
def build(options: Options, tmp_path: Path) -> None:
python_configurations = get_python_configurations(
options.globals.build_selector, options.globals.architectures
)
if not python_configurations:
return
try:
before_all_options_identifier = python_configurations[0].identifier
before_all_options = options.build_options(before_all_options_identifier)
if before_all_options.before_all:
log.step("Running before_all...")
env = before_all_options.environment.as_dictionary(prev_environment=os.environ)
before_all_prepared = prepare_command(
before_all_options.before_all, project=".", package=before_all_options.package_dir
)
shell(before_all_prepared, env=env)
built_wheels: list[Path] = []
for config in python_configurations:
build_options = options.build_options(config.identifier)
build_frontend = build_options.build_frontend or BuildFrontendConfig("build")
if build_frontend.name == "pip":
msg = "The pyodide platform doesn't support pip frontend"
raise errors.FatalError(msg)
log.build_start(config.identifier)
identifier_tmp_dir = tmp_path / config.identifier
built_wheel_dir = identifier_tmp_dir / "built_wheel"
repaired_wheel_dir = identifier_tmp_dir / "repaired_wheel"
identifier_tmp_dir.mkdir()
built_wheel_dir.mkdir()
repaired_wheel_dir.mkdir()
dependency_constraint_flags: Sequence[PathOrStr] = []
if build_options.dependency_constraints:
constraints_path = build_options.dependency_constraints.get_for_python_version(
config.version, variant="pyodide"
)
dependency_constraint_flags = ["-c", constraints_path]
env = setup_python(
identifier_tmp_dir / "build",
config,
dependency_constraint_flags,
build_options.environment,
)
pip_version = get_pip_version(env)
# The Pyodide command line runner mounts all directories in the host
# filesystem into the Pyodide file system, except for the custom
# file systems /dev, /lib, /proc, and /tmp. Mounting the mount
# points for alternate file systems causes some mysterious failure
# of the process (it just quits without any clear error).
#
# Because of this, by default Pyodide can't see anything under /tmp.
# This environment variable tells it also to mount our temp
# directory.
oldmounts = ""
extra_mounts = [str(identifier_tmp_dir)]
if str(Path(".").resolve()).startswith("/tmp"):
extra_mounts.append(str(Path(".").resolve()))
if "_PYODIDE_EXTRA_MOUNTS" in env:
oldmounts = env["_PYODIDE_EXTRA_MOUNTS"] + ":"
env["_PYODIDE_EXTRA_MOUNTS"] = oldmounts + ":".join(extra_mounts)
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
if compatible_wheel:
log.step_end()
print(
f"\nFound previously built wheel {compatible_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
)
built_wheel = compatible_wheel
else:
if build_options.before_build:
log.step("Running before_build...")
before_build_prepared = prepare_command(
build_options.before_build, project=".", package=build_options.package_dir
)
shell(before_build_prepared, env=env)
log.step("Building wheel...")
extra_flags = split_config_settings(build_options.config_settings, "build")
extra_flags += build_frontend.args
if not 0 <= build_options.build_verbosity < 2:
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
log.warning(msg)
build_env = env.copy()
if build_options.dependency_constraints:
combine_constraints(build_env, constraints_path, identifier_tmp_dir)
build_env["VIRTUALENV_PIP"] = pip_version
call(
"pyodide",
"build",
build_options.package_dir,
f"--outdir={built_wheel_dir}",
*extra_flags,
env=build_env,
)
built_wheel = next(built_wheel_dir.glob("*.whl"))
if built_wheel.name.endswith("none-any.whl"):
raise errors.NonPlatformWheelError()
if build_options.repair_command:
log.step("Repairing wheel...")
repair_command_prepared = prepare_command(
build_options.repair_command,
wheel=built_wheel,
dest_dir=repaired_wheel_dir,
)
shell(repair_command_prepared, env=env)
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
if build_options.test_command and build_options.test_selector(config.identifier):
log.step("Testing wheel...")
venv_dir = identifier_tmp_dir / "venv-test"
# set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time.
virtualenv_env = env.copy()
virtualenv_env["PATH"] = os.pathsep.join(
[
str(ensure_node(config.node_version)),
virtualenv_env["PATH"],
]
)
# pyodide venv uses virtualenv under the hood
# use the pip embedded with virtualenv & disable network updates
virtualenv_create_env = virtualenv_env.copy()
virtualenv_create_env["VIRTUALENV_PIP"] = pip_version
virtualenv_create_env["VIRTUALENV_NO_PERIODIC_UPDATE"] = "1"
call("pyodide", "venv", venv_dir, env=virtualenv_create_env)
virtualenv_env["PATH"] = os.pathsep.join(
[
str(venv_dir / "bin"),
virtualenv_env["PATH"],
]
)
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
# check that we are using the Python from the virtual environment
call("which", "python", env=virtualenv_env)
if build_options.before_test:
before_test_prepared = prepare_command(
build_options.before_test,
project=".",
package=build_options.package_dir,
)
shell(before_test_prepared, env=virtualenv_env)
# install the wheel
call(
"pip",
"install",
f"{repaired_wheel}{build_options.test_extras}",
env=virtualenv_env,
)
# test the wheel
if build_options.test_requires:
call("pip", "install", *build_options.test_requires, env=virtualenv_env)
# run the tests from a temp dir, with an absolute path in the command
# (this ensures that Python runs the tests against the installed wheel
# and not the repo code)
test_command_prepared = prepare_command(
build_options.test_command,
project=Path(".").resolve(),
package=build_options.package_dir.resolve(),
)
test_cwd = identifier_tmp_dir / "test_cwd"
test_cwd.mkdir(exist_ok=True)
(test_cwd / "test_fail.py").write_text(test_fail_cwd_file.read_text())
shell(test_command_prepared, cwd=test_cwd, env=virtualenv_env)
# we're all done here; move it to output (overwrite existing)
if compatible_wheel is None:
output_wheel = build_options.output_dir.joinpath(repaired_wheel.name)
moved_wheel = move_file(repaired_wheel, output_wheel)
if moved_wheel != output_wheel.resolve():
log.warning(
"{repaired_wheel} was moved to {moved_wheel} instead of {output_wheel}"
)
built_wheels.append(output_wheel)
finally:
pass
+82 -15
View File
@@ -7,6 +7,8 @@ python_configurations = [
{ identifier = "cp310-manylinux_x86_64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-manylinux_x86_64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-manylinux_x86_64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-manylinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-manylinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-manylinux_i686", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_i686", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" },
@@ -14,9 +16,13 @@ python_configurations = [
{ identifier = "cp310-manylinux_i686", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-manylinux_i686", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-manylinux_i686", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-manylinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-manylinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "pp37-manylinux_x86_64", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
{ identifier = "pp38-manylinux_x86_64", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" },
{ identifier = "pp39-manylinux_x86_64", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" },
{ identifier = "pp310-manylinux_x86_64", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" },
{ identifier = "pp311-manylinux_x86_64", version = "3.11", path_str = "/opt/python/pp311-pypy311_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" },
@@ -24,6 +30,8 @@ python_configurations = [
{ identifier = "cp310-manylinux_aarch64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-manylinux_aarch64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-manylinux_aarch64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-manylinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-manylinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-manylinux_ppc64le", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_ppc64le", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_ppc64le", version = "3.8", path_str = "/opt/python/cp38-cp38" },
@@ -31,6 +39,8 @@ python_configurations = [
{ identifier = "cp310-manylinux_ppc64le", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-manylinux_ppc64le", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-manylinux_ppc64le", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-manylinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-manylinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-manylinux_s390x", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_s390x", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_s390x", version = "3.8", path_str = "/opt/python/cp38-cp38" },
@@ -38,12 +48,27 @@ python_configurations = [
{ identifier = "cp310-manylinux_s390x", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-manylinux_s390x", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-manylinux_s390x", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-manylinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-manylinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-manylinux_armv7l", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_armv7l", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_armv7l", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_armv7l", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-manylinux_armv7l", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-manylinux_armv7l", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-manylinux_armv7l", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-manylinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-manylinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "pp37-manylinux_aarch64", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
{ identifier = "pp38-manylinux_aarch64", version = "3.8", path_str = "/opt/python/pp38-pypy38_pp73" },
{ identifier = "pp39-manylinux_aarch64", version = "3.9", path_str = "/opt/python/pp39-pypy39_pp73" },
{ identifier = "pp310-manylinux_aarch64", version = "3.10", path_str = "/opt/python/pp310-pypy310_pp73" },
{ identifier = "pp311-manylinux_aarch64", version = "3.11", path_str = "/opt/python/pp311-pypy311_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 = "pp311-manylinux_i686", version = "3.11", path_str = "/opt/python/pp311-pypy311_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" },
@@ -51,6 +76,8 @@ python_configurations = [
{ identifier = "cp310-musllinux_x86_64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-musllinux_x86_64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-musllinux_x86_64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_x86_64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-musllinux_i686", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-musllinux_i686", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-musllinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" },
@@ -58,6 +85,8 @@ python_configurations = [
{ identifier = "cp310-musllinux_i686", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-musllinux_i686", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-musllinux_i686", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_i686", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-musllinux_aarch64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-musllinux_aarch64", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-musllinux_aarch64", version = "3.8", path_str = "/opt/python/cp38-cp38" },
@@ -65,6 +94,8 @@ python_configurations = [
{ identifier = "cp310-musllinux_aarch64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-musllinux_aarch64", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-musllinux_aarch64", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_aarch64", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-musllinux_ppc64le", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-musllinux_ppc64le", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-musllinux_ppc64le", version = "3.8", path_str = "/opt/python/cp38-cp38" },
@@ -72,6 +103,8 @@ python_configurations = [
{ identifier = "cp310-musllinux_ppc64le", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-musllinux_ppc64le", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-musllinux_ppc64le", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_ppc64le", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-musllinux_s390x", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-musllinux_s390x", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-musllinux_s390x", version = "3.8", path_str = "/opt/python/cp38-cp38" },
@@ -79,6 +112,17 @@ python_configurations = [
{ identifier = "cp310-musllinux_s390x", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-musllinux_s390x", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-musllinux_s390x", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_s390x", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
{ identifier = "cp36-musllinux_armv7l", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-musllinux_armv7l", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-musllinux_armv7l", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-musllinux_armv7l", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-musllinux_armv7l", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp311-musllinux_armv7l", version = "3.11", path_str = "/opt/python/cp311-cp311" },
{ identifier = "cp312-musllinux_armv7l", version = "3.12", path_str = "/opt/python/cp312-cp312" },
{ identifier = "cp313-musllinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313" },
{ identifier = "cp313t-musllinux_armv7l", version = "3.13", path_str = "/opt/python/cp313-cp313t" },
]
[macos]
@@ -94,17 +138,27 @@ python_configurations = [
{ identifier = "cp310-macosx_x86_64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg" },
{ identifier = "cp310-macosx_arm64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg" },
{ identifier = "cp310-macosx_universal2", version = "3.10", url = "https://www.python.org/ftp/python/3.10.11/python-3.10.11-macos11.pkg" },
{ identifier = "cp311-macosx_x86_64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.4/python-3.11.4-macos11.pkg" },
{ identifier = "cp311-macosx_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.4/python-3.11.4-macos11.pkg" },
{ identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.4/python-3.11.4-macos11.pkg" },
{ identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0b2-macos11.pkg" },
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0b2-macos11.pkg" },
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.0/python-3.12.0b2-macos11.pkg" },
{ identifier = "cp311-macosx_x86_64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
{ identifier = "cp311-macosx_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
{ identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
{ identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.9/python-3.12.9-macos11.pkg" },
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.9/python-3.12.9-macos11.pkg" },
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.9/python-3.12.9-macos11.pkg" },
{ identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.2/python-3.13.2-macos11.pkg" },
{ identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.2/python-3.13.2-macos11.pkg" },
{ identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.2/python-3.13.2-macos11.pkg" },
{ identifier = "cp313t-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.2/python-3.13.2-macos11.pkg" },
{ identifier = "cp313t-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.2/python-3.13.2-macos11.pkg" },
{ identifier = "cp313t-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.2/python-3.13.2-macos11.pkg" },
{ identifier = "pp37-macosx_x86_64", version = "3.7", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.9-osx64.tar.bz2" },
{ identifier = "pp38-macosx_x86_64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_x86_64.tar.bz2" },
{ identifier = "pp38-macosx_arm64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_arm64.tar.bz2" },
{ identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.11-macos_x86_64.tar.bz2" },
{ identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.11-macos_arm64.tar.bz2" },
{ identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" },
{ identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2" },
{ identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_x86_64.tar.bz2" },
{ identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-macos_arm64.tar.bz2" },
{ identifier = "pp311-macosx_x86_64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.19-macos_x86_64.tar.bz2" },
{ identifier = "pp311-macosx_arm64", version = "3.11", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.19-macos_arm64.tar.bz2" },
]
[windows]
@@ -119,15 +173,28 @@ python_configurations = [
{ identifier = "cp39-win_amd64", version = "3.9.13", arch = "64" },
{ identifier = "cp310-win32", version = "3.10.11", arch = "32" },
{ identifier = "cp310-win_amd64", version = "3.10.11", arch = "64" },
{ identifier = "cp311-win32", version = "3.11.4", arch = "32" },
{ identifier = "cp311-win_amd64", version = "3.11.4", arch = "64" },
{ identifier = "cp312-win32", version = "3.12.0-b2", arch = "32" },
{ identifier = "cp312-win_amd64", version = "3.12.0-b2", arch = "64" },
{ identifier = "cp311-win32", version = "3.11.9", arch = "32" },
{ identifier = "cp311-win_amd64", version = "3.11.9", arch = "64" },
{ identifier = "cp312-win32", version = "3.12.9", arch = "32" },
{ identifier = "cp312-win_amd64", version = "3.12.9", arch = "64" },
{ identifier = "cp313-win32", version = "3.13.2", arch = "32" },
{ identifier = "cp313t-win32", version = "3.13.2", arch = "32" },
{ identifier = "cp313-win_amd64", version = "3.13.2", arch = "64" },
{ identifier = "cp313t-win_amd64", version = "3.13.2", arch = "64" },
{ identifier = "cp39-win_arm64", version = "3.9.10", arch = "ARM64" },
{ identifier = "cp310-win_arm64", version = "3.10.11", arch = "ARM64" },
{ identifier = "cp311-win_arm64", version = "3.11.4", arch = "ARM64" },
{ identifier = "cp312-win_arm64", version = "3.12.0-b2", arch = "ARM64" },
{ identifier = "cp311-win_arm64", version = "3.11.9", arch = "ARM64" },
{ identifier = "cp312-win_arm64", version = "3.12.9", arch = "ARM64" },
{ identifier = "cp313-win_arm64", version = "3.13.2", arch = "ARM64" },
{ identifier = "cp313t-win_arm64", version = "3.13.2", arch = "ARM64" },
{ identifier = "pp37-win_amd64", version = "3.7", arch = "64", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.9-win64.zip" },
{ identifier = "pp38-win_amd64", version = "3.8", arch = "64", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" },
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.11-win64.zip" },
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" },
{ identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.19-win64.zip" },
{ identifier = "pp311-win_amd64", version = "3.11", arch = "64", url = "https://downloads.python.org/pypy/pypy3.11-v7.3.19-win64.zip" },
]
[pyodide]
python_configurations = [
{ identifier = "cp312-pyodide_wasm32", version = "3.12", pyodide_version = "0.27.0", pyodide_build_version = "0.29.2", emscripten_version = "3.1.58", node_version = "v20" },
]
@@ -0,0 +1,897 @@
{
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/resources/cibuildwheel.schema.json",
"$defs": {
"inherit": {
"enum": [
"none",
"prepend",
"append"
],
"default": "none",
"description": "How to inherit the parent's value."
},
"enable": {
"enum": [
"cpython-eol",
"cpython-freethreading",
"cpython-prerelease",
"pypy-eol"
]
},
"description": "A Python version or flavor to enable."
},
"additionalProperties": false,
"description": "cibuildwheel's settings.",
"type": "object",
"properties": {
"archs": {
"description": "Change the architectures built on your machine by default.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_ARCHS"
},
"before-all": {
"description": "Execute a shell command on the build system before any wheels are built.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_BEFORE_ALL"
},
"before-build": {
"description": "Execute a shell command preparing each wheel's build.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_BEFORE_BUILD"
},
"before-test": {
"description": "Execute a shell command before testing each wheel.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_BEFORE_TEST"
},
"build": {
"default": [
"*"
],
"description": "Choose the Python versions to build.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_BUILD"
},
"build-frontend": {
"default": "default",
"description": "Set the tool to use to build, either \"pip\" (default for now), \"build\", or \"build[uv]\"",
"oneOf": [
{
"enum": [
"pip",
"build",
"build[uv]",
"default"
]
},
{
"type": "string",
"pattern": "^pip; ?args:"
},
{
"type": "string",
"pattern": "^build; ?args:"
},
{
"type": "string",
"pattern": "^build\\[uv\\]; ?args:"
},
{
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"enum": [
"pip",
"build",
"build[uv]"
]
},
"args": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
],
"title": "CIBW_BUILD_FRONTEND"
},
"build-verbosity": {
"type": "integer",
"minimum": -3,
"maximum": 3,
"default": 0,
"description": "Increase/decrease the output of pip wheel.",
"title": "CIBW_BUILD_VERBOSITY"
},
"config-settings": {
"description": "Specify config-settings for the build backend.",
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"patternProperties": {
".+": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
}
}
],
"title": "CIBW_CONFIG_SETTINGS"
},
"container-engine": {
"oneOf": [
{
"enum": [
"docker",
"podman"
]
},
{
"type": "string",
"pattern": "^docker; ?(create_args|disable_host_mount):"
},
{
"type": "string",
"pattern": "^podman; ?(create_args|disable_host_mount):"
},
{
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"enum": [
"docker",
"podman"
]
},
"create-args": {
"type": "array",
"items": {
"type": "string"
}
},
"disable-host-mount": {
"type": "boolean"
}
}
}
],
"title": "CIBW_CONTAINER_ENGINE"
},
"dependency-versions": {
"default": "pinned",
"description": "Specify how cibuildwheel controls the versions of the tools it uses",
"type": "string",
"title": "CIBW_DEPENDENCY_VERSIONS"
},
"enable": {
"description": "Enable or disable certain builds.",
"oneOf": [
{
"$ref": "#/$defs/enable"
},
{
"type": "array",
"items": {
"$ref": "#/$defs/enable"
}
}
],
"title": "CIBW_ENABLE"
},
"environment": {
"description": "Set environment variables needed during the build.",
"oneOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"patternProperties": {
".+": {
"type": "string"
}
}
}
],
"title": "CIBW_ENVIRONMENT"
},
"environment-pass": {
"description": "Set environment variables on the host to pass-through to the container during the build.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_ENVIRONMENT_PASS"
},
"free-threaded-support": {
"type": "boolean",
"default": false,
"description": "The project supports free-threaded builds of Python (PEP703)",
"title": "CIBW_FREE_THREADED_SUPPORT"
},
"manylinux-aarch64-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_AARCH64_IMAGE"
},
"manylinux-armv7l-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_ARMV7L_IMAGE"
},
"manylinux-i686-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_I686_IMAGE"
},
"manylinux-ppc64le-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_PPC64LE_IMAGE"
},
"manylinux-pypy_aarch64-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_PYPY_AARCH64_IMAGE"
},
"manylinux-pypy_i686-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_PYPY_I686_IMAGE"
},
"manylinux-pypy_x86_64-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_PYPY_X86_64_IMAGE"
},
"manylinux-s390x-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_S390X_IMAGE"
},
"manylinux-x86_64-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MANYLINUX_X86_64_IMAGE"
},
"musllinux-aarch64-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_AARCH64_IMAGE"
},
"musllinux-armv7l-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_ARMV7L_IMAGE"
},
"musllinux-i686-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_I686_IMAGE"
},
"musllinux-ppc64le-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_PPC64LE_IMAGE"
},
"musllinux-s390x-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_S390X_IMAGE"
},
"musllinux-x86_64-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
"title": "CIBW_MUSLLINUX_X86_64_IMAGE"
},
"repair-wheel-command": {
"description": "Execute a shell command to repair each built wheel.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_REPAIR_WHEEL_COMMAND"
},
"skip": {
"description": "Choose the Python versions to skip.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_SKIP"
},
"test-command": {
"description": "Execute a shell command to test each built wheel.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_TEST_COMMAND"
},
"test-extras": {
"description": "Install your wheel for testing using `extras_require`",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_TEST_EXTRAS"
},
"test-groups": {
"description": "Install extra groups when testing",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_TEST_GROUPS"
},
"test-requires": {
"description": "Install Python dependencies before running the tests",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_TEST_REQUIRES"
},
"test-skip": {
"description": "Skip running tests on some builds.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_TEST_SKIP"
},
"overrides": {
"type": "array",
"description": "An overrides array",
"items": {
"type": "object",
"required": [
"select"
],
"minProperties": 2,
"additionalProperties": false,
"properties": {
"select": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"inherit": {
"type": "object",
"additionalProperties": false,
"properties": {
"before-all": {
"$ref": "#/$defs/inherit"
},
"before-build": {
"$ref": "#/$defs/inherit"
},
"before-test": {
"$ref": "#/$defs/inherit"
},
"config-settings": {
"$ref": "#/$defs/inherit"
},
"container-engine": {
"$ref": "#/$defs/inherit"
},
"environment": {
"$ref": "#/$defs/inherit"
},
"environment-pass": {
"$ref": "#/$defs/inherit"
},
"repair-wheel-command": {
"$ref": "#/$defs/inherit"
},
"test-command": {
"$ref": "#/$defs/inherit"
},
"test-extras": {
"$ref": "#/$defs/inherit"
},
"test-requires": {
"$ref": "#/$defs/inherit"
}
}
},
"before-all": {
"$ref": "#/properties/before-all"
},
"before-build": {
"$ref": "#/properties/before-build"
},
"before-test": {
"$ref": "#/properties/before-test"
},
"build-frontend": {
"$ref": "#/properties/build-frontend"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
},
"config-settings": {
"$ref": "#/properties/config-settings"
},
"container-engine": {
"$ref": "#/properties/container-engine"
},
"dependency-versions": {
"$ref": "#/properties/dependency-versions"
},
"environment": {
"$ref": "#/properties/environment"
},
"environment-pass": {
"$ref": "#/properties/environment-pass"
},
"manylinux-aarch64-image": {
"$ref": "#/properties/manylinux-aarch64-image"
},
"manylinux-armv7l-image": {
"$ref": "#/properties/manylinux-armv7l-image"
},
"manylinux-i686-image": {
"$ref": "#/properties/manylinux-i686-image"
},
"manylinux-ppc64le-image": {
"$ref": "#/properties/manylinux-ppc64le-image"
},
"manylinux-pypy_aarch64-image": {
"$ref": "#/properties/manylinux-pypy_aarch64-image"
},
"manylinux-pypy_i686-image": {
"$ref": "#/properties/manylinux-pypy_i686-image"
},
"manylinux-pypy_x86_64-image": {
"$ref": "#/properties/manylinux-pypy_x86_64-image"
},
"manylinux-s390x-image": {
"$ref": "#/properties/manylinux-s390x-image"
},
"manylinux-x86_64-image": {
"$ref": "#/properties/manylinux-x86_64-image"
},
"musllinux-aarch64-image": {
"$ref": "#/properties/musllinux-aarch64-image"
},
"musllinux-armv7l-image": {
"$ref": "#/properties/musllinux-armv7l-image"
},
"musllinux-i686-image": {
"$ref": "#/properties/musllinux-i686-image"
},
"musllinux-ppc64le-image": {
"$ref": "#/properties/musllinux-ppc64le-image"
},
"musllinux-s390x-image": {
"$ref": "#/properties/musllinux-s390x-image"
},
"musllinux-x86_64-image": {
"$ref": "#/properties/musllinux-x86_64-image"
},
"repair-wheel-command": {
"$ref": "#/properties/repair-wheel-command"
},
"test-command": {
"$ref": "#/properties/test-command"
},
"test-extras": {
"$ref": "#/properties/test-extras"
},
"test-groups": {
"$ref": "#/properties/test-groups"
},
"test-requires": {
"$ref": "#/properties/test-requires"
}
}
}
},
"linux": {
"type": "object",
"additionalProperties": false,
"properties": {
"archs": {
"$ref": "#/properties/archs"
},
"before-all": {
"$ref": "#/properties/before-all"
},
"before-build": {
"$ref": "#/properties/before-build"
},
"before-test": {
"$ref": "#/properties/before-test"
},
"build-frontend": {
"$ref": "#/properties/build-frontend"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
},
"config-settings": {
"$ref": "#/properties/config-settings"
},
"container-engine": {
"$ref": "#/properties/container-engine"
},
"environment": {
"$ref": "#/properties/environment"
},
"environment-pass": {
"$ref": "#/properties/environment-pass"
},
"manylinux-aarch64-image": {
"$ref": "#/properties/manylinux-aarch64-image"
},
"manylinux-armv7l-image": {
"$ref": "#/properties/manylinux-armv7l-image"
},
"manylinux-i686-image": {
"$ref": "#/properties/manylinux-i686-image"
},
"manylinux-ppc64le-image": {
"$ref": "#/properties/manylinux-ppc64le-image"
},
"manylinux-pypy_aarch64-image": {
"$ref": "#/properties/manylinux-pypy_aarch64-image"
},
"manylinux-pypy_i686-image": {
"$ref": "#/properties/manylinux-pypy_i686-image"
},
"manylinux-pypy_x86_64-image": {
"$ref": "#/properties/manylinux-pypy_x86_64-image"
},
"manylinux-s390x-image": {
"$ref": "#/properties/manylinux-s390x-image"
},
"manylinux-x86_64-image": {
"$ref": "#/properties/manylinux-x86_64-image"
},
"musllinux-aarch64-image": {
"$ref": "#/properties/musllinux-aarch64-image"
},
"musllinux-armv7l-image": {
"$ref": "#/properties/musllinux-armv7l-image"
},
"musllinux-i686-image": {
"$ref": "#/properties/musllinux-i686-image"
},
"musllinux-ppc64le-image": {
"$ref": "#/properties/musllinux-ppc64le-image"
},
"musllinux-s390x-image": {
"$ref": "#/properties/musllinux-s390x-image"
},
"musllinux-x86_64-image": {
"$ref": "#/properties/musllinux-x86_64-image"
},
"repair-wheel-command": {
"description": "Execute a shell command to repair each built wheel.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_REPAIR_WHEEL_COMMAND",
"default": "auditwheel repair -w {dest_dir} {wheel}"
},
"test-command": {
"$ref": "#/properties/test-command"
},
"test-extras": {
"$ref": "#/properties/test-extras"
},
"test-groups": {
"$ref": "#/properties/test-groups"
},
"test-requires": {
"$ref": "#/properties/test-requires"
}
}
},
"windows": {
"type": "object",
"additionalProperties": false,
"properties": {
"archs": {
"$ref": "#/properties/archs"
},
"before-all": {
"$ref": "#/properties/before-all"
},
"before-build": {
"$ref": "#/properties/before-build"
},
"before-test": {
"$ref": "#/properties/before-test"
},
"build-frontend": {
"$ref": "#/properties/build-frontend"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
},
"config-settings": {
"$ref": "#/properties/config-settings"
},
"dependency-versions": {
"$ref": "#/properties/dependency-versions"
},
"environment": {
"$ref": "#/properties/environment"
},
"repair-wheel-command": {
"$ref": "#/properties/repair-wheel-command"
},
"test-command": {
"$ref": "#/properties/test-command"
},
"test-extras": {
"$ref": "#/properties/test-extras"
},
"test-groups": {
"$ref": "#/properties/test-groups"
},
"test-requires": {
"$ref": "#/properties/test-requires"
}
}
},
"macos": {
"type": "object",
"additionalProperties": false,
"properties": {
"archs": {
"$ref": "#/properties/archs"
},
"before-all": {
"$ref": "#/properties/before-all"
},
"before-build": {
"$ref": "#/properties/before-build"
},
"before-test": {
"$ref": "#/properties/before-test"
},
"build-frontend": {
"$ref": "#/properties/build-frontend"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
},
"config-settings": {
"$ref": "#/properties/config-settings"
},
"dependency-versions": {
"$ref": "#/properties/dependency-versions"
},
"environment": {
"$ref": "#/properties/environment"
},
"repair-wheel-command": {
"description": "Execute a shell command to repair each built wheel.",
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"title": "CIBW_REPAIR_WHEEL_COMMAND",
"default": "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
},
"test-command": {
"$ref": "#/properties/test-command"
},
"test-extras": {
"$ref": "#/properties/test-extras"
},
"test-groups": {
"$ref": "#/properties/test-groups"
},
"test-requires": {
"$ref": "#/properties/test-requires"
}
}
},
"pyodide": {
"type": "object",
"additionalProperties": false,
"properties": {
"archs": {
"$ref": "#/properties/archs"
},
"before-all": {
"$ref": "#/properties/before-all"
},
"before-build": {
"$ref": "#/properties/before-build"
},
"before-test": {
"$ref": "#/properties/before-test"
},
"build-frontend": {
"$ref": "#/properties/build-frontend"
},
"build-verbosity": {
"$ref": "#/properties/build-verbosity"
},
"config-settings": {
"$ref": "#/properties/config-settings"
},
"dependency-versions": {
"$ref": "#/properties/dependency-versions"
},
"environment": {
"$ref": "#/properties/environment"
},
"repair-wheel-command": {
"$ref": "#/properties/repair-wheel-command"
},
"test-command": {
"$ref": "#/properties/test-command"
},
"test-extras": {
"$ref": "#/properties/test-extras"
},
"test-groups": {
"$ref": "#/properties/test-groups"
},
"test-requires": {
"$ref": "#/properties/test-requires"
}
}
}
}
}
@@ -0,0 +1,112 @@
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
annotated-types==0.7.0
# via pydantic
anyio==4.9.0
# via httpx
auditwheel-emscripten==0.0.16
# via pyodide-build
build==1.2.2.post1
# via
# -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build
certifi==2025.1.31
# via
# httpcore
# httpx
# requests
charset-normalizer==3.4.1
# via requests
click==8.1.8
# via typer
cmake==3.31.6
# via pyodide-build
distlib==0.3.9
# via virtualenv
filelock==3.18.0
# via virtualenv
h11==0.14.0
# via httpcore
httpcore==1.0.7
# via httpx
httpx==0.28.1
# via unearth
idna==3.10
# via
# anyio
# httpx
# requests
leb128==1.0.8
# via auditwheel-emscripten
markdown-it-py==3.0.0
# via rich
mdurl==0.1.2
# via markdown-it-py
packaging==24.2
# via
# auditwheel-emscripten
# build
# pyodide-build
# unearth
pip==25.0.1
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
platformdirs==4.3.7
# via virtualenv
pydantic==2.10.6
# via
# pyodide-build
# pyodide-lock
pydantic-core==2.27.2
# via pydantic
pygments==2.19.1
# via rich
pyodide-build==0.29.2
# via -r .nox/update_constraints/tmp/constraints-pyodide.in
pyodide-cli==0.2.4
# via
# auditwheel-emscripten
# pyodide-build
pyodide-lock==0.1.0a7
# via pyodide-build
pyproject-hooks==1.2.0
# via build
requests==2.32.3
# via pyodide-build
resolvelib==1.1.0
# via pyodide-build
rich==13.9.4
# via
# pyodide-build
# pyodide-cli
# typer
ruamel-yaml==0.18.10
# via pyodide-build
ruamel-yaml-clib==0.2.12
# via ruamel-yaml
shellingham==1.5.4
# via typer
sniffio==1.3.1
# via anyio
typer==0.15.2
# via
# auditwheel-emscripten
# pyodide-build
# pyodide-cli
typing-extensions==4.12.2
# via
# anyio
# pydantic
# pydantic-core
# typer
unearth==0.17.3
# via pyodide-build
urllib3==2.3.0
# via requests
virtualenv==20.29.3
# via
# build
# pyodide-build
wheel==0.45.1
# via
# auditwheel-emscripten
# pyodide-build
@@ -1,28 +1,34 @@
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
# nox -s update_constraints-3.10
#
delocate==0.10.4
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.2.2.post1
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.12.0
filelock==3.18.0
# via virtualenv
packaging==23.1
importlib-metadata==8.6.1
# via build
macholib==1.16.3
# via delocate
platformdirs==3.5.1
packaging==24.2
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.7
# via virtualenv
typing-extensions==4.6.3
pyproject-hooks==1.2.0
# via build
tomli==2.2.1
# via build
typing-extensions==4.12.2
# via delocate
virtualenv==20.23.0
# via -r cibuildwheel/resources/constraints.in
wheel==0.40.0
# via -r cibuildwheel/resources/constraints.in
# The following packages are considered to be unsafe in a requirements file:
pip==23.1.2
# via -r cibuildwheel/resources/constraints.in
setuptools==67.8.0
virtualenv==20.29.3
# via -r cibuildwheel/resources/constraints.in
zipp==3.21.0
# via importlib-metadata
@@ -1,28 +1,28 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# nox -s update_constraints-3.11
#
delocate==0.10.4
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.2.2.post1
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.12.0
filelock==3.18.0
# via virtualenv
packaging==23.1
macholib==1.16.3
# via delocate
platformdirs==3.5.1
packaging==24.2
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.7
# via virtualenv
typing-extensions==4.6.3
pyproject-hooks==1.2.0
# via build
typing-extensions==4.12.2
# via delocate
virtualenv==20.23.0
# via -r cibuildwheel/resources/constraints.in
wheel==0.40.0
# via -r cibuildwheel/resources/constraints.in
# The following packages are considered to be unsafe in a requirements file:
pip==23.1.2
# via -r cibuildwheel/resources/constraints.in
setuptools==67.8.0
virtualenv==20.29.3
# via -r cibuildwheel/resources/constraints.in
@@ -1,28 +1,28 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# nox -s update_constraints-3.12
#
delocate==0.10.4
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.2.2.post1
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.12.0
filelock==3.18.0
# via virtualenv
packaging==23.1
macholib==1.16.3
# via delocate
platformdirs==3.5.1
packaging==24.2
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.7
# via virtualenv
typing-extensions==4.6.3
pyproject-hooks==1.2.0
# via build
typing-extensions==4.12.2
# via delocate
virtualenv==20.23.0
# via -r cibuildwheel/resources/constraints.in
wheel==0.40.0
# via -r cibuildwheel/resources/constraints.in
# The following packages are considered to be unsafe in a requirements file:
pip==23.1.2
# via -r cibuildwheel/resources/constraints.in
setuptools==67.8.0
virtualenv==20.29.3
# via -r cibuildwheel/resources/constraints.in
@@ -0,0 +1,28 @@
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.2.2.post1
# via -r cibuildwheel/resources/constraints.in
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.18.0
# via virtualenv
macholib==1.16.3
# via delocate
packaging==24.2
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.7
# via virtualenv
pyproject-hooks==1.2.0
# via build
typing-extensions==4.12.2
# via delocate
virtualenv==20.29.3
# via -r cibuildwheel/resources/constraints.in
@@ -4,18 +4,33 @@
#
# nox -s update_constraints-3.6
#
build==0.9.0
# via -r cibuildwheel/resources/constraints.in
delocate==0.10.2
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
distlib==0.3.8
# via virtualenv
filelock==3.4.1
# via virtualenv
importlib-metadata==4.8.3
# via virtualenv
# via
# build
# pep517
# virtualenv
importlib-resources==5.4.0
# via virtualenv
packaging==21.3
# via build
pep517==0.13.1
# via build
platformdirs==2.4.0
# via virtualenv
pyparsing==3.1.1
# via packaging
tomli==1.2.3
# via
# build
# pep517
typing-extensions==4.1.1
# via
# delocate
@@ -23,13 +38,12 @@ typing-extensions==4.1.1
virtualenv==20.17.1
# via -r cibuildwheel/resources/constraints.in
wheel==0.37.1
# via
# -r cibuildwheel/resources/constraints.in
# delocate
# via delocate
zipp==3.6.0
# via
# importlib-metadata
# importlib-resources
# pep517
# The following packages are considered to be unsafe in a requirements file:
pip==21.3.1
+27 -23
View File
@@ -1,35 +1,39 @@
#
# This file is autogenerated by pip-compile with Python 3.7
# by the following command:
#
# nox -s update_constraints-3.7
#
delocate==0.10.4
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.1.1
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.12.0
filelock==3.12.2
# via virtualenv
importlib-metadata==6.6.0
# via virtualenv
packaging==23.1
importlib-metadata==6.7.0
# via
# build
# virtualenv
macholib==1.16.3
# via delocate
platformdirs==3.5.1
packaging==24.0
# via
# build
# delocate
pip==24.0
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.0.0
# via virtualenv
typing-extensions==4.6.3
pyproject-hooks==1.2.0
# via build
tomli==2.0.1
# via build
typing-extensions==4.7.1
# via
# delocate
# importlib-metadata
# platformdirs
virtualenv==20.23.0
# via -r cibuildwheel/resources/constraints.in
wheel==0.40.0
virtualenv==20.26.6
# via -r cibuildwheel/resources/constraints.in
zipp==3.15.0
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
pip==23.1.2
# via -r cibuildwheel/resources/constraints.in
setuptools==67.8.0
# via -r cibuildwheel/resources/constraints.in
+27 -21
View File
@@ -1,28 +1,34 @@
#
# This file is autogenerated by pip-compile with Python 3.8
# by the following command:
#
# nox -s update_constraints-3.8
#
delocate==0.10.4
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.2.2.post1
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.12.0
filelock==3.16.1
# via virtualenv
packaging==23.1
importlib-metadata==8.5.0
# via build
macholib==1.16.3
# via delocate
platformdirs==3.5.1
packaging==24.2
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.6
# via virtualenv
typing-extensions==4.6.3
pyproject-hooks==1.2.0
# via build
tomli==2.2.1
# via build
typing-extensions==4.12.2
# via delocate
virtualenv==20.23.0
# via -r cibuildwheel/resources/constraints.in
wheel==0.40.0
# via -r cibuildwheel/resources/constraints.in
# The following packages are considered to be unsafe in a requirements file:
pip==23.1.2
# via -r cibuildwheel/resources/constraints.in
setuptools==67.8.0
virtualenv==20.29.3
# via -r cibuildwheel/resources/constraints.in
zipp==3.20.2
# via importlib-metadata
+27 -21
View File
@@ -1,28 +1,34 @@
#
# This file is autogenerated by pip-compile with Python 3.9
# by the following command:
#
# nox -s update_constraints-3.9
#
delocate==0.10.4
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.2.2.post1
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.12.0
filelock==3.18.0
# via virtualenv
packaging==23.1
importlib-metadata==8.6.1
# via build
macholib==1.16.3
# via delocate
platformdirs==3.5.1
packaging==24.2
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.7
# via virtualenv
typing-extensions==4.6.3
pyproject-hooks==1.2.0
# via build
tomli==2.2.1
# via build
typing-extensions==4.12.2
# via delocate
virtualenv==20.23.0
# via -r cibuildwheel/resources/constraints.in
wheel==0.40.0
# via -r cibuildwheel/resources/constraints.in
# The following packages are considered to be unsafe in a requirements file:
pip==23.1.2
# via -r cibuildwheel/resources/constraints.in
setuptools==67.8.0
virtualenv==20.29.3
# via -r cibuildwheel/resources/constraints.in
zipp==3.21.0
# via importlib-metadata
+1 -2
View File
@@ -1,5 +1,4 @@
pip
setuptools
wheel
build
delocate
virtualenv
+21 -21
View File
@@ -1,28 +1,28 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# nox -s update_constraints-3.12
#
delocate==0.10.4
# This file was autogenerated by uv via the following command:
# nox -s update_constraints
altgraph==0.17.4
# via macholib
build==1.2.2.post1
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.6
delocate==0.13.0
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.9
# via virtualenv
filelock==3.12.0
filelock==3.18.0
# via virtualenv
packaging==23.1
macholib==1.16.3
# via delocate
platformdirs==3.5.1
packaging==24.2
# via
# build
# delocate
pip==25.0.1
# via -r cibuildwheel/resources/constraints.in
platformdirs==4.3.7
# via virtualenv
typing-extensions==4.6.3
pyproject-hooks==1.2.0
# via build
typing-extensions==4.12.2
# via delocate
virtualenv==20.23.0
# via -r cibuildwheel/resources/constraints.in
wheel==0.40.0
# via -r cibuildwheel/resources/constraints.in
# The following packages are considered to be unsafe in a requirements file:
pip==23.1.2
# via -r cibuildwheel/resources/constraints.in
setuptools==67.8.0
virtualenv==20.29.3
# via -r cibuildwheel/resources/constraints.in
+13 -6
View File
@@ -2,6 +2,8 @@
build = "*"
skip = ""
test-skip = ""
free-threaded-support = false
enable = []
archs = ["auto"]
build-frontend = "default"
@@ -9,7 +11,7 @@ config-settings = {}
dependency-versions = "pinned"
environment = {}
environment-pass = []
build-verbosity = ""
build-verbosity = 0
before-all = ""
before-build = ""
@@ -19,6 +21,7 @@ test-command = ""
before-test = ""
test-requires = []
test-extras = []
test-groups = []
container-engine = "docker"
@@ -27,15 +30,17 @@ manylinux-i686-image = "manylinux2014"
manylinux-aarch64-image = "manylinux2014"
manylinux-ppc64le-image = "manylinux2014"
manylinux-s390x-image = "manylinux2014"
manylinux-armv7l-image = "manylinux_2_31"
manylinux-pypy_x86_64-image = "manylinux2014"
manylinux-pypy_i686-image = "manylinux2014"
manylinux-pypy_aarch64-image = "manylinux2014"
musllinux-x86_64-image = "musllinux_1_1"
musllinux-i686-image = "musllinux_1_1"
musllinux-aarch64-image = "musllinux_1_1"
musllinux-ppc64le-image = "musllinux_1_1"
musllinux-s390x-image = "musllinux_1_1"
musllinux-x86_64-image = "musllinux_1_2"
musllinux-i686-image = "musllinux_1_2"
musllinux-aarch64-image = "musllinux_1_2"
musllinux-ppc64le-image = "musllinux_1_2"
musllinux-s390x-image = "musllinux_1_2"
musllinux-armv7l-image = "musllinux_1_2"
[tool.cibuildwheel.linux]
@@ -45,3 +50,5 @@ repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}"
repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
[tool.cibuildwheel.windows]
[tool.cibuildwheel.pyodide]
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>attributeSetting</key>
<integer>1</integer>
<key>choiceAttribute</key>
<string>selected</string>
<key>choiceIdentifier</key>
<string>org.python.Python.PythonTFramework-3.13</string>
</dict>
</array>
</plist>
+3
View File
@@ -0,0 +1,3 @@
url = "https://nodejs.org/dist/"
v22 = "v22.14.0"
v20 = "v20.19.0"
+30 -21
View File
@@ -1,49 +1,58 @@
[x86_64]
manylinux1 = quay.io/pypa/manylinux1_x86_64:2023-06-07-3623bb5
manylinux1 = quay.io/pypa/manylinux1_x86_64:2024-04-29-76807b8
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-06-08-775c518
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2023-06-08-775c518
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.23-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2025.03.23-1
[i686]
manylinux1 = quay.io/pypa/manylinux1_i686:2023-06-07-3623bb5
manylinux1 = quay.io/pypa/manylinux1_i686:2024-04-29-76807b8
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2023-06-08-775c518
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2025.03.23-1
[pypy_x86_64]
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2023-06-08-775c518
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2025.03.23-1
[pypy_i686]
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_i686:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_i686:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
[aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-06-08-775c518
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2023-06-08-775c518
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.03.23-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2025.03.23-1
[ppc64le]
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2023-06-08-775c518
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2023-06-08-775c518
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2025.03.23-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2025.03.23-1
[s390x]
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2023-06-08-775c518
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2023-06-08-775c518
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2025.03.23-1
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2024.10.26-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2025.03.23-1
[pypy_aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2023-06-08-775c518
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2025.03.23-1
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2023-06-08-775c518
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2025.03.23-1
[armv7l]
manylinux_2_31 = quay.io/pypa/manylinux_2_31_armv7l:2025.03.23-1
musllinux_1_2 = quay.io/pypa/musllinux_1_2_armv7l:2025.03.23-1
+2 -2
View File
@@ -1,2 +1,2 @@
version = "20.21.1"
url = "https://github.com/pypa/get-virtualenv/blob/20.21.1/public/virtualenv.pyz?raw=true"
py36 = { version = "20.21.1", url = "https://github.com/pypa/get-virtualenv/blob/20.21.1/public/virtualenv.pyz?raw=true" }
default = { version = "20.29.3", url = "https://github.com/pypa/get-virtualenv/blob/20.29.3/public/virtualenv.pyz?raw=true" }
+15
View File
@@ -0,0 +1,15 @@
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
DIR = Path(__file__).parent.resolve()
def get_schema(tool_name: str = "cibuildwheel") -> dict[str, Any]:
"Get the stored complete schema for cibuildwheel settings."
assert tool_name == "cibuildwheel", "Only cibuildwheel is supported."
with DIR.joinpath("resources/cibuildwheel.schema.json").open(encoding="utf-8") as f:
return json.load(f) # type: ignore[no-any-return]
+4 -8
View File
@@ -3,15 +3,12 @@ from __future__ import annotations
import os
import subprocess
import typing
from typing import Union
from ._compat.typing import Final, Literal, Protocol
from typing import Final, Literal, Protocol, Union
__all__ = (
"PLATFORMS",
"PathOrStr",
"PlatformName",
"PLATFORMS",
"PopenBytes",
)
@@ -24,11 +21,10 @@ else:
PathOrStr = Union[str, "os.PathLike[str]"]
PlatformName = Literal["linux", "macos", "windows"]
PLATFORMS: Final[set[PlatformName]] = {"linux", "macos", "windows"}
PlatformName = Literal["linux", "macos", "windows", "pyodide"]
PLATFORMS: Final[set[PlatformName]] = {"linux", "macos", "windows", "pyodide"}
class GenericPythonConfiguration(Protocol):
@property
def identifier(self) -> str:
...
def identifier(self) -> str: ...
+360 -112
View File
@@ -1,26 +1,31 @@
from __future__ import annotations
import contextlib
import enum
import fnmatch
import itertools
import os
import re
import shlex
import shutil
import ssl
import subprocess
import sys
import tarfile
import textwrap
import time
import typing
import urllib.request
from collections import defaultdict
from collections.abc import Generator, Iterable, Mapping, Sequence
from collections.abc import Generator, Iterable, Mapping, MutableMapping, Sequence
from dataclasses import dataclass
from enum import Enum
from functools import lru_cache
from functools import lru_cache, total_ordering
from pathlib import Path, PurePath
from tempfile import TemporaryDirectory
from time import sleep
from typing import Any, ClassVar, TextIO, TypeVar
from typing import Any, Final, Literal, TextIO, TypeVar
from zipfile import ZipFile
import bracex
import certifi
@@ -32,42 +37,46 @@ from packaging.version import Version
from platformdirs import user_cache_path
from ._compat import tomllib
from ._compat.functools import cached_property
from ._compat.typing import Final, Literal
from .architecture import Architecture
from .errors import FatalError
from .typing import PathOrStr, PlatformName
__all__ = [
"resources_dir",
"MANYLINUX_ARCHS",
"EnableGroups",
"call",
"shell",
"find_compatible_wheel",
"format_safe",
"prepare_command",
"get_build_verbosity_extra_flags",
"read_python_configs",
"selector_matches",
"strtobool",
"cached_property",
"chdir",
"combine_constraints",
"find_compatible_wheel",
"find_uv",
"format_safe",
"get_build_verbosity_extra_flags",
"prepare_command",
"read_python_configs",
"resources_dir",
"selector_matches",
"shell",
"split_config_settings",
"strtobool",
]
resources_dir: Final[Path] = Path(__file__).parent / "resources"
install_certifi_script: Final[Path] = resources_dir / "install_certifi.py"
free_thread_enable_313: Final[Path] = resources_dir / "free-threaded-enable-313.xml"
test_fail_cwd_file: Final[Path] = resources_dir / "testing_temp_dir_file.py"
BuildFrontend = Literal["pip", "build"]
class EnableGroups(enum.Enum):
"""
Groups of build selectors that are not enabled by default.
"""
def build_frontend_or_default(
setting: BuildFrontend | Literal["default"], default: BuildFrontend = "pip"
) -> BuildFrontend:
if setting == "default":
return default
return setting
CPythonFreeThreading = "cpython-freethreading"
CPythonPrerelease = "cpython-prerelease"
PyPy = "pypy"
MANYLINUX_ARCHS: Final[tuple[str, ...]] = (
@@ -77,6 +86,7 @@ MANYLINUX_ARCHS: Final[tuple[str, ...]] = (
"aarch64",
"ppc64le",
"s390x",
"armv7l",
"pypy_aarch64",
"pypy_i686",
)
@@ -87,6 +97,7 @@ MUSLLINUX_ARCHS: Final[tuple[str, ...]] = (
"aarch64",
"ppc64le",
"s390x",
"armv7l",
)
DEFAULT_CIBW_CACHE_PATH: Final[Path] = user_cache_path(appname="cibuildwheel", appauthor="pypa")
@@ -103,8 +114,7 @@ def call(
env: Mapping[str, str] | None = None,
cwd: PathOrStr | None = None,
capture_stdout: Literal[False] = ...,
) -> None:
...
) -> None: ...
@typing.overload
@@ -113,8 +123,7 @@ def call(
env: Mapping[str, str] | None = None,
cwd: PathOrStr | None = None,
capture_stdout: Literal[True],
) -> str:
...
) -> str: ...
def call(
@@ -132,13 +141,32 @@ def call(
args_ = [str(arg) for arg in args]
# print the command executing for the logs
print("+ " + " ".join(shlex.quote(a) for a in args_))
kwargs: dict[str, Any] = {}
if capture_stdout:
kwargs["universal_newlines"] = True
kwargs["stdout"] = subprocess.PIPE
result = subprocess.run(args_, check=True, shell=IS_WIN, env=env, cwd=cwd, **kwargs)
# workaround platform behaviour differences outlined
# in https://github.com/python/cpython/issues/52803
path_env = env if env is not None else os.environ
path = path_env.get("PATH", None)
executable = shutil.which(args_[0], path=path)
if executable is None:
msg = f"Couldn't find {args_[0]!r} in PATH {path!r}"
raise FatalError(msg)
args_[0] = executable
try:
result = subprocess.run(
args_,
check=True,
shell=IS_WIN,
env=env,
cwd=cwd,
capture_output=capture_stdout,
text=capture_stdout,
)
except subprocess.CalledProcessError as e:
if capture_stdout:
sys.stderr.write(e.stderr)
raise
if not capture_stdout:
return None
sys.stderr.write(result.stderr)
return typing.cast(str, result.stdout)
@@ -209,7 +237,9 @@ def get_build_verbosity_extra_flags(level: int) -> list[str]:
return []
def split_config_settings(config_settings: str, frontend: Literal["pip", "build"]) -> list[str]:
def split_config_settings(
config_settings: str, frontend: Literal["pip", "build", "build[uv]"]
) -> list[str]:
config_settings_list = shlex.split(config_settings)
s = "s" if frontend == "pip" else ""
return [f"--config-setting{s}={setting}" for setting in config_settings_list]
@@ -250,23 +280,30 @@ class BuildSelector:
build_config: str
skip_config: str
requires_python: SpecifierSet | None = None
# a pattern that skips prerelease versions, when include_prereleases is False.
PRERELEASE_SKIP: ClassVar[str] = "cp312-*"
prerelease_pythons: bool = False
enable: frozenset[EnableGroups] = frozenset()
def __call__(self, build_id: str) -> bool:
# Filter build selectors by python_requires if set
if self.requires_python is not None:
py_ver_str = build_id.split("-")[0]
if py_ver_str.endswith("t"):
py_ver_str = py_ver_str[:-1]
major = int(py_ver_str[2])
minor = int(py_ver_str[3:])
version = Version(f"{major}.{minor}.99")
if not self.requires_python.contains(version):
return False
# filter out the prerelease pythons if self.prerelease_pythons is False
if not self.prerelease_pythons and selector_matches(self.PRERELEASE_SKIP, build_id):
# filter out groups that are not enabled
if EnableGroups.CPythonFreeThreading not in self.enable and selector_matches(
"cp3??t-*", build_id
):
return False
if EnableGroups.CPythonPrerelease not in self.enable and selector_matches(
"cp314*", build_id
):
return False
if EnableGroups.PyPy not in self.enable and selector_matches("pp*", build_id):
return False
should_build = selector_matches(self.build_config, build_id)
@@ -279,7 +316,7 @@ class BuildSelector:
"build_config": self.build_config,
"skip_config": self.skip_config,
"requires_python": str(self.requires_python),
"prerelease_pythons": self.prerelease_pythons,
"enable": sorted(group.value for group in self.enable),
}
@@ -339,6 +376,55 @@ def download(url: str, dest: Path) -> None:
sleep(3)
def extract_zip(zip_src: Path, dest: Path) -> None:
with ZipFile(zip_src) as zip_:
for zinfo in zip_.filelist:
zip_.extract(zinfo, dest)
# Set permissions to the same values as they were set in the archive
# We have to do this manually due to
# https://github.com/python/cpython/issues/59999
# But some files in the zipfile seem to have external_attr with 0
# permissions. In that case just use the default value???
permissions = (zinfo.external_attr >> 16) & 0o777
if permissions != 0:
dest.joinpath(zinfo.filename).chmod(permissions)
def extract_tar(tar_src: Path, dest: Path) -> None:
with tarfile.open(tar_src) as tar_:
tar_.extraction_filter = getattr(tarfile, "tar_filter", (lambda member, _: member))
tar_.extractall(dest)
def move_file(src_file: Path, dst_file: Path) -> Path:
"""Moves a file safely while avoiding potential semantic confusion:
1. `dst_file` must point to the target filename, not a directory
2. `dst_file` will be overwritten if it already exists
3. any missing parent directories will be created
Returns the fully resolved Path of the resulting file.
Raises:
NotADirectoryError: If any part of the intermediate path to `dst_file` is an existing file
IsADirectoryError: If `dst_file` points directly to an existing directory
"""
src_file = src_file.resolve(strict=True)
dst_file = dst_file.resolve()
if dst_file.is_dir():
msg = "dst_file must be a valid target filename, not an existing directory."
raise IsADirectoryError(msg)
dst_file.unlink(missing_ok=True)
dst_file.parent.mkdir(parents=True, exist_ok=True)
# using shutil.move() as Path.rename() is not guaranteed to work across filesystem boundaries
# explicit str() needed for Python 3.8
resulting_file = shutil.move(str(src_file), str(dst_file))
return Path(resulting_file).resolve(strict=True)
class DependencyConstraints:
def __init__(self, base_file_path: Path):
assert base_file_path.exists()
@@ -348,12 +434,14 @@ class DependencyConstraints:
def with_defaults() -> DependencyConstraints:
return DependencyConstraints(base_file_path=resources_dir / "constraints.txt")
def get_for_python_version(self, version: str) -> Path:
def get_for_python_version(
self, version: str, *, variant: Literal["python", "pyodide"] = "python"
) -> Path:
version_parts = version.split(".")
# try to find a version-specific dependency file e.g. if
# ./constraints.txt is the base, look for ./constraints-python36.txt
specific_stem = self.base_file_path.stem + f"-python{version_parts[0]}{version_parts[1]}"
specific_stem = self.base_file_path.stem + f"-{variant}{version_parts[0]}{version_parts[1]}"
specific_name = specific_stem + self.base_file_path.suffix
specific_file_path = self.base_file_path.with_name(specific_name)
@@ -378,35 +466,32 @@ class DependencyConstraints:
return self.base_file_path.name
class NonPlatformWheelError(Exception):
def __init__(self) -> None:
message = textwrap.dedent(
"""
cibuildwheel: Build failed because a pure Python wheel was generated.
If you intend to build a pure-Python wheel, you don't need cibuildwheel - use
`pip wheel -w DEST_DIR .` instead.
If you expected a platform wheel, check your project configuration, or run
cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
"""
)
super().__init__(message)
BuildFrontendName = Literal["pip", "build", "build[uv]"]
class AlreadyBuiltWheelError(Exception):
def __init__(self, wheel_name: str) -> None:
message = textwrap.dedent(
f"""
cibuildwheel: Build failed because a wheel named {wheel_name} was already generated in the current run.
@dataclass(frozen=True)
class BuildFrontendConfig:
name: BuildFrontendName
args: Sequence[str] = ()
If you expected another wheel to be generated, check your project configuration, or run
cibuildwheel with CIBW_BUILD_VERBOSITY=1 to view build logs.
"""
)
@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", "build[uv]"}:
msg = f"Unrecognised build frontend {name!r}, only 'pip', 'build', and 'build[uv]' are supported"
raise ValueError(msg)
super().__init__(message)
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)}
def strtobool(val: str) -> bool:
@@ -512,12 +597,47 @@ def get_pip_version(env: Mapping[str, str]) -> str:
@lru_cache(maxsize=None)
def _ensure_virtualenv() -> Path:
def ensure_node(major_version: str) -> Path:
input_file = resources_dir / "nodejs.toml"
with input_file.open("rb") as f:
loaded_file = tomllib.load(f)
version = str(loaded_file[major_version])
base_url = str(loaded_file["url"])
ext = "zip" if IS_WIN else "tar.xz"
platform = "win" if IS_WIN else ("darwin" if sys.platform.startswith("darwin") else "linux")
linux_arch = Architecture.native_arch("linux")
assert linux_arch is not None
arch = {"x86_64": "x64", "i686": "x86", "aarch64": "arm64"}.get(
linux_arch.value, linux_arch.value
)
name = f"node-{version}-{platform}-{arch}"
path = CIBW_CACHE_PATH / name
with FileLock(str(path) + ".lock"):
if not path.exists():
url = f"{base_url}{version}/{name}.{ext}"
with TemporaryDirectory() as tmp_path:
archive = Path(tmp_path) / f"{name}.{ext}"
download(url, archive)
if ext == "zip":
extract_zip(archive, path.parent)
else:
extract_tar(archive, path.parent)
assert path.exists()
if not IS_WIN:
return path / "bin"
return path
@lru_cache(maxsize=None)
def _ensure_virtualenv(version: str) -> Path:
version_parts = version.split(".")
key = f"py{version_parts[0]}{version_parts[1]}"
input_file = resources_dir / "virtualenv.toml"
with input_file.open("rb") as f:
loaded_file = tomllib.load(f)
version = str(loaded_file["version"])
url = str(loaded_file["url"])
configuration = loaded_file.get(key, loaded_file["default"])
version = str(configuration["version"])
url = str(configuration["url"])
path = CIBW_CACHE_PATH / f"virtualenv-{version}.pyz"
with FileLock(str(path) + ".lock"):
if not path.exists():
@@ -526,6 +646,7 @@ def _ensure_virtualenv() -> Path:
def _parse_constraints_for_virtualenv(
seed_packages: list[str],
dependency_constraint_flags: Sequence[PathOrStr],
) -> dict[str, str]:
"""
@@ -538,8 +659,8 @@ def _parse_constraints_for_virtualenv(
{macos|windows}.setup_python function.
"""
assert len(dependency_constraint_flags) in {0, 2}
packages = ["pip", "setuptools", "wheel"]
constraints_dict = {package: "embed" for package in packages}
# only seed pip if other seed packages do not appear in a constraint file
constraints_dict = {"pip": "embed"}
if len(dependency_constraint_flags) == 2:
assert dependency_constraint_flags[0] == "-c"
constraint_path = Path(dependency_constraint_flags[1])
@@ -555,7 +676,7 @@ def _parse_constraints_for_virtualenv(
requirement = Requirement(line)
package = requirement.name
if (
package not in packages
package not in seed_packages
or requirement.url is not None
or requirement.marker is not None
or len(requirement.extras) != 0
@@ -572,43 +693,68 @@ def _parse_constraints_for_virtualenv(
def virtualenv(
python: Path, venv_path: Path, dependency_constraint_flags: Sequence[PathOrStr]
version: str,
python: Path,
venv_path: Path,
dependency_constraint_flags: Sequence[PathOrStr],
*,
use_uv: bool,
) -> dict[str, str]:
"""
Create a virtual environment. If `use_uv` is True,
dependency_constraint_flags are ignored since nothing is installed in the
venv. Otherwise, pip is installed, and setuptools + wheel if Python < 3.12.
"""
# virtualenv may fail if this is a symlink.
python = python.resolve()
assert python.exists()
virtualenv_app = _ensure_virtualenv()
constraints = _parse_constraints_for_virtualenv(dependency_constraint_flags)
additional_flags = [f"--{package}={version}" for package, version in constraints.items()]
# Using symlinks to pre-installed seed packages is really the fastest way to get a virtual
# environment. The initial cost is a bit higher but reusing is much faster.
# Windows does not always allow symlinks so just disabling for now.
# Requires pip>=19.3 so disabling for "embed" because this means we don't know what's the
# version of pip that will end-up installed.
# c.f. https://virtualenv.pypa.io/en/latest/cli_interface.html#section-seeder
if (
not IS_WIN
and constraints["pip"] != "embed"
and Version(constraints["pip"]) >= Version("19.3")
):
additional_flags.append("--symlink-app-data")
call(
sys.executable,
"-sS", # just the stdlib, https://github.com/pypa/virtualenv/issues/2133#issuecomment-1003710125
virtualenv_app,
"--activators=",
"--no-periodic-update",
*additional_flags,
"--python",
python,
venv_path,
)
if IS_WIN:
paths = [str(venv_path), str(venv_path / "Scripts")]
if use_uv:
call("uv", "venv", venv_path, "--python", python)
else:
paths = [str(venv_path / "bin")]
virtualenv_app = _ensure_virtualenv(version)
allowed_seed_packages = ["pip", "setuptools", "wheel"]
constraints = _parse_constraints_for_virtualenv(
allowed_seed_packages, dependency_constraint_flags
)
additional_flags: list[str] = []
for package in allowed_seed_packages:
if package in constraints:
additional_flags.append(f"--{package}={constraints[package]}")
else:
additional_flags.append(f"--no-{package}")
# Using symlinks to pre-installed seed packages is really the fastest way to get a virtual
# environment. The initial cost is a bit higher but reusing is much faster.
# Windows does not always allow symlinks so just disabling for now.
# Requires pip>=19.3 so disabling for "embed" because this means we don't know what's the
# version of pip that will end-up installed.
# c.f. https://virtualenv.pypa.io/en/latest/cli_interface.html#section-seeder
if (
not IS_WIN
and constraints["pip"] != "embed"
and Version(constraints["pip"]) >= Version("19.3")
):
additional_flags.append("--symlink-app-data")
call(
sys.executable,
"-sS", # just the stdlib, https://github.com/pypa/virtualenv/issues/2133#issuecomment-1003710125
virtualenv_app,
"--activators=",
"--no-periodic-update",
*additional_flags,
"--python",
python,
venv_path,
)
paths = [str(venv_path), str(venv_path / "Scripts")] if IS_WIN else [str(venv_path / "bin")]
env = os.environ.copy()
env["PATH"] = os.pathsep.join([*paths, env["PATH"]])
env["VIRTUAL_ENV"] = str(venv_path)
return env
@@ -622,10 +768,13 @@ def find_compatible_wheel(wheels: Sequence[T], identifier: str) -> T | None:
"""
interpreter, platform = identifier.split("-")
free_threaded = interpreter.endswith("t")
if free_threaded:
interpreter = interpreter[:-1]
for wheel in wheels:
_, _, _, tags = parse_wheel_filename(wheel.name)
for tag in tags:
if tag.abi == "abi3":
if tag.abi == "abi3" and not free_threaded:
# ABI3 wheels must start with cp3 for impl and tag
if not (interpreter.startswith("cp3") and tag.interpreter.startswith("cp3")):
continue
@@ -701,28 +850,40 @@ def fix_ansi_codes_for_github_actions(text: str) -> str:
def parse_key_value_string(
key_value_string: str, positional_arg_names: list[str] | None = None
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 = []
shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";:")
all_field_names = [*positional_arg_names, *kw_arg_names]
shlexer = shlex.shlex(key_value_string, posix=True, punctuation_chars=";")
shlexer.commenters = ""
shlexer.whitespace_split = True
parts = list(shlexer)
# parts now looks like
# ['docker', ';', 'create_args',':', '--some-option=value', 'another-option']
# ['docker', ';', 'create_args:', '--some-option=value', 'another-option']
# split by semicolon
fields = [list(group) for k, group in itertools.groupby(parts, lambda x: x == ";") if not k]
result: dict[str, list[str]] = defaultdict(list)
result: defaultdict[str, list[str]] = defaultdict(list)
for field_i, field in enumerate(fields):
if len(field) > 1 and field[1] == ":":
field_name = field[0]
values = field[2:]
# check to see if the option name is specified
field_name, sep, first_value = field[0].partition(":")
if sep:
if field_name not in all_field_names:
msg = f"Failed to parse {key_value_string!r}. Unknown field name {field_name!r}"
raise ValueError(msg)
values = ([first_value] if first_value else []) + field[1:]
else:
try:
field_name = positional_arg_names[field_i]
@@ -734,4 +895,91 @@ def parse_key_value_string(
result[field_name] += values
return result
return dict(result)
def find_uv() -> Path | None:
# Prefer uv in our environment
with contextlib.suppress(ImportError, FileNotFoundError):
# pylint: disable-next=import-outside-toplevel
from uv import find_uv_bin
return Path(find_uv_bin())
uv_on_path = shutil.which("uv")
return Path(uv_on_path) if uv_on_path else None
def combine_constraints(
env: MutableMapping[str, str], /, constraints_path: Path, tmp_dir: Path | None
) -> None:
"""
This will workaround a bug in pip<=21.1.1 or uv<=0.2.0 if a tmp_dir is given.
If set to None, this will use the modern URI method.
"""
if tmp_dir:
if " " in str(constraints_path):
assert " " not in str(tmp_dir)
tmp_file = tmp_dir / "constraints.txt"
tmp_file.write_bytes(constraints_path.read_bytes())
constraints_path = tmp_file
our_constraints = str(constraints_path)
else:
our_constraints = (
constraints_path.as_uri() if " " in str(constraints_path) else str(constraints_path)
)
user_constraints = env.get("PIP_CONSTRAINT")
env["UV_CONSTRAINT"] = env["PIP_CONSTRAINT"] = " ".join(
c for c in [our_constraints, user_constraints] if c
)
@total_ordering
class FlexibleVersion:
version_str: str
version_parts: tuple[int, ...]
suffix: str
def __init__(self, version_str: str) -> None:
self.version_str = version_str
# Split into numeric parts and the optional suffix
match = re.match(r"^[v]?(\d+(\.\d+)*)(.*)$", version_str)
if not match:
msg = f"Invalid version string: {version_str}"
raise ValueError(msg)
version_part, _, suffix = match.groups()
# Convert numeric version part into a tuple of integers
self.version_parts = tuple(map(int, version_part.split(".")))
self.suffix = suffix.strip() if suffix else ""
# Normalize by removing trailing zeros
self.version_parts = self._remove_trailing_zeros(self.version_parts)
def _remove_trailing_zeros(self, parts: tuple[int, ...]) -> tuple[int, ...]:
# Remove trailing zeros for accurate comparisons
# without this, "3.0" would be considered greater than "3"
while parts and parts[-1] == 0:
parts = parts[:-1]
return parts
def __eq__(self, other: object) -> bool:
if not isinstance(other, FlexibleVersion):
raise NotImplementedError()
return (self.version_parts, self.suffix) == (other.version_parts, other.suffix)
def __lt__(self, other: object) -> bool:
if not isinstance(other, FlexibleVersion):
raise NotImplementedError()
return (self.version_parts, self.suffix) < (other.version_parts, other.suffix)
def __repr__(self) -> str:
return f"FlexibleVersion('{self.version_str}')"
def __str__(self) -> str:
return self.version_str
+154 -135
View File
@@ -4,18 +4,16 @@ import os
import platform as platform_module
import shutil
import subprocess
import sys
import textwrap
from collections.abc import MutableMapping, Sequence, Set
from contextlib import suppress
from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path
from zipfile import ZipFile
from filelock import FileLock
from packaging.version import Version
from . import errors
from ._compat.typing import assert_never
from .architecture import Architecture
from .environment import ParsedEnvironment
@@ -24,16 +22,18 @@ from .options import Options
from .typing import PathOrStr
from .util import (
CIBW_CACHE_PATH,
AlreadyBuiltWheelError,
BuildFrontend,
BuildFrontendConfig,
BuildFrontendName,
BuildSelector,
NonPlatformWheelError,
build_frontend_or_default,
call,
combine_constraints,
download,
extract_zip,
find_compatible_wheel,
find_uv,
get_build_verbosity_extra_flags,
get_pip_version,
move_file,
prepare_command,
read_python_configs,
shell,
@@ -44,7 +44,9 @@ from .util import (
)
def get_nuget_args(version: str, arch: str, output_directory: Path) -> list[str]:
def get_nuget_args(
version: str, arch: str, free_threaded: bool, output_directory: Path
) -> list[str]:
package_name = {
"32": "pythonx86",
"64": "python",
@@ -53,6 +55,8 @@ def get_nuget_args(version: str, arch: str, output_directory: Path) -> list[str]
"x86": "pythonx86",
"AMD64": "python",
}[arch]
if free_threaded:
package_name = f"{package_name}-freethreaded"
return [
package_name,
"-Version",
@@ -92,11 +96,6 @@ def get_python_configurations(
return python_configurations
def extract_zip(zip_src: Path, dest: Path) -> None:
with ZipFile(zip_src) as zip_:
zip_.extractall(dest)
@lru_cache(maxsize=None)
def _ensure_nuget() -> Path:
nuget = CIBW_CACHE_PATH / "nuget.exe"
@@ -106,11 +105,16 @@ def _ensure_nuget() -> Path:
return nuget
def install_cpython(version: str, arch: str) -> Path:
def install_cpython(configuration: PythonConfiguration, arch: str | None = None) -> Path:
version = configuration.version
free_threaded = "t-" in configuration.identifier
if arch is None:
arch = configuration.arch
base_output_dir = CIBW_CACHE_PATH / "nuget-cpython"
nuget_args = get_nuget_args(version, arch, base_output_dir)
nuget_args = get_nuget_args(version, arch, free_threaded, base_output_dir)
installation_path = base_output_dir / (nuget_args[0] + "." + version) / "tools"
with FileLock(str(base_output_dir) + f"-{version}-{arch}.lock"):
free_threaded_str = "-freethreaded" if free_threaded else ""
with FileLock(str(base_output_dir) + f"-{version}{free_threaded_str}-{arch}.lock"):
if not installation_path.exists():
nuget = _ensure_nuget()
call(nuget, "install", *nuget_args)
@@ -148,6 +152,16 @@ def setup_setuptools_cross_compile(
# set the platform name
map_plat = {"32": "win32", "64": "win-amd64", "ARM64": "win-arm64"}
plat_name = map_plat[python_configuration.arch]
# Set environment variable so that setuptools._distutils.get_platform()
# identifies the target, not the host
vscmd_arg_tgt_arch = {"32": "x86", "64": "x64", "ARM64": "arm64"}
current_tgt_arch = vscmd_arg_tgt_arch[python_configuration.arch]
if (env.get("VSCMD_ARG_TGT_ARCH") or current_tgt_arch) != current_tgt_arch:
msg = f"VSCMD_ARG_TGT_ARCH must be set to {current_tgt_arch!r}, got {env['VSCMD_ARG_TGT_ARCH']!r}. If you're setting up MSVC yourself (e.g. using vcvarsall.bat or msvc-dev-cmd), make sure to target the right architecture. Alternatively, run cibuildwheel without configuring MSVC, and let the build backend handle it."
raise errors.FatalError(msg)
env["VSCMD_ARG_TGT_ARCH"] = current_tgt_arch
# (This file must be default/locale encoding, so we can't pass 'encoding')
distutils_cfg.write_text(
textwrap.dedent(
@@ -211,31 +225,35 @@ def setup_rust_cross_compile(
)
def can_use_uv(python_configuration: PythonConfiguration) -> bool:
conditions = (
Version(python_configuration.version) >= Version("3.8"),
not python_configuration.identifier.startswith("pp38-"),
)
return all(conditions)
def setup_python(
tmp: Path,
python_configuration: PythonConfiguration,
dependency_constraint_flags: Sequence[PathOrStr],
environment: ParsedEnvironment,
build_frontend: BuildFrontend,
) -> dict[str, str]:
build_frontend: BuildFrontendName,
) -> tuple[Path, dict[str, str]]:
tmp.mkdir()
implementation_id = python_configuration.identifier.split("-")[0]
python_libs_base = None
log.step(f"Installing Python {implementation_id}...")
if implementation_id.startswith("cp"):
native_arch = platform_module.machine()
base_python = install_cpython(python_configuration)
if python_configuration.arch == "ARM64" != native_arch:
# To cross-compile for ARM64, we need a native CPython to run the
# build, and a copy of the ARM64 import libraries ('.\libs\*.lib')
# for any extension modules.
python_libs_base = install_cpython(
python_configuration.version, python_configuration.arch
)
python_libs_base = python_libs_base.parent / "libs"
python_libs_base = base_python.parent / "libs"
log.step(f"Installing native Python {native_arch} for cross-compilation...")
base_python = install_cpython(python_configuration.version, native_arch)
else:
base_python = install_cpython(python_configuration.version, python_configuration.arch)
base_python = install_cpython(python_configuration, arch=native_arch)
elif implementation_id.startswith("pp"):
assert python_configuration.url is not None
base_python = install_pypy(tmp, python_configuration.arch, python_configuration.url)
@@ -244,28 +262,35 @@ def setup_python(
raise ValueError(msg)
assert base_python.exists()
if build_frontend == "build[uv]" and not can_use_uv(python_configuration):
build_frontend = "build"
use_uv = build_frontend == "build[uv]"
uv_path = find_uv()
log.step("Setting up build environment...")
venv_path = tmp / "venv"
env = virtualenv(base_python, venv_path, dependency_constraint_flags)
env = virtualenv(
python_configuration.version,
base_python,
venv_path,
dependency_constraint_flags,
use_uv=use_uv,
)
# set up environment variables for run_with_env
env["PYTHON_VERSION"] = python_configuration.version
env["PYTHON_ARCH"] = python_configuration.arch
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
# pip older than 21.3 builds executables such as pip.exe for x64 platform.
# The first re-install of pip updates pip module but builds pip.exe using
# the old pip which still generates x64 executable. But the second
# re-install uses updated pip and correctly builds pip.exe for the target.
# This can be removed once ARM64 Pythons (currently 3.9 and 3.10) bundle
# pip versions newer than 21.3.
if python_configuration.arch == "ARM64" and Version(get_pip_version(env)) < Version("21.3"):
# upgrade pip to the version matching our constraints
# if necessary, reinstall it to ensure that it's available on PATH as 'pip.exe'
if not use_uv:
call(
"python",
"-m",
"pip",
"install",
"--force-reinstall",
"--upgrade",
"pip",
*dependency_constraint_flags,
@@ -273,59 +298,30 @@ def setup_python(
cwd=venv_path,
)
# upgrade pip to the version matching our constraints
# if necessary, reinstall it to ensure that it's available on PATH as 'pip.exe'
call(
"python",
"-m",
"pip",
"install",
"--upgrade",
"pip",
*dependency_constraint_flags,
env=env,
cwd=venv_path,
)
# update env with results from CIBW_ENVIRONMENT
env = environment.as_dictionary(prev_environment=env)
# check what Python version we're on
call("where", "python", env=env)
where_python = call("where", "python", env=env, capture_stdout=True).splitlines()[0].strip()
print(where_python)
if where_python != str(venv_path / "Scripts" / "python.exe"):
msg = "python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it."
raise errors.FatalError(msg)
call("python", "--version", env=env)
call("python", "-c", "\"import struct; print(struct.calcsize('P') * 8)\"", env=env)
where_python = call("where", "python", env=env, capture_stdout=True).splitlines()[0].strip()
if where_python != str(venv_path / "Scripts" / "python.exe"):
print(
"cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.",
file=sys.stderr,
)
sys.exit(1)
# check what pip version we're on
assert (venv_path / "Scripts" / "pip.exe").exists()
where_pip = call("where", "pip", env=env, capture_stdout=True).splitlines()[0].strip()
if where_pip.strip() != str(venv_path / "Scripts" / "pip.exe"):
print(
"cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.",
file=sys.stderr,
)
sys.exit(1)
call("pip", "--version", env=env)
if not use_uv:
assert (venv_path / "Scripts" / "pip.exe").exists()
where_pip = call("where", "pip", env=env, capture_stdout=True).splitlines()[0].strip()
print(where_pip)
if where_pip.strip() != str(venv_path / "Scripts" / "pip.exe"):
msg = "pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it."
raise errors.FatalError(msg)
call("pip", "--version", env=env)
log.step("Installing build tools...")
if build_frontend == "pip":
call(
"pip",
"install",
"--upgrade",
"setuptools",
"wheel",
*dependency_constraint_flags,
env=env,
)
elif build_frontend == "build":
if build_frontend == "build":
call(
"pip",
"install",
@@ -334,15 +330,24 @@ def setup_python(
*dependency_constraint_flags,
env=env,
)
else:
assert_never(build_frontend)
elif build_frontend == "build[uv]":
assert uv_path is not None
call(
uv_path,
"pip",
"install",
"--upgrade",
"build[virtualenv]",
*dependency_constraint_flags,
env=env,
)
if python_libs_base:
# Set up the environment for various backends to enable cross-compilation
setup_setuptools_cross_compile(tmp, python_configuration, python_libs_base, env)
setup_rust_cross_compile(tmp, python_configuration, python_libs_base, env)
return env
return base_python, env
def build(options: Options, tmp_path: Path) -> None:
@@ -369,7 +374,8 @@ def build(options: Options, tmp_path: Path) -> None:
for config in python_configurations:
build_options = options.build_options(config.identifier)
build_frontend = build_frontend_or_default(build_options.build_frontend)
build_frontend = build_options.build_frontend or BuildFrontendConfig("pip")
use_uv = build_frontend.name == "build[uv]" and can_use_uv(config)
log.build_start(config.identifier)
identifier_tmp_dir = tmp_path / config.identifier
@@ -385,13 +391,15 @@ def build(options: Options, tmp_path: Path) -> None:
]
# install Python
env = setup_python(
base_python, env = setup_python(
identifier_tmp_dir / "build",
config,
dependency_constraint_flags,
build_options.environment,
build_frontend,
build_frontend.name,
)
if not use_uv:
pip_version = get_pip_version(env)
compatible_wheel = find_compatible_wheel(built_wheels, config.identifier)
if compatible_wheel:
@@ -414,9 +422,22 @@ def build(options: Options, tmp_path: Path) -> None:
log.step("Building wheel...")
built_wheel_dir.mkdir()
extra_flags = split_config_settings(build_options.config_settings, build_frontend)
extra_flags = split_config_settings(
build_options.config_settings, build_frontend.name
)
extra_flags += build_frontend.args
if build_frontend == "pip":
build_env = env.copy()
if not use_uv:
build_env["VIRTUALENV_PIP"] = pip_version
if build_options.dependency_constraints:
constraints_path = build_options.dependency_constraints.get_for_python_version(
config.version
)
combine_constraints(build_env, constraints_path, identifier_tmp_dir)
if build_frontend.name == "pip":
extra_flags += get_build_verbosity_extra_flags(build_options.build_verbosity)
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/pypa/cibuildwheel/pull/369
@@ -429,41 +450,24 @@ def build(options: Options, tmp_path: Path) -> None:
f"--wheel-dir={built_wheel_dir}",
"--no-deps",
*extra_flags,
env=env,
env=build_env,
)
elif build_frontend == "build":
elif build_frontend.name == "build" or build_frontend.name == "build[uv]":
if not 0 <= build_options.build_verbosity < 2:
msg = f"build_verbosity {build_options.build_verbosity} is not supported for build frontend. Ignoring."
log.warning(msg)
build_env = env.copy()
if build_options.dependency_constraints:
constraints_path = (
build_options.dependency_constraints.get_for_python_version(
config.version
)
)
# Bug in pip <= 21.1.3 - we can't have a space in the
# constraints file, and pip doesn't support drive letters
# in uhi. After probably pip 21.2, we can use uri. For
# now, use a temporary file.
if " " in str(constraints_path):
assert " " not in str(identifier_tmp_dir)
tmp_file = identifier_tmp_dir / "constraints.txt"
tmp_file.write_bytes(constraints_path.read_bytes())
constraints_path = tmp_file
build_env["PIP_CONSTRAINT"] = str(constraints_path)
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
call(
"python",
"-m",
"build",
build_options.package_dir,
"--wheel",
f"--outdir={built_wheel_dir}",
*extra_flags,
env=build_env,
)
if use_uv and "--no-isolation" not in extra_flags and "-n" not in extra_flags:
extra_flags.append("--installer=uv")
call(
"python",
"-m",
"build",
build_options.package_dir,
"--wheel",
f"--outdir={built_wheel_dir}",
*extra_flags,
env=build_env,
)
else:
assert_never(build_frontend)
@@ -473,7 +477,7 @@ def build(options: Options, tmp_path: Path) -> None:
repaired_wheel_dir.mkdir()
if built_wheel.name.endswith("none-any.whl"):
raise NonPlatformWheelError()
raise errors.NonPlatformWheelError()
if build_options.repair_command:
log.step("Repairing wheel...")
@@ -486,10 +490,13 @@ def build(options: Options, tmp_path: Path) -> None:
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
try:
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
except StopIteration:
raise errors.RepairStepProducedNoWheelError() from None
if repaired_wheel.name in {wheel.name for wheel in built_wheels}:
raise AlreadyBuiltWheelError(repaired_wheel.name)
raise errors.AlreadyBuiltWheelError(repaired_wheel.name)
test_selected = options.globals.test_selector(config.identifier)
if test_selected and config.arch == "ARM64" != platform_module.machine():
@@ -498,7 +505,7 @@ def build(options: Options, tmp_path: Path) -> None:
"""
While arm64 wheels can be built on other platforms, they cannot
be tested. An arm64 runner is required. To silence this warning,
set `CIBW_TEST_SKIP: *-win_arm64`.
set `CIBW_TEST_SKIP: "*-win_arm64"`.
"""
)
)
@@ -507,12 +514,20 @@ def build(options: Options, tmp_path: Path) -> None:
log.step("Testing wheel...")
# set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time.
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
if not use_uv:
call("pip", "install", "virtualenv", *dependency_constraint_flags, env=env)
venv_dir = identifier_tmp_dir / "venv-test"
# Use --no-download to ensure determinism by using seed libraries
# built into virtualenv
call("python", "-m", "virtualenv", "--no-download", venv_dir, env=env)
if use_uv:
call("uv", "venv", venv_dir, f"--python={base_python}", env=env)
else:
# Use pip version from the initial env to ensure determinism
venv_args = ["--no-periodic-update", f"--pip={pip_version}"]
# In Python<3.12, setuptools & wheel are installed as well, use virtualenv embedded ones
if Version(config.version) < Version("3.12"):
venv_args.extend(("--setuptools=embed", "--wheel=embed"))
call("python", "-m", "virtualenv", *venv_args, venv_dir, env=env)
virtualenv_env = env.copy()
virtualenv_env["PATH"] = os.pathsep.join(
@@ -521,6 +536,7 @@ def build(options: Options, tmp_path: Path) -> None:
virtualenv_env["PATH"],
]
)
virtualenv_env["VIRTUAL_ENV"] = str(venv_dir)
# check that we are using the Python from the virtual environment
call("where", "python", env=virtualenv_env)
@@ -533,9 +549,11 @@ def build(options: Options, tmp_path: Path) -> None:
)
shell(before_test_prepared, env=virtualenv_env)
pip = ["uv", "pip"] if use_uv else ["pip"]
# install the wheel
call(
"pip",
*pip,
"install",
str(repaired_wheel) + build_options.test_extras,
env=virtualenv_env,
@@ -543,7 +561,7 @@ def build(options: Options, tmp_path: Path) -> None:
# test the wheel
if build_options.test_requires:
call("pip", "install", *build_options.test_requires, env=virtualenv_env)
call(*pip, "install", *build_options.test_requires, env=virtualenv_env)
# run the tests from a temp dir, with an absolute path in the command
# (this ensures that Python runs the tests against the installed wheel
@@ -552,6 +570,7 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.test_command,
project=Path(".").resolve(),
package=options.globals.package_dir.resolve(),
wheel=repaired_wheel,
)
test_cwd = identifier_tmp_dir / "test_cwd"
test_cwd.mkdir()
@@ -561,11 +580,13 @@ def build(options: Options, tmp_path: Path) -> None:
# we're all done here; move it to output (remove if already exists)
if compatible_wheel is None:
with suppress(FileNotFoundError):
(build_options.output_dir / repaired_wheel.name).unlink()
shutil.move(str(repaired_wheel), build_options.output_dir)
built_wheels.append(build_options.output_dir / repaired_wheel.name)
output_wheel = build_options.output_dir.joinpath(repaired_wheel.name)
moved_wheel = move_file(repaired_wheel, output_wheel)
if moved_wheel != output_wheel.resolve():
log.warning(
"{repaired_wheel} was moved to {moved_wheel} instead of {output_wheel}"
)
built_wheels.append(output_wheel)
# clean up
# (we ignore errors because occasionally Windows fails to unlink a file and we
@@ -574,7 +595,5 @@ def build(options: Options, tmp_path: Path) -> None:
log.build_end()
except subprocess.CalledProcessError as error:
log.step_end_with_error(
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
)
sys.exit(1)
msg = f"Command {error.cmd} failed with code {error.returncode}. {error.stdout or ''}"
raise errors.FatalError(msg) from error
+301 -40
View File
@@ -4,6 +4,267 @@ title: Changelog
# Changelog
### v2.23.2
_24 March 2025_
- 🐛 Workaround an issue with pyodide builds when running cibuildwheel with a Python that was installed via UV (#2328 via #2331)
- 🛠 Dependency updates, including a manylinux update that fixes an ['undefined symbol' error](https://github.com/pypa/manylinux/issues/1760) in gcc-toolset (#2334)
### v2.23.1
_15 March 2025_
- ⚠️ Added warnings when the shorthand values `manylinux1`, `manylinux2010`, `manylinux_2_24`, and `musllinux_1_1` are used to specify the images in linux builds. The shorthand to these (unmaintainted) images will be removed in v3.0. If you want to keep using these images, explicitly opt-in using the full image URL, which can be found in [this file](https://github.com/pypa/cibuildwheel/blob/v2.23.1/cibuildwheel/resources/pinned_docker_images.cfg). (#2312)
- 🛠 Dependency updates, including a manylinux update which fixes an [issue with rustup](https://github.com/pypa/cibuildwheel/issues/2303). (#2315)
### v2.23.0
_1 March 2025_
- ✨ Adds official support for the new GitHub Actions Arm runners. In fact these worked out-of-the-box, now we include them in our tests and example configs. (#2135 via #2281)
- ✨ Adds support for building PyPy 3.11 wheels (#2268 via #2281)
- 🛠 Adopts the beta pypa/manylinux image for armv7l builds (#2269 via #2281)
- 🛠 Dependency updates, including Pyodide 0.27 (#2117 and #2281)
### v2.22.0
_23 November 2024_
- 🌟 Added a new `CIBW_ENABLE`/`enable` feature that replaces `CIBW_FREETHREADED_SUPPORT`/`free-threaded-support` and `CIBW_PRERELEASE_PYTHONS` with a system that supports both. In cibuildwheel 3, this will also include a PyPy setting and the deprecated options will be removed. (#2048)
- 🌟 [Dependency groups](https://peps.python.org/pep-0735/) are now supported for tests. Use `CIBW_TEST_GROUPS`/`test-groups` to specify groups in `[dependency-groups]` for testing. (#2063)
- 🌟 Support for the experimental Ubuntu-based ARMv7l manylinux image (#2052)
- ✨ Show a warning when cibuildwheel is run from Python 3.10 or older; cibuildwheel 3.0 will require Python 3.11 or newer as host (#2050)
- 🐛 Fix issue with stderr interfering with checking the docker version (#2074)
- 🛠 Python 3.9 is now used in `CIBW_BEFORE_ALL`/`before-all` on linux, replacing 3.8, which is now EoL (#2043)
- 🛠 Error messages for producing a pure-Python wheel are slightly more informative (#2044)
- 🛠 Better error when `uname -m` fails on ARM (#2049)
- 🛠 Better error when repair fails and docs for abi3audit on Windows (#2058)
- 🛠 Better error when `manylinux-interpreters ensure` fails (#2066)
- 🛠 Update Pyodide to 0.26.4, and adapt to the unbundled pyodide-build (now 0.29) (#2090)
- 🛠 Now cibuildwheel uses dependency-groups for development dependencies (#2064, #2085)
- 📚 Docs updates and tidy ups (#2061, #2067, #2072)
### v2.21.3
_9 October 2024_
- 🛠 Update CPython 3.13 to 3.13.0 final release (#2032)
- 📚 Docs updates and tidy ups (#2035)
### v2.21.2
_2 October 2024_
- ✨ Adds support for building 32-bit armv7l wheels on musllinux. On a Linux system with emulation set up, set [CIBW_ARCHS](https://cibuildwheel.pypa.io/en/stable/options/#archs) to `armv7l` on Linux to try it out if you're interested! (#2017)
- 🐛 Fix Linux Podman builds on some systems (#2016)
- ✨ Adds official support for running on Python 3.13 (#2026)
- 🛠 Update CPython 3.13 to 3.13.0rc3 (#2029)
Note: the default [manylinux image](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) is **scheduled to change** from `manylinux2014` to `manylinux_2_28` in a cibuildwheel release on or after **6th May 2025** - you can set the value now to avoid getting upgraded if you want. (#1992)
### v2.21.1
_16 September 2024_
- 🐛 Fix a bug in the Linux build, where files copied to the container would have invalid ownership permissions (#2007)
- 🐛 Fix a bug on Windows where cibuildwheel would call upon `uv` to install dependencies for versions of CPython that it does not support (#2005)
- 🐛 Fix a bug where `uv 0.4.10` would not use the right Python when testing on Linux. (#2008)
- 🛠 Bump our documentation pins, fixes an issue with a missing package (#2011)
### v2.21.0
_13 September 2024_
- ⚠️ Update CPython 3.12 to 3.12.6, which changes the macOS minimum deployment target on CPython 3.12 from macOS 10.9 to macOS 10.13 (#1998)
- 🛠 Changes the behaviour when inheriting `config-settings` in TOML overrides - rather than extending each key, which is rarely useful, individual keys will override previously set values. (#1803)
- 🛠 Update CPython 3.13 to 3.13.0rc2 (#1998)
- ✨ Adds support for multiarch OCI images (#1961)
- 🐛 Fixes some bugs building Linux wheels on macOS. (#1961)
- ⚠️ Changes the minimum version of Docker/Podman to Docker API version 1.43, Podman API version 3. The only mainstream runner this should affect is Travis Graviton2 runners - if so you can [upgrade your version of Docker](https://github.com/pypa/cibuildwheel/pull/1961#issuecomment-2304060019). (#1961)
### v2.20.0
_4 August 2024_
- 🌟 CPython 3.13 wheels are now built by default - without the `CIBW_PRERELEASE_PYTHONS` flag. It's time to build and upload these wheels to PyPI! This release includes CPython 3.13.0rc1, which is guaranteed to be ABI compatible with the final release. Free-threading is still behind a flag/config option. (#1950)
- ✨ Provide a `CIBW_ALLOW_EMPTY` environment variable as an alternative to the command line flag. (#1937)
- 🐛 Don't use uv on PyPy3.8 on Windows, it stopped working starting in 0.2.25. Note that PyPy 3.8 is EoL. (#1868)
- 🛠 Set the `VSCMD_ARG_TGT_ARCH` variable based on target arch. (#1876)
- 🛠 Undo cleaner output on pytest 8-8.2 now that 8.3 is out. (#1943)
- 📚 Update examples to use Python 3.12 on host (cibuildwheel will require Python 3.11+ on the host machine starting in October 2024) (#1919)
### v2.19.2
_2 July 2024_
- 🐛 Update manylinux2014 pins to versions that support past-EoL CentOS 7 mirrors. (#1917)
- 🐛 Support `--no-isolation` with `build[uv]` build-frontend. (#1889)
- 🛠 Provide attestations for releases at <https://github.com/pypa/cibuildwheel/attestations>. (#1916)
- 🛠 Provide CPython 3.13.0b3. (#1913)
- 🛠 Remove some workarounds now that pip 21.1 is available. (#1891, #1892)
- 📚 Remove nosetest from our docs. (#1821)
- 📚 Document the macOS ARM workaround for 3.8 on GHA. (#1871)
- 📚 GitLab CI + macOS is now a supported platform with an example. (#1911)
### v2.19.1
_13 June 2024_
- 🐛 Don't require setup-python on GHA for Pyodide (#1868)
- 🐛 Specify full python path for uv (fixes issue in 0.2.10 & 0.2.11) (#1881)
- 🛠 Update for pip 24.1b2 on CPython 3.13. (#1879)
- 🛠 Fix a warning in our schema generation script. (#1866)
- 🛠 Cleaner output on pytest 8-8.2. (#1865)
### v2.19.0
_10 June 2024_
See the [release post](https://iscinumpy.dev/post/cibuildwheel-2-19-0/) for more info on new features!
- 🌟 Add Pyodide platform. Set with `--platform pyodide` or `CIBW_PLATFORM: pyodide` on Linux with a host Python 3.12 to build WebAssembly wheels. Not accepted on PyPI currently, but usable directly in a website using Pyodide, for live docs, etc. (#1456, #1859)
- 🌟 Add `build[uv]` backend, which will take a pre-existing uv install (or install `cibuildwheel[uv]`) and use `uv` for all environment setup and installs on Python 3.8+. This is significantly faster in most cases. (#1856)
- ✨ Add free-threaded macOS builds and update CPython to 3.13.0b2. (#1854)
- 🐛 Issue copying a wheel to a non-existent output dir fixed. (#1851, #1862)
- 🐛 Better determinism for the test environment seeding. (#1835)
- 🛠 `VIRTUAL_ENV` variable now set. (#1842)
- 🛠 Remove a pip<21.3 workaround. (#1842)
- 🛠 Error handling was refactored to use exceptions. (#1719)
- 🛠 Hardcoded paths in tests avoided. (#1834)
- 🛠 Single Python tests made more generic. (#1835)
- 🛠 Sped up our ci by splitting up emulation tests. (#1839)
### v2.18.1
_20 May 2024_
- 🌟 Add free-threaded Linux and Windows builds for 3.13. New identifiers `cp313t-*`, new option `CIBW_FREE_THREADED_SUPPORT`/`tool.cibuildwheel.free-threaded-support` required to opt-in. [See the docs](https://cibuildwheel.pypa.io/en/stable/options/#free-threaded-support) for more information. (#1831)
- ✨ The `container-engine` is now a build (non-global) option. (#1792)
- 🛠 The build backend for cibuildwheel is now hatchling. (#1297)
- 🛠 Significant improvements and modernization to our noxfile. (#1823)
- 🛠 Use pylint's new GitHub Actions reporter instead of a custom matcher. (#1823)
- 🛠 Unpin virtualenv updates for Python 3.7+ (#1830)
- 🐛 Fix running linux tests from Windows or macOS ARM. (#1788)
- 📚 Fix our documentation build. (#1821)
### v2.18.0
_12 May 2024_
- ✨ Adds CPython 3.13 support, under the prerelease flag [CIBW_PRERELEASE_PYTHONS](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons). This version of cibuildwheel uses 3.13.0b1. Free-threading mode is not available yet (#1657), waiting on official binaries (planned for beta 2) and pip support.
_While CPython is in beta, the ABI can change, so your wheels might not be compatible with the final release. For this reason, we don't recommend distributing wheels until RC1, at which point 3.13 will be available in cibuildwheel without the flag._ (#1815)
- ✨ Musllinux now defaults to `musllinux_1_2`. You can set the older `musllinux_1_1` via config if needed. (#1817)
- 🛠 No longer pre-seed setuptools/wheel in virtual environments (#1819)
- 🛠 Respect the constraints file when building with pip, matching build (#1818)
- 🛠 Use uv to compile our pinned dependencies, 10x faster and doesn't require special setup (#1778)
- 🐛 Fix an issue with the schema (#1788)
- 📚 Document the new delocate error checking macOS versions (#1766)
- 📚 Document Rust builds (#1816)
- 📚 Speed up our readthedocs builds with uv, 26 seconds -> 6 seconds to install dependencies (#1816)
### v2.17.0
_11 March 2024_
- 🌟 Adds the ability to inherit configuration in TOML overrides. This makes certain configurations much simpler. If you're overriding an option like `before-build` or `environment`, and you just want to add an extra command or environment variable, you can just append (or prepend) to the previous config. See [the docs](https://cibuildwheel.pypa.io/en/stable/options/#inherit) for more information. (#1730)
- 🌟 Adds official support for native `arm64` macOS GitHub runners. To use them, just specify `macos-14` as an `os` of your job in your workflow file. You can also keep `macos-13` in your build matrix to build `x86_64`. Check out the new [GitHub Actions example config](https://cibuildwheel.pypa.io/en/stable/setup/#github-actions).
- ✨ You no longer need to specify `--platform` to run cibuildwheel locally! Instead it will detect your platform automatically. This was a safety feature, no longer necessary. (#1727)
- 🛠 Removed setuptools and wheel pinned versions. This only affects old-style projects without a `pyproject.toml`, projects with `pyproject.toml` are already getting fresh versions of their `build-system.requires` installed into an isolated environment. (#1725)
- 🛠 Improve how the GitHub Action passes arguments (#1757)
- 🛠 Remove a system-wide install of pipx in the GitHub Action (#1745)
- 🐛 No longer will cibuildwheel override the `PIP_CONSTRAINT` environment variable when using the `build` frontend. Instead it will be extended. (#1675)
- 🐛 Fix a bug where building and testing both `x86_86` and `arm64` wheels on the same runner caused the wrong architectures in the test environment (#1750)
- 🐛 Fix a bug that prevented testing a CPython 3.8 wheel targeting macOS 11+ on `x86_64` (#1768)
- 📚 Moved the docs onto the official PyPA domain - they're now available at https://cibuildwheel.pypa.io . (#1775)
- 📚 Docs and examples improvements (#1762, #1734)
### v2.16.5
_30 January 2024_
- 🐛 Fix an incompatibility with the GitHub Action and new GitHub Runner images for Windows that bundle Powershell 7.3+ (#1741)
- 🛠 Preliminary support for new `macos-14` arm64 runners (#1743)
### v2.16.4
_28 January 2024_
- 🛠 Update manylinux pins to upgrade from a problematic PyPy version. (#1737)
### v2.16.3
_26 January 2024_
- 🐛 Fix a bug when building from sdist, where relative paths to files in the package didn't work because the working directory was wrong (#1687)
- 🛠 Adds the ability to disable mounting the host filesystem in containers to `/host`, through the `disable_host_mount` suboption on [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine).
- 📚 A lot of docs improvements! (#1708, #1705, #1686, #1679, #1667, #1665)
### v2.16.2
_3 October 2023_
- 🛠 Updates CPython 3.12 version to 3.12.0, final release (#1635)
- ✨ Adds a debug option [`CIBW_DEBUG_KEEP_CONTAINER`](https://cibuildwheel.pypa.io/en/stable/options/#cibw_debug_keep_container) to stop cibuildwheel deleting build containers after the build finishes. (#1620)
- 📚 Adds support for `[tool.cibuildwheel]` checking by adding a schema compatible with the [validate-pyproject](https://github.com/abravalheri/validate-pyproject/) tool (#1622, #1628, #1629)
- 🐛 Fix parsing of `CIBW_CONTAINER_ENGINE` and `CIBW_BUILD_FRONTEND` options to not break arguments on `:` characters (#1621)
- 🐛 Fix the evaluation order of `CIBW_ENVIRONMENT` and `CIBW_ENVIRONMENT_PASS` so that `CIBW_ENVIRONMENT` assignments can reference environment variables passed through from the host machine. (#1617)
- 🛠 Supports manylinux images' deferred installation of interpreters through the `manylinux-interpreters` tool (#1630)
### v2.16.1
_26 September 2023_
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0rc3 (#1625)
- 🛠 Only calls `linux32` in containers when necessary (#1599)
### v2.16.0
_18 September 2023_
- ✨ Add the ability to pass additional flags to a build frontend through the [CIBW_BUILD_FRONTEND](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) option (#1588).
- ✨ The environment variable SOURCE_DATE_EPOCH is now automatically passed through to container Linux builds (useful for [reproducible builds](https://reproducible-builds.org/docs/source-date-epoch/)!) (#1589)
- 🛠 Updates the prerelease CPython 3.12 version to 3.12.0rc2 (#1604)
- 🐛 Fix `requires_python` auto-detection from setup.py when the call to `setup()` is within an `if __name__ == "__main__"` block (#1613)
- 🐛 Fix 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_
@@ -15,11 +276,11 @@ _10 June 2023_
_28 May 2023_
- ✨ Adds CPython 3.12 support, under the prerelease flag [CIBW_PRERELEASE_PYTHONS](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons). This version of cibuildwheel uses 3.12.0b1.
- ✨ Adds CPython 3.12 support, under the prerelease flag [CIBW_PRERELEASE_PYTHONS](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons). This version of cibuildwheel uses 3.12.0b1.
While CPython is in beta, the ABI can change, so your wheels might not be compatible with the final release. For this reason, we don't recommend distributing wheels until RC1, at which point 3.12 will be available in cibuildwheel without the flag. (#1507)
- ✨ Adds the ability to pass arguments to the container engine when the container is created, using the [CIBW_CONTAINER_ENGINE](https://cibuildwheel.readthedocs.io/en/stable/options/#container-engine) option. (#1499)
- ✨ Adds the ability to pass arguments to the container engine when the container is created, using the [CIBW_CONTAINER_ENGINE](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) option. (#1499)
### v2.12.3
@@ -74,7 +335,7 @@ _26 October 2022_
- 🛠 Fix the default `MACOSX_DEPLOYMENT_TARGET` on arm64 (#1312)
- 🛠 Hide irrelevant pip warnings on linux (#1311)
- 🐛 Fix a bug that caused the stdout and stderr of commands in containers to be in the wrong order Previously, stdout could appear after stderr. (#1324)
- 📚 Added [a FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64) describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
- 📚 Added [a FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#macos-building-cpython-38-wheels-on-arm64) describing how to perform native builds of CPython 3.8 wheels on Apple Silicon. (#1323)
- 📚 Other docs improvements
### v2.11.1
@@ -87,7 +348,7 @@ _13 October 2022_
_13 October 2022_
- 🌟 Adds support for cross-compiling Windows ARM64 wheels. To use this feature, add `ARM64` to the [CIBW_ARCHS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs) option on a Windows Intel runner. (#1144)
- 🌟 Adds support for cross-compiling Windows ARM64 wheels. To use this feature, add `ARM64` to the [CIBW_ARCHS](https://cibuildwheel.pypa.io/en/stable/options/#archs) option on a Windows Intel runner. (#1144)
- ✨ Adds support for building Linux aarch64 wheels on Circle CI. (#1307)
- ✨ Adds support for building Windows wheels on Gitlab CI. (#1295)
- ✨ Adds support for building Linux aarch64 wheels under emulation on Gitlab CI. (#1295)
@@ -114,10 +375,10 @@ _18 September 2022_
_13 September 2022_
- 🌟 Adds support for [building wheels on Cirrus CI](https://cibuildwheel.readthedocs.io/en/stable/setup/#cirrus-ci). This is exciting for us, as it's the first public CI platform that natively supports macOS Apple Silicon (aka. M1, `arm64`) runners. As such, it's the first platform that you can natively build _and test_ macOS `arm64` wheels. It also has native Linux ARM (aarch64) runners, for fast, native builds there. (#1191)
- 🌟 Adds support for [building wheels on Cirrus CI](https://cibuildwheel.pypa.io/en/stable/setup/#cirrus-ci). This is exciting for us, as it's the first public CI platform that natively supports macOS Apple Silicon (aka. M1, `arm64`) runners. As such, it's the first platform that you can natively build _and test_ macOS `arm64` wheels. It also has native Linux ARM (aarch64) runners, for fast, native builds there. (#1191)
- 🌟 Adds support for running cibuildwheel on Apple Silicon machines. For a while, we've supported cross-compilation of Apple Silicon wheels on `x86_64`, but now that we have Cirrus CI we can run our test suite and officially support running cibuildwheel on `arm64`. (#1191)
- ✨ Adds the `--only` [command line option](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line), to specify a single build to run. Previously, it could be cumbersome to set all the build selection options to target a specific build - for example, you might have to run something like `CIBW_BUILD=cp39-manylinux_x86_64 cibuildwheel --platform linux --archs x86_64`. The new `--only` option overrides all the build selection options to simplify running a single build, which now looks like `cibuildwheel --only cp39-manylinux_x86_64`. (#1098)
- ✨ Adds the [`CIBW_CONFIG_SETTINGS`](https://cibuildwheel.readthedocs.io/en/stable/options/#config-settings) option, so you can pass arguments to your package's build backend (#1244)
- ✨ Adds the `--only` [command line option](https://cibuildwheel.pypa.io/en/stable/options/#command-line), to specify a single build to run. Previously, it could be cumbersome to set all the build selection options to target a specific build - for example, you might have to run something like `CIBW_BUILD=cp39-manylinux_x86_64 cibuildwheel --platform linux --archs x86_64`. The new `--only` option overrides all the build selection options to simplify running a single build, which now looks like `cibuildwheel --only cp39-manylinux_x86_64`. (#1098)
- ✨ Adds the [`CIBW_CONFIG_SETTINGS`](https://cibuildwheel.pypa.io/en/stable/options/#config-settings) option, so you can pass arguments to your package's build backend (#1244)
- 🛠 Updates the CPython 3.11 version to the latest release candidate - v3.11.0rc2. (#1265)
- 🐛 Fix a bug that can cause a RecursionError on Windows when building from an sdist. (#1253)
- 🛠 Add support for the s390x architecture on manylinux_2_28 (#1255)
@@ -144,7 +405,7 @@ _18 July 2022_
_5 July 2022_
- ✨ You can now run cibuildwheel on Podman, as an alternate container engine to Docker (which remains the default). This is useful in environments where a Docker daemon isn't available, for example, it can be run inside a Docker container, or without root access. To use Podman, set the [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.readthedocs.io/en/stable/options/#container-engine) option. (#966)
- ✨ You can now run cibuildwheel on Podman, as an alternate container engine to Docker (which remains the default). This is useful in environments where a Docker daemon isn't available, for example, it can be run inside a Docker container, or without root access. To use Podman, set the [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) option. (#966)
- ✨ Adds support for building `py3-none-{platform}` wheels. This works the same as ABI3 - wheels won't be rebuilt, but tests will still be run across all selected versions of Python.
These wheels contain native extension code, but don't use the Python APIs. Typically, they're bridged to Python using a FFI module like [ctypes](https://docs.python.org/3/library/ctypes.html) or [cffi](https://cffi.readthedocs.io/en/latest/). Because they don't use Python ABI, the wheels are more compatible - they work across many Python versions.
@@ -158,7 +419,7 @@ _5 July 2022_
_17 June 2022_
- 🌟 Added support for the new `manylinux_2_28` images. These new images are based on AlmaLinux, the community-driven successor to CentOS, unlike manylinux_2_24, which was based on Debian. To build on these images, set your [`CIBW_MANYLINUX_*_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image) option to `manylinux_2_28`. (#1026)
- 🌟 Added support for the new `manylinux_2_28` images. These new images are based on AlmaLinux, the community-driven successor to CentOS, unlike manylinux_2_24, which was based on Debian. To build on these images, set your [`CIBW_MANYLINUX_*_IMAGE`](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) option to `manylinux_2_28`. (#1026)
- 🐛 Fix a bug where tests were not being run on CPython 3.11 (when CIBW_PRERELEASE_PYTHONS was set) (#1138)
- ✨ You can now build Linux wheels on Windows, as long as you have Docker installed and set to 'Linux containers' (#1117)
- 🐛 Fix a bug on macOS that caused cibuildwheel to crash trying to overwrite a previously-built wheel of the same name. (#1129)
@@ -173,15 +434,15 @@ _7 June 2022_
_25 May 2022_
- 🌟 Added the ability to test building wheels on CPython 3.11! Because CPython 3.11 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons) to test. This version of cibuildwheel includes CPython 3.11.0b1. (#1109)
- 📚 Added an interactive diagram showing how cibuildwheel works to the [docs](https://cibuildwheel.readthedocs.io/en/stable/#how-it-works) (#1100)
- 🌟 Added the ability to test building wheels on CPython 3.11! Because CPython 3.11 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons) to test. This version of cibuildwheel includes CPython 3.11.0b1. (#1109)
- 📚 Added an interactive diagram showing how cibuildwheel works to the [docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works) (#1100)
### v2.5.0
_29 April 2022_
- ✨ Added support for building ABI3 wheels. cibuildwheel will now recognise when an ABI3 wheel was produced, and skip subsequent build steps where the previously built wheel is compatible. Tests still will run on all selected versions of Python, using the ABI3 wheel. Check [this entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#abi3) in the docs for more info. (#1091)
- ✨ You can now build wheels directly from sdist archives, in addition to source directories. Just call cibuildwheel with an sdist argument on the command line, like `cibuildwheel mypackage-1.0.0.tar.gz`. For more details, check the [`--help` output](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line) (#1096)
- ✨ Added support for building ABI3 wheels. cibuildwheel will now recognise when an ABI3 wheel was produced, and skip subsequent build steps where the previously built wheel is compatible. Tests still will run on all selected versions of Python, using the ABI3 wheel. Check [this entry](https://cibuildwheel.pypa.io/en/stable/faq/#abi3) in the docs for more info. (#1091)
- ✨ You can now build wheels directly from sdist archives, in addition to source directories. Just call cibuildwheel with an sdist argument on the command line, like `cibuildwheel mypackage-1.0.0.tar.gz`. For more details, check the [`--help` output](https://cibuildwheel.pypa.io/en/stable/options/#command-line) (#1096)
- 🐛 Fix a bug where cibuildwheel would crash when no builds are selected and `--allow-empty` is passed (#1086)
- 🐛 Workaround a permissions issue on Linux relating to newer versions of git and setuptools_scm (#1095)
- 📚 Minor docs improvements
@@ -190,7 +451,7 @@ _29 April 2022_
_2 April 2022_
- ✨ cibuildwheel now supports running locally on Windows and macOS (as well as Linux). On macOS, you'll have to install the versions of Pythons that you want to use from Python.org, and cibuildwheel will use them. On Windows, cibuildwheel will install it's own versions of Python. Check out [the documentation](https://cibuildwheel.readthedocs.io/en/stable/setup/#local) for instructions. (#974)
- ✨ cibuildwheel now supports running locally on Windows and macOS (as well as Linux). On macOS, you'll have to install the versions of Pythons that you want to use from Python.org, and cibuildwheel will use them. On Windows, cibuildwheel will install it's own versions of Python. Check out [the documentation](https://cibuildwheel.pypa.io/en/stable/setup/#local) for instructions. (#974)
- ✨ Added support for building PyPy 3.9 wheels. (#1031)
- ✨ Listing at the end of the build now displays the size of each wheel (#975)
- 🐛 Workaround a connection timeout bug on Travis CI ppc64le runners (#906)
@@ -210,12 +471,12 @@ _14 December 2021_
_26 November 2021_
- 📈 cibuildwheel now defaults to manylinux2014 image for linux builds, rather than manylinux2010. If you want to stick with manylinux2010, it's simple to set this using [the image options](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image). (#926)
- ✨ You can now pass environment variables from the host machine into the Docker container during a Linux build. Check out [the docs for `CIBW_ENVIRONMENT_PASS_LINUX `](https://cibuildwheel.readthedocs.io/en/latest/options/#environment-pass) for the details. (#914)
- 📈 cibuildwheel now defaults to manylinux2014 image for linux builds, rather than manylinux2010. If you want to stick with manylinux2010, it's simple to set this using [the image options](https://cibuildwheel.pypa.io/en/stable/options/#linux-image). (#926)
- ✨ You can now pass environment variables from the host machine into the Docker container during a Linux build. Check out [the docs for `CIBW_ENVIRONMENT_PASS_LINUX `](https://cibuildwheel.pypa.io/en/latest/options/#environment-pass) for the details. (#914)
- ✨ Added support for building PyPy 3.8 wheels. (#881)
- ✨ Added support for building Windows arm64 CPython wheels on a Windows arm64 runner. We can't test this in CI yet, so for now, this is experimental. (#920)
- 📚 Improved the deployment documentation (#911)
- 🛠 Changed the escaping behaviour inside cibuildwheel's option placeholders e.g. `{project}` in `before_build` or `{dest_dir}` in `repair_wheel_command`. This allows bash syntax like `${SOME_VAR}` to passthrough without being interpreted as a placeholder by cibuildwheel. See [this section](https://cibuildwheel.readthedocs.io/en/stable/options/#placeholders) in the docs for more info. (#889)
- 🛠 Changed the escaping behaviour inside cibuildwheel's option placeholders e.g. `{project}` in `before_build` or `{dest_dir}` in `repair_wheel_command`. This allows bash syntax like `${SOME_VAR}` to passthrough without being interpreted as a placeholder by cibuildwheel. See [this section](https://cibuildwheel.pypa.io/en/stable/options/#placeholders) in the docs for more info. (#889)
- 🛠 Pip updated to 21.3, meaning it now defaults to in-tree builds again. If this causes an issue with your project, setting environment variable `PIP_USE_DEPRECATED=out-of-tree-build` is available as a temporary flag to restore the old behaviour. However, be aware that this flag will probably be removed soon. (#881)
- 🐛 You can now access the current Python interpreter using `python3` within a build on Windows (#917)
@@ -238,15 +499,15 @@ _22 October 2021_
- 🌟 Added support for [musllinux](https://www.python.org/dev/peps/pep-0656/). Support for this new wheel format lets projects build wheels for Linux distributions that use [musl libc](https://musl.libc.org/), notably, [Alpine](https://alpinelinux.org/) Docker containers. (#768)
Musllinux builds are enabled by default. If you're not ready to build musllinux, add `*-musllinux_*` to your [`CIBW_SKIP`/`skip`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) option. Or, you might have to make some changes to your options - to simplify that process, you can use...
Musllinux builds are enabled by default. If you're not ready to build musllinux, add `*-musllinux_*` to your [`CIBW_SKIP`/`skip`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) option. Or, you might have to make some changes to your options - to simplify that process, you can use...
- 🌟 TOML option overrides! This provides much greater flexibility in configuration via pyproject.toml. (#854)
You can now set build options for any subset of your builds using a match pattern. So, for example, you can customise CPython 3.8 builds with an override on `cp38-*` or musllinux builds by selecting `*musllinux*`. Check out [the docs](https://cibuildwheel.readthedocs.io/en/latest/options/#overrides) for more info on the specifics.
You can now set build options for any subset of your builds using a match pattern. So, for example, you can customise CPython 3.8 builds with an override on `cp38-*` or musllinux builds by selecting `*musllinux*`. Check out [the docs](https://cibuildwheel.pypa.io/en/latest/options/#overrides) for more info on the specifics.
- 🛠 Added support for building PyPy wheels on macOS 11 CI runners. (#875)
- 🛠 Setting an empty string for the [`CIBW_*_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) option will now fallthrough to the config file or cibuildwheel's default, rather than causing an error. This makes the option easier to use in CI build matricies. (#829)
- 🛠 Setting an empty string for the [`CIBW_*_IMAGE`](https://cibuildwheel.pypa.io/en/stable/options/#manylinux-image) option will now fallthrough to the config file or cibuildwheel's default, rather than causing an error. This makes the option easier to use in CI build matrices. (#829)
- 🛠 Support for TOML 1.0 when reading config files, via the `tomli` package. (#876)
@@ -285,9 +546,9 @@ _25 July 2021_
_16 July 2021_
- 🌟 You can now configure cibuildwheel options inside your project's `pyproject.toml`! Environment variables still work of course. Check out the [documentation](https://cibuildwheel.readthedocs.io/en/stable/options/#setting-options) for more info.
- 🌟 Added support for building wheels with [build](https://github.com/pypa/build), as well as pip. This feature is controlled with the [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-frontend) option.
- 🌟 Added the ability to test building wheels on CPython 3.10! Because CPython 3.10 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons) to test. (#675) This version of cibuildwheel includes CPython 3.10.0b4.
- 🌟 You can now configure cibuildwheel options inside your project's `pyproject.toml`! Environment variables still work of course. Check out the [documentation](https://cibuildwheel.pypa.io/en/stable/options/#setting-options) for more info.
- 🌟 Added support for building wheels with [build](https://github.com/pypa/build), as well as pip. This feature is controlled with the [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) option.
- 🌟 Added the ability to test building wheels on CPython 3.10! Because CPython 3.10 is in beta, these wheels should not be distributed, because they might not be compatible with the final release, but it's available to build for testing purposes. Use the flag [`--prerelease-pythons` or `CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons) to test. (#675) This version of cibuildwheel includes CPython 3.10.0b4.
- ⚠️ **Removed support for building Python 2.7 and Python 3.5 wheels**, for both CPython and PyPy. If you still need to build on these versions, please use the latest v1.x version. (#596)
- ✨ Added the ability to build CPython 3.8 wheels for Apple Silicon. (#704)
- 🛠 Update to the latest build dependencies, including Auditwheel 4. (#633)
@@ -314,7 +575,7 @@ _1 May 2021_
- 📚 Lots of docs improvements! (#650, #623, #616, #609, #606)
- 🐛 Fix nuget "Package is not found" error on Windows. (#653)
- ⚠️ cibuildwheel will no longer build Windows 2.7 wheels, unless you specify a custom toolchain using `DISTUTILS_USE_SDK=1` and `MSSdk=1`. This is because Microsoft have stopped distributing Visual C++ Compiler for Python 2.7. See [this FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#windows-and-python-27) for more details. (#649)
- ⚠️ cibuildwheel will no longer build Windows 2.7 wheels, unless you specify a custom toolchain using `DISTUTILS_USE_SDK=1` and `MSSdk=1`. This is because Microsoft have stopped distributing Visual C++ Compiler for Python 2.7. See [this FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#windows-and-python-27) for more details. (#649)
- 🐛 Fix crash on Windows due to missing `which` command (#641).
### v1.10.0
@@ -322,7 +583,7 @@ _1 May 2021_
_22 Feb 2021_
- ✨ Added `manylinux_2_24` support. To use these new Debian-based manylinux
images, set your [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image)
images, set your [manylinux image](https://cibuildwheel.pypa.io/en/stable/options/#linux-image)
options to `manylinux_2_24`.
- 🛠 On macOS, we now set `MACOSX_DEPLOYMENT_TARGET` in before running
`CIBW_BEFORE_ALL`. This is useful when using `CIBW_BEFORE_ALL` to build a
@@ -339,10 +600,10 @@ _5 February 2021_
- 🌟 Added support for Apple Silicon wheels on macOS! You can now
cross-compile `universal2` and `arm64` wheels on your existing macOS Intel
runners, by setting
[CIBW_ARCHS_MACOS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs).
[CIBW_ARCHS_MACOS](https://cibuildwheel.pypa.io/en/stable/options/#archs).
Xcode 12.2 or later is required, but you don't need macOS 11.0 - you can
still build on macOS 10.15. See
[this FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#apple-silicon)
[this FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#apple-silicon)
for more information. (#484)
- 🌟 Added auto-detection of your package's Python compatibility, via declared
[`requires-python`](https://www.python.org/dev/peps/pep-0621/#requires-python)
@@ -352,7 +613,7 @@ _5 February 2021_
will automatically skip builds on versions of Python that your package
doesn't support. Hopefully this makes the first-run experience of
cibuildwheel a bit easier. If you need to override this for any reason,
look at [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.readthedocs.io/en/stable/options/#requires-python).
look at [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.pypa.io/en/stable/options/#requires-python).
(#536)
- 🌟 cibuildwheel can now be invoked as a native GitHub Action! You can now
invoke cibuildwheel in a GHA build step like:
@@ -367,10 +628,10 @@ _5 February 2021_
```
This saves a bit of boilerplate, and you can [use Dependabot to keep the
pinned version up-to-date](https://cibuildwheel.readthedocs.io/en/stable/faq/#automatic-updates).
pinned version up-to-date](https://cibuildwheel.pypa.io/en/stable/faq/#automatic-updates).
- ✨ Added `auto64` and `auto32` shortcuts to the
[CIBW_ARCHS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs)
[CIBW_ARCHS](https://cibuildwheel.pypa.io/en/stable/options/#archs)
option. (#553)
- ✨ cibuildwheel now prints a list of the wheels built at the end of each
run. (#570)
@@ -383,9 +644,9 @@ _22 January 2021_
- 🌟 Added support for emulated builds! You can now build manylinux wheels on
ARM64`aarch64`, as well as `ppc64le` and 's390x'. To build under emulation,
register QEMU via binfmt_misc and set the
[`CIBW_ARCHS_LINUX`](https://cibuildwheel.readthedocs.io/en/stable/options/#archs)
[`CIBW_ARCHS_LINUX`](https://cibuildwheel.pypa.io/en/stable/options/#archs)
option to the architectures you want to run. See
[this FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#emulation)
[this FAQ entry](https://cibuildwheel.pypa.io/en/stable/faq/#emulation)
for more information. (#482)
- ✨ Added `CIBW_TEST_SKIP` option. This allows you to choose certain builds
whose tests you'd like to skip. This might be useful when running a slow
@@ -411,7 +672,7 @@ _1 January 2021_
in a virtualenv. (#502)
- 🛠 Some preparatory work towards using cibuildwheel as a GitHub Action.
Check out
[the FAQ](https://cibuildwheel.readthedocs.io/en/stable/faq/#option-1-github-action)
[the FAQ](https://cibuildwheel.pypa.io/en/stable/faq/#option-1-github-action)
for information on how to use it. We'll be fully updating the docs to this
approach in a subsequent release (#494)
@@ -533,7 +794,7 @@ _25 June 2020_
_24 June 2020_
- 🌟 Add [`CIBW_BEFORE_ALL`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-all)
- 🌟 Add [`CIBW_BEFORE_ALL`](https://cibuildwheel.pypa.io/en/stable/options/#before-all)
option, which lets you run a command on the build machine before any wheels
are built. This is especially useful when building on Linux, to `make`
something external to Python, or to `yum install` a dependency. (#342)
@@ -576,15 +837,15 @@ _2 May 2020_
environment on macOS and Windows, where the version of Xcode and Visual
Studio can still effect things.
This can be controlled using the [CIBW_DEPENDENCY_VERSIONS](https://cibuildwheel.readthedocs.io/en/stable/options/#dependency-versions)
and [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image)
This can be controlled using the [CIBW_DEPENDENCY_VERSIONS](https://cibuildwheel.pypa.io/en/stable/options/#dependency-versions)
and [manylinux image](https://cibuildwheel.pypa.io/en/stable/options/#linux-image)
options - if you always want to use the latest toolchain, you can still do
that, or you can specify your own pip constraints file and manylinux image.
(#256)
- ✨ Added `package_dir` command line option, meaning we now support building
a package that lives in a subdirectory and pulls in files from the wider
project. See [the `package_dir` option help](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line-options)
project. See [the `package_dir` option help](https://cibuildwheel.pypa.io/en/stable/options/#command-line-options)
for more information.
Note that this change makes the working directory (where you call
@@ -602,7 +863,7 @@ _2 May 2020_
_12 March 2020_
- 🌟 Add support for building on GitHub Actions! Check out the
[docs](https://cibuildwheel.readthedocs.io/en/stable/setup/#github-actions)
[docs](https://cibuildwheel.pypa.io/en/stable/setup/#github-actions)
for information on how to set it up. (#194)
- ✨ Add the `CIBW_BEFORE_TEST` option, which lets you run a command to
prepare the environment before your tests are run. (#242)
@@ -652,9 +913,9 @@ _10 November 2019_
build using the manylinux2010 images by default. If your project is still
manylinux1 compatible, you should get both manylinux1 and manylinux2010
wheels - you can upload both to PyPI. If you always require manylinux1 wheels, you can
build using the old manylinux1 image using the [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#linux-image) option.
build using the old manylinux1 image using the [manylinux image](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) option.
(#155)
- 📚 Documentation is now on its [own mini-site](https://cibuildwheel.readthedocs.io),
- 📚 Documentation is now on its [own mini-site](https://cibuildwheel.pypa.io),
rather than on the README (#169)
- ✨ Add support for building Windows wheels on Travis CI. (#160)
- 🛠 If you set `CIBW_TEST_COMMAND`, your tests now run in a virtualenv. (#164)
+95 -23
View File
@@ -12,17 +12,16 @@ If you have an idea for a modification or feature, it's probably best to raise a
Everyone contributing to the cibuildwheel project is expected to follow the [PSF Code of Conduct](https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md).
Design Goals
------------
## Design Goals
- `cibuildwheel` should wrap the complexity of wheel building.
- The user interface to `cibuildwheel` is the build script (e.g. `.travis.yml`). Feature additions should not increase the complexity of this script.
- Options should be environment variables (these lend themselves better to YML config files). They should be prefixed with `CIBW_`.
- Options should be generalise to all platforms. If platform-specific options are required, they should be namespaced e.g. `CIBW_TEST_COMMAND_MACOS`
- Options should be generalised to all platforms. If platform-specific options are required, they should be namespaced e.g. `CIBW_TEST_COMMAND_MACOS`
Other notes:
- The platforms are very similar, until they're not. I'd rather have straight-forward code than totally DRY code, so let's keep airy platform abstractions to a minimum.
- The platforms are very similar, until they're not. I'd rather have straightforward code than totally DRY code, so let's keep airy platform abstractions to a minimum.
- I might want to break the options into a shared config file one day, so that config is more easily shared. That has motivated some of the design decisions.
### cibuildwheel's relationship with build errors
@@ -33,41 +32,112 @@ We're not responsible for errors in those tools, for fixing errors/crashes there
So, if we can, I'd like to improve the experience on errors as well. In [this](https://github.com/pypa/cibuildwheel/issues/139) case, it takes a bit of knowledge to understand that the Linux builds are happening in a different OS via Docker, that the linked symbols won't match, that auditwheel will fail because of this. A problem with how the tools fit together, instead of the tools themselves.
Maintainer notes
----------------
## Development
### Nox support
### Running the tests
Most developer tasks have a nox interface. This allows you to very simply run tasks without worrying about setting up a development environment (as shown below). This is a slower than setting up a development environment and reusing it, but has the (important) benefit of being highly reproducible; an earlier run does not affect a current run, or anything else on your machine.
When making a change to the codebase, you can run tests locally for quicker feedback than the CI runs on a PR. You can [run them directly](#making-a-venv), but the easiest way to run tests is using [nox](https://nox.thea.codes/).
Install [nox](https://nox.thea.codes); homebrew is recommend on macOS, otherwise, pipx is a great choice - in fact, you can use `pipx run nox` and avoid installing completely.
You can run all the tests locally by doing:
```bash
nox -s tests
```
However, because this takes a while, you might prefer to be more specific.
#### Unit tests
To run the project's unit tests, do:
```bash
nox -s tests -- unit_test
```
There are a few custom options to enable different parts of the test suite - check `nox -s tests -- unit_test --help` for details.
If you're calling this a lot, you might consider using the `-r` or `-R` arguments to nox to make it a bit faster. This calls pytest under the hood, so to target a specific test, use pytest's `-k` option after the `--` above to select a specific test.
#### Integration tests
To run the project's integration tests, do:
```bash
nox -s tests -- test
```
The integration test suite is big - it can take more than 30 minutes to run the whole thing.
Because it takes such a long time, normally you'd choose specific tests to run locally, and rely on the project's CI for the rest. Use pytest's `-k` option to choose specific tests. You can pass a test name or a filename, it'll run everything that matches.
```bash
nox -s tests -- test -k <test_name_or_filename>
# e.g.
nox -s tests -- test -k before_build
```
A few notes-
- Because they run inside a container, Linux tests can run on all platforms where Docker is installed, so they're convenient for running integration tests locally. Set CIBW_PLATFORM to do this: `CIBW_PLATFORM=linux nox -s tests -- test`.
- Running the macOS integration tests requires _system installs_ of Python from python.org for all the versions that are tested. We won't attempt to install these when running locally, but you can do so manually using the URL in the error message that is printed when the install is not found.
#### Running pytest directly
More advanced users might prefer to invoke pytest directly. Set up a [dev environment](#setting-up-a-dev-environment), then,
```bash
# run the unit tests
pytest unit_test
# run the whole integration test suite
pytest test
# run a specific integration test
pytest test -k test_build_frontend_args
# run a specific integration test on a different platform
CIBW_PLATFORM=linux pytest test -k test_build_frontend_args
```
### Linting, docs
Most developer tasks have a nox interface. This allows you to very simply run tasks without worrying about setting up a development environment (as shown below). This is slower than setting up a development environment and reusing it, but has the (important) benefit of being highly reproducible; an earlier run does not affect a current run, or anything else on your machine.
You can see a list of sessions by typing `nox -l`; here are a few common ones:
```console
nox -s lint # Run the linters (default)
nox -s tests # Run the tests (default)
nox -s docs -- serve # Build and serve the documentation
nox -s build # Make SDist and wheel
nox -s lint # Run the linters (default)
nox -s tests [-- PYTEST-ARGS] # Run the tests (default)
nox -s docs # Build and serve the documentation
nox -s build # Make SDist and wheel
```
More advanced users can run the update scripts. `update_pins` should work directly, but `update_constraints` needs all versions of Python installed. If you don't want to do that locally, a fast way to run it to use docker to run nox:
More advanced users can run the update scripts:
```console
docker run --rm -itv $PWD:/src -w /src quay.io/pypa/manylinux_2_24_x86_64:latest pipx run nox -s update_constraints
nox -s update_constraints # update all constraints files in cibuildwheel/resources
nox -s update_pins # update tools, python interpreters & docker images used by cibuildwheel
```
### Local testing
### Setting up a dev environment
You should run:
A dev environment isn't required for any of the `nox` tasks above. However, a dev environment is still useful, to be able to point an editor at, and a few other jobs.
```console
python3 -m venv venv
. venv/bin/activate
pip install -e .[dev]
cibuildwheel uses dependency groups. Set up a dev environment with UV by doing
```bash
uv sync
```
To prepare a development environment.
Or, if you're not using `uv`, you can do:
```bash
python3 -m venv .venv
source .venv/bin/activate
pipx run dependency-groups dev | xargs pip install -e.
```
Your virtualenv is at `.venv`.
## Maintainer notes
### Testing sample configs
@@ -125,7 +195,7 @@ Then, increment the project version number using:
bin/bump_version.py
```
You'll be prompted to enter the new version number. Update the changelog when prompted. The script will create a 'bump version' commit and version tag.
(or `nox -s bump_version`) You'll be prompted to enter the new version number. Update the changelog when prompted. The script will create a 'bump version' commit and version tag.
Finally, cut the release and push to GitHub.
@@ -134,3 +204,5 @@ git push && git push --tags
```
Then head to https://github.com/pypa/cibuildwheel/releases and create a GitHub release from the new tag, pasting in the changelog entry. Once the release is created inside GitHub, a CI job will create the assets and upload them to PyPI.
If there were any schema updates, run `pipx run ./bin/generate_schema.py --schemastore > partial-cibuildwheel.json` and contribute the changes to SchemaStore.
+2 -3
View File
@@ -8,7 +8,7 @@ Building Python wheels with modern C++ standards (C++11 and later) requires a fe
## manylinux1 and C++14
The old `manylinux1` image (based on CentOS 5) contains a version of GCC and libstdc++ that only supports C++11 and earlier standards. There are however ways to compile wheels with the C++14 standard (and later): https://github.com/pypa/manylinux/issues/118
The past end-of-life `manylinux1` image (based on CentOS 5) contains a version of GCC and libstdc++ that only supports C++11 and earlier standards. There are however ways to compile wheels with the C++14 standard (and later): https://github.com/pypa/manylinux/issues/118
`manylinux2010` and `manylinux2014` are newer and support all C++ standards (up to C++17).
@@ -18,9 +18,8 @@ OS X/macOS allows you to specify a so-called "deployment target" version that wi
However, to enable modern C++ standards, the deployment target needs to be set high enough (since older OS X/macOS versions did not have the necessary modern C++ standard library).
To get C++11 and C++14 support, `MACOSX_DEPLOYMENT_TARGET` needs to be set to (at least) `"10.9"`. By default, `cibuildwheel` already does this, building 64-bit-only wheels for macOS 10.9 and later.
To get C++17 support, Xcode 9.3+ is needed, requiring at least macOS 10.13 on the build machine. To use C++17 library features and link against the C++ runtime library, set `MACOSX_DEPLOYMENT_TARGET` to `"10.13"` or `"10.14"` (or higher) - macOS 10.13 offers partial C++17 support (e.g., the filesystem header is in experimental, offering `#include <experimental/filesystem>` instead of `#include <filesystem>`); macOS 10.14 has full C++17 support.
To get C++17 support, Xcode 9.3+ is needed, requiring at least macOS 10.13 on the build machine. To use C++17 library features and link against the C++ runtime library, set `MACOSX_DEPLOYMENT_TARGET` to `"10.13"` or `"10.14"` (or higher) - macOS 10.13 offers partial C++17 support (e.g., the filesystem header is in experimental, offering `#include <experimental/filesystem>` instead of `#include <filesystem>`); macOS 10.14 has full C++17 support. CPython 3.12+ require 10.13+ anyway.
However, if only C++17 compiler and standard template library (STL) features are used (not needing a C++17 runtime) it might be possible to set `MACOSX_DEPLOYMENT_TARGET` to a lower value, such as `"10.9"`. To find out if this is the case, try compiling and running with a lower `MACOSX_DEPLOYMENT_TARGET`: if C++17 features are used that require a more recent deployment target, building the wheel should fail.
+37
View File
@@ -0,0 +1,37 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/docs/data/projects.schema.json",
"type": "array",
"description": "The projects file for cibuildwheel",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"name": { "type": "string" },
"gh": { "type": "string", "pattern": "[^/]*/[^/]*" },
"stars": { "$ref": "#/items/properties/gh" },
"pypi": { "type": "string" },
"notes": { "type": "string" },
"ci": {
"type": "array",
"items": {
"enum": [
"github",
"travisci",
"appveyor",
"circleci",
"gitlab",
"cirrusci",
"azurepipelines"
]
}
},
"ci_config": { "type": "string" },
"os": {
"type": "array",
"items": { "enum": ["windows", "apple", "linux"] }
}
},
"required": ["name", "gh", "ci", "os"]
}
}
+45 -11
View File
@@ -26,7 +26,7 @@
notes: A simple C extension, without external dependencies
- name: websockets
gh: aaugustin/websockets
gh: python-websockets/websockets
ci: [travisci]
ci_config: .travis.yml
os: [apple, linux]
@@ -325,12 +325,12 @@
notes: Full range of wheels for setuptools rust, with auto release and PyPI deploy.
- name: python-snappy
gh: andrix/python-snappy
gh: intake/python-snappy
ci: [github]
os: [apple, linux, windows]
- name: sourmash
gh: dib-lab/sourmash
gh: sourmash-bio/sourmash
ci: [github]
os: [apple, linux, windows]
@@ -413,11 +413,12 @@
- 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
gh: facebookresearch/fairseq
ci: [github]
os: [apple, linux]
@@ -474,7 +475,7 @@
os: [apple, linux, windows]
- name: OpenSpiel
gh: deepmind/open_spiel
gh: google-deepmind/open_spiel
ci: [github]
os: [apple, linux]
@@ -504,7 +505,7 @@
os: [apple, linux, windows]
- name: OpenTimelineIO
gh: PixarAnimationStudios/OpenTimelineIO
gh: AcademySoftwareFoundation/OpenTimelineIO
ci: [github]
os: [apple, linux, windows]
@@ -583,7 +584,7 @@
notes: Includes GPU support for linux wheels
- name: power-grid-model
gh: alliander-opensource/power-grid-model
gh: PowerGridModel/power-grid-model
ci: [github]
os: [windows, apple, linux]
notes: Python/C++ library for distribution power system analysis
@@ -602,13 +603,13 @@
gh: tensorchord/envd
ci: [github]
os: [apple, linux, windows]
note: A machine learning development environment build tool
notes: A machine learning development environment build tool
- name: mosec
gh: mosecorg/mosec
ci: [github]
os: [linux, apple]
note: A machine learning model serving framework powered by Rust
notes: A machine learning model serving framework powered by Rust
- name: ril
gh: Cryptex-github/ril-py
@@ -630,3 +631,36 @@
os: [windows, apple, linux]
pypi: aalink
notes: Async Python interface for Ableton Link.
- name: werpy
gh: analyticsinmotion/werpy
ci: [github]
os: [windows, linux, apple]
pypi: werpy
notes: An ultra-fast python package using optimized dynamic programming to compute the Word Error Rate (WER).
- name: keyvi
gh: KeyviDev/keyvi
ci: [github]
os: [linux, apple]
pypi: keyvi
notes: FST based key value index highly optimized for size and lookup performance, utilizes ccache action for improved runtime
- name: pedalboard
gh: spotify/pedalboard
ci: [github]
os: [windows, linux, apple]
pypi: pedalboard
notes: >
A Python library for working with audio data and audio plugins
by wrapping the [JUCE](https://github.com/juce-framework/JUCE/)
C++ framework. Uses cibuildwheel to deploy on as many operating
systems and Python versions as possible with only one dependency
(any NumPy).
- name: streaming-form-data
gh: siddhantgoel/streaming-form-data
ci: [github]
os: [apple, linux, windows]
pypi: streaming-form-data
notes: Streaming parser for multipart/form-data written in Cython
+13 -11
View File
@@ -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
@@ -56,35 +56,37 @@ well as several useful actions. Alongside your existing job(s) that runs cibuild
- name: Build SDist
run: pipx run build --sdist
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-sdist
path: dist/*.tar.gz
```
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:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: artifact
pattern: cibw-*
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@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
example, the same name (the default, "artifact" is used for all upload-artifact
runs, so we can just download all of the in one step into a common directory.
runs, so we can just download all of them in one step into a common directory.
See
[`examples/github-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml)
+17 -1
View File
@@ -255,7 +255,17 @@ h1, h2, h3, h4, h5, h6 {
border: none;
color: inherit;
background-color: #f0f1f1;
font-size: 100%;
font-size: 80%;
}
.rst-content table.docutils td code,
.rst-content table.docutils th code,
.rst-content table.field-list td code,
.rst-content table.field-list th code,
.wy-table td code,
.wy-table th code {
/* table elements are already made smaller, the code styling on top of that makes the text too small */
font-size: 82.5%;
}
@@ -315,3 +325,9 @@ h1, h2, h3, h4, h5, h6 {
.wy-menu-vertical li.current a {
}
/* word wrap in table cells */
.wy-table-responsive table td, .wy-table-responsive table th {
white-space: normal;
line-height: 1.4;
}
+92 -59
View File
@@ -10,19 +10,23 @@ title: Tips and tricks
Linux wheels are built in [`manylinux`/`musllinux` containers](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 600](https://www.python.org/dev/peps/pep-0600/) / [PEP 656](https://www.python.org/dev/peps/pep-0656/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2010` or `manylinux2014`, `apt-get` for `manylinux_2_24` and `apk` for `musllinux_1_1`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.
- Programs and libraries are not installed on the CI runner host, but rather should be installed inside the container - using `yum` for `manylinux2010` or `manylinux2014`, `apt-get` for `manylinux_2_24`/`manylinux_2_31`, `dnf` for `manylinux_2_28` and `apk` for `musllinux_1_1` or `musllinux_1_2`, or manually. The same goes for environment variables that are potentially needed to customize the wheel building.
`cibuildwheel` supports this by providing the [`CIBW_ENVIRONMENT`](options.md#environment) and [`CIBW_BEFORE_ALL`](options.md#before-all) options to setup the build environment inside the running container.
- The project directory is copied into the container as `/project`, the output directory for the wheels to be copied out is `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that `/host` is not available on CircleCI due to their Docker policies.
- The project directory is copied into the container as `/project`, the output directory for the wheels to be copied out is `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that `/host` is not available on CircleCI and GitLab CI due to their Docker policies.
- Alternative Docker images can be specified with the `CIBW_MANYLINUX_*_IMAGE`/`CIBW_MUSLLINUX_*_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [options](options.md#linux-image) for more details.
### Building macOS wheels for Apple Silicon {: #apple-silicon}
`cibuildwheel` supports cross-compiling `universal2` and `arm64` wheels on `x86_64` runners. With the introduction of Apple Silicon, you now have several choices for wheels for Python 3.8+:
`cibuildwheel` supports both native builds and cross-compiling between `arm64` (Apple Silicon) and `x86_64` (Intel) architectures, including the cross-compatible `universal2` format.
#### `x86_64`
#### Overview of Mac architectures
You 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,66 +34,59 @@ 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.
!!! important
When cross-compiling on Intel, it is not possible to test `arm64` and the `arm64` part of a `universal2` wheel.
See [GitHub issue 1333](https://github.com/pypa/cibuildwheel/issues/1333) for more discussion.
`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`.
#### How?
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`.
It's easiest to build `x86_64` wheels on `x86_64` runners, and `arm64` wheels on `arm64` runners.
On GitHub Actions, `macos-14` runners are `arm64`, and `macos-13` runners are `x86_64`. So all you need to do is ensure both are in your build matrix.
#### Cross-compiling
If your CI provider doesn't offer arm64 runners yet, or you want to create `universal2`, you'll have to cross-compile. Cross-compilation can be enabled by adding extra archs to the [`CIBW_ARCHS_MACOS` option](options.md#archs) - e.g. `CIBW_ARCHS_MACOS="x86_64 universal2"`. Cross-compilation is provided by Xcode toolchain v12.2+.
Regarding testing,
- On an arm64 runner, it is possible to test x86_64 wheels and both parts of a universal2 wheel using Rosetta 2 emulation.
- On an x86_64 runner, arm64 code can be compiled but it can't be tested. `cibuildwheel` will raise a warning to notify you of this - these warnings can be silenced by skipping testing on these platforms: `CIBW_TEST_SKIP: "*_arm64 *_universal2:arm64"`.
!!! note
Your runner needs Xcode Command Line Tools 12.2 or later to build `universal2` or `arm64`.
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`.
Only CPython 3.8 and newer support `universal2` and `arm64` wheels.
Here's an example GitHub Actions workflow with a job that builds for Apple Silicon:
> .github/workflows/build_macos.yml
```yml
{% include "../examples/github-apple-silicon.yml" %}
```
Here's an example Cirrus CI workflow with a job that builds for macOS Intel through Rosetta 2 emulation and for Apple Silicon natively:
> .cirrus.yml
```yml
{% include "../examples/cirrus-ci-intel-mac.yml" %}
```
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`.
### Building Linux wheels for non-native archs using emulation {: #emulation}
@@ -136,7 +133,7 @@ myextension = Extension(
### Automatic updates using Dependabot {: #automatic-updates}
Selecting a moving target (like the latest release) is generally a bad idea in CI. If something breaks, you can't tell whether it was your code or an upstream update that caused the breakage, and in a worse-case scenario, it could occur during a release.
Selecting a moving target (like the latest release) is generally a bad idea in CI. If something breaks, you can't tell whether it was your code or an upstream update that caused the breakage, and in a worst-case scenario, it could occur during a release.
There are two suggested methods for keeping cibuildwheel up to date that instead involve scheduled pull requests using GitHub's Dependabot.
@@ -145,7 +142,7 @@ There are two suggested methods for keeping cibuildwheel up to date that instead
If you use GitHub Actions for builds, you can use cibuildwheel as an action:
```yaml
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.23.2
```
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.
@@ -167,7 +164,7 @@ The second option, and the only one that supports other CI systems, is using a `
```bash
# requirements-cibw.txt
cibuildwheel==2.13.1
cibuildwheel==2.23.2
```
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:
@@ -187,7 +184,7 @@ This will also try to update other pins in all requirement files, so be sure you
### Alternatives to cibuildwheel options {: #cibw-options-alternatives}
cibuildwheel provides lots of opportunities to configure the build
environment. However, you might consider adding this build configuration into
environment. However, you might consider adding this build configuration into
the package itself - in general, this is preferred, because users of your
package 'sdist' will also benefit.
@@ -202,7 +199,6 @@ to build, your pyproject.toml might include a section like this:
[build-system]
requires = [
"setuptools>=42",
"wheel",
"Cython",
]
@@ -253,7 +249,7 @@ Consider incorporating these into your package, for example, in `setup.py` using
### Python 2.7 / PyPy2 wheels
See the [cibuildwheel version 1 docs](https://cibuildwheel.readthedocs.io/en/1.x/) for information about building Python 2.7 or PyPy2 wheels. There are lots of tricks and workaround there that are no longer required for Python 3 in cibuildwheel 2.
See the [cibuildwheel version 1 docs](https://cibuildwheel.pypa.io/en/1.x/) for information about building Python 2.7 or PyPy2 wheels. There are lots of tricks and workaround there that are no longer required for Python 3 in cibuildwheel 2.
## Troubleshooting
@@ -286,6 +282,27 @@ For these reasons, it's strongly recommended to not use brew for native library
[Homebrew]: https://brew.sh/
[delocate]: https://github.com/matthew-brett/delocate
### Building Rust wheels
If you build Rust wheels, you need to download the Rust compilers in manylinux.
If you support 32-bit Windows, you need to add this as a potential target. You
can do this on GitHub Actions, for example, with:
```yaml
CIBW_BEFORE_ALL_LINUX: curl -sSf https://sh.rustup.rs | sh -s -- -y
CIBW_BEFORE_ALL_WINDOWS: rustup target add i686-pc-windows-msvc
CIBW_ENVIRONMENT_LINUX: "PATH=$HOME/.cargo/bin:$PATH"
```
Rust does not provide Cargo for musllinux 32-bit, so that needs to be skipped:
```toml
[tool.cibuildwheel]
skip = ["*-musllinux_i686"]
```
Also see [maturin-action](https://github.com/PyO3/maturin-action) which is optimized for Rust wheels, builds the non-Python Rust modules once, and can cross-compile (and can build 32-bit musl, for example).
### macOS: ModuleNotFoundError
Calling cibuildwheel from a python3 script and getting a `ModuleNotFoundError`? Due to a (fixed) [bug](https://bugs.python.org/issue22490) in CPython, you'll need to [unset the `__PYVENV_LAUNCHER__` variable](https://github.com/pypa/cibuildwheel/issues/133#issuecomment-478288597) before activating a venv.
@@ -311,7 +328,7 @@ Solutions to this vary, but the simplest is to use pipx:
# most runners have pipx preinstalled, but in case you don't
python3 -m pip install pipx
pipx run cibuildwheel==2.13.1 --output-dir wheelhouse
pipx run cibuildwheel==2.23.2 --output-dir wheelhouse
pipx run twine upload wheelhouse/*.whl
```
@@ -319,7 +336,7 @@ pipx run twine upload wheelhouse/*.whl
macOS has built-in [System Integrity protections](https://developer.apple.com/library/archive/documentation/Security/Conceptual/System_Integrity_Protection_Guide/RuntimeProtections/RuntimeProtections.html) which limits the use of `DYLD_LIBRARY_PATH` and `LD_LIBRARY_PATH` so that it does not automatically pass to children processes. This means if you set `DYLD_LIBRARY_PATH` before running cibuildwheel, or even set it in `CIBW_ENVIRONMENT`, it will be stripped out of the environment before delocate is called.
To work around this, use a different environment variable such as `REPAIR_LIBRARY_PATH` to store the library path, and set `DYLD_LIBRARY_PATH` in [`CIBW_REPAIR_WHEEL_COMMAND_MACOS`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command), like this:
To work around this, use a different environment variable such as `REPAIR_LIBRARY_PATH` to store the library path, and set `DYLD_LIBRARY_PATH` in [`CIBW_REPAIR_WHEEL_COMMAND_MACOS`](https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command), like this:
!!! tab examples "Environment variables"
@@ -346,19 +363,35 @@ If you're building on an arm64 runner, you might notice something strange about
This is fine for simple C extensions, but for more complicated builds on arm64 it becomes an issue.
So, if the cross-compilation is an issue for you, there is an 'experimental' installer available that's built natively for arm64.
To use this installer and perform native CPython 3.8 building, before invoking cibuildwheel, install the universal2 version of Python on your arm64 runner, something like:
So, if you want to build macOS arm64 wheels on an arm64 runner (e.g., `macos-14`) on Python 3.8, before invoking cibuildwheel, you should install a native arm64 Python 3.8 interpreter on the runner:
```bash
curl -o /tmp/Python38.pkg https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg
sudo installer -pkg /tmp/Python38.pkg -target /
sh "/Applications/Python 3.8/Install Certificates.command"
```
!!! tab "GitHub Actions"
```yaml
- uses: actions/setup-python@v5
with:
python-version: 3.8
if: runner.os == 'macOS' && runner.arch == 'ARM64'
```
!!! tab "Generic"
```bash
curl -o /tmp/Python38.pkg https://www.python.org/ftp/python/3.8.10/python-3.8.10-macos11.pkg
sudo installer -pkg /tmp/Python38.pkg -target /
sh "/Applications/Python 3.8/Install Certificates.command"
```
Then cibuildwheel will detect that it's installed and use it instead. However, you probably don't want to build x86_64 wheels on this Python, unless you're happy with them only supporting macOS 11+.
### macOS: Library dependencies do not satisfy target MacOS
Since delocate 0.11.0 there is added verification that the library binary dependencies match the target macOS version. This is to prevent the situation where a wheel platform tag is lower than the actual minimum macOS version required by the library. To resolve this error you need to build the library to the same macOS version as the target wheel (for example using `MACOSX_DEPLOYMENT_TARGET` environment variable).
Alternatively, you could set `MACOSX_DEPLOYMENT_TARGET` in `CIBW_ENVIRONMENT` to correctly label the wheel as incompatible with older macOS versions.
This error may happen when you install a library using a package manager like Homebrew, which compiles the library for the macOS version of the build machine. This is not suitable for wheels, as the library will only work on the same macOS version as the build machine. You should compile the library yourself, or use a precompiled binary that matches the target macOS version.
### Windows: 'ImportError: DLL load failed: The specific module could not be found'
Visual Studio and MSVC link the compiled binary wheels to the Microsoft Visual C++ Runtime. Normally, the C parts of the runtime are included with Python, but the C++ components are not. When compiling modules using C++, it is possible users will run into problems on systems that do not have the full set of runtime libraries installed. The solution is to ask users to download the corresponding Visual C++ Redistributable from the [Microsoft website](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) and install it.
@@ -381,7 +414,7 @@ To investigate the dependencies of a C extension (i.e., the `.pyd` file, a DLL i
### Windows ARM64 builds {: #windows-arm64}
`cibuildwheel` supports cross-compiling `ARM64` wheels on all Windows runners, but a native ARM64 runner is required for testing. On non-native runners, tests for ARM64 wheels will be automatically skipped with a warning. Add `*-win_arm64` to your `CIBW_TEST_SKIP` setting to suppress the warning.
`cibuildwheel` supports cross-compiling `ARM64` wheels on all Windows runners, but a native ARM64 runner is required for testing. On non-native runners, tests for ARM64 wheels will be automatically skipped with a warning. Add `"*-win_arm64"` to your `CIBW_TEST_SKIP` setting to suppress the warning.
Cross-compilation on Windows relies on a supported build backend. Supported backends use an environment variable to specify their target platform (the one they are compiling native modules for, as opposed to the one they are running on), which is set in [cibuildwheels/windows.py](https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/windows.py) before building. Currently, `setuptools>=65.4.1` and `setuptools_rust` are the only supported backends.
+1 -1
View File
@@ -18,7 +18,7 @@ How it works
This diagram summarises the steps that cibuildwheel takes on each platform to build your package's wheels.
{%
include-markdown "diagram.md"
include "diagram.html"
%}
This isn't exhaustive, for a full list of the things cibuildwheel can do, check the [options](options.md) page.
+7 -4
View File
@@ -1,15 +1,18 @@
from __future__ import annotations
import os
import subprocess
import sysconfig
from typing import Any
# Requires Python 3.7+
def define_env(env: Any) -> None:
"Hook function for mkdocs-macros"
@env.macro
@env.macro # type: ignore[misc]
def subprocess_run(*args: str) -> str:
"Run a subprocess and return the stdout"
return subprocess.run(args, check=True, capture_output=True, text=True).stdout
env = os.environ.copy()
scripts = sysconfig.get_path("scripts")
env["PATH"] = f"{scripts}{os.pathsep}{env.get('PATH', '')}"
return subprocess.run(args, check=True, capture_output=True, text=True, env=env).stdout
+430 -108
View File
@@ -91,9 +91,9 @@ You can configure cibuildwheel with a config file, such as `pyproject.toml`.
Options have the same names as the environment variable overrides, but are
placed in `[tool.cibuildwheel]` and are lower case, with dashes, following
common [TOML][] practice. Anything placed in subsections `linux`, `windows`,
or `macos` will only affect those platforms. Lists can be used instead of
strings for items that are naturally a list. Multiline strings also work just
like in the environment variables. Environment variables will take
`macos`, or `pyodide` will only affect those platforms. Lists can be used
instead of strings for items that are naturally a list. Multiline strings also
work just like in the environment variables. Environment variables will take
precedence if defined.
The example above using environment variables could have been written like this:
@@ -135,6 +135,10 @@ trigger new containers, one per image. Some commands are not supported;
`output-dir`, build/skip/test_skip selectors, and architectures cannot be
overridden.
You can specify a table of overrides in `inherit={}`, any list or table in this
list will inherit from previous overrides or the main configuration. The valid
options are `"none"` (the default), `"append"`, and `"prepend"`.
##### Examples:
```toml
@@ -169,6 +173,69 @@ This example will build CPython 3.6 wheels on manylinux1, CPython 3.7-3.9
wheels on manylinux2010, and manylinux2014 wheels for any newer Python
(like 3.10).
```toml
[tool.cibuildwheel]
environment = {FOO="BAR", "HAM"="EGGS"}
test-command = ["pyproject"]
[[tool.cibuildwheel.overrides]]
select = "cp311*"
inherit.test-command = "prepend"
test-command = ["pyproject-before"]
inherit.environment="append"
environment = {FOO="BAZ", "PYTHON"="MONTY"}
[[tool.cibuildwheel.overrides]]
select = "cp311*"
inherit.test-command = "append"
test-command = ["pyproject-after"]
```
This example will provide the command `"pyproject-before && pyproject && pyproject-after"`
on Python 3.11, and will have `environment = {FOO="BAZ", "PYTHON"="MONTY", "HAM"="EGGS"}`.
### Extending existing options {: #inherit }
In the TOML configuration, you can choose how tables and lists are inherited.
By default, all values are overridden completely (`"none"`) but sometimes you'd
rather `"append"` or `"prepend"` to an existing list or table. You can do this
with the `inherit` table in overrides. For example, if you want to add an environment
variable for CPython 3.11, without `inherit` you'd have to repeat all the
original environment variables in the override. With `inherit`, it's just:
```toml
[[tool.cibuildwheel.overrides]]
select = "cp311*"
inherit.environment = "append"
environment.NEWVAR = "Added!"
```
For a table, `"append"` will replace a key if it exists, while `"prepend"` will
only add a new key, older keys take precedence.
Lists are also supported (and keep in mind that commands are lists). For
example, you can print a message before and after a wheel is repaired:
```toml
[[tool.cibuildwheel.overrides]]
select = "*"
inherit.repair-wheel-command = "prepend"
repair-wheel-command = "echo 'Before repair'"
[[tool.cibuildwheel.overrides]]
select = "*"
inherit.repair-wheel-command = "append"
repair-wheel-command = "echo 'After repair'"
```
As seen in this example, you can have multiple overrides match - they match top
to bottom, with the config being accumulated. If you need platform-specific
inheritance, you can use `select = "*-????linux_*"` for Linux, `select =
"*-win_*"` for Windows, and `select = "*-macosx_*"` for macOS. As always,
environment variables will completely override any TOML configuration.
## Options summary
@@ -180,19 +247,20 @@ wheels on manylinux2010, and manylinux2014 wheels for any newer Python
> Override the auto-detected target platform
Options: `auto` `linux` `macos` `windows`
Options: `auto` `linux` `macos` `windows` `pyodide`
Default: `auto`
`auto` will auto-detect platform using environment variables, such as `TRAVIS_OS_NAME`/`APPVEYOR`/`CIRCLECI`.
`auto` will build wheels for the current platform.
- For `linux`, you need [Docker or Podman](#container-engine) running, on Linux, macOS, or Windows.
- For `macos` and `windows`, you need to be running on the respective system, with a working compiler toolchain installed - Xcode Command Line tools for macOS, and MSVC for Windows.
- For `pyodide` you need to be on an x86-64 linux runner and `python3.12` must be available in `PATH`.
This option can also be set using the [command-line option](#command-line) `--platform`. This option is not available in the `pyproject.toml` config.
!!! tip
You can use this option to locally debug your cibuildwheel config, instead of pushing to CI to test every change. For example:
You can use this option to locally debug your cibuildwheel config on Linux, instead of pushing to CI to test every change. For example:
```bash
export CIBW_BUILD='cp37-*'
@@ -200,6 +268,8 @@ This option can also be set using the [command-line option](#command-line) `--pl
cibuildwheel --platform linux .
```
Linux builds are the easiest to test locally, because all the build tools are supplied in the container, and they run exactly the same locally as in CI.
This is even more convenient if you store your cibuildwheel config in [`pyproject.toml`](#configuration-file).
You can also run a single identifier with `--only <identifier>`. This will
@@ -218,27 +288,43 @@ 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 |
| 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 |
| | 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-manylinux_armv7l<br/>cp36-musllinux_aarch64<br/>cp36-musllinux_ppc64le<br/>cp36-musllinux_s390x<br/>cp36-musllinux_armv7l |
| 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-manylinux_armv7l<br/>cp37-musllinux_aarch64<br/>cp37-musllinux_ppc64le<br/>cp37-musllinux_s390x<br/>cp37-musllinux_armv7l |
| 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-manylinux_armv7l<br/>cp38-musllinux_aarch64<br/>cp38-musllinux_ppc64le<br/>cp38-musllinux_s390x<br/>cp38-musllinux_armv7l |
| 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-manylinux_armv7l<br/>cp39-musllinux_aarch64<br/>cp39-musllinux_ppc64le<br/>cp39-musllinux_s390x<br/>cp39-musllinux_armv7l |
| 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-manylinux_armv7l<br/>cp310-musllinux_aarch64<br/>cp310-musllinux_ppc64le<br/>cp310-musllinux_s390x<br/>cp310-musllinux_armv7l |
| 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-manylinux_armv7l<br/>cp311-musllinux_aarch64<br/>cp311-musllinux_ppc64le<br/>cp311-musllinux_s390x<br/>cp311-musllinux_armv7l |
| 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_armv7l<br/>cp312-musllinux_ppc64le<br/>cp312-musllinux_s390x<br/>cp312-musllinux_armv7l |
| Python 3.13 | cp313-macosx_x86_64<br/>cp313-macosx_universal2<br/>cp313-macosx_arm64 | cp313-win_amd64<br/>cp313-win32<br/>cp313-win_arm64 | cp313-manylinux_x86_64<br/>cp313-manylinux_i686<br/>cp313-musllinux_x86_64<br/>cp313-musllinux_i686 | cp313-manylinux_aarch64<br/>cp313-manylinux_ppc64le<br/>cp313-manylinux_s390x<br/>cp313-manylinux_armv7l<br/>cp313-musllinux_aarch64<br/>cp313-musllinux_ppc64le<br/>cp313-musllinux_s390x<br/>cp313-musllinux_armv7l |
| 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 |
| PyPy3.11 v7.3 | pp311-macosx_x86_64<br/>pp311-macosx_arm64 | pp311-win_amd64 | pp311-manylinux_x86_64<br/>pp311-manylinux_i686 | pp311-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).
For CPython, the minimally supported macOS version is 10.9; for PyPy 3.7, macOS 10.13 or higher is required.
The lowest value you can set `MACOSX_DEPLOYMENT_TARGET` is as follows:
| Arch | Python version range | Minimum target |
|-------|----------------------|----------------|
| Intel | CPython 3.6-3.11 | 10.9 |
| Intel | CPython 3.12+ | 10.13 |
| AS | CPython or PyPy | 11 |
| Intel | PyPy 3.7-3.8 | 10.13 |
| Intel | PyPy 3.9+ | 10.15 |
If you set the value lower, cibuildwheel will cap it to the lowest supported value for each target as needed.
Windows arm64 platform support is experimental.
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) for past end-of-life versions of Python, and PyPy2.7.
For an experimental WebAssembly build with `--platform pyodide`,
`cp312-pyodide_wasm32` is the only platform identifier.
See the [cibuildwheel 1 documentation](https://cibuildwheel.pypa.io/en/1.x/) for past end-of-life versions of Python, and PyPy2.7.
#### Examples
@@ -337,13 +423,14 @@ See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.
}
</style>
### `CIBW_ARCHS` {: #archs}
> Change the architectures built on your machine by default.
A list of architectures to build.
On macOS, this option can be used to cross-compile between `x86_64`,
`universal2` and `arm64` for Apple Silicon support.
On macOS, this option can be used to [cross-compile](faq.md#cross-compiling)
between `x86_64`, `universal2` and `arm64`.
On Linux, this option can be used to build non-native architectures under
emulation. See [this guide](faq.md#emulation) for more information.
@@ -353,9 +440,10 @@ machine, provided the cross-compiling tools are installed.
Options:
- Linux: `x86_64` `i686` `aarch64` `ppc64le` `s390x`
- Linux: `x86_64` `i686` `aarch64` `ppc64le` `s390x` `armv7l`
- macOS: `x86_64` `arm64` `universal2`
- Windows: `AMD64` `x86` `ARM64`
- Pyodide: `wasm32`
- `auto`: The default archs for your machine - see the table below.
- `auto64`: Just the 64-bit auto archs
- `auto32`: Just the 32-bit auto archs
@@ -470,24 +558,53 @@ the package is compatible with all versions of Python that it can build.
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.6"
```
### `CIBW_PRERELEASE_PYTHONS` {: #prerelease-pythons}
> Enable building with pre-release versions of Python if available
### `CIBW_ENABLE` {: #enable}
> Enable building with extra categories of selectors present.
This option lets you opt-in to non-default builds, like pre-releases and
free-threaded Python. These are not included by default to give a nice default
for new users, but can be added to the selectors available here. The allowed
values are:
- `cypython-prerelease`: Enables beta versions of Pythons if any are available
(May-July, approximately). For backward compatibility, `CIBW_PRERELEASE_PYTHONS`
is also supported until cibuildwheel 3.
- `cpython-freethreading`: [PEP 703](https://www.python.org/dev/peps/pep-0703)
introduced variants of CPython that can be built without the Global
Interpreter Lock (GIL). Those variants are also known as free-threaded /
no-gil. This will enable building these wheels while they are experimental.
The build identifiers for those variants have a `t` suffix in their
`python_tag` (e.g. `cp313t-manylinux_x86_64`). For backward compatibility,
`CIBW_FREE_THREADED_SUPPORT` is also supported until cibuildwheel 3.
- `pypy`: Enable PyPy. For backward compatibility, this is always enabled until
cibuildwheel 3 is released.
During the beta period, when new versions of Python are being tested,
cibuildwheel will often gain early support for beta releases. If you would
like to test wheel building with these versions, you can enable this flag.
!!! caution
This option is provided for testing purposes only. It is not
recommended to distribute wheels built when `CIBW_PRERELEASE_PYTHONS` is
set, such as uploading to PyPI. Please _do not_ upload these wheels to
PyPI, as they are not guaranteed to work with the final Python release.
Once Python is ABI stable and enters the release candidate phase, that
version of Python will become available without this flag.
`cpython-prerelease` is provided for testing purposes only. It is not
recommended to distribute wheels built with beta releases, such as
uploading to PyPI. Please _do not_ upload these wheels to PyPI, as they are
not guaranteed to work with the final Python release. Once Python is ABI
stable and enters the release candidate phase, that version of Python will
become available without this flag.
Default: Off (0) if Python is available in beta phase. No effect otherwise.
!!! note
Free threading is experimental: [Whats New In Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython)
Default: empty (`pypy` is always injected).
This option doesn't support overrides or platform specific variants; it is
intended as a way to acknowledge that a project is aware that these extra
selectors exist. If you need to enable/disable it per platform or python
version, set this option to `true` and use
[`CIBW_BUILD`](#build-skip)/[`CIBW_SKIP`](#build-skip) options to filter the
builds.
Unlike all other cibuildwheel options, the environment variable setting will
only add to the TOML config; you can't remove an enable by setting an empty or
partial list in environment variables; use `CIBW_SKIP` instead.
This option can also be set using the [command-line option](#command-line) `--prerelease-pythons`. This option is not available in the `pyproject.toml` config.
#### Examples
@@ -495,25 +612,105 @@ This option can also be set using the [command-line option](#command-line) `--pr
```yaml
# Include latest Python beta
CIBW_PRERELEASE_PYTHONS: True
CIBW_ENABLE: cpython-prerelease
# Include free-threaded support
CIBW_ENABLE: cpython-freethreading
# Include both
CIBW_ENABLE: cpython-prerelease cpython-freethreading
# Skip building free-threaded compatible wheels on Windows
CIBW_ENABLE: cpython-freethreading
CIBW_SKIP: *t-win*
```
It is generally recommended to use `cpython-freethreading` in a config
file as you can statically declare that you support free-threaded builds.
!!! tab examples "pyproject.toml"
```toml
[tool.cibuildwheel]
# Enable free-threaded support
enable = ["cpython-freethreading"]
# Skip building free-threaded compatible wheels on Windows
enable = ["cpython-freethreading"]
skip = "*t-win*"
```
It is generally not recommended to use `cpython-prerelease` in a config file,
as it's intended for testing pre-releases for a 2-3 month period only.
### `CIBW_ALLOW_EMPTY` {: #allow-empty}
> Suppress the error code if no wheels match the specified build identifiers
When none of the specified build identifiers match any available versions,
cibuildwheel will typically return error code 3, indicating that there are
no wheels to build. Enabling this option will suppress this error, allowing
the build process to complete without signaling an error.
Default: Off (0). Error code 3 is returned when no builds are selected.
This option can also be set using the [command-line option](#command-line)
`--allow-empty`. This option is not available in the `pyproject.toml` config.
#### Examples
!!! tab examples "Environment variables"
```yaml
# Prevent an error code if the build does not match any wheels
CIBW_ALLOW_EMPTY: True
```
## Build customization
### `CIBW_BUILD_FRONTEND` {: #build-frontend}
> Set the tool to use to build, either "pip" (default for now) or "build"
> Set the tool to use to build, either "pip" (default for now), "build", or "build\[uv\]"
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 also use "build\[uv\]", which will use an external [uv][] everywhere
possible, both through `--installer=uv` passed to build, as well as when making
all build and test environments. This will generally speed up cibuildwheel.
Make sure you have an external uv on Windows and macOS, either by
pre-installing it, or installing cibuildwheel with the uv extra,
`cibuildwheel[uv]`. `uv` will not be used for Python 3.6 or Python 3.7. You
cannot use uv currently on Windows for ARM or for musllinux on s390x as
binaries are not provided by uv. Legacy dependencies like setuptools on Python
< 3.12 and pip are not installed if using uv.
Pyodide ignores this setting, as only "build" is supported.
You can specify extra arguments to pass to `pip wheel` or `build` using the
optional `args` option.
!!! tip
Until v2.0.0, [pip] was the only way to build wheels, and is still the
Until v2.0.0, [pip][] was the only way to build wheels, and is still the
default. However, we expect that at some point in the future, cibuildwheel
will change the default to [build], in line with the PyPA's recommendation.
will change the default to [build][], in line with the PyPA's recommendation.
If you want to try `build` before this, you can use this option.
!!! warning
If you are using `build[uv]` and are passing `--no-isolation` or `-n`, we
will detect this and avoid passing `--installer=uv` to build, but still
install all packages with uv. We do not currently detect combined short
options, like `-xn`!
[pip]: https://pip.pypa.io/en/stable/cli/pip_wheel/
[build]: https://github.com/pypa/build/
[uv]: https://github.com/astral-sh/uv
#### Examples
@@ -525,6 +722,15 @@ 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"
# Use uv and build
CIBW_BUILD_FRONTEND: "build[uv]"
# Use uv and build with an argument
CIBW_BUILD_FRONTEND: "build[uv]; args: --no-isolation"
```
!!! tab examples "pyproject.toml"
@@ -536,6 +742,15 @@ 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"] }
# Use uv and build
build-frontend = "build[uv]"
# Use uv and build with an argument
build-frontend = { name = "build[uv]", args = ["--no-isolation"] }
```
### `CIBW_CONFIG_SETTINGS` {: #config-settings}
@@ -550,7 +765,7 @@ a table of items, including arrays.
single values.
Platform-specific environment variables also available:<br/>
`CIBW_CONFIG_SETTINGS_MACOS` | `CIBW_CONFIG_SETTINGS_WINDOWS` | `CIBW_CONFIG_SETTINGS_LINUX`
`CIBW_CONFIG_SETTINGS_MACOS` | `CIBW_CONFIG_SETTINGS_WINDOWS` | `CIBW_CONFIG_SETTINGS_LINUX` | `CIBW_CONFIG_SETTINGS_PYODIDE`
#### Examples
@@ -570,18 +785,18 @@ Platform-specific environment variables also available:<br/>
### `CIBW_ENVIRONMENT` {: #environment}
> Set environment variables needed during the build
> Set environment variables
A list of environment variables to set during the build. Bash syntax should be used, even on Windows.
A list of environment variables to set during the build and test phases. Bash syntax should be used, even on Windows.
You must set this variable to pass variables to Linux builds (since they execute in a container). It also works for the other platforms.
You must use this variable to pass variables to Linux builds, since they execute in a container. It also works for the other platforms.
You can use `$PATH` syntax to insert other variables, or the `$(pwd)` syntax to insert the output of other shell commands.
To specify more than one environment variable, separate the assignments by spaces.
Platform-specific environment variables are also available:<br/>
`CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX`
`CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX` | `CIBW_ENVIRONMENT_PYODIDE`
#### Examples
@@ -654,15 +869,21 @@ Platform-specific environment variables are also available:<br/>
In configuration mode, you can use a [TOML][] table instead of a raw string as shown above.
!!! note
cibuildwheel always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#building-packages-with-optional-c-extensions).
cibuildwheel always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#optional-extensions).
!!! note
To do its work, cibuildwheel sets the variables `VIRTUALENV_PIP`, `DIST_EXTRA_CONFIG`, `SETUPTOOLS_EXT_SUFFIX`, `PIP_DISABLE_PIP_VERSION_CHECK`, `PIP_ROOT_USER_ACTION`, and it extends the variables `PATH` and `PIP_CONSTRAINT`. Your assignments to these options might be replaced or extended.
### `CIBW_ENVIRONMENT_PASS_LINUX` {: #environment-pass}
> Set environment variables on the host to pass-through to the container during the build.
> Set environment variables on the host to pass-through to the container.
A list of environment variables to pass into the linux container during the build. It has no effect on the other platforms, which can already access all environment variables directly.
A list of environment variables to pass into the linux container during each build and test. It has no effect on the other platforms, which can already access all environment variables directly.
To specify more than one environment variable, separate the variable names by spaces.
!!! 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"
@@ -707,7 +928,7 @@ On linux, overriding it triggers a new container launch. It cannot be overridden
on macOS and Windows.
Platform-specific environment variables also available:<br/>
`CIBW_BEFORE_ALL_MACOS` | `CIBW_BEFORE_ALL_WINDOWS` | `CIBW_BEFORE_ALL_LINUX`
`CIBW_BEFORE_ALL_MACOS` | `CIBW_BEFORE_ALL_WINDOWS` | `CIBW_BEFORE_ALL_LINUX` | `CIBW_BEFORE_ALL_PYODIDE`
!!! note
@@ -755,9 +976,9 @@ Platform-specific environment variables also available:<br/>
In configuration files, you can use a TOML array, and each line will be run sequentially - joined with `&&`.
Note that manylinux_2_24 builds occur inside a Debian9 docker, where
Note that manylinux_2_24/manylinux_2_31 builds occur inside a debian derivative docker container, where
manylinux2010 and manylinux2014 builds occur inside a CentOS one. So for
`manylinux_2_24` the `CIBW_BEFORE_ALL_LINUX` command must use `apt-get -y`
`manylinux_2_24`/`manylinux_2_31` the `CIBW_BEFORE_ALL_LINUX` command must use `apt-get -y`
instead.
### `CIBW_BEFORE_BUILD` {: #before-build}
@@ -772,7 +993,7 @@ The active Python binary can be accessed using `python`, and pip with `pip`; cib
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific environment variables are also available:<br/>
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX` | `CIBW_BEFORE_BUILD_PYODIDE`
#### Examples
@@ -826,7 +1047,6 @@ Platform-specific environment variables are also available:<br/>
[build-system]
requires = [
"setuptools>=42",
"wheel",
"Cython",
"numpy==1.13.3; python_version<'3.5'",
"oldest-supported-numpy; python_version>='3.5'",
@@ -854,6 +1074,7 @@ Default:
- on Linux: `'auditwheel repair -w {dest_dir} {wheel}'`
- on macOS: `'delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}'`
- on Windows: `''`
- on Pyodide: `''`
A shell command to repair a built wheel by copying external library dependencies into the wheel tree and relinking them.
The command is run on each built wheel (except for pure Python ones) before testing it.
@@ -867,7 +1088,7 @@ The following placeholders must be used inside the command and will be replaced
The command is run in a shell, so you can run multiple commands like `cmd1 && cmd2`.
Platform-specific environment variables are also available:<br/>
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX`
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX` | `CIBW_REPAIR_WHEEL_COMMAND_PYODIDE`
!!! tip
cibuildwheel doesn't yet ship a default repair command for Windows.
@@ -878,6 +1099,12 @@ Platform-specific environment variables are also available:<br/>
[Delvewheel]: https://github.com/adang1345/delvewheel
!!! tip
When using `--platform pyodide`, `pyodide build` is used to do the build,
which already uses `auditwheel-emscripten` to repair the wheel, so the default
repair command is empty. If there is a way to do this in two steps in the future,
this could change.
#### Examples
!!! tab examples "Environment variables"
@@ -897,9 +1124,7 @@ Platform-specific environment variables are also available:<br/>
CIBW_REPAIR_WHEEL_COMMAND: >
python scripts/repair_wheel.py -w {dest_dir} {wheel} &&
python scripts/check_repaired_wheel.py -w {dest_dir} {wheel}
```
```yaml
# Use abi3audit to catch issues with Limited API wheels
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >
auditwheel repair -w {dest_dir} {wheel} &&
@@ -908,6 +1133,7 @@ Platform-specific environment variables are also available:<br/>
delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} &&
pipx run abi3audit --strict --report {wheel}
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >
copy {wheel} {dest_dir} &&
pipx run abi3audit --strict --report {wheel}
```
@@ -933,9 +1159,7 @@ Platform-specific environment variables are also available:<br/>
'python scripts/repair_wheel.py -w {dest_dir} {wheel}',
'python scripts/check_repaired_wheel.py -w {dest_dir} {wheel}',
]
```
```toml
# Use abi3audit to catch issues with Limited API wheels
[tool.cibuildwheel.linux]
repair-wheel-command = [
@@ -948,7 +1172,10 @@ Platform-specific environment variables are also available:<br/>
"pipx run abi3audit --strict --report {wheel}",
]
[tool.cibuildwheel.windows]
repair-wheel-command = "pipx run abi3audit --strict --report {wheel}"
repair-wheel-command = [
"copy {wheel} {dest_dir}",
"pipx run abi3audit --strict --report {wheel}",
]
```
In configuration mode, you can use an inline array, and the items will be joined with `&&`.
@@ -957,34 +1184,42 @@ Platform-specific environment variables are also available:<br/>
<div class="link-target" id="manylinux-image"></div>
### `CIBW_MANYLINUX_*_IMAGE`, `CIBW_MUSLLINUX_*_IMAGE` {: #linux-image}
> Specify alternative manylinux / musllinux container images
The available options are (default value):
> Specify manylinux / musllinux container images
- `CIBW_MANYLINUX_X86_64_IMAGE` ([`quay.io/pypa/manylinux2014_x86_64`](https://quay.io/pypa/manylinux2014_x86_64))
- `CIBW_MANYLINUX_I686_IMAGE` ([`quay.io/pypa/manylinux2014_i686`](https://quay.io/pypa/manylinux2014_i686))
- `CIBW_MANYLINUX_PYPY_X86_64_IMAGE` ([`quay.io/pypa/manylinux2014_x86_64`](https://quay.io/pypa/manylinux2014_x86_64))
- `CIBW_MANYLINUX_AARCH64_IMAGE` ([`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64))
- `CIBW_MANYLINUX_PPC64LE_IMAGE` ([`quay.io/pypa/manylinux2014_ppc64le`](https://quay.io/pypa/manylinux2014_ppc64le))
- `CIBW_MANYLINUX_S390X_IMAGE` ([`quay.io/pypa/manylinux2014_s390x`](https://quay.io/pypa/manylinux2014_s390x))
- `CIBW_MANYLINUX_PYPY_AARCH64_IMAGE` ([`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64))
- `CIBW_MANYLINUX_PYPY_I686_IMAGE` ([`quay.io/pypa/manylinux2014_i686`](https://quay.io/pypa/manylinux2014_i686))
- `CIBW_MUSLLINUX_X86_64_IMAGE` ([`quay.io/pypa/musllinux_1_1_x86_64`](https://quay.io/pypa/musllinux_1_1_x86_64))
- `CIBW_MUSLLINUX_I686_IMAGE` ([`quay.io/pypa/musllinux_1_1_i686`](https://quay.io/pypa/musllinux_1_1_i686))
- `CIBW_MUSLLINUX_AARCH64_IMAGE` ([`quay.io/pypa/musllinux_1_1_aarch64`](https://quay.io/pypa/musllinux_1_1_aarch64))
- `CIBW_MUSLLINUX_PPC64LE_IMAGE` ([`quay.io/pypa/musllinux_1_1_ppc64le`](https://quay.io/pypa/musllinux_1_1_ppc64le))
- `CIBW_MUSLLINUX_S390X_IMAGE` ([`quay.io/pypa/musllinux_1_1_s390x`](https://quay.io/pypa/musllinux_1_1_s390x))
The available options are:
Set an alternative Docker image to be used for building [manylinux / musllinux](https://github.com/pypa/manylinux) wheels.
| Option | Default | Future default* |
|-----------------------------------|----------------------------------------------------------------|-----------------------------------------------------------------|
| CIBW_MANYLINUX_X86_64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_x86_64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_x86_64) |
| CIBW_MANYLINUX_I686_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_i686) | |
| CIBW_MANYLINUX_PYPY_X86_64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_x86_64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_x86_64) |
| CIBW_MANYLINUX_AARCH64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_aarch64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_aarch64) |
| CIBW_MANYLINUX_PPC64LE_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_ppc64le) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_ppc64le) |
| CIBW_MANYLINUX_S390X_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_s390x) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_s390x) |
| CIBW_MANYLINUX_ARMV7L_IMAGE | [`manylinux_2_31`](https://quay.io/pypa/manylinux_2_31_armv7l) | |
| CIBW_MANYLINUX_PYPY_AARCH64_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_aarch64) | [`manylinux_2_28`](https://quay.io/pypa/manylinux_2_28_aarch64) |
| CIBW_MANYLINUX_PYPY_I686_IMAGE | [`manylinux2014`](https://quay.io/pypa/manylinux2014_i686) | |
| CIBW_MUSLLINUX_X86_64_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_x86_64) | |
| CIBW_MUSLLINUX_I686_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_i686) | |
| CIBW_MUSLLINUX_AARCH64_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_aarch64) | |
| CIBW_MUSLLINUX_PPC64LE_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_ppc64le) | |
| CIBW_MUSLLINUX_S390X_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_s390x) | |
| CIBW_MUSLLINUX_ARMV7L_IMAGE | [`musllinux_1_2`](https://quay.io/pypa/musllinux_1_2_armv7l) | |
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
<small>* The default is scheduled to change in a cibuildwheel release on or after 6th May 2025 - if you don't want the new default, you should set the value to `manylinux2014`.</small>
Set the Docker image to be used for building [manylinux / musllinux](https://github.com/pypa/manylinux) wheels.
For `CIBW_MANYLINUX_*_IMAGE`, except `CIBW_MANYLINUX_ARMV7L_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_MANYLINUX_ARMV7L_IMAGE`, the value of this option can either be set to `manylinux_2_31` or a custom image. Support is experimental for now. The `manylinux_2_31` value is only available for `armv7`.
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).
If setting a custom image, you'll need to make sure it can be used in the same way as the default images: all necessary Python and pip versions need to be present in `/opt/python/`, and the auditwheel tool needs to be present for cibuildwheel to work. Apart from that, the architecture and relevant shared system libraries need to be compatible to the relevant standard to produce valid manylinux1/manylinux2010/manylinux2014/manylinux_2_24/manylinux_2_28/musllinux_1_1 wheels (see [pypa/manylinux on GitHub](https://github.com/pypa/manylinux), [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/), [PEP 599](https://www.python.org/dev/peps/pep-0599/), [PEP 600](https://www.python.org/dev/peps/pep-0600/) and [PEP 656](https://www.python.org/dev/peps/pep-0656/) for more details).
If setting a custom image, you'll need to make sure it can be used in the same way as the default images: all necessary Python and pip versions need to be present in `/opt/python/`, and the auditwheel tool needs to be present for cibuildwheel to work. Apart from that, the architecture and relevant shared system libraries need to be compatible to the relevant standard to produce valid manylinux1/manylinux2010/manylinux2014/manylinux_2_24/manylinux_2_28/musllinux_1_1/musllinux_1_2 wheels (see [pypa/manylinux on GitHub](https://github.com/pypa/manylinux), [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/), [PEP 599](https://www.python.org/dev/peps/pep-0599/), [PEP 600](https://www.python.org/dev/peps/pep-0600/) and [PEP 656](https://www.python.org/dev/peps/pep-0656/) for more details).
Auditwheel detects the version of the manylinux / musllinux standard in the image through the `AUDITWHEEL_PLAT` environment variable, as cibuildwheel has no way of detecting the correct `--plat` command line argument to pass to auditwheel for a custom image. If a custom image does not correctly set this `AUDITWHEEL_PLAT` environment variable, the `CIBW_ENVIRONMENT` option can be used to do so (e.g., `CIBW_ENVIRONMENT='AUDITWHEEL_PLAT="manylinux2010_$(uname -m)"'`).
@@ -1015,6 +1250,10 @@ Auditwheel detects the version of the manylinux / musllinux standard in the imag
# Build using a different image from the docker registry
CIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64
CIBW_MANYLINUX_I686_IMAGE: dockcross/manylinux-x86
# Build musllinux wheels using the musllinux_1_1 image
CIBW_MUSLLINUX_X86_64_IMAGE: musllinux_1_1
CIBW_MUSLLINUX_I686_IMAGE: musllinux_1_1
```
!!! tab examples "pyproject.toml"
@@ -1042,6 +1281,10 @@ Auditwheel detects the version of the manylinux / musllinux standard in the imag
# Build using a different image from the docker registry
manylinux-x86_64-image = "dockcross/manylinux-x64"
manylinux-i686-image = "dockcross/manylinux-x86"
# Build musllinux wheels using the musllinux_1_1 image
musllinux-x86_64-image = "musllinux_1_1"
musllinux-i686-image = "musllinux_1_1"
```
Like any other option, these can be placed in `[tool.cibuildwheel.linux]`
@@ -1053,8 +1296,8 @@ Auditwheel detects the version of the manylinux / musllinux standard in the imag
Options:
- `docker[;create_args: ...]`
- `podman[;create_args: ...]`
- `docker[;create_args: ...][;disable_host_mount: true/false]`
- `podman[;create_args: ...][;disable_host_mount: true/false]`
Default: `docker`
@@ -1063,11 +1306,13 @@ Set the container engine to use. Docker is the default, or you can switch to
running and `docker` available on PATH. To use Podman, it needs to be
installed and `podman` available on PATH.
Arguments can be supplied to the container engine. Currently, the only option
that's customisable is 'create_args'. Parameters to create_args are
space-separated strings, which are passed to the container engine on the
command line when it's creating the container. If you want to include spaces
inside a parameter, use shell-style quoting.
Options can be supplied after the name.
| Option name | Description
|---|---
| `create_args` | Space-separated strings, which are passed to the container engine on the command line when it's creating the container. If you want to include spaces inside a parameter, use shell-style quoting.
| `disable_host_mount` | By default, cibuildwheel will mount the root of the host filesystem as a volume at `/host` in the container. To disable the host mount, pass `true` to this option.
!!! tip
@@ -1088,6 +1333,9 @@ inside a parameter, use shell-style quoting.
# pass command line options to 'docker create'
CIBW_CONTAINER_ENGINE: "docker; create_args: --gpus all"
# disable the /host mount
CIBW_CONTAINER_ENGINE: "docker; disable_host_mount: true"
```
!!! tab examples "pyproject.toml"
@@ -1099,6 +1347,9 @@ inside a parameter, use shell-style quoting.
# pass command line options to 'docker create'
container-engine = { name = "docker", create-args = ["--gpus", "all"]}
# disable the /host mount
container-engine = { name = "docker", disable-host-mount = true }
```
@@ -1130,7 +1381,7 @@ here and it will be used instead.
`./constraints.txt` if that's not found.
Platform-specific environment variables are also available:<br/>
`CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS`
`CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS` | `CIBW_DEPENDENCY_VERSIONS_PYODIDE`
!!! note
This option does not affect the tools used on the Linux build - those versions
@@ -1188,16 +1439,13 @@ not be installed after building.
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific environment variables are also available:<br/>
`CIBW_TEST_COMMAND_MACOS` | `CIBW_TEST_COMMAND_WINDOWS` | `CIBW_TEST_COMMAND_LINUX`
`CIBW_TEST_COMMAND_MACOS` | `CIBW_TEST_COMMAND_WINDOWS` | `CIBW_TEST_COMMAND_LINUX` | `CIBW_TEST_COMMAND_PYODIDE`
#### Examples
!!! tab examples "Environment variables"
```yaml
# Run the project tests against the installed wheel using `nose`
CIBW_TEST_COMMAND: nosetests {project}/tests
# Run the package tests using `pytest`
CIBW_TEST_COMMAND: pytest {package}/tests
@@ -1214,9 +1462,6 @@ Platform-specific environment variables are also available:<br/>
```toml
[tool.cibuildwheel]
# Run the project tests against the installed wheel using `nose`
test-command = "nosetests {project}/tests"
# Run the package tests using `pytest`
test-command = "pytest {package}/tests"
@@ -1251,7 +1496,7 @@ The active Python binary can be accessed using `python`, and pip with `pip`; cib
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
Platform-specific environment variables are also available:<br/>
`CIBW_BEFORE_TEST_MACOS` | `CIBW_BEFORE_TEST_WINDOWS` | `CIBW_BEFORE_TEST_LINUX`
`CIBW_BEFORE_TEST_MACOS` | `CIBW_BEFORE_TEST_WINDOWS` | `CIBW_BEFORE_TEST_LINUX` | `CIBW_BEFORE_TEST_PYODIDE`
#### Examples
@@ -1311,7 +1556,7 @@ Platform-specific environment variables are also available:<br/>
Space-separated list of dependencies required for running the tests.
Platform-specific environment variables are also available:<br/>
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX`
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX` | `CIBW_TEST_REQUIRES_PYODIDE`
#### Examples
@@ -1322,7 +1567,7 @@ Platform-specific environment variables are also available:<br/>
CIBW_TEST_REQUIRES: pytest
# Install specific versions of test dependencies
CIBW_TEST_REQUIRES: nose==1.3.7 moto==0.4.31
CIBW_TEST_REQUIRES: pytest==8.2.2 packaging==24.1
```
!!! tab examples "pyproject.toml"
@@ -1334,7 +1579,7 @@ Platform-specific environment variables are also available:<br/>
# Install specific versions of test dependencies
[tool.cibuildwheel]
test-requires = ["nose==1.3.7", "moto==0.4.31"]
test-requires = ["pytest==8.2.2", "packaging==24.1"]
```
In configuration files, you can use an array, and the items will be joined with a space.
@@ -1344,14 +1589,14 @@ 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`
`CIBW_TEST_EXTRAS_MACOS` | `CIBW_TEST_EXTRAS_WINDOWS` | `CIBW_TEST_EXTRAS_LINUX` | `CIBW_TEST_EXTRAS_PYODIDE`
#### Examples
@@ -1374,6 +1619,40 @@ Platform-specific environment variables are also available:<br/>
In configuration files, you can use an inline array, and the items will be joined with a comma.
### `CIBW_TEST_GROUPS` {: #test-groups}
> Specify test dependencies from your project's `dependency-groups`
List of
[dependency-groups](https://peps.python.org/pep-0735)
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 `pyproject.toml`.
Platform-specific environment variables are also available:<br/>
`CIBW_TEST_GROUPS_MACOS` | `CIBW_TEST_GROUPS_WINDOWS` | `CIBW_TEST_GROUPS_LINUX` | `CIBW_TEST_GROUPS_PYODIDE`
#### Examples
!!! tab examples "Environment variables"
```yaml
# Will cause the wheel to be installed with these groups of dependencies
CIBW_TEST_GROUPS: "test qt"
```
Separate multiple items with a space.
!!! tab examples "pyproject.toml"
```toml
[tool.cibuildwheel]
# Will cause the wheel to be installed with these groups of dependencies
test-groups = ["test", "qt"]
```
In configuration files, you can use an inline array, and the items will be joined with a space.
### `CIBW_TEST_SKIP` {: #test-skip}
> Skip running tests on some builds
@@ -1389,7 +1668,7 @@ This option is not supported in the overrides section in `pyproject.toml`.
```yaml
# Will avoid testing on emulated architectures
CIBW_TEST_SKIP: "*-*linux_{aarch64,ppc64le,s390x}"
CIBW_TEST_SKIP: "*-*linux_{aarch64,ppc64le,s390x,armv7l}"
# Skip trying to test arm64 builds on Intel Macs
CIBW_TEST_SKIP: "*-macosx_arm64 *-macosx_universal2:arm64"
@@ -1400,13 +1679,43 @@ This option is not supported in the overrides section in `pyproject.toml`.
```toml
[tool.cibuildwheel]
# Will avoid testing on emulated architectures
test-skip = "*-*linux_{aarch64,ppc64le,s390x}"
test-skip = "*-*linux_{aarch64,ppc64le,s390x,armv7l}"
# Skip trying to test arm64 builds on Intel Macs
test-skip = "*-macosx_arm64 *-macosx_universal2:arm64"
```
## Other
## Debugging
### `CIBW_DEBUG_KEEP_CONTAINER`
Enable this flag to keep the container around for inspection after a build. This
option is provided for debugging purposes only.
Default: Off (0).
!!! caution
This option can only be set as environment variable on the host machine
#### Examples
```shell
export CIBW_DEBUG_KEEP_CONTAINER=TRUE
```
### `CIBW_DEBUG_TRACEBACK`
> Print full traceback when errors occur.
Print a full traceback for the cibuildwheel process when errors occur. This
option is provided for debugging cibuildwheel.
This option can also be set using the [command-line option](#command-line) `--debug-traceback`.
#### Examples
```shell
export CIBW_DEBUG_TRACEBACK=TRUE
```
### `CIBW_BUILD_VERBOSITY` {: #build-verbosity}
> Increase/decrease the output of pip wheel
@@ -1414,7 +1723,7 @@ This option is not supported in the overrides section in `pyproject.toml`.
A number from 1 to 3 to increase the level of verbosity (corresponding to invoking pip with `-v`, `-vv`, and `-vvv`), between -1 and -3 (`-q`, `-qq`, and `-qqq`), or just 0 (default verbosity). These flags are useful while debugging a build when the output of the actual build invoked by `pip wheel` is required. Has no effect on the `build` backend, which produces verbose output by default.
Platform-specific environment variables are also available:<br/>
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX`
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX` | `CIBW_BUILD_VERBOSITY_PYODIDE`
#### Examples
@@ -1434,12 +1743,25 @@ Platform-specific environment variables are also available:<br/>
```
## Command line options {: #command-line}
## Command line {: #command-line}
### Options
```text
« subprocess_run("cibuildwheel", "--help") »
```
### Return codes
cibuildwheel exits 0 on success, or >0 if an error occurs.
Specific error codes are defined:
- 2 means a configuration error
- 3 means no builds are selected (and [`--allow-empty`](#allow-empty) wasn't passed)
- 4 means you specified an option that has been deprecated.
## Placeholders
Some options support placeholders, like `{project}`, `{package}` or `{wheel}`, that are substituted by cibuildwheel before they are used. If, for some reason, you need to write the literal name of a placeholder, e.g. literally `{project}` in a command that would ordinarily substitute `{project}`, prefix it with a hash character - `#{project}`. This is only necessary in commands where the specific string between the curly brackets would be substituted - otherwise, strings not modified.
@@ -1555,7 +1877,7 @@ Some options support placeholders, like `{project}`, `{package}` or `{wheel}`, t
}
var optionNames = option.name.trim().split(', ')
var url = 'https://cibuildwheel.readthedocs.io/en/stable/options/#'+option.id;
var url = 'https://cibuildwheel.pypa.io/en/stable/options/#'+option.id;
var namesMarkdown = $.map(optionNames, function(n) {
return '[`'+n+'`]('+url+') '
}).join(' <br> ')
+33 -53
View File
@@ -11,45 +11,14 @@ locally to quickly iterate and track down issues without even touching CI.
Install cibuildwheel and run a build like this:
!!! tab "Linux"
```sh
# using pipx (https://github.com/pypa/pipx)
pipx run cibuildwheel
Using [pipx](https://github.com/pypa/pipx):
```sh
pipx run cibuildwheel --platform linux
```
Or,
```sh
pip install cibuildwheel
cibuildwheel --platform linux
```
!!! tab "macOS"
Using [pipx](https://github.com/pypa/pipx):
```sh
pipx run cibuildwheel --platform macos
```
Or,
```sh
pip install cibuildwheel
cibuildwheel --platform macos
```
!!! tab "Windows"
Using [pipx](https://github.com/pypa/pipx):
```bat
pipx run cibuildwheel --platform windows
```
Or,
```bat
pip install cibuildwheel
cibuildwheel --platform windows
```
# or,
pip install cibuildwheel
cibuildwheel
```
You should see the builds taking place. You can experiment with options using environment variables or pyproject.toml.
@@ -61,17 +30,17 @@ You should see the builds taking place. You can experiment with options using en
```sh
# run a command to set up the build system
export CIBW_BEFORE_ALL='apt install libpng-dev'
export CIBW_BEFORE_ALL='uname -a'
cibuildwheel --platform linux
cibuildwheel
```
> CMD (Windows)
```bat
set CIBW_BEFORE_ALL='apt install libpng-dev'
set CIBW_BEFORE_ALL='uname -a'
cibuildwheel --platform linux
cibuildwheel
```
!!! tab "pyproject.toml"
@@ -82,13 +51,13 @@ You should see the builds taking place. You can experiment with options using en
```
[tool.cibuildwheel]
before-all = "apt install libpng-dev"
before-all = "uname -a"
```
Then invoke cibuildwheel, like:
```console
cibuildwheel --platform linux
cibuildwheel
```
### Linux builds
@@ -138,6 +107,13 @@ You can override the cache folder using the ``CIBW_CACHE_PATH`` environment vari
Download link: https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg
```
### Pyodide (WebAssembly) builds (experimental)
Pre-requisite: you need to have a matching host version of Python (unlike all
other cibuildwheel platforms). Linux host highly recommended; macOS hosts may
work (e.g. invoking `pytest` directly in [`CIBW_TEST_COMMAND`](options.md#test-command) is [currently failing](https://github.com/pyodide/pyodide/issues/4802)) and Windows hosts will not work.
You must target pyodide with `--platform pyodide` (or use `--only` on the identifier).
## Configure a CI service
@@ -178,16 +154,18 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-11]
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build wheels
run: pipx run cibuildwheel==2.13.1
run: pipx run cibuildwheel==2.23.2
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
```
@@ -210,22 +188,24 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-11]
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-latest, windows-latest, macos-13, macos-14]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Used to host cibuildwheel
- uses: actions/setup-python@v3
- uses: actions/setup-python@v5
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.13.1
run: python -m pip install cibuildwheel==2.23.2
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
```
+110 -102
View File
@@ -11,19 +11,19 @@ title: Working examples
| [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. |
| [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][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
| [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. |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
| [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
| [Triton][] | ![github icon][] | ![linux icon][] | Self hosted runners |
| [MemRay][] | ![github icon][] | ![linux icon][] | Memray is a memory profiler for Python |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an in-process SQL OLAP Database Management System |
| [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 |
| [vaex][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Out-of-Core hybrid Apache Arrow/NumPy DataFrame for Python, ML, visualization and exploration of big tabular data at a billion rows per second 🚀 |
| [Google Benchmark][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A microbenchmark support library |
| [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 🚀 |
| [Apache Beam][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Apache Beam is a unified programming model for Batch and Streaming data processing. |
| [PyGame][] | ![github icon][] | ![apple icon][] ![linux icon][] | 🐍🎮 pygame (the library) is a Free and Open Source python programming language library for making multimedia applications like games built on top of the excellent SDL library. C, Python, Native, OpenGL. |
| [asyncpg][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A fast PostgreSQL Database Client Library for Python/asyncio. |
@@ -31,105 +31,109 @@ title: Working examples
| [scikit-image][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Image processing library. Uses cibuildwheel to build and test a project that uses Cython with platform-native code. |
| [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. |
| [PyOxidizer][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A modern Python application packaging and distribution tool |
| [websockets][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Library for building WebSocket servers and clients. Mostly written in Python, with a small C 'speedups' extension module. |
| [cvxpy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A Python-embedded modeling language for convex optimization problems. |
| [pedalboard][] | ![github icon][] | ![windows icon][] ![linux icon][] ![apple icon][] | A Python library for working with audio data and audio plugins by wrapping the [JUCE](https://github.com/juce-framework/JUCE/) C++ framework. Uses cibuildwheel to deploy on as many operating systems and Python versions as possible with only one dependency (any NumPy). |
| [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. |
| [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 |
| [vispy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Main repository for Vispy |
| [OpenSpiel][] | ![github icon][] | ![apple icon][] ![linux icon][] | OpenSpiel is a collection of environments and algorithms for research in general reinforcement learning and search/planning in games. |
| [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI |
| [pyzmq][] | ![github icon][] ![circleci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python bindings for zeromq, the networking library. Uses Cython on CPython and CFFI on PyPy. ARM wheels for linux are built natively on CircleCI. |
| [Implicit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes GPU support for linux wheels |
| [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. |
| [tinyobjloader][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Tiny but powerful single file wavefront obj loader |
| [vispy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Main repository for Vispy |
| [coverage.py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The coverage tool for Python |
| [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 |
| [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. |
| [Line Profiler][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Line-by-line profiling for Python |
| [PyYAML][] | ![github icon][] | ![apple icon][] | Canonical source repository for PyYAML |
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, Pandas, PyTables and more |
| [pikepdf][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by QPDF |
| [h5py][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | HDF5 for Python -- The h5py package is a Pythonic interface to the HDF5 binary data format. |
| [Wrapt][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python module for decorators, wrappers and monkey patching. |
| [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 for AI/ML |
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
| [envd][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A machine learning development environment build tool |
| [OpenColorIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A color management framework for visual effects and animation. |
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
| [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 |
| [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. |
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
| [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data |
| [google neuroglancer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | WebGL-based viewer for volumetric data |
| [Parselmouth][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. |
| [DeepForest][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | An Efficient, Scalable and Optimized Python Framework for Deep Forest (2021.2.1) |
| [google neuroglancer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | WebGL-based viewer for volumetric data |
| [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 |
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS ¶ |
| [markupsafe][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Safely add untrusted strings to HTML/XML markup. |
| [Picologging][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A high-performance logging library for Python. |
| [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system |
| [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 |
| [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 |
| [mosec][] | ![github icon][] | ![linux icon][] ![apple icon][] | A machine learning model serving framework powered by Rust |
| [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. |
| [tgcalls][] | ![github icon][] | ![apple icon][] ![windows icon][] | Python `pybind11` binding to Telegram's WebRTC library with third party dependencies like `OpenSSL`, `MozJPEG`, `FFmpeg`, etc. |
| [Picologging][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A high-performance logging library for Python. |
| [markupsafe][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Safely add untrusted strings to HTML/XML markup. |
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS |
| [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system |
| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python |
| [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub |
| [tgcalls][] | ![github icon][] | ![apple icon][] ![windows icon][] | Python `pybind11` binding to Telegram's WebRTC library with third party dependencies like `OpenSSL`, `MozJPEG`, `FFmpeg`, etc. |
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
| [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Quickly search, compare, and analyze genomic and metagenomic data sets. |
| [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing |
| [matrixprofile][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python 3 library making time series data mining tasks, utilizing matrix profile algorithms, accessible to everyone. |
| [abess][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A fast best-subset selection library. It uses cibuildwheel to build a large project with C++ extensions. |
| [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing |
| [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq |
| [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. |
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 |
| [Tokenizer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast and customizable text tokenization library with BPE and SentencePiece support |
| [keyvi][] | ![github icon][] | ![linux icon][] ![apple icon][] | FST based key value index highly optimized for size and lookup performance, utilizes ccache action for improved runtime |
| [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. |
| [PyGLM][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Fast OpenGL Mathematics (GLM) for Python |
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
| [iDynTree][] | ![github icon][] | ![linux icon][] | Uses manylinux_2_24 |
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. |
| [Python-WebRTC][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | a Python extension that provides bindings to WebRTC M92 |
| [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. |
| [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 |
| [streaming-form-data][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Streaming parser for multipart/form-data written in Cython |
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. |
| [pybase64][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast Base64 encoding/decoding in Python |
| [Python-WebRTC][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | a Python extension that provides bindings to WebRTC M92 |
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
| [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. |
| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
| [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. |
| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. |
| [clang-format][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Scikit-build wrapper around LLVM's CMake, all platforms, generic wheels. |
| [etebase-py][] | ![travisci icon][] | ![linux icon][] | Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. |
| [cf-units][] | ![github icon][] | ![apple icon][] ![linux icon][] | Units of measure as required by the Climate and Forecast (CF) Metadata Conventions |
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
| [clang-format][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Scikit-build wrapper around LLVM's CMake, all platforms, generic wheels. |
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA 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. |
| [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 |
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
| [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. |
| [SiPM][] | ![github icon][] | ![apple icon][] ![linux icon][] | High performance library for SiPM detectors simulation using C++17, OpenMP and AVX2 intrinsics. |
| [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. |
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
| [aalink][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Async Python interface for Ableton Link. |
| [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. |
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
| [werpy][] | ![github icon][] | ![windows icon][] ![linux icon][] ![apple icon][] | An ultra-fast python package using optimized dynamic programming to compute the Word Error Rate (WER). |
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
| [pybind11 cross build example][] | ![github icon][] ![gitlab icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Same as pybind11 cmake_example but used to demo Linux ARM + Windows + macOS builds on GitLab |
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
[pytorch-fairseq]: https://github.com/pytorch/fairseq
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy
[Tornado]: https://github.com/tornadoweb/tornado
[Matplotlib]: https://github.com/matplotlib/matplotlib
[NCNN]: https://github.com/Tencent/ncnn
[Prophet]: https://github.com/facebook/prophet
[Kivy]: https://github.com/kivy/kivy
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
[MemRay]: https://github.com/bloomberg/memray
[duckdb]: https://github.com/duckdb/duckdb
[Tornado]: https://github.com/tornadoweb/tornado
[NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib
[Prophet]: https://github.com/facebook/prophet
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
[Kivy]: https://github.com/kivy/kivy
[Triton]: https://github.com/openai/triton
[MemRay]: https://github.com/bloomberg/memray
[uvloop]: https://github.com/MagicStack/uvloop
[psutil]: https://github.com/giampaolo/psutil
[vaex]: https://github.com/vaexio/vaex
[Google Benchmark]: https://github.com/google/benchmark
[Triton]: https://github.com/openai/triton
[vaex]: https://github.com/vaexio/vaex
[Apache Beam]: https://github.com/apache/beam
[PyGame]: https://github.com/pygame/pygame
[asyncpg]: https://github.com/MagicStack/asyncpg
@@ -137,87 +141,91 @@ title: Working examples
[scikit-image]: https://github.com/scikit-image/scikit-image
[twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport
[PyOxidizer]: https://github.com/indygreg/PyOxidizer
[websockets]: https://github.com/aaugustin/websockets
[cvxpy]: https://github.com/cvxpy/cvxpy
[pedalboard]: https://github.com/spotify/pedalboard
[websockets]: https://github.com/python-websockets/websockets
[River]: https://github.com/online-ml/river
[UltraJSON]: https://github.com/ultrajson/ultrajson
[OpenSpiel]: https://github.com/deepmind/open_spiel
[aiortc]: https://github.com/aiortc/aiortc
[pyzmq]: https://github.com/zeromq/pyzmq
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
[Implicit]: https://github.com/benfred/implicit
[vispy]: https://github.com/vispy/vispy
[OpenSpiel]: https://github.com/google-deepmind/open_spiel
[Dependency Injector]: https://github.com/ets-labs/python-dependency-injector
[pyzmq]: https://github.com/zeromq/pyzmq
[Implicit]: https://github.com/benfred/implicit
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
[tinyobjloader]: https://github.com/tinyobjloader/tinyobjloader
[vispy]: https://github.com/vispy/vispy
[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
[PyAV]: https://github.com/PyAV-Org/PyAV
[h5py]: https://github.com/h5py/h5py
[Line Profiler]: https://github.com/pyutils/line_profiler
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
[PyYAML]: https://github.com/yaml/pyyaml
[PyAV]: https://github.com/PyAV-Org/PyAV
[numexpr]: https://github.com/pydata/numexpr
[pikepdf]: https://github.com/pikepdf/pikepdf
[h5py]: https://github.com/h5py/h5py
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
[envd]: https://github.com/tensorchord/envd
[SimpleJSON]: https://github.com/simplejson/simplejson
[OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO
[aioquic]: https://github.com/aiortc/aioquic
[OpenTimelineIO]: https://github.com/PixarAnimationStudios/OpenTimelineIO
[ruptures]: https://github.com/deepcharles/ruptures
[PyTables]: https://github.com/PyTables/PyTables
[Psycopg 3]: https://github.com/psycopg/psycopg
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
[aioquic]: https://github.com/aiortc/aioquic
[SimpleJSON]: https://github.com/simplejson/simplejson
[ruptures]: https://github.com/deepcharles/ruptures
[OpenTimelineIO]: https://github.com/AcademySoftwareFoundation/OpenTimelineIO
[PyTables]: https://github.com/PyTables/PyTables
[google neuroglancer]: https://github.com/google/neuroglancer
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
[DeepForest]: https://github.com/LAMDA-NJU/Deep-Forest
[google neuroglancer]: https://github.com/google/neuroglancer
[AutoPy]: https://github.com/autopilot-rs/autopy
[H3-py]: https://github.com/uber/h3-py
[Rtree]: https://github.com/Toblerity/rtree
[markupsafe]: https://github.com/pallets/markupsafe
[Picologging]: https://github.com/microsoft/picologging
[pybind11 cmake_example]: https://github.com/pybind/cmake_example
[mosec]: https://github.com/mosecorg/mosec
[KDEpy]: https://github.com/tommyod/KDEpy
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
[python-snappy]: https://github.com/andrix/python-snappy
[time-machine]: https://github.com/adamchainz/time-machine
[tgcalls]: https://github.com/MarshalX/tgcalls
[Picologging]: https://github.com/microsoft/picologging
[markupsafe]: https://github.com/pallets/markupsafe
[Rtree]: https://github.com/Toblerity/rtree
[pybind11 cmake_example]: https://github.com/pybind/cmake_example
[KDEpy]: https://github.com/tommyod/KDEpy
[dd-trace-py]: https://github.com/DataDog/dd-trace-py
[tgcalls]: https://github.com/MarshalX/tgcalls
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
[pybind11 python_example]: https://github.com/pybind/python_example
[sourmash]: https://github.com/dib-lab/sourmash
[cyvcf2]: https://github.com/brentp/cyvcf2
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
[python-snappy]: https://github.com/intake/python-snappy
[sourmash]: https://github.com/sourmash-bio/sourmash
[abess]: https://github.com/abess-team/abess
[cyvcf2]: https://github.com/brentp/cyvcf2
[jq.py]: https://github.com/mwilliamson/jq.py
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
[iminuit]: https://github.com/scikit-hep/iminuit
[Tokenizer]: https://github.com/OpenNMT/Tokenizer
[keyvi]: https://github.com/KeyviDev/keyvi
[pillow-heif]: https://github.com/bigcat88/pillow_heif
[PyGLM]: https://github.com/Zuzu-Typ/PyGLM
[TgCrypto]: https://github.com/pyrogram/tgcrypto
[bx-python]: https://github.com/bxlab/bx-python
[iDynTree]: https://github.com/robotology/idyntree
[streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data
[bx-python]: https://github.com/bxlab/bx-python
[power-grid-model]: https://github.com/PowerGridModel/power-grid-model
[boost-histogram]: https://github.com/scikit-hep/boost-histogram
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
[pillow-heif]: https://github.com/bigcat88/pillow_heif
[pybase64]: https://github.com/mayeut/pybase64
[Arbor]: https://github.com/arbor-sim/arbor
[fathon]: https://github.com/stfbnc/fathon
[power-grid-model]: https://github.com/alliander-opensource/power-grid-model
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
[fathon]: https://github.com/stfbnc/fathon
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
[Arbor]: https://github.com/arbor-sim/arbor
[polaroid]: https://github.com/daggy1234/polaroid
[clang-format]: https://github.com/ssciwr/clang-format-wheel
[etebase-py]: https://github.com/etesync/etebase-py
[cf-units]: https://github.com/SciTools/cf-units
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
[clang-format]: https://github.com/ssciwr/clang-format-wheel
[numpythia]: https://github.com/scikit-hep/numpythia
[ninja]: https://github.com/scikit-build/ninja-python-distributions
[numpythia]: https://github.com/scikit-hep/numpythia
[pyjet]: https://github.com/scikit-hep/pyjet
[GSD]: https://github.com/glotzerlab/gsd
[ril]: https://github.com/Cryptex-github/ril-py
[SiPM]: https://github.com/EdoPro98/SimSiPM
[CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
[GSD]: https://github.com/glotzerlab/gsd
[aalink]: https://github.com/artfwo/aalink
[CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
[werpy]: https://github.com/analyticsinmotion/werpy
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
[pybind11 cross build example]: https://github.com/wbarnha/pybind_cmake_example_crossbuild
[appveyor icon]: data/readme_icons/appveyor.svg
+8 -11
View File
@@ -1,18 +1,15 @@
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu
APPVEYOR_JOB_NAME: "python37-x64-ubuntu"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
APPVEYOR_JOB_NAME: "python37-x64-vs2015"
- APPVEYOR_BUILD_WORKER_IMAGE: macos
APPVEYOR_JOB_NAME: "python37-x64-macos"
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204
APPVEYOR_JOB_NAME: "linux-x64"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: "windows-x64"
- APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
APPVEYOR_JOB_NAME: "macos-x64"
stack: python 3.7
stack: python 3.12
init:
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
install: python -m pip install cibuildwheel==2.13.1
install: python -m pip install cibuildwheel==2.23.2
build_script: python -m cibuildwheel --output-dir wheelhouse
+4 -4
View File
@@ -6,7 +6,7 @@ jobs:
- bash: |
set -o errexit
python3 -m pip install --upgrade pip
pip3 install cibuildwheel==2.13.1
pip3 install cibuildwheel==2.23.2
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
@@ -14,13 +14,13 @@ jobs:
inputs: {pathtoPublish: 'wheelhouse'}
- job: macos
pool: {vmImage: 'macOS-11'}
pool: {vmImage: 'macOS-13'}
steps:
- task: UsePythonVersion@0
- bash: |
set -o errexit
python3 -m pip install --upgrade pip
python3 -m pip install cibuildwheel==2.13.1
python3 -m pip install cibuildwheel==2.23.2
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.13.1
pip install cibuildwheel==2.23.2
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
+8 -6
View File
@@ -4,14 +4,14 @@ jobs:
linux-wheels:
working_directory: ~/linux-wheels
docker:
- image: circleci/python:3.9
- image: cimg/python:3.12
steps:
- checkout
- setup_remote_docker
- run:
name: Build the Linux wheels.
command: |
pip3 install --user cibuildwheel==2.13.1
python3 -m pip install --user cibuildwheel==2.23.2
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
@@ -19,7 +19,7 @@ jobs:
linux-aarch64-wheels:
working_directory: ~/linux-aarch64-wheels
machine:
image: ubuntu-2004:2022.04.1
image: default
# resource_class is what tells CircleCI to use an ARM worker for native arm builds
# https://circleci.com/product/features/resource-classes/
resource_class: arm.medium
@@ -28,7 +28,7 @@ jobs:
- run:
name: Build the Linux aarch64 wheels.
command: |
python3 -m pip install --user cibuildwheel==2.13.1
python3 -m pip install --user cibuildwheel==2.23.2
python3 -m cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
@@ -36,13 +36,15 @@ jobs:
osx-wheels:
working_directory: ~/osx-wheels
macos:
xcode: 12.5.1
xcode: 15.4.0
resource_class: macos.m1.medium.gen1
steps:
- checkout
- run:
name: Build the OS X wheels.
command: |
pip3 install cibuildwheel==2.13.1
sudo softwareupdate --install-rosetta --agree-to-license # for python<=3.8 or x86_64/universal2 tests
pip3 install cibuildwheel==2.23.2
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
+6 -6
View File
@@ -1,6 +1,6 @@
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
install_cibuildwheel_script:
- python -m pip install cibuildwheel==2.13.1
- python -m pip install cibuildwheel==2.23.2
run_cibuildwheel_script:
- cibuildwheel
wheels_artifacts:
@@ -10,12 +10,12 @@ build_and_store_wheels: &BUILD_AND_STORE_WHEELS
macos_task:
name: Build macOS x86_64 and arm64 wheels.
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode
image: ghcr.io/cirruslabs/macos-runner:sonoma
env:
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
VENV_ROOT: ${HOME}/venv-cibuildwheel
PATH: ${VENV_ROOT}/bin:${PATH}
CIBW_ARCHS_MACOS: x86_64 arm64
install_pre_requirements_script:
- brew install python@3.10
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
- brew install python@3.12
- python3.12 -m venv ${VENV_ROOT}
<<: *BUILD_AND_STORE_WHEELS
+21 -11
View File
@@ -1,6 +1,6 @@
build_and_store_wheels: &BUILD_AND_STORE_WHEELS
install_cibuildwheel_script:
- python -m pip install cibuildwheel==2.13.1
- python -m pip install cibuildwheel==2.23.2
run_cibuildwheel_script:
- cibuildwheel
wheels_artifacts:
@@ -15,9 +15,14 @@ linux_x86_task:
platform: linux
cpu: 4
memory: 4G
env:
VENV_ROOT: ${HOME}/venv-cibuildwheel
PATH: ${VENV_ROOT}/bin:${PATH}
install_pre_requirements_script:
- apt install -y python3-venv python-is-python3
- add-apt-repository -y ppa:deadsnakes/ppa
- apt-get update
- apt-get install -y python3.12-venv
- python3.12 -m venv ${VENV_ROOT}
<<: *BUILD_AND_STORE_WHEELS
linux_aarch64_task:
@@ -29,9 +34,14 @@ linux_aarch64_task:
platform: linux
cpu: 4
memory: 4G
env:
VENV_ROOT: ${HOME}/venv-cibuildwheel
PATH: ${VENV_ROOT}/bin:${PATH}
install_pre_requirements_script:
- apt install -y python3-venv python-is-python3
- add-apt-repository -y ppa:deadsnakes/ppa
- apt-get update
- apt-get install -y python3.12-venv
- python3.12 -m venv ${VENV_ROOT}
<<: *BUILD_AND_STORE_WHEELS
windows_x86_task:
@@ -42,7 +52,7 @@ windows_x86_task:
memory: 4G
install_pre_requirements_script:
- choco install -y --no-progress python3 --version 3.10.6
- choco install -y --no-progress python3 --version 3.12.4
- refreshenv
- echo PATH=%PATH% >> "%CIRRUS_ENV%"
<<: *BUILD_AND_STORE_WHEELS
@@ -50,11 +60,11 @@ windows_x86_task:
macos_arm64_task:
name: Build macOS arm64 wheels.
macos_instance:
image: ghcr.io/cirruslabs/macos-monterey-xcode
image: ghcr.io/cirruslabs/macos-runner:sonoma
env:
PATH: /opt/homebrew/opt/python@3.10/bin:$PATH
VENV_ROOT: ${HOME}/venv-cibuildwheel
PATH: ${VENV_ROOT}/bin:${PATH}
install_pre_requirements_script:
- brew install python@3.10
- ln -s python3 /opt/homebrew/opt/python@3.10/bin/python
- brew install python@3.12
- python3.12 -m venv ${VENV_ROOT}
<<: *BUILD_AND_STORE_WHEELS
-19
View File
@@ -1,19 +0,0 @@
name: Build
on: [push, pull_request]
jobs:
build_wheels_macos:
name: Build wheels on macos-11
runs-on: macos-11
steps:
- uses: actions/checkout@v3
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
env:
CIBW_ARCHS_MACOS: x86_64 arm64
- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl
+30 -27
View File
@@ -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,48 +16,51 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-11]
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-14]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.23.2
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
build_sdist:
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
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-sdist
path: dist/*.tar.gz
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
- uses: actions/download-artifact@v4
with:
# unpacks default artifact into dist/
# if `name: artifact` is omitted, the action will create extra parent dir
name: artifact
# unpacks all CIBW artifacts into dist/
pattern: cibw-*
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@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/
+6 -4
View File
@@ -8,13 +8,14 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-11]
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-14]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.23.2
# env:
# CIBW_SOME_OPTION: value
# ...
@@ -23,6 +24,7 @@ jobs:
# output-dir: wheelhouse
# config-file: "{package}/pyproject.toml"
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
+15 -9
View File
@@ -8,24 +8,30 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, windows-2019, macos-11]
# macos-13 is an intel runner, macos-14 is apple silicon
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-13, macos-14]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v2
if: runner.os == 'Linux' && runner.arch == 'X64'
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v2.13.1
uses: pypa/cibuildwheel@v2.23.2
env:
# configure cibuildwheel to build native archs ('auto'), and some
# emulated ones
CIBW_ARCHS_LINUX: auto aarch64 ppc64le s390x
# configure cibuildwheel on Linux to build native archs ('auto'),
# and to split the remaining architectures between the x86_64 and
# ARM runners
# armv7l can be built without QEMU on GitHub Actions ARM runners but that's
# not the case on all ARM64 hardware hence 'auto armv7l' for native archs
# on the GHA ARM64 runner
CIBW_ARCHS_LINUX: ${{ runner.arch == 'X64' && 'auto ppc64le s390x' || 'auto armv7l' }}
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
path: ./wheelhouse/*.whl
+17 -5
View File
@@ -1,5 +1,5 @@
linux:
image: python:3.8
image: python:3.12
# make a docker daemon available for cibuildwheel to use
services:
- name: docker:dind
@@ -12,7 +12,7 @@ linux:
DOCKER_TLS_CERTDIR: ""
script:
- curl -sSL https://get.docker.com/ | sh
- python -m pip install cibuildwheel==2.13.1
- python -m pip install cibuildwheel==2.23.2
- cibuildwheel --output-dir wheelhouse
artifacts:
paths:
@@ -21,13 +21,25 @@ linux:
windows:
image: mcr.microsoft.com/windows/servercore:1809
before_script:
- choco install python -y --version 3.8.6
- choco install python -y --version 3.12.4
- choco install git.install -y
- py -m pip install cibuildwheel==2.13.1
- py -m pip install cibuildwheel==2.23.2
script:
- py -m cibuildwheel --output-dir wheelhouse --platform windows
artifacts:
paths:
- wheelhouse/
tags:
- windows
- saas-windows-medium-amd64
macos:
image: macos-14-xcode-15
before_script:
- python3 -m pip install cibuildwheel==2.23.2
script:
- python3 -m cibuildwheel --output-dir wheelhouse
artifacts:
paths:
- wheelhouse/
tags:
- saas-macos-medium-m1
+2 -2
View File
@@ -1,5 +1,5 @@
linux:
image: python:3.8
image: python:3.12
# make a docker daemon available for cibuildwheel to use
services:
- name: docker:dind
@@ -14,7 +14,7 @@ linux:
- curl -sSL https://get.docker.com/ | sh
# Warning: This is extremely slow, be careful with how many wheels you build
- docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- python -m pip install cibuildwheel==2.13.1
- python -m pip install cibuildwheel==2.23.2
# Assuming your CI runner's default architecture is x86_64...
- cibuildwheel --output-dir wheelhouse --platform linux --archs aarch64
artifacts:

Some files were not shown because too many files have changed in this diff Show More