Compare commits

..
20 Commits
Author SHA1 Message Date
Joe Rickerby bf3a5590c9 Bump version: v1.12.0 2021-06-22 18:13:50 +01:00
Henry Schreiner 8734e0e4e6 ci: pin dockcross for tests 2021-06-21 12:27:18 -04:00
Henry Schreiner 744812b7d3 ci: pin dockcross for tests 2021-06-21 12:27:18 -04:00
Henry Schreiner 548e0cefe3 feat: support building universal2/arm64 from x64_86 Python 3.8 (#704) 2021-06-21 12:27:18 -04:00
Joe Rickerby 6c62f9ee62 Bump version: v1.11.1.post1 2021-05-28 15:58:38 +01:00
Joe Rickerby 9a608b0b94 Fix mkdocs "Edit in Github" links 2021-05-28 15:53:26 +01:00
Joe Rickerby 5ea360607d Bump version: v1.11.1 2021-05-28 15:50:45 +01:00
Matthieu Darbois dc127cd69d Revert "Temporarily disable CircleCI mac builds (#685)" (#687)
This reverts commit af45aface9.
2021-05-28 14:24:46 +01:00
Joe Rickerby d1898152f7 Fix bump_version script 2021-05-28 14:13:04 +01:00
Joe Rickerby e4a917f717 Revert "Remove travis-ci macOS from docs/examples"
This reverts commit 5de574d36820c2481f4e7557ed6aa0e431ee3e63.
2021-05-24 17:24:36 -04:00
Henry Schreiner 6d5c80c624 ci: use native actions syntax (#662) 2021-05-24 17:24:36 -04:00
Henry SchreinerandJoe Rickerby 6ab9906ff0 chore: rename joerick/cibuildwheel -> pypa/cibuildwheel (#682)
* chore: rename joerick/cibuildwheel -> pypa/cibuildwheel

* Update Appveyor status badge markup

Note that it still has joerick/cibuildwheel - confusingly it's still within my appveyor account, but this is the new project that points to the pypa github repo

* Update Appveyor badge markup again

I went through a few passes to enable that project, here's the latest.

* Update Azure badge, also

* Update Travis badge to reference the .com

Co-authored-by: Joe Rickerby <joerick@mac.com>
2021-05-24 17:24:36 -04:00
Matthieu Darbois 5150122a95 Fix Travis CI tests on ppc64le/s390x (#689)
* Disable manylinux only tests on Travis CI ppc64le

Those tests are taking too much disk space for the Travis CI runner right now.
c.f. https://travis-ci.community/t/running-out-of-disk-space-quota-when-using-docker-on-ppc64le/11634

* Use focal to run aarch64/ppc64le/s390x jobs on Travis CI

This removes allow_failures from the Travis CI s390x job

* Use `focal` distribution for all Travis CI configurations

* Revert "Disable manylinux only tests on Travis CI ppc64le"

This reverts commit d0a09c689c058985c7dcb60b1e11a85a7bfce5e0.

* Skip test_manylinuxXXXX_only on Travis CI ppc64le

* Add a comment on why test_manylinuxXXXX_only test is skipped
2021-05-24 17:24:36 -04:00
Matthieu Darbois e5556f67f4 Remove macOS build on travis-ci (#686)
* Remove macOS build on travis-ci
* Remove travis-ci macOS from docs/examples
2021-05-24 17:24:36 -04:00
Edoardopre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
f6fc96400b docs: update projects.yml (#673)
* Update projects.yml

Added EdoPro98/SimSiPM project

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

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

* docs: add more projects

* docs: rerun projects.py

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2021-05-24 17:24:36 -04:00
Joe Rickerby 7e3bbe6e04 Temporarily disable CircleCI mac builds (#685) 2021-05-24 17:24:36 -04:00
Henry Schreiner 13f875a04a chore: move to PyPA (PSF) CoC (#679) 2021-05-18 13:51:04 -04:00
Henry SchreinerandMatthieu Darbois 339beb061c [1.x] chore: bump to final Python 3.5 pin (#674)
* chore: bump to final Python 3.5 pin

* Update pinned_docker_images.cfg

* 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>
2021-05-14 16:41:12 -04:00
Henry Schreiner fee39c2f35 fix: missing f for fstrings in bin (#659) 2021-05-07 18:17:44 -04:00
Joe Rickerby 73adde0b9f Enable tests on 1.x branch 2021-05-05 08:51:06 +01:00
69 changed files with 23506 additions and 892 deletions
+7
View File
@@ -0,0 +1,7 @@
# config file for https://github.com/bobvanderlinden/probot-auto-merge
# no approvals required, just the label is enough
minApprovals: {}
requiredLabels:
- merge when green
-10
View File
@@ -1,10 +0,0 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
ignore:
- dependency-name: "actions/*"
update-types: ["version-update:semver-minor", "version-update:semver-patch"]
+3 -2
View File
@@ -3,7 +3,8 @@ name: Test
on:
push:
branches:
- main
- master
- 1.x
pull_request:
paths-ignore:
- 'docs/**'
@@ -17,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: pre-commit/action@v2.0.3
- uses: pre-commit/action@v2.0.0
test:
name: Test cibuildwheel on ${{ matrix.os }}
+11 -16
View File
@@ -11,23 +11,19 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: excitedleigh/setup-nox@v2.0.0
- name: "Run update: dependencies"
run: nox --force-color -s update_constraints
- name: "Run update: python configs"
run: nox --force-color -s update_pins
# 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
- uses: actions/setup-python@v2
name: Install Python 3.9
with:
app_id: ${{ secrets.CIBUILDWHEEL_BOT_APP_ID }}
private_key: ${{ secrets.CIBUILDWHEEL_BOT_APP_PRIVATE_KEY }}
python-version: 3.9
architecture: x64
- name: Install dependencies
run: python -m pip install ".[dev]"
- name: "Run update: dependencies"
run: python ./bin/update_dependencies.py
- name: "Run update: python configs"
run: python ./bin/update_pythons.py --force
- name: Create Pull Request
if: github.ref == 'refs/heads/main' && github.repository == 'pypa/cibuildwheel'
if: github.ref == 'refs/heads/master' && github.repository == 'pypa/cibuildwheel'
uses: peter-evans/create-pull-request@v3
with:
commit-message: Update dependencies
@@ -37,5 +33,4 @@ jobs:
PR generated by "Update dependencies" [workflow](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}).
branch: update-dependencies-pr
token: ${{ steps.generate-token.outputs.token }}
delete-branch: true
-3
View File
@@ -114,6 +114,3 @@ site/
# Virtual environments
venv*
# PyCharm
.idea/
+15 -15
View File
@@ -1,7 +1,7 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v3.4.0
hooks:
- id: check-case-conflict
- id: check-merge-conflict
@@ -13,25 +13,13 @@ repos:
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v2.19.0
hooks:
- id: pyupgrade
name: PyUpgrade 3.6+
args: ["--py36-plus"]
exclude: ^bin/
- id: pyupgrade
name: PyUpgrade 3.7+ on bin
exclude: ^(cibuildwheel|unit_test|test)/
args: ["--py37-plus"]
- repo: https://github.com/PyCQA/isort
rev: 5.8.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 21.5b2
rev: 21.4b2
hooks:
- id: black
@@ -54,8 +42,20 @@ repos:
additional_dependencies: [packaging]
args: ["--python-version=3.7", "--ignore-missing-imports", "--scripts-are-modules"]
- repo: https://github.com/asottile/pyupgrade
rev: v2.14.0
hooks:
- id: pyupgrade
name: PyUpgrade 3.6+
args: ["--py36-plus"]
exclude: ^bin/
- id: pyupgrade
name: PyUpgrade 3.7+ on bin
exclude: ^(cibuildwheel|unit_test|test)/
args: ["--py37-plus"]
- repo: https://github.com/PyCQA/flake8
rev: 3.9.2
rev: 3.9.1
hooks:
- id: flake8
exclude: cibuildwheel/resources/
+2 -5
View File
@@ -4,7 +4,7 @@ language: python
branches:
only:
- main
- master
jobs:
include:
@@ -16,16 +16,13 @@ jobs:
- name: Linux | arm64 | Python 3.6
python: 3.6
services: docker
arch: arm64-graviton2
group: edge
virt: vm
arch: arm64
env: PYTHON=python
- name: Linux | ppc64le | Python 3.6
python: 3.6
services: docker
arch: ppc64le
allow_failure: True
env:
- PYTHON=python
# skip test_manylinuxXXXX_only, it uses too much disk space
+7 -6
View File
@@ -1,11 +1,12 @@
This is a summary of the Python versions and platforms covered by the different CI platforms:
| | 3.6 | 3.7 | 3.8 |
|----------|------------------------------|-----------------------------|------------------|
| Linux | Travis CI / CircleCI | AppVeyor¹ / GitHub Actions | Azure Pipelines |
| macOS | CircleCI | AppVeyor¹ / GitHub Actions | Azure Pipelines |
| Windows | Travis CI / Azure Pipelines | AppVeyor¹ / GitHub Actions | Azure Pipelines |
| | 3.6 | 3.7 | 3.8 |
|----------|------------------------------|------------------------------------------|------------------|
| Linux | Travis CI / CircleCI | AppVeyor² / GitHub Actions | Azure Pipelines |
| macOS | CircleCI | AppVeyor² / Travis CI¹ / GitHub Actions | Azure Pipelines |
| Windows | Travis CI / Azure Pipelines | AppVeyor² / GitHub Actions | Azure Pipelines |
> ¹ AppVeyor only runs the "basic" test to reduce load.
> ¹ Python version not really pinned, but dependent on the (default) version of image used.
> ² AppVeyor only runs the "basic" test to reduce load.
Non-x86 architectures are covered on Travis CI using Python 3.6.
+4
View File
@@ -22,3 +22,7 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Get-pip and Pip (bundled in cibuildwheel/resources) are licensed under the MIT
license. See https://github.com/pypa/get-pip/blob/master/LICENSE.txt
+22 -29
View File
@@ -4,10 +4,10 @@ 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)
[![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)
[![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)
[![Travis Status](https://img.shields.io/travis/com/pypa/cibuildwheel/master?logo=travis)](https://travis-ci.com/pypa/cibuildwheel)
[![Appveyor status](https://ci.appveyor.com/api/projects/status/gt3vwl88yt0y3hur/branch/master?svg=true)](https://ci.appveyor.com/project/joerick/cibuildwheel/branch/master)
[![CircleCI Status](https://img.shields.io/circleci/build/gh/pypa/cibuildwheel/master?logo=circleci)](https://circleci.com/gh/pypa/cibuildwheel)
[![Azure Status](https://dev.azure.com/joerick0429/cibuildwheel/_apis/build/status/pypa.cibuildwheel?branchName=master)](https://dev.azure.com/joerick0429/cibuildwheel/_build/latest?definitionId=4&branchName=master)
[Documentation](https://cibuildwheel.readthedocs.org)
@@ -23,23 +23,24 @@ What does it do?
----------------
| | macOS Intel | macOS Apple Silicon | Windows 64bit | Windows 32bit | manylinux x86_64 | manylinux i686 | manylinux aarch64 | manylinux ppc64le | manylinux s390x |
|---------------|----|-----|-----|-----|----|-----|----|-----|-----|
| CPython 3.6 | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | | | |
| CPython 3.7 | ✅ | N/A | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.8 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.9 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.10¹ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| PyPy 3.7 v7.3 | ✅ | N/A | ✅ | N/A | ✅ | ✅ | ✅ | N/A | N/A |
|---|---|---|---|---|---|---|---|---|---|
| CPython 2.7 | ✅ | | ✅¹ | ✅¹ | ✅ | ✅ | | | |
| CPython 3.5 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.6 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.7 | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.8 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| CPython 3.9 | ✅ | | ✅ | | ✅ | ✅ | ✅ | ✅ | ✅ |
| PyPy 2.7 v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
| PyPy 3.6 v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
| PyPy 3.7 (beta) v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
<sup>¹ Available as a prerelease under a [flag](https://cibuildwheel.readthedocs.io/en/stable/options/#prerelease-pythons)</sup><br>
<sup>¹ Only using a workaround with a newer compiler; Microsoft removed the 2008 compiler for Python 2.7 in April 2021.</sup><br>
- Builds manylinux, macOS 10.9+, and Windows wheels for CPython and PyPy
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, and GitLab 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.
Usage
-----
@@ -49,7 +50,7 @@ Usage
|-----------------|-------|-------|---------|--------------|
| GitHub Actions | ✅ | ✅ | ✅ | ✅¹ |
| Azure Pipelines | ✅ | ✅ | ✅ | |
| Travis CI | ✅ | | ✅ | ✅ |
| Travis CI | ✅ | | ✅ | ✅ |
| AppVeyor | ✅ | ✅ | ✅ | |
| CircleCI | ✅ | ✅ | | |
| Gitlab CI | ✅ | | | |
@@ -85,7 +86,7 @@ jobs:
- uses: actions/setup-python@v2
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.0.0a1
run: python -m pip install cibuildwheel==1.12.0
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
@@ -98,7 +99,7 @@ jobs:
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 building on Python 2, 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/master/examples).
Options
-------
@@ -109,12 +110,11 @@ Options
| | [`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 |
| **Build customization** | [`CIBW_ENVIRONMENT`](https://cibuildwheel.readthedocs.io/en/stable/options/#environment) | Set environment variables needed 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 (non-pure Python) built wheel |
| | [`CIBW_MANYLINUX_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_I686_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PYPY_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_AARCH64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PPC64LE_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_S390X_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PYPY_AARCH64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PYPY_I686_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) | Specify alternative manylinux docker images |
| | [`CIBW_MANYLINUX_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_I686_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PYPY_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_AARCH64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PPC64LE_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_S390X_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) | Specify alternative manylinux docker images |
| | [`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 |
@@ -346,18 +346,11 @@ Changelog
<!--changelog-start-->
### v2.0.0 (prerelease)
### v1.12.0
_This release is currently in prerelease. The below release notes will be condensed into a single entry when we do a final release._
_v2.0.0a1 (1 Jun 2021)_
- 🌟 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/latest/options/#prerelease-pythons) to test. (#675)
- ✨ Added the ability to build CPython 3.8 wheels on Apple Silicon. (#704)
- 🛠 Update to the latest build dependencies, including auditwheel 4. (#633)
- 🛠 Use the unified pypa/manylinux images to build PyPy (#671)
- ⚠️ 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)
_22 June 2021_
- ✨ Adds support building universal2/arm64 wheels on Python 3.8.
### v1.11.1
+2 -2
View File
@@ -15,7 +15,7 @@ init:
- cmd: set PATH=C:\Python37;C:\Python37\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-'))) {
if (-not ($BRANCH -eq 'master' -or $BRANCH.ToLower().StartsWith('appveyor-'))) {
$env:PYTEST_ADDOPTS='-k "unit_test or test_0_basic" --suppress-no-test-exit-code'
}
@@ -27,7 +27,7 @@ test_script: python -u ./bin/run_tests.py
branches:
only:
- main
- master
skip_commits:
files:
+2 -2
View File
@@ -40,7 +40,7 @@ def main():
timestamp = time.strftime("%Y-%m-%dT%H-%M-%S", time.gmtime())
branch_name = f"update-constraints-{timestamp}"
shell(f"git checkout -b {branch_name} origin/main", check=True)
shell(f"git checkout -b {branch_name} origin/master", check=True)
try:
shell("bin/update_dependencies.py", check=True)
@@ -63,7 +63,7 @@ def main():
"pr",
"create",
"--repo=pypa/cibuildwheel",
"--base=main",
"--base=master",
"--title=Update dependencies",
f"--body='{body}'",
],
+127 -25
View File
@@ -1,40 +1,142 @@
#!/usr/bin/env python3
# This file supports 3.6+
from __future__ import annotations
import configparser
import os
import shutil
import subprocess
import sys
from pathlib import Path
from typing import NamedTuple
DIR = Path(__file__).parent.resolve()
RESOURCES = DIR.parent / "cibuildwheel/resources"
import requests
python_version = "".join(str(v) for v in sys.version_info[:2])
env = os.environ.copy()
os.chdir(os.path.dirname(__file__))
os.chdir("..")
# CUSTOM_COMPILE_COMMAND is a pip-compile option that tells users how to
# regenerate the constraints files
env["CUSTOM_COMPILE_COMMAND"] = "bin/update_dependencies.py"
os.environ["CUSTOM_COMPILE_COMMAND"] = "bin/update_dependencies.py"
os.chdir(DIR.parent)
PYTHON_VERSIONS = ["27", "35", "36", "37", "38", "39"]
subprocess.run(
[
"pip-compile",
"--allow-unsafe",
"--upgrade",
"cibuildwheel/resources/constraints.in",
f"--output-file=cibuildwheel/resources/constraints-python{python_version}.txt",
],
check=True,
env=env,
)
if "--no-docker" in sys.argv:
for python_version in PYTHON_VERSIONS:
subprocess.run(
[
f"./env{python_version}/bin/pip-compile",
"--allow-unsafe",
"--upgrade",
"cibuildwheel/resources/constraints.in",
f"--output-file=cibuildwheel/resources/constraints-python{python_version}.txt",
],
check=True,
)
else:
# latest manylinux2010 image with cpython 2.7 support
image_runner = "quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5"
subprocess.run(["docker", "pull", image_runner], check=True)
for python_version in PYTHON_VERSIONS:
abi_flags = "" if int(python_version) >= 38 else "m"
python_path = f"/opt/python/cp{python_version}-cp{python_version}{abi_flags}/bin/"
command = (
f"{python_path}pip install pip-tools && "
f"{python_path}pip-compile --allow-unsafe --upgrade "
"cibuildwheel/resources/constraints.in "
f"--output-file cibuildwheel/resources/constraints-python{python_version}.txt"
)
subprocess.run(
[
"docker",
"run",
"--rm",
"--env=CUSTOM_COMPILE_COMMAND",
f"--volume={os.getcwd()}:/volume",
"--workdir=/volume",
image_runner,
"bash",
"-c",
command,
],
check=True,
)
# default constraints.txt
if python_version == "39":
shutil.copyfile(
RESOURCES / f"constraints-python{python_version}.txt",
RESOURCES / "constraints.txt",
)
shutil.copyfile(
f"cibuildwheel/resources/constraints-python{PYTHON_VERSIONS[-1]}.txt",
"cibuildwheel/resources/constraints.txt",
)
class Image(NamedTuple):
manylinux_version: str
platform: str
image_name: str
tag: str | None
images = [
Image("manylinux1", "x86_64", "quay.io/pypa/manylinux1_x86_64", None),
Image("manylinux1", "i686", "quay.io/pypa/manylinux1_i686", None),
# Images for manylinux2010 are pinned to the latest tag supporting cp27
Image("manylinux2010", "x86_64", "quay.io/pypa/manylinux2010_x86_64", "2021-02-06-3d322a5"),
Image("manylinux2010", "i686", "quay.io/pypa/manylinux2010_i686", "2021-02-06-3d322a5"),
Image("manylinux2010", "pypy_x86_64", "pypywheels/manylinux2010-pypy_x86_64", None),
# 2014 images
Image("manylinux2014", "x86_64", "quay.io/pypa/manylinux2014_x86_64", None),
Image("manylinux2014", "i686", "quay.io/pypa/manylinux2014_i686", None),
Image("manylinux2014", "aarch64", "quay.io/pypa/manylinux2014_aarch64", None),
Image("manylinux2014", "ppc64le", "quay.io/pypa/manylinux2014_ppc64le", None),
Image("manylinux2014", "s390x", "quay.io/pypa/manylinux2014_s390x", None),
# 2_24 images
Image("manylinux_2_24", "x86_64", "quay.io/pypa/manylinux_2_24_x86_64", None),
Image("manylinux_2_24", "i686", "quay.io/pypa/manylinux_2_24_i686", None),
Image("manylinux_2_24", "aarch64", "quay.io/pypa/manylinux_2_24_aarch64", None),
Image("manylinux_2_24", "ppc64le", "quay.io/pypa/manylinux_2_24_ppc64le", None),
Image("manylinux_2_24", "s390x", "quay.io/pypa/manylinux_2_24_s390x", None),
]
config = configparser.ConfigParser()
for image in images:
# get the tag name whose digest matches 'latest'
if image.tag is not None:
# image has been pinned, do not update
tag_name = image.tag
elif image.image_name.startswith("quay.io/"):
_, _, repository_name = image.image_name.partition("/")
response = requests.get(
f"https://quay.io/api/v1/repository/{repository_name}?includeTags=true"
)
response.raise_for_status()
repo_info = response.json()
tags_dict = repo_info["tags"]
latest_tag = tags_dict.pop("latest")
# find the tag whose manifest matches 'latest'
tag_name = next(
name
for (name, info) in tags_dict.items()
if info["manifest_digest"] == latest_tag["manifest_digest"]
)
else:
response = requests.get(f"https://hub.docker.com/v2/repositories/{image.image_name}/tags")
response.raise_for_status()
tags = response.json()["results"]
latest_tag = next(tag for tag in tags if tag["name"] == "latest")
# i don't know what it would mean to have multiple images per tag
assert len(latest_tag["images"]) == 1
digest = latest_tag["images"][0]["digest"]
pinned_tag = next(
tag for tag in tags if tag != latest_tag and tag["images"][0]["digest"] == digest
)
tag_name = pinned_tag["name"]
if not config.has_section(image.platform):
config[image.platform] = {}
config[image.platform][image.manylinux_version] = f"{image.image_name}:{tag_name}"
with open("cibuildwheel/resources/pinned_docker_images.cfg", "w") as f:
config.write(f)
-93
View File
@@ -1,93 +0,0 @@
#!/usr/bin/env python3
from __future__ import annotations
import configparser
from pathlib import Path
from typing import NamedTuple
import requests
DIR = Path(__file__).parent.resolve()
RESOURCES = DIR.parent / "cibuildwheel/resources"
class Image(NamedTuple):
manylinux_version: str
platform: str
image_name: str
tag: str | None # Set this to pin the image
images = [
Image("manylinux1", "x86_64", "quay.io/pypa/manylinux1_x86_64", None),
Image("manylinux1", "i686", "quay.io/pypa/manylinux1_i686", None),
# 2010 images
Image("manylinux2010", "x86_64", "quay.io/pypa/manylinux2010_x86_64", None),
Image("manylinux2010", "i686", "quay.io/pypa/manylinux2010_i686", None),
Image("manylinux2010", "pypy_x86_64", "quay.io/pypa/manylinux2010_x86_64", None),
Image("manylinux2010", "pypy_i686", "quay.io/pypa/manylinux2010_i686", None),
# 2014 images
Image("manylinux2014", "x86_64", "quay.io/pypa/manylinux2014_x86_64", None),
Image("manylinux2014", "i686", "quay.io/pypa/manylinux2014_i686", None),
Image("manylinux2014", "aarch64", "quay.io/pypa/manylinux2014_aarch64", None),
Image("manylinux2014", "ppc64le", "quay.io/pypa/manylinux2014_ppc64le", None),
Image("manylinux2014", "s390x", "quay.io/pypa/manylinux2014_s390x", None),
Image("manylinux2014", "pypy_x86_64", "quay.io/pypa/manylinux2014_x86_64", None),
Image("manylinux2014", "pypy_i686", "quay.io/pypa/manylinux2014_i686", None),
Image("manylinux2014", "pypy_aarch64", "quay.io/pypa/manylinux2014_aarch64", None),
# 2_24 images
Image("manylinux_2_24", "x86_64", "quay.io/pypa/manylinux_2_24_x86_64", None),
Image("manylinux_2_24", "i686", "quay.io/pypa/manylinux_2_24_i686", None),
Image("manylinux_2_24", "aarch64", "quay.io/pypa/manylinux_2_24_aarch64", None),
Image("manylinux_2_24", "ppc64le", "quay.io/pypa/manylinux_2_24_ppc64le", None),
Image("manylinux_2_24", "s390x", "quay.io/pypa/manylinux_2_24_s390x", None),
Image("manylinux_2_24", "pypy_x86_64", "quay.io/pypa/manylinux_2_24_x86_64", None),
Image("manylinux_2_24", "pypy_i686", "quay.io/pypa/manylinux_2_24_i686", None),
Image("manylinux_2_24", "pypy_aarch64", "quay.io/pypa/manylinux_2_24_aarch64", None),
]
config = configparser.ConfigParser()
for image in images:
# get the tag name whose digest matches 'latest'
if image.tag is not None:
# image has been pinned, do not update
tag_name = image.tag
elif image.image_name.startswith("quay.io/"):
_, _, repository_name = image.image_name.partition("/")
response = requests.get(
f"https://quay.io/api/v1/repository/{repository_name}?includeTags=true"
)
response.raise_for_status()
repo_info = response.json()
tags_dict = repo_info["tags"]
latest_tag = tags_dict.pop("latest")
# find the tag whose manifest matches 'latest'
tag_name = next(
name
for (name, info) in tags_dict.items()
if info["manifest_digest"] == latest_tag["manifest_digest"]
)
else:
response = requests.get(f"https://hub.docker.com/v2/repositories/{image.image_name}/tags")
response.raise_for_status()
tags = response.json()["results"]
latest_tag = next(tag for tag in tags if tag["name"] == "latest")
# i don't know what it would mean to have multiple images per tag
assert len(latest_tag["images"]) == 1
digest = latest_tag["images"][0]["digest"]
pinned_tag = next(
tag for tag in tags if tag != latest_tag and tag["images"][0]["digest"] == digest
)
tag_name = pinned_tag["name"]
if not config.has_section(image.platform):
config[image.platform] = {}
config[image.platform][image.manylinux_version] = f"{image.image_name}:{tag_name}"
with open(RESOURCES / "pinned_docker_images.cfg", "w") as f:
config.write(f)
+52 -66
View File
@@ -6,7 +6,7 @@ import copy
import difflib
import logging
from pathlib import Path
from typing import Any, Iterable, Union, cast
from typing import Union
import click
import requests
@@ -79,26 +79,23 @@ class WindowsVersions:
response.raise_for_status()
cp_info = response.json()
self.version_dict = {Version(v): v for v in cp_info["versions"]}
versions = (Version(v) for v in cp_info["versions"])
self.versions = sorted(v for v in versions if not v.is_devrelease)
def update_version_windows(self, spec: Specifier) -> ConfigWinCP | None:
# Specifier.filter selects all non pre-releases that match the spec,
# unless there are only pre-releases, then it selects pre-releases
# instead (like pip)
unsorted_versions = cast(Iterable[Version], spec.filter(self.version_dict))
versions = sorted(unsorted_versions, reverse=True)
versions = sorted(v for v in self.versions if spec.contains(v))
if not all(v.is_prerelease for v in versions):
versions = [v for v in versions if not v.is_prerelease]
log.debug(f"Windows {self.arch} {spec} has {', '.join(str(v) for v in versions)}")
if not versions:
return None
version = versions[0]
version = versions[-1]
identifier = f"cp{version.major}{version.minor}-{self.arch}"
return ConfigWinCP(
identifier=identifier,
version=self.version_dict[version],
version=str(version),
arch=self.arch_str,
)
@@ -121,33 +118,26 @@ class PyPyVersions:
]
self.arch = arch_str
def get_arch_file(self, release: dict[str, Any]) -> str:
urls = [
rf["download_url"]
for rf in release["files"]
if "" in rf["platform"] == f"win{self.arch}"
]
return urls[0] if urls else ""
def update_version_windows(self, spec: Specifier) -> ConfigWinCP:
if self.arch != "32":
raise RuntimeError("64 bit releases not supported yet on Windows")
releases = [r for r in self.releases if spec.contains(r["python_version"])]
releases = sorted(releases, key=lambda r: r["pypy_version"])
releases = [r for r in releases if self.get_arch_file(r)]
if not releases:
raise RuntimeError(f"PyPy Win {self.arch} not found for {spec}! {self.releases}")
version_arch = "win32" if self.arch == "32" else "win_amd64"
release = releases[-1]
version = release["python_version"]
identifier = f"pp{version.major}{version.minor}-{version_arch}"
url = self.get_arch_file(release)
identifier = f"pp{version.major}{version.minor}-win32"
(url,) = [rf["download_url"] for rf in release["files"] if "" in rf["platform"] == "win32"]
return ConfigWinPP(
identifier=identifier,
version=f"{version.major}.{version.minor}",
arch=self.arch,
arch="32",
url=url,
)
@@ -165,11 +155,11 @@ class PyPyVersions:
version = release["python_version"]
identifier = f"pp{version.major}{version.minor}-macosx_x86_64"
(url,) = (
(url,) = [
rf["download_url"]
for rf in release["files"]
if "" in rf["platform"] == "darwin" and rf["arch"] == "x64"
)
]
return ConfigMacOS(
identifier=identifier,
@@ -193,38 +183,31 @@ class CPythonVersions:
# Removing the prefix, Python 3.9 would use: release["name"].removeprefix("Python ")
version = Version(release["name"][7:])
uri = int(release["resource_uri"].rstrip("/").split("/")[-1])
self.versions_dict[version] = uri
if not version.is_prerelease and not version.is_devrelease:
uri = int(release["resource_uri"].rstrip("/").split("/")[-1])
self.versions_dict[version] = uri
def update_version_macos(
self, identifier: str, version: Version, spec: Specifier
) -> ConfigMacOS | None:
def update_version_macos(self, identifier: str, spec: Specifier) -> ConfigMacOS | None:
file_idents = ("macos11.pkg", "macosx10.9.pkg", "macosx10.6.pkg")
sorted_versions = sorted(v for v in self.versions_dict if spec.contains(v))
# see note above on Specifier.filter
unsorted_versions = cast(Iterable[Version], 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"
for new_version in sorted_versions:
for version in reversed(sorted_versions):
# Find the first patch version that contains the requested file
uri = self.versions_dict[new_version]
uri = self.versions_dict[version]
response = requests.get(
f"https://www.python.org/api/v2/downloads/release_file/?release={uri}"
)
response.raise_for_status()
file_info = response.json()
urls = [rf["url"] for rf in file_info if file_ident in rf["url"]]
if urls:
return ConfigMacOS(
identifier=identifier,
version=f"{new_version.major}.{new_version.minor}",
url=urls[0],
)
for file_ident in file_idents:
urls = [rf["url"] for rf in file_info if file_ident in rf["url"]]
if urls:
return ConfigMacOS(
identifier=identifier,
version=f"{version.major}.{version.minor}",
url=urls[0],
)
return None
@@ -237,7 +220,7 @@ class AllVersions:
def __init__(self) -> None:
self.windows_32 = WindowsVersions("32")
self.windows_64 = WindowsVersions("64")
self.windows_pypy_64 = PyPyVersions("64")
self.windows_pypy = PyPyVersions("32")
self.macos_cpython = CPythonVersions()
self.macos_pypy = PyPyVersions("64")
@@ -248,25 +231,28 @@ class AllVersions:
spec = Specifier(f"=={version.major}.{version.minor}.*")
log.info(f"Reading in '{identifier}' -> {spec} @ {version}")
orig_config = copy.copy(config)
config_update: AnyConfig | None = None
config_update: AnyConfig | None
# We need to use ** in update due to MyPy (probably a bug)
if "macos" in identifier:
if identifier.startswith("cp"):
config_update = self.macos_cpython.update_version_macos(identifier, version, spec)
elif identifier.startswith("pp"):
if identifier.startswith("pp"):
config_update = self.macos_pypy.update_version_macos(spec)
elif "win32" in identifier:
if identifier.startswith("cp"):
config_update = self.windows_32.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)
else:
config_update = self.macos_cpython.update_version_macos(identifier, spec)
assert config_update is not None, f"{identifier} not found!"
config.update(**config_update)
assert config_update is not None, f"MacOS {spec} not found!"
config.update(**config_update)
elif "win32" in identifier:
if identifier.startswith("pp"):
config.update(**self.windows_pypy.update_version_windows(spec))
else:
config_update = self.windows_32.update_version_windows(spec)
if config_update:
config.update(**config_update)
elif "win_amd64" in identifier:
config_update = self.windows_64.update_version_windows(spec)
if config_update:
config.update(**config_update)
if config != orig_config:
log.info(f" Updated {orig_config} to {config}")
@@ -275,7 +261,7 @@ class AllVersions:
@click.command()
@click.option("--force", is_flag=True)
@click.option(
"--level", default="INFO", type=click.Choice(["WARNING", "INFO", "DEBUG"], case_sensitive=False)
"--level", default="INFO", type=click.Choice(["INFO", "DEBUG", "TRACE"], case_sensitive=False)
)
def update_pythons(force: bool, level: str) -> None:
+1 -1
View File
@@ -1 +1 @@
__version__ = "2.0.0a1"
__version__ = "1.12.0"
+33 -33
View File
@@ -132,14 +132,10 @@ def main() -> None:
help="Do not report an error code if the build does not match any wheels.",
)
parser.add_argument(
"--prerelease-pythons",
action="store_true",
help="Enable pre-release Python versions if available.",
)
args = parser.parse_args()
detect_obsolete_options()
if args.platform != "auto":
platform = args.platform
else:
@@ -210,9 +206,6 @@ def main() -> None:
build_verbosity_str = get_option_from_environment(
"CIBW_BUILD_VERBOSITY", platform=platform, default=""
)
prerelease_pythons = args.prerelease_pythons or cibuildwheel.util.strtobool(
os.environ.get("CIBW_PRERELEASE_PYTHONS", "0")
)
package_files = {"setup.py", "setup.cfg", "pyproject.toml"}
@@ -229,15 +222,8 @@ def main() -> None:
) or get_requires_python_str(package_dir)
requires_python = None if requires_python_str is None else SpecifierSet(requires_python_str)
deprecated_selectors("CIBW_BUILD", build_config, error=True)
deprecated_selectors("CIBW_SKIP", skip_config)
deprecated_selectors("CIBW_TEST_SKIP", test_skip)
build_selector = BuildSelector(
build_config=build_config,
skip_config=skip_config,
requires_python=requires_python,
prerelease_pythons=prerelease_pythons,
build_config=build_config, skip_config=skip_config, requires_python=requires_python
)
test_selector = TestSelector(skip_config=test_skip)
@@ -299,16 +285,7 @@ def main() -> None:
manylinux_images = {}
for build_platform in [
"x86_64",
"i686",
"pypy_x86_64",
"aarch64",
"ppc64le",
"s390x",
"pypy_aarch64",
"pypy_i686",
]:
for build_platform in ["x86_64", "i686", "pypy_x86_64", "aarch64", "ppc64le", "s390x"]:
pinned_images = all_pinned_docker_images[build_platform]
config_name = f"CIBW_MANYLINUX_{build_platform.upper()}_IMAGE"
@@ -375,12 +352,35 @@ def main() -> None:
assert_never(platform)
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)
def detect_obsolete_options() -> None:
# Check the old 'MANYLINUX1_*_IMAGE' options
for (deprecated, alternative) in [
("CIBW_MANYLINUX1_X86_64_IMAGE", "CIBW_MANYLINUX_X86_64_IMAGE"),
("CIBW_MANYLINUX1_I686_IMAGE", "CIBW_MANYLINUX_I686_IMAGE"),
]:
if deprecated in os.environ:
print(
f"'{deprecated}' has been deprecated, and will be removed in a future release. Use the option '{alternative}' instead."
)
if alternative not in os.environ:
print(f"Using value of option '{deprecated}' as replacement for '{alternative}'")
os.environ[alternative] = os.environ[deprecated]
else:
print(f"Option '{alternative}' is not empty. Please unset '{deprecated}'")
sys.exit(2)
# Check for deprecated identifiers in 'CIBW_BUILD' and 'CIBW_SKIP' options
for option in ["CIBW_BUILD", "CIBW_SKIP"]:
for deprecated, alternative in [
("manylinux1", "manylinux"),
("macosx_10_6_intel", "macosx_x86_64"),
("macosx_10_9_x86_64", "macosx_x86_64"),
]:
if option in os.environ and deprecated in os.environ[option]:
print(
f"Build identifiers with '{deprecated}' have been deprecated. Replacing all occurences of '{deprecated}' with '{alternative}' in the option '{option}'"
)
os.environ[option] = os.environ[option].replace(deprecated, alternative)
def print_preamble(platform: str, build_options: BuildOptions) -> None:
+21 -2
View File
@@ -15,6 +15,7 @@ from .util import (
get_build_verbosity_extra_flags,
prepare_command,
read_python_configs,
resources_dir,
)
@@ -69,8 +70,6 @@ def build(options: BuildOptions) -> None:
("cp", "manylinux_ppc64le", options.manylinux_images["ppc64le"]),
("cp", "manylinux_s390x", options.manylinux_images["s390x"]),
("pp", "manylinux_x86_64", options.manylinux_images["pypy_x86_64"]),
("pp", "manylinux_aarch64", options.manylinux_images["pypy_aarch64"]),
("pp", "manylinux_i686", options.manylinux_images["pypy_i686"]),
]
cwd = Path.cwd()
@@ -123,6 +122,26 @@ def build(options: BuildOptions) -> None:
log.build_start(config.identifier)
dependency_constraint_flags: List[PathOrStr] = []
if config.identifier.startswith("pp"):
# Patch PyPy to make sure headers get installed into a venv
patch_version = "_27" if config.version == "2.7" else ""
patch_path = resources_dir / f"pypy_venv{patch_version}.patch"
patch_docker_path = PurePath("/pypy_venv.patch")
docker.copy_into(patch_path, patch_docker_path)
try:
docker.call(
[
"patch",
"--force",
"-p1",
"-d",
config.path,
"-i",
patch_docker_path,
]
)
except subprocess.CalledProcessError:
print("PyPy patch not applied", file=sys.stderr)
if options.dependency_constraints:
constraints_file = options.dependency_constraints.get_for_python_version(
+2 -2
View File
@@ -186,7 +186,7 @@ def build_description_from_identifier(identifier: str) -> str:
build_description = ""
python_interpreter = python_identifier[0:2]
python_version = python_identifier[2:]
python_version = python_identifier[2:4]
if python_interpreter == "cp":
build_description += "CPython"
@@ -195,7 +195,7 @@ def build_description_from_identifier(identifier: str) -> str:
else:
raise Exception("unknown python")
build_description += f" {python_version[0]}.{python_version[1:]} "
build_description += f" {python_version[0]}.{python_version[1]} "
try:
build_description += PLATFORM_IDENTIFIER_DESCIPTIONS[platform_identifier]
+52 -29
View File
@@ -19,9 +19,11 @@ from .util import (
NonPlatformWheelError,
download,
get_build_verbosity_extra_flags,
get_pip_script,
install_certifi_script,
prepare_command,
read_python_configs,
resources_dir,
unwrap,
)
@@ -109,6 +111,21 @@ def get_python_configurations(
c for c in python_configurations if not c.identifier.startswith("pp")
]
if any(c.identifier.startswith("cp35") for c in python_configurations):
# CPython 3.5 doesn't work on macOS 11
log.warning(
unwrap(
"""
CPython 3.5 is unsupported when building on macOS 11. To build CPython 3.5
wheels, build on an older OS, such as macOS 10.15. To silence this warning,
deselect CPython 3.5 by adding "cp35-macosx_x86_64" to your CIBW_SKIP option.
"""
)
)
python_configurations = [
c for c in python_configurations if not c.identifier.startswith("cp35")
]
return python_configurations
@@ -139,7 +156,7 @@ def install_cpython(version: str, url: str) -> Path:
# 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_executable = "python3"
python_executable = "python3" if version[0] == "3" else "python"
installation_bin_path = Path(f"/Library/Frameworks/Python.framework/Versions/{version}/bin")
if python_package_identifier not in installed_system_packages:
@@ -147,9 +164,24 @@ def install_cpython(version: str, url: str) -> Path:
download(url, Path("/tmp/Python.pkg"))
# install
call(["sudo", "installer", "-pkg", "/tmp/Python.pkg", "-target", "/"])
# patch open ssl
if version == "3.5":
open_ssl_patch_url = f"https://github.com/mayeut/patch-macos-python-openssl/releases/download/v1.1.1h/patch-macos-python-{version}-openssl-v1.1.1h.tar.gz"
download(open_ssl_patch_url, Path("/tmp/python-patch.tar.gz"))
call(
[
"sudo",
"tar",
"-C",
f"/Library/Frameworks/Python.framework/Versions/{version}/",
"-xmf",
"/tmp/python-patch.tar.gz",
]
)
call(["sudo", str(installation_bin_path / python_executable), str(install_certifi_script)])
pip_executable = "pip3"
pip_executable = "pip3" if version[0] == "3" else "pip"
make_symlinks(installation_bin_path, python_executable, pip_executable)
return installation_bin_path
@@ -165,10 +197,14 @@ def install_pypy(version: str, url: str) -> Path:
downloaded_tar_bz2 = Path("/tmp") / pypy_tar_bz2
download(url, downloaded_tar_bz2)
call(["tar", "-C", "/tmp", "-xf", downloaded_tar_bz2])
# Patch PyPy to make sure headers get installed into a venv
patch_version = "_27" if version == "2.7" else ""
patch_path = resources_dir / f"pypy_venv{patch_version}.patch"
call(["patch", "--force", "-p1", "-d", installation_path, "-i", patch_path])
installation_bin_path = installation_path / "bin"
python_executable = "pypy3"
pip_executable = "pip3"
python_executable = "pypy3" if version[0] == "3" else "pypy"
pip_executable = "pip3" if version[0] == "3" else "pip"
make_symlinks(installation_bin_path, python_executable, pip_executable)
return installation_bin_path
@@ -227,29 +263,8 @@ def setup_python(
)
sys.exit(1)
# Install pip
requires_reinstall = not (installation_bin_path / "pip").exists()
if requires_reinstall:
# maybe pip isn't installed at all. ensurepip resolves that.
call(["python", "-m", "ensurepip"], env=env, cwd="/tmp")
# 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",
"--force-reinstall" if requires_reinstall else "--upgrade",
"pip",
*dependency_constraint_flags,
],
env=env,
cwd="/tmp",
)
# install pip & wheel
call(["python", get_pip_script, *dependency_constraint_flags], env=env, cwd="/tmp")
assert (installation_bin_path / "pip").exists()
call(["which", "pip"], env=env)
call(["pip", "--version"], env=env)
@@ -264,13 +279,21 @@ def setup_python(
sys.exit(1)
# Set MACOSX_DEPLOYMENT_TARGET to 10.9, if the user didn't set it.
# PyPy defaults to 10.7, causing inconsistencies if it's left unset.
# CPython 3.5 defaults to 10.6, and pypy defaults to 10.7, causing
# inconsistencies if it's left unset.
env.setdefault("MACOSX_DEPLOYMENT_TARGET", "10.9")
config_is_arm64 = python_configuration.identifier.endswith("arm64")
config_is_universal2 = python_configuration.identifier.endswith("universal2")
if python_configuration.version not in {"3.6", "3.7"}:
if python_configuration.version == "3.5":
# Cross-compilation platform override - CPython 3.5 has an
# i386/x86_64 version of Python, but we only want a x64_64 build
env.setdefault("_PYTHON_HOST_PLATFORM", "macosx-10.9-x86_64")
# https://github.com/python/cpython/blob/a5ed2fe0eedefa1649aa93ee74a0bafc8e628a10/Lib/_osx_support.py#L260
env.setdefault("ARCHFLAGS", "-arch x86_64")
elif python_configuration.version not in {"3.6", "3.7"}:
if config_is_arm64:
# macOS 11 is the first OS with arm64 support, so the wheels
# have that as a minimum.
+27 -18
View File
@@ -1,37 +1,43 @@
[linux]
python_configurations = [
{ identifier = "cp27-manylinux_x86_64", version = "2.7", path_str = "/opt/python/cp27-cp27m" },
{ identifier = "cp27-manylinux_x86_64", version = "2.7", path_str = "/opt/python/cp27-cp27mu" },
{ identifier = "cp35-manylinux_x86_64", version = "3.5", path_str = "/opt/python/cp35-cp35m" },
{ identifier = "cp36-manylinux_x86_64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_x86_64", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_x86_64", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_x86_64", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-manylinux_x86_64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp27-manylinux_i686", version = "2.7", path_str = "/opt/python/cp27-cp27m" },
{ identifier = "cp27-manylinux_i686", version = "2.7", path_str = "/opt/python/cp27-cp27mu" },
{ identifier = "cp35-manylinux_i686", version = "3.5", path_str = "/opt/python/cp35-cp35m" },
{ identifier = "cp36-manylinux_i686", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_i686", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_i686", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_i686", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-manylinux_i686", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "pp27-manylinux_x86_64", version = "2.7", path_str = "/opt/python/pp27-pypy_73" },
{ identifier = "pp36-manylinux_x86_64", version = "3.6", path_str = "/opt/python/pp36-pypy36_pp73" },
{ identifier = "pp37-manylinux_x86_64", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
{ identifier = "cp35-manylinux_aarch64", version = "3.5", path_str = "/opt/python/cp35-cp35m" },
{ identifier = "cp36-manylinux_aarch64", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_aarch64", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_aarch64", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_aarch64", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-manylinux_aarch64", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp35-manylinux_ppc64le", version = "3.5", path_str = "/opt/python/cp35-cp35m" },
{ identifier = "cp36-manylinux_ppc64le", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_ppc64le", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_ppc64le", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_ppc64le", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-manylinux_ppc64le", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "cp35-manylinux_s390x", version = "3.5", path_str = "/opt/python/cp35-cp35m" },
{ identifier = "cp36-manylinux_s390x", version = "3.6", path_str = "/opt/python/cp36-cp36m" },
{ identifier = "cp37-manylinux_s390x", version = "3.7", path_str = "/opt/python/cp37-cp37m" },
{ identifier = "cp38-manylinux_s390x", version = "3.8", path_str = "/opt/python/cp38-cp38" },
{ identifier = "cp39-manylinux_s390x", version = "3.9", path_str = "/opt/python/cp39-cp39" },
{ identifier = "cp310-manylinux_s390x", version = "3.10", path_str = "/opt/python/cp310-cp310" },
{ identifier = "pp37-manylinux_aarch64", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
{ identifier = "pp37-manylinux_i686", version = "3.7", path_str = "/opt/python/pp37-pypy37_pp73" },
]
[macos]
python_configurations = [
{ identifier = "cp27-macosx_x86_64", version = "2.7", url = "https://www.python.org/ftp/python/2.7.18/python-2.7.18-macosx10.9.pkg" },
{ identifier = "cp35-macosx_x86_64", version = "3.5", url = "https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg" },
{ identifier = "cp36-macosx_x86_64", version = "3.6", url = "https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg" },
{ identifier = "cp37-macosx_x86_64", version = "3.7", url = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-macosx10.9.pkg" },
{ identifier = "cp38-macosx_x86_64", version = "3.8", url = "https://www.python.org/ftp/python/3.8.10/python-3.8.10-macosx10.9.pkg" },
@@ -40,23 +46,26 @@ python_configurations = [
{ identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.5/python-3.9.5-macos11.pkg" },
{ identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.5/python-3.9.5-macos11.pkg" },
{ identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.5/python-3.9.5-macos11.pkg" },
{ identifier = "cp310-macosx_x86_64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.0/python-3.10.0b1-macos11.pkg" },
{ identifier = "cp310-macosx_arm64", version = "3.10", url = "https://www.python.org/ftp/python/3.10.0/python-3.10.0b1-macos11.pkg" },
{ identifier = "cp310-macosx_universal2", version = "3.10", url = "https://www.python.org/ftp/python/3.10.0/python-3.10.0b1-macos11.pkg" },
{ identifier = "pp37-macosx_x86_64", version = "3.7", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.5-osx64.tar.bz2" },
{ identifier = "pp27-macosx_x86_64", version = "2.7", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-osx64.tar.bz2" },
{ identifier = "pp36-macosx_x86_64", version = "3.6", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-osx64.tar.bz2" },
{ identifier = "pp37-macosx_x86_64", version = "3.7", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-osx64.tar.bz2" },
]
[windows]
python_configurations = [
{ identifier = "cp27-win32", version = "2.7.18", arch = "32" },
{ identifier = "cp27-win_amd64", version = "2.7.18", arch = "64" },
{ identifier = "cp35-win32", version = "3.5.4", arch = "32" },
{ identifier = "cp35-win_amd64", version = "3.5.4", arch = "64" },
{ identifier = "cp36-win32", version = "3.6.8", arch = "32" },
{ identifier = "cp36-win_amd64", version = "3.6.8", arch = "64" },
{ identifier = "cp37-win32", version = "3.7.9", arch = "32" },
{ identifier = "cp37-win_amd64", version = "3.7.9", arch = "64" },
{ identifier = "cp38-win32", version = "3.8.10", arch = "32" },
{ identifier = "cp38-win_amd64", version = "3.8.10", arch = "64" },
{ identifier = "cp39-win32", version = "3.9.5", arch = "32" },
{ identifier = "cp39-win_amd64", version = "3.9.5", arch = "64" },
{ identifier = "cp310-win32", version = "3.10.0-b1", arch = "32" },
{ identifier = "cp310-win_amd64", version = "3.10.0-b1", arch = "64" },
{ identifier = "pp37-win_amd64", version = "3.7", arch = "64", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.5-win64.zip" },
{ identifier = "cp38-win32", version = "3.8.9", arch = "32" },
{ identifier = "cp38-win_amd64", version = "3.8.9", arch = "64" },
{ identifier = "cp39-win32", version = "3.9.4", arch = "32" },
{ identifier = "cp39-win_amd64", version = "3.9.4", arch = "64" },
{ identifier = "pp27-win32", version = "2.7", arch = "32", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-win32.zip" },
{ identifier = "pp36-win32", version = "3.6", arch = "32", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-win32.zip" },
{ identifier = "pp37-win32", version = "3.7", arch = "32", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-win32.zip" },
]
@@ -0,0 +1,55 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_dependencies.py
#
appdirs==1.4.4
# via virtualenv
configparser==4.0.2
# via importlib-metadata
contextlib2==0.6.0.post1
# via
# importlib-metadata
# importlib-resources
delocate==0.8.2
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
importlib-metadata==2.1.1
# via virtualenv
importlib-resources==3.3.1
# via virtualenv
pathlib2==2.3.5
# via
# importlib-metadata
# importlib-resources
# virtualenv
scandir==1.10.0
# via pathlib2
singledispatch==3.6.1
# via importlib-resources
six==1.15.0
# via
# pathlib2
# virtualenv
typing==3.7.4.3
# via importlib-resources
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.2
# via
# -r cibuildwheel/resources/constraints.in
# delocate
zipp==1.2.0
# via
# importlib-metadata
# importlib-resources
# The following packages are considered to be unsafe in a requirements file:
pip==20.3.4
# via -r cibuildwheel/resources/constraints.in
setuptools==44.1.1
# via -r cibuildwheel/resources/constraints.in
@@ -0,0 +1,36 @@
#
# This file is autogenerated by pip-compile
# To update, run:
#
# bin/update_dependencies.py
#
appdirs==1.4.4
# via virtualenv
delocate==0.8.2
# via -r cibuildwheel/resources/constraints.in
distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
importlib-metadata==2.1.1
# via virtualenv
importlib-resources==3.2.1
# via virtualenv
six==1.15.0
# via virtualenv
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.2
# via
# -r cibuildwheel/resources/constraints.in
# delocate
zipp==1.2.0
# via
# importlib-metadata
# importlib-resources
# The following packages are considered to be unsafe in a requirements file:
pip==20.3.4
# via -r cibuildwheel/resources/constraints.in
setuptools==50.3.2
# via -r cibuildwheel/resources/constraints.in
@@ -12,15 +12,15 @@ distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
importlib-metadata==4.0.1
importlib-metadata==3.10.0
# via virtualenv
importlib-resources==5.1.3
importlib-resources==5.1.2
# via virtualenv
six==1.16.0
six==1.15.0
# via virtualenv
typing-extensions==3.10.0.0
typing-extensions==3.7.4.3
# via importlib-metadata
virtualenv==20.4.6
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.2
# via
@@ -32,7 +32,7 @@ zipp==3.4.1
# importlib-resources
# The following packages are considered to be unsafe in a requirements file:
pip==21.1.1
pip==21.0.1
# via -r cibuildwheel/resources/constraints.in
setuptools==56.2.0
setuptools==54.2.0
# via -r cibuildwheel/resources/constraints.in
@@ -12,13 +12,13 @@ distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
importlib-metadata==4.0.1
importlib-metadata==3.10.0
# via virtualenv
six==1.16.0
six==1.15.0
# via virtualenv
typing-extensions==3.10.0.0
typing-extensions==3.7.4.3
# via importlib-metadata
virtualenv==20.4.6
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.2
# via
@@ -28,7 +28,7 @@ zipp==3.4.1
# via importlib-metadata
# The following packages are considered to be unsafe in a requirements file:
pip==21.1.1
pip==21.0.1
# via -r cibuildwheel/resources/constraints.in
setuptools==56.2.0
setuptools==54.2.0
# via -r cibuildwheel/resources/constraints.in
@@ -12,9 +12,9 @@ distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
six==1.16.0
six==1.15.0
# via virtualenv
virtualenv==20.4.6
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.2
# via
@@ -22,7 +22,7 @@ wheel==0.36.2
# delocate
# The following packages are considered to be unsafe in a requirements file:
pip==21.1.1
pip==21.0.1
# via -r cibuildwheel/resources/constraints.in
setuptools==56.2.0
setuptools==54.2.0
# via -r cibuildwheel/resources/constraints.in
@@ -12,9 +12,9 @@ distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
six==1.16.0
six==1.15.0
# via virtualenv
virtualenv==20.4.6
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.2
# via
@@ -22,7 +22,7 @@ wheel==0.36.2
# delocate
# The following packages are considered to be unsafe in a requirements file:
pip==21.1.1
pip==21.0.1
# via -r cibuildwheel/resources/constraints.in
setuptools==56.2.0
setuptools==54.2.0
# via -r cibuildwheel/resources/constraints.in
+4 -4
View File
@@ -12,9 +12,9 @@ distlib==0.3.1
# via virtualenv
filelock==3.0.12
# via virtualenv
six==1.16.0
six==1.15.0
# via virtualenv
virtualenv==20.4.6
virtualenv==20.4.3
# via -r cibuildwheel/resources/constraints.in
wheel==0.36.2
# via
@@ -22,7 +22,7 @@ wheel==0.36.2
# delocate
# The following packages are considered to be unsafe in a requirements file:
pip==21.1.1
pip==21.0.1
# via -r cibuildwheel/resources/constraints.in
setuptools==56.2.0
setuptools==54.2.0
# via -r cibuildwheel/resources/constraints.in
File diff suppressed because it is too large Load Diff
@@ -24,6 +24,9 @@ STAT_0o775 = (
| stat.S_IXOTH
)
if sys.version_info[0] == 2:
FileNotFoundError = OSError
def main():
openssl_dir, openssl_cafile = os.path.split(ssl.get_default_verify_paths().openssl_cafile)
+15 -27
View File
@@ -1,38 +1,26 @@
[x86_64]
manylinux1 = quay.io/pypa/manylinux1_x86_64:2021-05-24-df68af6
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-05-24-84874a2
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2021-05-24-84874a2
manylinux1 = quay.io/pypa/manylinux1_x86_64:2021-05-05-b64d921
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-05-01-28d233a
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2021-05-01-28d233a
[i686]
manylinux1 = quay.io/pypa/manylinux1_i686:2021-05-24-df68af6
manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-05-24-84874a2
manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2021-05-24-84874a2
manylinux1 = quay.io/pypa/manylinux1_i686:2021-05-05-b64d921
manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-02-06-3d322a5
manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-05-01-28d233a
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2021-05-01-28d233a
[pypy_x86_64]
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-05-24-84874a2
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2021-05-24-84874a2
[pypy_i686]
manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-05-24-84874a2
manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2021-05-24-84874a2
manylinux2010 = pypywheels/manylinux2010-pypy_x86_64:2020-12-11-f1e0e80
[aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2021-05-24-84874a2
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2021-05-01-28d233a
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2021-05-01-28d233a
[ppc64le]
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2021-05-24-84874a2
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2021-05-01-28d233a
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2021-05-01-28d233a
[s390x]
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2021-05-24-84874a2
[pypy_aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2021-05-24-84874a2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2021-05-24-84874a2
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2021-05-01-28d233a
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2021-05-01-28d233a
+36
View File
@@ -0,0 +1,36 @@
diff --git a/lib-python/3/sysconfig.py b/lib-python/3/sysconfig.py
index 0d08cde66b4150e1772c13fdc6fe34d079c2b10d..30c77d165a2505d98bc7660ff0cc3b728f56c682 100644
--- a/lib-python/3/sysconfig.py
+++ b/lib-python/3/sysconfig.py
@@ -618,9 +618,6 @@ def get_config_vars(*args):
import _osx_support
_osx_support.customize_config_vars(_CONFIG_VARS)
- _CONFIG_VARS['INCLUDEPY'] = os.path.join(_CONFIG_VARS['prefix'],
- 'include')
-
if args:
vals = []
for name in args:
diff --git a/lib_pypy/_sysconfigdata.py b/lib_pypy/_sysconfigdata.py
index f1cca41a4b7553819bb1a2a63af1c1a9b8591ce9..a34216e8e12b82abd72fabdd7793b3e8bb19bbcf 100644
--- a/lib_pypy/_sysconfigdata.py
+++ b/lib_pypy/_sysconfigdata.py
@@ -5,6 +5,7 @@ from distutils.spawn import find_executable
so_ext = _imp.extension_suffixes()[0]
+mybase = os.path.dirname(os.path.dirname(__file__))
build_time_vars = {
# SOABI is PEP 3149 compliant, but CPython3 has so_ext.split('.')[1]
@@ -25,7 +26,8 @@ build_time_vars = {
'AR': "ar",
'ARFLAGS': "rc",
'EXE': "",
- 'LIBDIR': os.path.join(sys.prefix, 'bin'),
+ 'LIBDIR': os.path.join(mybase, 'lib'),
+ 'INCLUDEPY': os.path.join(mybase, 'include'),
}
if find_executable("gcc"):
+27
View File
@@ -0,0 +1,27 @@
--- a/lib-python/2.7/sysconfig.py
+++ b/lib-python/2.7/sysconfig.py
@@ -553,9 +553,6 @@ def get_config_vars(*args):
if type_ == imp.C_EXTENSION:
_CONFIG_VARS['SOABI'] = suffix.split('.')[1]
break
- _CONFIG_VARS['INCLUDEPY'] = os.path.join(_CONFIG_VARS['prefix'],
- 'include')
-
if args:
vals = []
for name in args:
--- a/lib_pypy/_sysconfigdata.py
+++ b/lib_pypy/_sysconfigdata.py
@@ -1,5 +1,11 @@
-import imp
+import imp, os
+
+mybase = os.path.dirname(os.path.dirname(__file__))
build_time_vars = {
"SO": [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION][0]
}
+
+build_time_vars['LIBDIR'] = os.path.join(mybase, 'lib')
+build_time_vars['INCLUDEPY'] = os.path.join(mybase, 'include')
+
+9 -34
View File
@@ -24,6 +24,7 @@ from .typing import PathOrStr, PlatformName
resources_dir = Path(__file__).parent / "resources"
get_pip_script = resources_dir / "get-pip.py"
install_certifi_script = resources_dir / "install_certifi.py"
@@ -58,25 +59,15 @@ class IdentifierSelector:
This class holds a set of build/skip patterns. You call an instance with a
build identifier, and it returns True if that identifier should be
included. Only call this on valid identifiers, ones that have at least 2
numeric digits before the first dash. If a pre-release version X.Y is present,
you can filter it with prerelease="XY".
numeric digits before the first dash.
"""
# a pattern that skips prerelease versions, when include_prereleases is False.
PRERELEASE_SKIP = "cp310-*"
def __init__(
self,
*,
build_config: str,
skip_config: str,
requires_python: Optional[SpecifierSet] = None,
prerelease_pythons: bool = False,
self, *, build_config: str, skip_config: str, requires_python: Optional[SpecifierSet] = None
):
self.build_patterns = build_config.split()
self.skip_patterns = skip_config.split()
self.requires_python = requires_python
self.prerelease_pythons = prerelease_pythons
def __call__(self, build_id: str) -> bool:
# Filter build selectors by python_requires if set
@@ -91,33 +82,17 @@ class IdentifierSelector:
build_patterns = itertools.chain.from_iterable(
bracex.expand(p) for p in self.build_patterns
)
unexpanded_skip_patterns = self.skip_patterns.copy()
if not self.prerelease_pythons:
# filter out the prerelease pythons, alongside the user-defined
# skip patterns
unexpanded_skip_patterns += BuildSelector.PRERELEASE_SKIP.split()
skip_patterns = itertools.chain.from_iterable(
bracex.expand(p) for p in unexpanded_skip_patterns
)
skip_patterns = itertools.chain.from_iterable(bracex.expand(p) for p in self.skip_patterns)
build: bool = any(fnmatch.fnmatch(build_id, pat) for pat in build_patterns)
skip: bool = any(fnmatch.fnmatch(build_id, pat) for pat in skip_patterns)
return build and not skip
def __repr__(self) -> str:
result = f'{self.__class__.__name__}(build_config={" ".join(self.build_patterns)!r}'
if self.skip_patterns:
result += f', skip_config={" ".join(self.skip_patterns)!r}'
if self.prerelease_pythons:
result += ", prerelease_pythons=True"
result += ")"
return result
if not self.skip_patterns:
return f'{self.__class__.__name__}({" ".join(self.build_patterns)!r})'
else:
return f'{self.__class__.__name__}({" ".join(self.build_patterns)!r} - {" ".join(self.skip_patterns)!r})'
class BuildSelector(IdentifierSelector):
@@ -188,7 +163,7 @@ class DependencyConstraints:
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
# ./constraints.txt is the base, look for ./constraints-python27.txt
specific_stem = self.base_file_path.stem + f"-python{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)
+58 -28
View File
@@ -7,6 +7,8 @@ from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence, Set
from zipfile import ZipFile
import toml
from .architecture import Architecture
from .environment import ParsedEnvironment
from .logger import log
@@ -17,10 +19,13 @@ from .util import (
NonPlatformWheelError,
download,
get_build_verbosity_extra_flags,
get_pip_script,
prepare_command,
read_python_configs,
)
IS_RUNNING_ON_AZURE = Path("C:\\hostedtoolcache").exists()
def call(
args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None
@@ -37,7 +42,7 @@ def shell(command: str, env: Optional[Dict[str, str]] = None, cwd: Optional[str]
def get_nuget_args(version: str, arch: str) -> List[str]:
python_name = "python"
python_name = "python" if version[0] == "3" else "python2"
if arch == "32":
python_name += "x86"
return [
@@ -72,6 +77,13 @@ def get_python_configurations(
"64": Architecture.AMD64,
}
# Only supported with custom compiler, since MS removed the 2008 compiler download
custom_compiler = os.environ.get("DISTUTILS_USE_SDK") and os.environ.get("MSSdk")
if not custom_compiler:
python_configurations = [
c for c in python_configurations if not c.version.startswith("2.7")
]
# skip builds as required
python_configurations = [
c
@@ -95,7 +107,7 @@ def install_cpython(version: str, arch: str, nuget: Path) -> Path:
def install_pypy(version: str, arch: str, url: str) -> Path:
assert arch == "64" and "win64" in url
assert arch == "32"
# Inside the PyPy zip file is a directory with the same name
zip_filename = url.rsplit("/", 1)[-1]
extension = ".zip"
@@ -106,7 +118,8 @@ def install_pypy(version: str, arch: str, url: str) -> Path:
download(url, pypy_zip)
# Extract to the parent directory because the zip file still contains a directory
extract_zip(pypy_zip, installation_path.parent)
(installation_path / "python.exe").symlink_to(installation_path / "pypy3.exe")
pypy_exe = "pypy3.exe" if version[0] == "3" else "pypy.exe"
(installation_path / "python.exe").symlink_to(installation_path / pypy_exe)
return installation_path
@@ -173,31 +186,9 @@ def setup_python(
)
sys.exit(1)
log.step("Installing build tools...")
# Install pip
requires_reinstall = not (installation_path / "Scripts" / "pip.exe").exists()
if requires_reinstall:
# maybe pip isn't installed at all. ensurepip resolves that.
call(["python", "-m", "ensurepip"], env=env, cwd="C:\\cibw")
# 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",
"--force-reinstall" if requires_reinstall else "--upgrade",
"pip",
*dependency_constraint_flags,
],
env=env,
cwd="C:\\cibw",
)
# make sure pip is installed
if not (installation_path / "Scripts" / "pip.exe").exists():
call(["python", get_pip_script, *dependency_constraint_flags], env=env, cwd="C:\\cibw")
assert (installation_path / "Scripts" / "pip.exe").exists()
where_pip = (
subprocess.run(
@@ -213,6 +204,12 @@ def setup_python(
)
sys.exit(1)
log.step("Installing build tools...")
call(
["python", "-m", "pip", "install", "--upgrade", "pip", *dependency_constraint_flags],
env=env,
)
call(["pip", "--version"], env=env)
call(
["pip", "install", "--upgrade", "setuptools", "wheel", *dependency_constraint_flags],
@@ -222,6 +219,34 @@ def setup_python(
return env
def pep_518_cp35_workaround(package_dir: Path, env: Dict[str, str]) -> None:
"""
Python 3.5 PEP 518 hack (see https://github.com/pypa/pip/issues/8392#issuecomment-639563494)
Basically, nuget's Python is an embedded Python distribution, which is not supported by pip.
Before version 3.6, there was no way to disable the "embedded" behavior, including the ignoring
of environment variables, including the ones pip uses to setup PEP 518 builds.
The fix here is as suggested in that issue; we manually setup the PEP 518 requirements. Since we
are in a fresh environment (except for pinned cibuildweel dependencies), the build is already
mostly "isolated".
"""
pyproject_path = package_dir / "pyproject.toml"
if pyproject_path.exists():
data = toml.load(pyproject_path)
requirements = data["build-system"].get("requires", []) if "build-system" in data else []
if requirements:
log.step("Performing PEP518 workaround...")
with tempfile.TemporaryDirectory() as d:
reqfile = Path(d) / "requirements.txt"
with reqfile.open("w") as f:
for r in requirements:
print(r, file=f)
call(["pip", "install", "-r", reqfile], env=env)
def build(options: BuildOptions) -> None:
temp_dir = Path(tempfile.mkdtemp(prefix="cibuildwheel"))
built_wheel_dir = temp_dir / "built_wheel"
@@ -261,6 +286,11 @@ def build(options: BuildOptions) -> None:
)
shell(before_build_prepared, env=env)
# activate the PEP 518 patch if on Windows Python 3.5
# (will only have an effect if PEP 517 builds are used):
if config.version.startswith("3.5"):
pep_518_cp35_workaround(options.package_dir, env)
log.step("Building wheel...")
if built_wheel_dir.exists():
shutil.rmtree(built_wheel_dir)
+6 -22
View File
@@ -34,32 +34,11 @@ So, if we can, I'd like to improve the experience on errors as well. In [this](h
Maintainer notes
----------------
### Nox support
Most developer tasks have a nox interface. This allows you to very simply run tasks without worrying about setting up a development environment (as shown below). This is a slower than setting up a development environment and reusing it, but has the (important) benefit of being highly reproducible; an earlier run does not affect a current run, or anything else on your machine.
Install [nox](https://nox.thea.codes); homebrew is recommend on macOS, otherwise, pipx is a great choice - in fact, you can use `pipx run nox` and avoid installing completely.
You can see a list of sessions by typing `nox -l`; here are a few common ones:
```console
nox -s lint # Run the linters (default)
nox -s tests # Run the tests (default)
nox -s docs -- serve # Build and serve the documentation
nox -s build # Make SDist and wheel
```
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:
```console
docker run --rm -itv $PWD:/src -w /src quay.io/pypa/manylinux_2_24_x86_64:latest pipx run nox -s update_constraints
```
### Local testing
You should run:
```console
```python
python3 -m venv venv
. venv/bin/activate
pip install -e .[dev]
@@ -94,6 +73,8 @@ This has been moved to using docker, so you only need the following instructions
The dependency update script in the next section requires multiple python versions installed. One way to do this is to use `pyenv`:
```bash
pyenv install 2.7.18
pyenv install 3.5.9
pyenv install 3.6.11
pyenv install 3.7.8
# Optionally add 3.8 and make it the local version;
@@ -103,6 +84,9 @@ pyenv install 3.7.8
Then, you need to make the required virtual environments:
```bash
$(pyenv prefix 2.7.18)/bin/python -m pip install virtualenv
$(pyenv prefix 2.7.18)/bin/python -m virtualenv env27
$(pyenv prefix 3.5.9)/bin/python -m venv env35
$(pyenv prefix 3.6.11)/bin/python -m venv env36
$(pyenv prefix 3.7.8)/bin/python -m venv env37
```
+46
View File
@@ -5,6 +5,10 @@ title: Modern C++ standards
Building Python wheels with modern C++ standards (C++11 and later) requires a few tricks.
## Python 2.7 and C++17
The Python 2.7 header files use the `register` keyword, which is [reserved and unused from C+17 onwards](https://en.cppreference.com/w/cpp/keyword/register). Compiling a wheel for Python 2.7 with the C++17 standard is still possible to allow usage of `register` using proper flag `-Wno-register` for gcc/clang and `/wd5033` for MSVC.
## manylinux1 and C++14
The default `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
@@ -23,3 +27,45 @@ To get C++17 support, Xcode 9.3+ is needed, requiring at least macOS 10.13 on th
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.
For more details see https://en.cppreference.com/w/cpp/compiler_support, https://en.wikipedia.org/wiki/Xcode, and https://xcodereleases.com/: Xcode 10 needs macOS 10.13 and Xcode 11 needs macOS 10.14.
## Windows and Python 2.7
In previous years, Microsoft distributed a compiler toolchain called 'Visual C++ for Python 2.7', which was a distribution of MSVC 2008 that was created to make it easier to build Python 2.7 extensions on Windows, because it was fully compatible with the toolchain that built Python 2.7.
This toolchain does not support modern C++ standards (i.e., C++11 and later). And it is hard to find this toolchain these days, since Microsoft removed the download for the required Visual Studio 2008 needed to build a native extension in April, 2021. So, by default, cibuildwheel does not attempt to build Python 2.7 extensions on Windows.
There is an optional workaround, though: the pybind11 project argues and shows that it is [possible to compile Python 2.7 extension with a newer compiler](https://pybind11.readthedocs.io/en/stable/faq.html#working-with-ancient-visual-studio-2008-builds-on-windows) and has an example project showing how to do this: https://github.com/pybind/python_example. The main catch is that a user might need to install [a newer "Microsoft Visual C++ Redistributable"](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads), since the newer C++ standard library's binaries are not included by default with the Python 2.7 installation.
Forcing `distutils` or `setuptools` to use a more recent version of MSVC that supports modern C++ can be done in the following way:
1. Set the environment variables `DISTUTILS_USE_SDK=1` and `MSSdk=1`. These two environment variables will tell `distutils`/`setuptools` to not search and set up a build environment that uses Visual C++ for Python 2.7 (aka. MSVC 9).
2. Set up the build Visual Studio build environment you want to use, making sure that e.g. `PATH` contains `cl`, `link`, etc.
- Usually, this can be done through `vcvarsall.bat x86` or `vcvarsall.bat x64`. The exact location of this file depends on the installation, but the default path for VS 2019 Community (e.g. used in AppVeyor's `Visual Studio 2019` image) is `C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat`. **Note**: `vcvarsall.bat` changes the environment variables, so this cannot be run in a subprocess/subshell and consequently running `vsvarsall.bat` in `CIBW_BEFORE_BUILD` does not have any effect.
- In Azure Pipelines, [a `VSBuild` task is available](https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/build/visual-studio-build)
- In GitHub Actions, the default shell is powershell, so you'll need to use `shell: cmd` to source a `.bat` file, and the directory is `"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"`. Or you can use an action, such as the [`ilammy/msvc-dev-cmd@v1`](https://github.com/ilammy/msvc-dev-cmd) action to setup the environment (see example below).
3. Next, call `cibuildwheel`. Unfortunately, MSVC has separate toolchains for compiling 32-bit and 64-bit, so you will need to run `cibuildwheel` twice: once with `CIBW_BUILD=*-win32` after setting up the `x86` build environment, and once with `CIBW_BUILD=*-win_amd64` in a `x64` environment (see previous step).
**GitHub Action example with ilammy/msvc-dev-cmd**:
```yaml
- uses: ilammy/msvc-dev-cmd@v1
- name: Build 64-bit wheel
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_BUILD: cp27-win_amd64
DISTUTILS_USE_SDK: 1
MSSdk: 1
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: x86
- name: Build 32-bit wheel
run: python -m cibuildwheel --output-dir wheelhouse
env:
CIBW_BUILD: cp27-win32
DISTUTILS_USE_SDK: 1
MSSdk: 1
```
+1 -1
View File
@@ -33,4 +33,4 @@ Obviously, manual steps are for chumps, so we can automate this a little by usin
If you don't need much control over the release of a package, you can set up cibuildwheel to deliver the wheels straight to PyPI. This doesn't require anycloud storage to work - you just need to bump the version and tag it.
[`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/travis-ci-deploy.yml) and [`examples/github-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml) are example configurations that automatically upload wheels to PyPI. Also check out [this example repo](https://github.com/pypa/cibuildwheel-autopypi-example) for more detailed instructions on how to set this up.
[`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/master/examples/travis-ci-deploy.yml) and [`examples/github-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/master/examples/github-deploy.yml) are example configurations that automatically upload wheels to PyPI. Also check out [this example repo](https://github.com/pypa/cibuildwheel-autopypi-example) for more detailed instructions on how to set this up.
+32 -7
View File
@@ -14,10 +14,6 @@ If your wheel didn't compile, check the list below for some debugging tips.
- MacOS: 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.
### Building Python 2.7 / PyPy2 wheels
See the [cibuildwheel verison 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.
### Linux builds on Docker
Linux wheels are built in the [`manylinux` docker images](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 571](https://www.python.org/dev/peps/pep-0571/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
@@ -140,6 +136,35 @@ Here's an example GitHub Actions workflow with a job that builds for Apple Silic
{% include "../examples/github-apple-silicon.yml" %}
```
### Windows and Python 2.7
Building 2.7 extensions on Windows is difficult, because the VS 2008 compiler that was used for the original Python compilation was discontinued in 2018, and has since been removed from Microsoft's downloads. Most people choose to not build Windows 2.7 wheels, or to override the compiler to something more modern.
To override, you need to have a modern compiler toolchain activated, and set `DISTUTILS_USE_SDK=1` and `MSSdk=1`. For example, on GitHub Actions, you would add these steps:
```yaml
- name: Prepare compiler environment for Windows
if: runner.os == 'Windows'
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Set Windows environment variables
if: runner.os == 'Windows'
shell: bash
run: |
echo "DISTUTILS_USE_SDK=1" >> $GITHUB_ENV
echo "MSSdk=1" >> $GITHUB_ENV
# invoke cibuildwheel...
```
cibuildwheel will not try to build 2.7 on Windows unless it detects that the above two variables are set. Note that changing to a more modern compiler will mean your wheel picks up a runtime dependency to a different [Visual C++ Redistributable][]. You also need to be [a bit careful][] in designing your extension; some major binding tools like pybind11 do this for you.
More on setting a custom Windows toolchain in our docs on modern C++ standards [here](cpp_standards.md#windows-and-python-27).
[Visual C++ Redistributable]: https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0
[a bit careful]: https://pybind11.readthedocs.io/en/stable/faq.html#working-with-ancient-visual-studio-2008-builds-on-windows
### Building packages with optional C extensions
@@ -181,7 +206,7 @@ python3 -m twine upload wheelhouse/*.whl
### 'ImportError: DLL load failed: The specific module could not be found' error on Windows
Visual Studio and MSVC link the compiled binary wheels to the Microsoft Visual C++ Runtime. Normally, these are included with Python, but when compiling with a newer version of Visual Studio, it is possible users will run into problems on systems that do not have these 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. Since a Python installation normally includes these VC++ Redistributable files for [the version of the MSVC compiler used to compile Python](https://wiki.python.org/moin/WindowsCompilers), this is typically only a problem when compiling a Python C extension with a newer compiler.
Visual Studio and MSVC link the compiled binary wheels to the Microsoft Visual C++ Runtime. Normally, these are included with Python, but when compiling with a newer version of Visual Studio, it is possible users will run into problems on systems that do not have these 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. Since a Python installation normally includes these VC++ Redistributable files for [the version of the MSVC compiler used to compile Python](https://wiki.python.org/moin/WindowsCompilers), this is typically only a problem when compiling a Python 2.7 C extension with a newer compiler, e.g. to support a modern C++ standard (see [the section on modern C++ standards for Python 2.7](cpp_standards.md#windows-and-python-27) for more details).
Additionally, Visual Studio 2019 started linking to an even newer DLL, `VCRUNTIME140_1.dll`, besides the `VCRUNTIME140.dll` that is included with recent Python versions (starting from Python 3.5; see [here](https://wiki.python.org/moin/WindowsCompilers) for more details on the corresponding Visual Studio & MSVC versions used to compile the different Python versions). To avoid this extra dependency on `VCRUNTIME140_1.dll`, the [`/d2FH4-` flag](https://devblogs.microsoft.com/cppblog/making-cpp-exception-handling-smaller-x64/) can be added to the MSVC invocations (check out [this issue](https://github.com/pypa/cibuildwheel/issues/423) for details and references).
@@ -210,7 +235,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.0.0a1
uses: pypa/cibuildwheel@v1.12.0
```
This is a composite step that just runs cibuildwheel using pipx. You can set command-line options as `with:` parameters, and use `env:` as normal.
@@ -236,7 +261,7 @@ The second option, and the only one that supports other CI systems, is using a `
```bash
# requirements-cibw.txt
cibuildwheel==2.0.0a1
cibuildwheel==1.12.0
```
Then your install step would have `python -m pip install -r requirements-cibw.txt` in it. Your `dependabot.yml` file could look like this:
+31 -57
View File
@@ -110,7 +110,7 @@ This option can also be set using the [command-line option](#command-line) `--pl
> Choose the Python versions to build
Space-separated list of builds to build and skip. Each build has an identifier like `cp38-manylinux_x86_64` or `cp37-macosx_x86_64` - you can list specific ones to build and cibuildwheel will only build those, and/or list ones to skip and cibuildwheel won't try to build them.
Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_x86_64` or `cp35-macosx_x86_64` - you can list specific ones to build and cibuildwheel will only build those, and/or list ones to skip and cibuildwheel won't try to build them.
When both options are specified, both conditions are applied and only builds with a tag that matches `CIBW_BUILD` and does not match `CIBW_SKIP` will be built.
@@ -120,50 +120,56 @@ When setting the options, you can use shell-style globbing syntax, as per [fnmat
| | macOS | Windows | Manylinux Intel | Manylinux Other |
|--------------|---------------------------------------------------------------------|-------------------------------|-----------------------------------------------|----------------------------------------------------------------------------|
| Python 2.7 | cp27-macosx_x86_64 | cp27-win_amd64<br/>cp27-win32 | cp27-manylinux_x86_64<br/>cp27-manylinux_i686 | |
| Python 3.5 | cp35-macosx_x86_64 | cp35-win_amd64<br/>cp35-win32 | cp35-manylinux_x86_64<br/>cp35-manylinux_i686 | cp35-manylinux_aarch64<br/>cp35-manylinux_ppc64le<br/>cp35-manylinux_s390x |
| Python 3.6 | cp36-macosx_x86_64 | cp36-win_amd64<br/>cp36-win32 | cp36-manylinux_x86_64<br/>cp36-manylinux_i686 | cp36-manylinux_aarch64<br/>cp36-manylinux_ppc64le<br/>cp36-manylinux_s390x |
| Python 3.7 | cp37-macosx_x86_64 | cp37-win_amd64<br/>cp37-win32 | cp37-manylinux_x86_64<br/>cp37-manylinux_i686 | cp37-manylinux_aarch64<br/>cp37-manylinux_ppc64le<br/>cp37-manylinux_s390x |
| Python 3.8 | cp38-macosx_x86_64 | cp38-win_amd64<br/>cp38-win32 | cp38-manylinux_x86_64<br/>cp38-manylinux_i686 | cp38-manylinux_aarch64<br/>cp38-manylinux_ppc64le<br/>cp38-manylinux_s390x |
| Python 3.9 | cp39-macosx_x86_64<br/>cp39-macosx_universal2<br/>cp39-macosx_arm64 | cp39-win_amd64<br/>cp39-win32 | cp39-manylinux_x86_64<br/>cp39-manylinux_i686 | cp39-manylinux_aarch64<br/>cp39-manylinux_ppc64le<br/>cp39-manylinux_s390x |
| PyPy3.7 v7.3 | pp37-macosx_x86_64 | pp37-win_amd64 | pp37-manylinux_x86_64 | |
| PyPy2.7 v7.3 | pp27-macosx_x86_64 | pp27-win32 | pp27-manylinux_x86_64 | |
| PyPy3.6 v7.3 | pp36-macosx_x86_64 | pp36-win32 | pp36-manylinux_x86_64 | |
| PyPy3.7 v7.3 | pp37-macosx_x86_64 | pp37-win32 | pp37-manylinux_x86_64 | |
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.
See the [cibuildwheel 1 documentation](https://cibuildwheel.readthedocs.io/en/1.x/) for past end of life versions of Python, and PyPy2.7.
For CPython, the minimally supported macOS version is 10.9; for PyPy 2.7 and PyPy 3.6/3.7, respectively macOS 10.7 and 10.13 or higher is required.
#### Examples
```yaml
# Only build on CPython 3.6
# Only build on Python 3.6
CIBW_BUILD: cp36-*
# Skip building on CPython 3.6 on the Mac
CIBW_SKIP: cp36-macosx_x86_64
# Skip building on Python 2.7 on the Mac
CIBW_SKIP: cp27-macosx_x86_64
# Skip building on CPython 3.8 on the Mac
# Skip building on Python 3.8 on the Mac
CIBW_SKIP: cp38-macosx_x86_64
# Skip building on CPython 3.6 on all platforms
CIBW_SKIP: cp36-*
# Skip building on Python 2.7 on all platforms
CIBW_SKIP: cp27-*
# Skip CPython 3.6 on Windows
CIBW_SKIP: cp36-win*
# Skip Python 2.7 on Windows
CIBW_SKIP: cp27-win*
# Skip CPython 3.6 on 32-bit Windows
CIBW_SKIP: cp36-win32
# Skip Python 2.7 on 32-bit Windows
CIBW_SKIP: cp27-win32
# Skip CPython 3.6 and CPython 3.7
CIBW_SKIP: cp36-* cp37-*
# Skip Python 2.7 and Python 3.5
CIBW_SKIP: cp27-* cp35-*
# Skip Python 3.6 on Linux
CIBW_SKIP: cp36-manylinux*
# Skip 32-bit builds
# Only build on Python 3 (ready for 3.10 when it comes) and skip 32-bit builds
CIBW_BUILD: {cp,pp}3*-*
CIBW_SKIP: "*-win32 *-manylinux_i686"
# Only build PyPy and CPython 3
CIBW_BUILD: pp* cp3*-*
# Disable building PyPy wheels on all platforms
CIBW_SKIP: pp*
```
@@ -299,32 +305,6 @@ 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
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.
Default: Off (0) if Python is available in beta phase. No effect otherwise.
This option can also be set using the [command-line option](#command-line) `--prerelease-pythons`.
#### Examples
```yaml
# Include latest Python beta
CIBW_PRERELEASE_PYTHONS: True
```
## Build customization
### `CIBW_ENVIRONMENT` {: #environment}
@@ -504,14 +484,13 @@ The available options are:
- `CIBW_MANYLINUX_AARCH64_IMAGE`
- `CIBW_MANYLINUX_PPC64LE_IMAGE`
- `CIBW_MANYLINUX_S390X_IMAGE`
- `CIBW_MANYLINUX_PYPY_AARCH64_IMAGE`
- `CIBW_MANYLINUX_PYPY_I686_IMAGE`
Set an alternative Docker image to be used for building [manylinux](https://github.com/pypa/manylinux) wheels. cibuildwheel will then pull these instead of the default images, [`quay.io/pypa/manylinux2010_x86_64`](https://quay.io/pypa/manylinux2010_x86_64), [`quay.io/pypa/manylinux2010_i686`](https://quay.io/pypa/manylinux2010_i686), [`quay.io/pypa/manylinux2010_x86_64`](https://quay.io/pypa/manylinux2010_x86_64), [`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64), [`quay.io/pypa/manylinux2014_ppc64le`](https://quay.io/pypa/manylinux2014_ppc64le), and [`quay.io/pypa/manylinux2014_s390x`](https://quay.io/pypa/manylinux2010_s390x).
Set an alternative Docker image to be used for building [manylinux](https://github.com/pypa/manylinux) wheels. cibuildwheel will then pull these instead of the default images, [`quay.io/pypa/manylinux2010_x86_64`](https://quay.io/pypa/manylinux2010_x86_64), [`quay.io/pypa/manylinux2010_i686`](https://quay.io/pypa/manylinux2010_i686), [`pypywheels/manylinux2010-pypy_x86_64`](https://hub.docker.com/r/pypywheels/manylinux2010-pypy_x86_64), [`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64), [`quay.io/pypa/manylinux2014_ppc64le`](https://quay.io/pypa/manylinux2014_ppc64le), and [`quay.io/pypa/manylinux2014_s390x`](https://quay.io/pypa/manylinux2010_s390x).
The value of this option can either be set to `manylinux1`, `manylinux2010`, `manylinux2014` or `manylinux_2_24` 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
The value of this option can either be set to `manylinux1`, `manylinux2010`, `manylinux2014` or `manylinux_2_24` to use a pinned version of the [official manylinux images](https://github.com/pypa/manylinux) and [PyPy manylinux images](https://github.com/pypy/manylinux). Alternatively, set these options to any other valid Docker image name. For PyPy, only the official `manylinux2010` image is currently available. For architectures other
than x86 (x86\_64 and i686) `manylinux2014` or `manylinux_2_24` must be used, because the first version of the manylinux specification that supports additional architectures is `manylinux2014`.
Note that `manylinux2014`/`manylinux_2_24` don't support builds with Python 2.7 - when building with `manylinux2014`/`manylinux_2_24`, skip Python 2.7 using `CIBW_SKIP` (see example below).
If setting a custom Docker image, you'll need to make sure it can be used in the same way as the official, default Docker 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 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/) and [PEP 600](https://www.python.org/dev/peps/pep-0600/) for more details).
@@ -529,15 +508,12 @@ CIBW_SKIP: pp*
# build using the manylinux2014 image
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_I686_IMAGE: manylinux2014
CIBW_MANYLINUX_PYPY_X86_64_IMAGE: manylinux2014
CIBW_MANYLINUX_PYPY_I686_IMAGE: manylinux2014
CIBW_SKIP: cp27-manylinux*
# build using the latest manylinux2010 release, instead of the cibuildwheel
# pinned version
CIBW_MANYLINUX_X86_64_IMAGE: quay.io/pypa/manylinux2010_x86_64:latest
CIBW_MANYLINUX_I686_IMAGE: quay.io/pypa/manylinux2010_i686:latest
CIBW_MANYLINUX_PYPY_X86_64_IMAGE: quay.io/pypa/manylinux2010_x86_64:latest
CIBW_MANYLINUX_PYPY_I686_IMAGE: quay.io/pypa/manylinux2010_i686:latest
# build using a different image from the docker registry
CIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64
@@ -569,7 +545,7 @@ here and it will be used instead.
If you need different dependencies for each python version, provide them
in the same folder with a `-pythonXY` suffix. e.g. if your
`CIBW_DEPENDENCY_VERSIONS=./constraints.txt`, cibuildwheel will use
`./constraints-python37.txt` on Python 3.7, or fallback to
`./constraints-python27.txt` on Python 2.7, or fallback to
`./constraints.txt` if that's not found.
Platform-specific variants also available:<br/>
@@ -741,7 +717,6 @@ CIBW_BUILD_VERBOSITY: 1
usage: cibuildwheel [-h] [--platform {auto,linux,macos,windows}]
[--archs ARCHS] [--output-dir OUTPUT_DIR]
[--print-build-identifiers] [--allow-empty]
[--prerelease-pythons]
[package_dir]
Build wheels for all the platforms.
@@ -768,8 +743,8 @@ optional arguments:
natively supported on this machine. Set this option to
build an architecture via emulation, for example,
using binfmt_misc and QEMU. Default: auto. Choices:
auto, auto64, auto32, native, all, x86_64, i686,
aarch64, ppc64le, s390x, universal2, arm64, x86, AMD64
auto, native, all, x86_64, i686, aarch64, ppc64le,
s390x, x86, AMD64
--output-dir OUTPUT_DIR
Destination folder for the wheels.
--print-build-identifiers
@@ -777,7 +752,6 @@ optional arguments:
invocation and exit.
--allow-empty Do not report an error code if the build does not
match any wheels.
--prerelease-pythons Enable pre-release Python versions if available.
```
<style>
+11 -6
View File
@@ -46,7 +46,7 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
- uses: actions/checkout@v2
- name: Build wheels
run: pipx run cibuildwheel==2.0.0a1
run: pipx run cibuildwheel==1.12.0
- uses: actions/upload-artifact@v2
with:
@@ -81,7 +81,7 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
- uses: actions/setup-python@v2
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.0.0a1
run: python -m pip install cibuildwheel==1.12.0
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
@@ -96,7 +96,7 @@ Commit this file, and push to GitHub - either to your default branch, or to a PR
For more info on this file, check out the [docs](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions).
[`examples/github-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
[`examples/github-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/master/examples/github-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
# Azure Pipelines [linux/mac/windows] {: #azure-pipelines}
@@ -109,13 +109,16 @@ To build Linux, Mac, and Windows wheels on Azure Pipelines, create a `azure-pipe
{% include "../examples/azure-pipelines-minimal.yml" %}
```
!!! note
To support Python 3.5 on Windows, make sure to specify the use of `{vmImage: 'vs2017-win2016'}` on Windows, to ensure the required toolchain is available.
Commit this file, enable building of your repo on Azure Pipelines, and push.
Wheels will be stored for you and available through the Pipelines interface. For more info on this file, check out the [docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema).
# Travis CI [linux/windows] {: #travis-ci}
# Travis CI [linux/mac/windows] {: #travis-ci}
To build Linux and Windows wheels on Travis CI, create a `.travis.yml` file in your repo.
To build Linux, Mac, and Windows wheels on Travis CI, create a `.travis.yml` file in your repo.
> .travis.yml
@@ -123,11 +126,13 @@ To build Linux and Windows wheels on Travis CI, create a `.travis.yml` file in y
{% include "../examples/travis-ci-minimal.yml" %}
```
Note that building Windows Python 2.7 wheels on Travis is unsupported unless using a newer compiler [via a workaround](cpp_standards.md).
Commit this file, enable building of your repo on Travis CI, and push.
Then setup a deployment method by following the [Travis CI deployment docs](https://docs.travis-ci.com/user/deployment/), or see [Delivering to PyPI](deliver-to-pypi.md). For more info on `.travis.yml`, check out the [docs](https://docs.travis-ci.com/).
[`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/main/examples/travis-ci-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
[`examples/travis-ci-deploy.yml`](https://github.com/pypa/cibuildwheel/blob/master/examples/travis-ci-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
# AppVeyor [linux/mac/windows] {: #appveyor}
+1 -1
View File
@@ -12,7 +12,7 @@ stack: python 3.7
init:
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
install: python -m pip install cibuildwheel==2.0.0a1
install: python -m pip install cibuildwheel==1.12.0
build_script: python -m cibuildwheel --output-dir wheelhouse
+3 -3
View File
@@ -6,7 +6,7 @@ jobs:
- bash: |
set -o errexit
python3 -m pip install --upgrade pip
pip3 install cibuildwheel==2.0.0a1
pip3 install cibuildwheel==1.12.0
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
@@ -20,7 +20,7 @@ jobs:
- bash: |
set -o errexit
python3 -m pip install --upgrade pip
python3 -m pip install cibuildwheel==2.0.0a1
python3 -m pip install cibuildwheel==1.12.0
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
@@ -34,7 +34,7 @@ jobs:
- bash: |
set -o errexit
python -m pip install --upgrade pip
pip install cibuildwheel==2.0.0a1
pip install cibuildwheel==1.12.0
displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels
+2 -2
View File
@@ -11,7 +11,7 @@ jobs:
- run:
name: Build the Linux wheels.
command: |
pip3 install --user cibuildwheel==2.0.0a1
pip3 install --user cibuildwheel==1.12.0
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
@@ -25,7 +25,7 @@ jobs:
- run:
name: Build the OS X wheels.
command: |
pip3 install cibuildwheel==2.0.0a1
pip3 install cibuildwheel==1.12.0
cibuildwheel --output-dir wheelhouse
- store_artifacts:
path: wheelhouse/
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
- uses: actions/checkout@v2
- name: Build wheels
uses: pypa/cibuildwheel@v2.0.0a1
uses: pypa/cibuildwheel@v1.12.0
env:
CIBW_ARCHS_MACOS: x86_64 universal2
+2 -2
View File
@@ -27,7 +27,7 @@ jobs:
python-version: '3.8'
- name: Build wheels
uses: pypa/cibuildwheel@v2.0.0a1
uses: pypa/cibuildwheel@v1.12.0
- uses: actions/upload-artifact@v2
with:
@@ -64,7 +64,7 @@ jobs:
name: artifact
path: dist
- uses: pypa/gh-action-pypi-publish@v1.4.2
- uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_password }}
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v2
- name: Build wheels
uses: pypa/cibuildwheel@v2.0.0a1
uses: pypa/cibuildwheel@v1.12.0
# to supply options, put them in 'env', like:
# env:
# CIBW_SOME_OPTION: value
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
platforms: all
- name: Build wheels
uses: pypa/cibuildwheel@v2.0.0a1
uses: pypa/cibuildwheel@v1.12.0
env:
# configure cibuildwheel to build native archs ('auto'), and some
# emulated ones
+1 -1
View File
@@ -12,7 +12,7 @@ linux:
DOCKER_TLS_CERTDIR: ""
script:
- curl -sSL https://get.docker.com/ | sh
- python -m pip install cibuildwheel==2.0.0a1
- python -m pip install cibuildwheel==1.12.0
- cibuildwheel --output-dir wheelhouse
artifacts:
paths:
+4 -1
View File
@@ -9,6 +9,9 @@ jobs:
include:
# perform a linux build
- services: docker
# and a mac build
- os: osx
language: shell
# and a windows build
- os: windows
language: shell
@@ -19,7 +22,7 @@ jobs:
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
install:
- python3 -m pip install cibuildwheel==2.0.0a1
- python3 -m pip install cibuildwheel==1.12.0
script:
# build the wheels, put them into './wheelhouse'
+4 -1
View File
@@ -15,6 +15,9 @@ jobs:
# perform a linux S390X build
- services: docker
arch: s390x
# and a mac build
- os: osx
language: shell
# and a windows build
- os: windows
language: shell
@@ -25,7 +28,7 @@ jobs:
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
install:
- python3 -m pip install cibuildwheel==2.0.0a1
- python3 -m pip install cibuildwheel==1.12.0
script:
# build the wheels, put them into './wheelhouse'
+13 -3
View File
@@ -1,7 +1,7 @@
# In this configuration, the package is tested against multiple versions of python
# on Linux and on one version of Python on Windows. If and only if all tests pass
# will the wheels be built and deployed. Further, deployment is only initiated if
# the current branch is "main", the current commit is tagged, and the current
# the current branch is "master", the current commit is tagged, and the current
# repo is yours (e.g. it won't run on a Pull Request). For convenience, a source
# distribution is also created.
@@ -57,7 +57,17 @@ jobs:
- stage: deploy
name: Build and deploy Linux wheels
services: docker
install: python3 -m pip install cibuildwheel==2.0.0a1
install: python3 -m pip install cibuildwheel==1.12.0
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
python3 -m twine upload --skip-existing wheelhouse/*.whl
# Deploy on mac
- stage: deploy
name: Build and deploy macOS wheels
os: osx
language: shell
install: python3 -m pip install cibuildwheel==1.12.0
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
@@ -67,7 +77,7 @@ jobs:
name: Build and deploy Windows wheels
os: windows
language: shell
install: python3 -m pip install cibuildwheel==2.0.0a1
install: python3 -m pip install cibuildwheel==1.12.0
script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: |
python3 -m pip install twine
-96
View File
@@ -1,96 +0,0 @@
import shutil
import sys
from pathlib import Path
import nox
nox.options.sessions = ["lint", "tests"]
PYTHON_ALL_VERSIONS = ["3.6", "3.7", "3.8", "3.9"]
DIR = Path(__file__).parent.resolve()
@nox.session
def tests(session):
"""
Run the unit and regular tests.
"""
unit_test_args = ["--run-docker"] if sys.platform.startswith("linux") else []
session.install("-e", ".[test]")
if session.posargs:
session.run("pytest", *session.posargs)
else:
session.run("pytest", "unit_test", *unit_test_args)
session.run("pytest", "test", "-x", "--durations", "0", "--timeout=2400", "test")
@nox.session
def lint(session):
"""
Run the linter.
"""
session.install("pre-commit")
session.run("pre-commit", "run", "--all-files")
@nox.session(python=PYTHON_ALL_VERSIONS)
def update_constraints(session):
"""
Update the dependencies inplace.
"""
session.install("requests", "pip-tools")
session.run("python", "bin/update_dependencies.py")
@nox.session
def update_pins(session):
"""
Update the python and docker pins version inplace.
"""
session.install("-e", ".[dev]")
session.run("python", "bin/update_pythons.py", "--force")
session.run("python", "bin/update_docker.py")
@nox.session
def update_proj(session):
"""
Update the README inplace.
"""
session.install("-e", ".[dev]")
session.run("./bin/projects.py", "docs/data/projects.yml", "--readme=README.md")
@nox.session
def docs(session):
"""
Build the docs.
"""
session.install("-e", ".[docs]")
if session.posargs:
if "serve" in session.posargs:
session.run("mkdocs", "serve")
else:
print("Unrecognized args, use 'serve'")
else:
session.run("mkdocs", "build")
@nox.session
def build(session):
"""
Build an SDist and wheel.
"""
build_p = DIR.joinpath("build")
if build_p.exists():
shutil.rmtree(build_p)
dist_p = DIR.joinpath("dist")
if dist_p.exists():
shutil.rmtree(dist_p)
session.install("build")
session.run("python", "-m", "build")
+1 -1
View File
@@ -1,6 +1,6 @@
[metadata]
name = cibuildwheel
version = 2.0.0a1
version = 1.12.0
description = Build Python wheels on CI with minimal configuration.
long_description = file: README.md
long_description_content_type = text/markdown
+13 -4
View File
@@ -1,3 +1,4 @@
import platform
import textwrap
import pytest
@@ -52,8 +53,16 @@ def test_build_identifiers(tmp_path):
# check that the number of expected wheels matches the number of build
# identifiers
expected_wheels = utils.expected_wheels("spam", "0.1.0")
build_identifiers = utils.cibuildwheel_get_build_identifiers(
project_dir, prerelease_pythons=True
)
# after adding CIBW_MANYLINUX_IMAGE to support manylinux2010, there
# can be multiple wheels for each wheel, though, so we need to limit
# the expected wheels
if platform.machine() in ["x86_64", "i686"]:
expected_wheels = [
w
for w in utils.expected_wheels("spam", "0.1.0")
if "-manylinux" not in w or "-manylinux1" in w
]
else:
expected_wheels = utils.expected_wheels("spam", "0.1.0")
build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir)
assert len(expected_wheels) == len(build_identifiers)
+3 -3
View File
@@ -49,11 +49,11 @@ def test(tmp_path):
# checked in setup.py
"CIBW_BEFORE_TEST": """python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonprefix.txt', 'w').write(sys.prefix)" && python -m pip install {project}/dependency""",
"CIBW_BEFORE_TEST_WINDOWS": """python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonprefix.txt', 'w').write(sys.prefix)" && python -m pip install {project}/dependency""",
"CIBW_TEST_REQUIRES": "pytest",
"CIBW_TEST_REQUIRES": "nose",
# the 'false ||' bit is to ensure this command runs in a shell on
# mac/linux.
"CIBW_TEST_COMMAND": "false || pytest {project}/test",
"CIBW_TEST_COMMAND_WINDOWS": "pytest {project}/test",
"CIBW_TEST_COMMAND": "false || nosetests {project}/test",
"CIBW_TEST_COMMAND_WINDOWS": "nosetests {project}/test",
},
)
+6 -6
View File
@@ -5,11 +5,11 @@ from . import test_projects, utils
project_with_skip_asserts = test_projects.new_c_project(
setup_py_add=textwrap.dedent(
r"""
# explode if run on PyPyor Python 3.7 (these should be skipped)
if sys.implementation.name != "cpython":
raise Exception("Only CPython shall be built")
# explode if run on Python 2.7 or Python 3.7 (these should be skipped)
if sys.version_info[0:2] == (2, 7):
raise Exception("Python 2.7 should not be built")
if sys.version_info[0:2] == (3, 7):
raise Exception("CPython 3.7 should be skipped")
raise Exception("Python 3.7 should be skipped")
"""
)
)
@@ -23,12 +23,12 @@ def test(tmp_path):
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env={
"CIBW_BUILD": "cp3*-*",
"CIBW_BUILD": "cp3?-*",
"CIBW_SKIP": "cp37-*",
},
)
# check that we got the right wheels. There should be no PyPy or 3.7.
# check that we got the right wheels. There should be no 2.7 or 3.7.
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if ("-cp3" in w) and ("-cp37" not in w)
]
+105 -14
View File
@@ -36,18 +36,38 @@ spam_system(PyObject *self, PyObject *args)
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
PyMODINIT_FUNC PyInit_spam(void)
MOD_INIT(spam)
{
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT, "spam", "Example module", -1, module_methods,
};
return PyModule_Create(&moduledef);
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
"""
@@ -67,8 +87,15 @@ def test_cpp11(tmp_path):
cpp11_project.generate(project_dir)
actual_wheels = utils.cibuildwheel_run(project_dir)
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0")]
# VC++ for Python 2.7 does not support modern standards
add_env = {"CIBW_SKIP": "cp27-win* pp27-win32"}
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [
w
for w in utils.expected_wheels("spam", "0.1.0")
if "cp27-cp27m-win" not in w and "pp27-pypy_73-win32" not in w
]
assert set(actual_wheels) == set(expected_wheels)
@@ -86,17 +113,27 @@ def test_cpp14(tmp_path):
cpp14_project.generate(project_dir)
actual_wheels = utils.cibuildwheel_run(project_dir)
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0")]
# VC++ for Python 2.7 does not support modern standards
# The manylinux1 docker image does not have a compiler which supports C++11
add_env = {"CIBW_SKIP": "cp27-win* pp27-win32"}
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
expected_wheels = [
w
for w in utils.expected_wheels("spam", "0.1.0")
if "cp27-cp27m-win" not in w and "pp27-pypy_73-win32" not in w
]
assert set(actual_wheels) == set(expected_wheels)
cpp17_project = cpp_test_project.copy()
cpp17_project.template_context["extra_compile_args"] = [
"/std:c++17" if utils.platform == "windows" else "-std=c++17"
]
# Python and PyPy 2.7 headers use the `register` keyword, which is forbidden in
# the C++17 standard, so we need the -Wno-register or /wd5033 options
cpp17_project.template_context["extra_compile_args"] = (
["/std:c++17", "/wd5033"] if utils.platform == "windows" else ["-std=c++17", "-Wno-register"]
)
cpp17_project.template_context[
"spam_cpp_top_level_add"
] = r"""
@@ -116,7 +153,7 @@ def test_cpp17(tmp_path):
# Pypy's distutils sets the default compiler to 'msvc9compiler', which
# is too old to support cpp17.
add_env = {"CIBW_SKIP": "pp??-*"}
add_env = {"CIBW_SKIP": "cp27-win* pp??-*"}
if utils.platform == "macos":
add_env["MACOSX_DEPLOYMENT_TARGET"] = "10.13"
@@ -125,7 +162,61 @@ def test_cpp17(tmp_path):
expected_wheels = [
w
for w in utils.expected_wheels("spam", "0.1.0", macosx_deployment_target="10.13")
if "-pp" not in w
if "cp27-cp27m-win" not in w and "-pp" not in w
]
assert set(actual_wheels) == set(expected_wheels)
def test_cpp17_py27_modern_msvc_workaround(tmp_path):
# This test checks the workaround for building Python 2.7 wheel with MSVC 14
if utils.platform != "windows":
pytest.skip("the test is only relevant to the Windows build")
if os.environ.get("APPVEYOR_BUILD_WORKER_IMAGE", "") == "Visual Studio 2015":
pytest.skip("Visual Studio 2015 does not support C++17")
project_dir = tmp_path / "project"
cpp17_project.generate(project_dir)
# VC++ for Python 2.7 (i.e., MSVC 9) does not support modern standards
# This is a workaround which forces distutils/setupstools to a newer version
# Wheels compiled need a more modern C++ redistributable installed, which is not
# included with Python: see documentation for more info
# DISTUTILS_USE_SDK and MSSdk=1 tell distutils/setuptools that we are adding
# MSVC's compiler, tools, and libraries to PATH ourselves
add_env = {"DISTUTILS_USE_SDK": "1", "MSSdk": "1"}
# Use existing setuptools code to run Visual Studio's vcvarsall.bat and get the
# necessary environment variables, since running vcvarsall.bat in a subprocess
# does not keep the relevant environment variables
# There are different environment variables for 32-bit/64-bit targets, so we
# need to run cibuildwheel twice, once for 32-bit with `vcvarsall.bat x86, and
# once for 64-bit with `vcvarsall.bat x64`
# In a normal CI setup, just run vcvarsall.bat before running cibuildwheel and set
# DISTUTILS_USE_SDK and MSSdk
import setuptools
def add_vcvars(prev_env, platform):
vcvarsall_env = setuptools.msvc.msvc14_get_vc_env(platform)
env = prev_env.copy()
for vcvar in ["path", "include", "lib"]:
env[vcvar] = vcvarsall_env[vcvar]
return env
add_env_x86 = add_vcvars(add_env, "x86")
add_env_x86["CIBW_BUILD"] = "?p27-win32"
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env_x86)
add_env_x64 = add_vcvars(add_env, "x64")
add_env_x64["CIBW_BUILD"] = "cp27-win_amd64"
actual_wheels += utils.cibuildwheel_run(project_dir, add_env=add_env_x64)
expected_wheels = [
w
for w in utils.expected_wheels("spam", "0.1.0", exclude_27=False)
if "cp27-cp27m-win" in w or "pp27-pypy_73-win32" in w
]
assert set(actual_wheels) == set(expected_wheels)
+43 -14
View File
@@ -47,28 +47,39 @@ def get_versions_from_constraint_file(constraint_file):
}
@pytest.mark.parametrize("python_version", ["3.6", "3.8", "3.9"])
@pytest.mark.parametrize("python_version", ["2.7", "3.5", "3.6", "3.8"])
def test_pinned_versions(tmp_path, python_version):
if utils.platform == "linux":
pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead")
if utils.platform == "windows" and python_version == "2.7":
pytest.skip("Windows requires a workaround")
is_macos_11_or_later = utils.platform == "macos" and utils.get_macos_version() >= (10, 16)
if is_macos_11_or_later and python_version == "3.5":
pytest.skip("CPython 3.5 doesn't work on macOS Big Sur+")
project_dir = tmp_path / "project"
project_with_expected_version_checks.generate(project_dir)
build_environment = {}
if python_version == "3.6":
if python_version == "2.7":
constraint_filename = "constraints-python27.txt"
build_pattern = "[cp]p27-*"
elif python_version == "3.5":
constraint_filename = "constraints-python35.txt"
build_pattern = "[cp]p35-*"
elif python_version == "3.6":
constraint_filename = "constraints-python36.txt"
build_pattern = "[cp]p36-*"
elif python_version == "3.7":
constraint_filename = "constraints-python37.txt"
build_pattern = "[cp]p37-*"
elif python_version == "3.8":
constraint_filename = "constraints-python38.txt"
build_pattern = "[cp]p38-*"
else:
constraint_filename = "constraints.txt"
build_pattern = "[cp]p39-*"
build_pattern = "[cp]p38-*"
constraint_file = cibuildwheel.util.resources_dir / constraint_filename
constraint_versions = get_versions_from_constraint_file(constraint_file)
@@ -89,7 +100,15 @@ def test_pinned_versions(tmp_path, python_version):
)
# also check that we got the right wheels
if python_version == "3.6":
if python_version == "2.7":
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp27" in w or "-pp27" in w
]
elif python_version == "3.5":
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp35" in w or "-pp35" in w
]
elif python_version == "3.6":
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp36" in w or "-pp36" in w
]
@@ -97,26 +116,26 @@ def test_pinned_versions(tmp_path, python_version):
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp38" in w or "-pp38" in w
]
elif python_version == "3.9":
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp39" in w or "-pp39" in w
]
else:
raise ValueError("unhandled python version")
assert set(actual_wheels) == set(expected_wheels)
def test_dependency_constraints_file(tmp_path):
@pytest.mark.parametrize("python_version", ["2.7", "3.x"])
def test_dependency_constraints_file(tmp_path, python_version):
if utils.platform == "linux":
pytest.skip("linux doesn't pin individual tool versions, it pins manylinux images instead")
if utils.platform == "windows" and python_version == "2.7":
pytest.skip("Windows + Travis CI requires a workaround")
project_dir = tmp_path / "project"
project_with_expected_version_checks.generate(project_dir)
tool_versions = {
"pip": "20.0.2",
"setuptools": "53.0.0",
"setuptools": "44.0.0" if python_version == "2.7" else "46.0.0",
"wheel": "0.34.2",
"virtualenv": "20.0.10",
}
@@ -147,12 +166,22 @@ def test_dependency_constraints_file(tmp_path):
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env={
"CIBW_BUILD": "[cp]p27-*" if python_version == "2.7" else "[cp]p3?-*",
"CIBW_ENVIRONMENT": cibw_environment_option,
"CIBW_DEPENDENCY_VERSIONS": str(constraints_file),
},
)
# also check that we got the right wheels
expected_wheels = utils.expected_wheels("spam", "0.1.0")
if python_version == "2.7":
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0") if "-cp27" in w or "-pp27" in w
]
else:
expected_wheels = [
w
for w in utils.expected_wheels("spam", "0.1.0")
if "-cp27" not in w and "-pp27" not in w
]
assert set(actual_wheels) == set(expected_wheels)
+5 -9
View File
@@ -35,20 +35,16 @@ def test(tmp_path):
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env={
"CIBW_MANYLINUX_X86_64_IMAGE": "dockcross/manylinux2010-x64",
"CIBW_MANYLINUX_I686_IMAGE": "dockcross/manylinux2010-x86",
"CIBW_BUILD": "cp3{6,7,8,9}-*",
"CIBW_MANYLINUX_X86_64_IMAGE": "dockcross/manylinux2010-x64:20210210-84c47e5",
"CIBW_MANYLINUX_I686_IMAGE": "dockcross/manylinux2010-x86:20210210-84c47e5",
"CIBW_SKIP": "pp* cp27-* cp39-*",
},
)
# also check that we got the right wheels built
# there's no auditwheel 4+ on dockcross image
# remove manylinux1 wheels from the list of actual_wheels
# and restrict expected_wheels to manylinux2010 wheels
actual_wheels = [w for w in actual_wheels if "-manylinux1" not in w]
expected_wheels = [
w
for w in utils.expected_wheels("spam", "0.1.0", manylinux_versions=["manylinux2010"])
if "-cp36-" in w or "-cp37-" in w or "-cp38-" in w or "-cp39-" in w
for w in utils.expected_wheels("spam", "0.1.0")
if "-pp" not in w and "-cp39-" not in w and "-cp27-" not in w
]
assert set(actual_wheels) == set(expected_wheels)
+14 -17
View File
@@ -64,24 +64,21 @@ def test(manylinux_image, tmp_path):
"CIBW_MANYLINUX_AARCH64_IMAGE": manylinux_image,
"CIBW_MANYLINUX_PPC64LE_IMAGE": manylinux_image,
"CIBW_MANYLINUX_S390X_IMAGE": manylinux_image,
"CIBW_MANYLINUX_PYPY_AARCH64_IMAGE": manylinux_image,
"CIBW_MANYLINUX_PYPY_I686_IMAGE": manylinux_image,
}
if manylinux_image in {"manylinux1"}:
# We don't have a manylinux1 image for PyPy & CPython 3.10 and above
add_env["CIBW_SKIP"] = "pp* cp31*"
if manylinux_image == "manylinux1":
# We don't have a manylinux1 image for PyPy
add_env["CIBW_SKIP"] = "pp*"
elif manylinux_image in {"manylinux2014", "manylinux_2_24"}:
# We don't have a manylinux2014 / 'manylinux_2_24' image for PyPy (yet?)
# Python 2.7 not available on manylinux2014 / 'manylinux_2_24'
add_env["CIBW_SKIP"] = "cp27* pp*"
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
platform_tag_map = {
"manylinux1": ["manylinux_2_5", "manylinux1"],
"manylinux2010": ["manylinux_2_12", "manylinux2010"],
"manylinux2014": ["manylinux_2_17", "manylinux2014"],
}
expected_wheels = utils.expected_wheels(
"spam", "0.1.0", manylinux_versions=platform_tag_map.get(manylinux_image, [manylinux_image])
)
if manylinux_image in {"manylinux1"}:
# remove PyPy & CPython 3.10 and above
expected_wheels = [w for w in expected_wheels if "-pp" not in w and "-cp31" not in w]
expected_wheels = [
w for w in utils.expected_wheels("spam", "0.1.0", manylinux_versions=[manylinux_image])
]
if manylinux_image in {"manylinux2014", "manylinux_2_24"}:
expected_wheels = [w for w in expected_wheels if "-cp27" not in w]
if manylinux_image in {"manylinux1", "manylinux2014", "manylinux_2_24"}:
expected_wheels = [w for w in expected_wheels if "-pp" not in w]
assert set(actual_wheels) == set(expected_wheels)
+6 -2
View File
@@ -8,7 +8,10 @@ basic_project = test_projects.new_c_project(
"""
# Will fail if PEP 518 does work
import requests
assert requests.__version__ == "2.23.0", "Requests found but wrong version ({0})".format(requests.__version__)
if sys.version_info < (3, 6, 0):
assert requests.__version__ == "2.22.0", "Requests found but wrong version ({0})".format(requests.__version__)
else:
assert requests.__version__ == "2.23.0", "Requests found but wrong version ({0})".format(requests.__version__)
# Just making sure environment is still set
import os
@@ -26,7 +29,8 @@ requires = [
"setuptools >= 42",
"setuptools_scm[toml]>=4.1.2",
"wheel",
"requests==2.23.0"
"requests==2.22.0; python_version<'3.6'",
"requests==2.23.0; python_version>='3.6'"
]
build-backend = "setuptools.build_meta"
+25 -5
View File
@@ -24,18 +24,38 @@ spam_system(PyObject *self, PyObject *args)
}
/* Module initialization */
#if PY_MAJOR_VERSION >= 3
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
static struct PyModuleDef moduledef = { \
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
m = PyModule_Create(&moduledef);
#define MOD_RETURN(m) return m;
#else
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
#define MOD_DEF(m, name, doc, methods, module_state_size) \
m = Py_InitModule3(name, methods, doc);
#define MOD_RETURN(m) return;
#endif
static PyMethodDef module_methods[] = {
{"system", (PyCFunction)spam_system, METH_VARARGS,
"Execute a shell command."},
{NULL} /* Sentinel */
};
PyMODINIT_FUNC PyInit_spam(void)
MOD_INIT(spam)
{
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT, "spam", "Example module", -1, module_methods,
};
return PyModule_Create(&moduledef);
PyObject* m;
MOD_DEF(m,
"spam",
"Example module",
module_methods,
-1)
MOD_RETURN(m)
}
"""
+6 -3
View File
@@ -7,12 +7,15 @@ project_with_ssl_tests = test_projects.new_c_project(
r"""
import ssl
from urllib.request import urlopen
if sys.version_info[0] == 2:
from urllib2 import urlopen
else:
from urllib.request import urlopen
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
data = urlopen("https://www.nist.gov", context=context)
data = urlopen("https://raw.githubusercontent.com/pypa/cibuildwheel/main/CI.md", context=context)
data = urlopen("https://raw.githubusercontent.com/pypa/cibuildwheel/main/CI.md")
data = urlopen("https://raw.githubusercontent.com/pypa/cibuildwheel/master/CI.md", context=context)
data = urlopen("https://raw.githubusercontent.com/pypa/cibuildwheel/master/CI.md")
"""
)
)
+12 -7
View File
@@ -10,7 +10,7 @@ project_with_a_test = test_projects.new_c_project(
setup_cfg_add=textwrap.dedent(
r"""
[options.extras_require]
test = pytest
test = nose
"""
)
)
@@ -52,7 +52,8 @@ class TestSpam(TestCase):
# sys.prefix is different from sys.base_prefix when running a virtualenv
# See https://docs.python.org/3/library/venv.html, which virtualenv seems
# to honor in recent releases
if sys.prefix == sys.base_prefix:
# Python 2 doesn't have sys.base_prefix by default
if not hasattr(sys, 'base_prefix') or sys.prefix == sys.base_prefix:
self.fail("Not running in a virtualenv")
self.assertTrue(path_contains(sys.prefix, sys.executable))
@@ -66,6 +67,10 @@ class TestSpam(TestCase):
bits = struct.calcsize("P") * 8
if bits == 32:
self.assertEqual(platform.machine(), "i686")
def test_time_to_remove_the_pypy_venv_patch(self):
if sys.platform == "darwin":
assert not hasattr(sys, "pypy_version_info") or sys.pypy_version_info < (7,3,4)
'''
@@ -77,11 +82,11 @@ def test(tmp_path):
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env={
"CIBW_TEST_REQUIRES": "pytest",
"CIBW_TEST_REQUIRES": "nose",
# the 'false ||' bit is to ensure this command runs in a shell on
# mac/linux.
"CIBW_TEST_COMMAND": "false || pytest {project}/test",
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || pytest {project}/test",
"CIBW_TEST_COMMAND": "false || nosetests {project}/test",
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || nosetests {project}/test",
},
)
@@ -101,8 +106,8 @@ def test_extras_require(tmp_path):
"CIBW_TEST_EXTRAS": "test",
# the 'false ||' bit is to ensure this command runs in a shell on
# mac/linux.
"CIBW_TEST_COMMAND": "false || pytest {project}/test",
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || pytest {project}/test",
"CIBW_TEST_COMMAND": "false || nosetests {project}/test",
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || nosetests {project}/test",
},
)
+42 -24
View File
@@ -6,9 +6,11 @@ This file is added to the PYTHONPATH in the test runner at bin/run_test.py.
import os
import platform as pm
import shutil
import subprocess
import sys
from tempfile import TemporaryDirectory
from contextlib import contextmanager
from tempfile import mkdtemp
platform: str
@@ -24,17 +26,24 @@ else:
raise Exception("Unsupported platform")
def cibuildwheel_get_build_identifiers(project_path, env=None, *, prerelease_pythons=False):
# Python 2 does not have a tempfile.TemporaryDirectory context manager
@contextmanager
def TemporaryDirectoryIfNone(path):
_path = path or mkdtemp()
try:
yield _path
finally:
if path is None:
shutil.rmtree(_path)
def cibuildwheel_get_build_identifiers(project_path, env=None):
"""
Returns the list of build identifiers that cibuildwheel will try to build
for the current platform.
"""
cmd = [sys.executable, "-m", "cibuildwheel", "--print-build-identifiers", str(project_path)]
if prerelease_pythons:
cmd.append("--prerelease-pythons")
cmd_output = subprocess.run(
cmd,
[sys.executable, "-m", "cibuildwheel", "--print-build-identifiers", str(project_path)],
universal_newlines=True,
env=env,
check=True,
@@ -67,22 +76,21 @@ def cibuildwheel_run(project_path, package_dir=".", env=None, add_env=None, outp
if add_env is not None:
env.update(add_env)
with TemporaryDirectory() as tmp_output_dir:
with TemporaryDirectoryIfNone(output_dir) as _output_dir:
subprocess.run(
[
sys.executable,
"-m",
"cibuildwheel",
"--prerelease-pythons",
"--output-dir",
str(output_dir or tmp_output_dir),
str(_output_dir),
str(package_dir),
],
env=env,
cwd=project_path,
check=True,
)
wheels = os.listdir(output_dir or tmp_output_dir)
wheels = os.listdir(_output_dir)
return wheels
@@ -105,6 +113,8 @@ def expected_wheels(
manylinux_versions=None,
macosx_deployment_target="10.9",
machine_arch=None,
*,
exclude_27=platform == "windows",
):
"""
Returns a list of expected wheels from a run of cibuildwheel.
@@ -119,23 +129,28 @@ def expected_wheels(
if manylinux_versions is None:
if machine_arch == "x86_64":
manylinux_versions = ["manylinux_2_5", "manylinux1", "manylinux_2_12", "manylinux2010"]
manylinux_versions = ["manylinux1", "manylinux2010"]
else:
manylinux_versions = ["manylinux_2_17", "manylinux2014"]
manylinux_versions = ["manylinux2014"]
python_abi_tags = ["cp36-cp36m", "cp37-cp37m", "cp38-cp38", "cp39-cp39", "cp310-cp310"]
python_abi_tags = ["cp35-cp35m", "cp36-cp36m", "cp37-cp37m", "cp38-cp38", "cp39-cp39"]
if machine_arch in ["x86_64", "AMD64", "x86", "aarch64"]:
python_abi_tags += ["pp37-pypy37_pp73"]
if machine_arch in ["x86_64", "AMD64", "x86"]:
python_abi_tags += ["cp27-cp27m", "pp27-pypy_73", "pp36-pypy36_pp73", "pp37-pypy37_pp73"]
if platform == "linux":
python_abi_tags.append("cp27-cp27mu") # python 2.7 has 2 different ABI on manylinux
if platform == "macos" and get_macos_version() >= (10, 16):
# 10.16 is sometimes reported as the macOS version on macOS 11.
# CPython 3.5 doesn't work on macOS 11.
python_abi_tags.remove("cp35-cp35m")
# pypy not supported on macOS 11.
python_abi_tags = [t for t in python_abi_tags if not t.startswith("pp")]
if platform == "macos" and machine_arch == "arm64":
# currently, arm64 macs are only supported by cp39 & cp310
python_abi_tags = ["cp39-cp39", "cp310-cp310"]
# currently, arm64 macs are only supported by cp39
python_abi_tags = ["cp39-cp39"]
wheels = []
@@ -145,22 +160,20 @@ def expected_wheels(
if platform == "linux":
architectures = [machine_arch]
if machine_arch == "x86_64":
if machine_arch == "x86_64" and python_abi_tag.startswith("cp"):
architectures.append("i686")
platform_tags = [
".".join(
f"{manylinux_version}_{architecture}"
for manylinux_version in manylinux_versions
)
f"{manylinux_version}_{architecture}"
for architecture in architectures
for manylinux_version in manylinux_versions
]
elif platform == "windows":
if python_abi_tag.startswith("cp"):
platform_tags = ["win32", "win_amd64"]
else:
platform_tags = ["win_amd64"]
platform_tags = ["win32"]
elif platform == "macos":
if python_abi_tag == "cp39-cp39" and machine_arch == "arm64":
@@ -182,6 +195,11 @@ def expected_wheels(
for platform_tag in platform_tags:
wheels.append(f"{package_name}-{package_version}-{python_abi_tag}-{platform_tag}.whl")
# Travis on Windows does not support using the default Python 2.7 compiler,
# so we support skipping here.
if exclude_27:
wheels = [w for w in wheels if "-cp27-" not in w and "-pp2" not in w]
return wheels
+59 -74
View File
@@ -4,85 +4,65 @@ from cibuildwheel.util import BuildSelector
def test_build():
build_selector = BuildSelector(build_config="cp3*-* *-manylinux*", skip_config="")
build_selector = BuildSelector(build_config="cp3?-* *-manylinux1*", skip_config="")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert not build_selector("cp310-manylinux_x86_64")
assert build_selector("pp36-manylinux_x86_64")
assert build_selector("pp37-manylinux_x86_64")
assert build_selector("cp36-manylinux_i686")
assert build_selector("cp37-manylinux_i686")
assert build_selector("cp36-macosx_intel")
assert build_selector("cp37-macosx_intel")
assert build_selector("cp39-macosx_intel")
assert build_selector("cp39-macosx_universal2")
assert build_selector("cp39-macosx_arm64")
assert not build_selector("pp36-macosx_intel")
assert not build_selector("pp37-macosx_intel")
assert build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert build_selector("cp27-manylinux1_i686")
assert build_selector("cp36-manylinux1_i686")
assert build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-macosx_10_6_intel")
assert build_selector("cp36-macosx_10_6_intel")
assert build_selector("cp37-macosx_10_6_intel")
assert not build_selector("cp27-win32")
assert build_selector("cp36-win32")
assert build_selector("cp37-win32")
assert not build_selector("pp36-win32")
assert not build_selector("pp37-win32")
assert not build_selector("cp27-win_amd64")
assert build_selector("cp36-win_amd64")
assert build_selector("cp37-win_amd64")
assert not build_selector("cp310-win_amd64")
assert not build_selector("pp36-win_amd64")
assert not build_selector("pp37-win_amd64")
def test_build_filter_pre():
build_selector = BuildSelector(
build_config="cp3*-* *-manylinux*",
skip_config="",
prerelease_pythons=True,
)
assert build_selector("cp37-manylinux_x86_64")
assert build_selector("cp310-manylinux_x86_64")
assert build_selector("cp37-win_amd64")
assert build_selector("cp310-win_amd64")
def test_skip():
build_selector = BuildSelector(
build_config="*", skip_config="pp36-* cp3?-manylinux_i686 cp36-win* *-win32"
build_config="*", skip_config="cp27-* cp3?-manylinux1_i686 cp36-win* *-win32"
)
assert not build_selector("pp36-manylinux_x86_64")
assert build_selector("pp37-manylinux_x86_64")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert not build_selector("cp36-manylinux_i686")
assert not build_selector("cp37-manylinux_i686")
assert not build_selector("pp36-macosx_10_6_intel")
assert build_selector("pp37-macosx_10_6_intel")
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp27-manylinux1_i686")
assert not build_selector("cp36-manylinux1_i686")
assert not build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-macosx_10_6_intel")
assert build_selector("cp36-macosx_10_6_intel")
assert build_selector("cp37-macosx_10_6_intel")
assert not build_selector("cp27-win32")
assert not build_selector("cp36-win32")
assert not build_selector("cp37-win32")
assert not build_selector("cp27-win_amd64")
assert not build_selector("cp36-win_amd64")
assert build_selector("cp37-win_amd64")
def test_build_and_skip():
build_selector = BuildSelector(
build_config="cp36-* cp37-macosx* *-manylinux*", skip_config="pp37-* cp37-manylinux_i686"
build_config="cp36-* cp37-macosx* *-manylinux1*", skip_config="cp27-* cp37-manylinux1_i686"
)
assert not build_selector("pp37-manylinux_x86_64")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert not build_selector("pp37-manylinux_i686")
assert build_selector("cp36-manylinux_i686")
assert not build_selector("cp37-manylinux_i686")
assert not build_selector("pp37-macosx_10_6_intel")
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp27-manylinux1_i686")
assert build_selector("cp36-manylinux1_i686")
assert not build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-macosx_10_6_intel")
assert build_selector("cp36-macosx_10_6_intel")
assert build_selector("cp37-macosx_10_6_intel")
assert not build_selector("pp37-win32")
assert not build_selector("cp27-win32")
assert build_selector("cp36-win32")
assert not build_selector("cp37-win32")
assert not build_selector("pp37-win_amd64")
assert not build_selector("cp27-win_amd64")
assert build_selector("cp36-win_amd64")
assert not build_selector("cp37-win_amd64")
@@ -90,44 +70,49 @@ def test_build_and_skip():
def test_build_braces():
build_selector = BuildSelector(build_config="cp{36,37}*", skip_config="")
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert not build_selector("cp38-manylinux_x86_64")
assert not build_selector("cp39-manylinux_x86_64")
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp38-manylinux1_x86_64")
assert not build_selector("cp39-manylinux1_x86_64")
def test_build_limited_python():
build_selector = BuildSelector(
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.7")
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6")
)
assert not build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert build_selector("cp38-manylinux_x86_64")
assert not build_selector("cp36-manylinux_i686")
assert build_selector("cp37-manylinux_i686")
assert build_selector("cp38-manylinux_i686")
assert not build_selector("cp36-win32")
assert not build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
assert not build_selector("cp27-manylinux1_i686")
assert build_selector("cp36-manylinux1_i686")
assert build_selector("cp37-manylinux1_i686")
assert not build_selector("cp27-win32")
assert build_selector("cp36-win32")
assert build_selector("cp37-win32")
assert build_selector("cp38-win32")
assert build_selector("pp37-win_amd64")
assert not build_selector("pp27-win32")
assert build_selector("pp36-win32")
assert build_selector("pp37-win32")
def test_build_limited_python_partial():
build_selector = BuildSelector(
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6, !=3.7.*")
build_config="*",
skip_config="",
requires_python=SpecifierSet(">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"),
)
assert build_selector("cp36-manylinux_x86_64")
assert not build_selector("cp37-manylinux_x86_64")
assert build_selector("cp38-manylinux_x86_64")
assert build_selector("cp39-manylinux_x86_64")
assert build_selector("cp27-manylinux1_x86_64")
assert not build_selector("cp35-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
def test_build_limited_python_patch():
build_selector = BuildSelector(
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.6.8")
build_config="*", skip_config="", requires_python=SpecifierSet(">=2.7.9")
)
assert build_selector("cp36-manylinux_x86_64")
assert build_selector("cp37-manylinux_x86_64")
assert build_selector("cp27-manylinux1_x86_64")
assert build_selector("cp36-manylinux1_x86_64")
assert build_selector("cp37-manylinux1_x86_64")
+6
View File
@@ -19,3 +19,9 @@ def test_defaults():
assert dependency_constraints.get_for_python_version("3.6").samefile(
resources_dir / "constraints-python36.txt"
)
assert dependency_constraints.get_for_python_version("3.5").samefile(
resources_dir / "constraints-python35.txt"
)
assert dependency_constraints.get_for_python_version("2.7").samefile(
resources_dir / "constraints-python27.txt"
)
+24 -30
View File
@@ -81,11 +81,10 @@ def test_empty_selector(platform, intercepted_build_args, monkeypatch):
("i686", "manylinux2014", "quay.io/pypa/manylinux2014_i686:*"),
("i686", "manylinux_2_24", "quay.io/pypa/manylinux_2_24_i686:*"),
("i686", "custom_image", "custom_image"),
("pypy_x86_64", None, "quay.io/pypa/manylinux2010_x86_64:*"),
("pypy_x86_64", None, "pypywheels/manylinux2010-pypy_x86_64:*"),
("pypy_x86_64", "manylinux1", "manylinux1"), # Does not exist
("pypy_x86_64", "manylinux2010", "quay.io/pypa/manylinux2010_x86_64:*"),
("pypy_x86_64", "manylinux2014", "quay.io/pypa/manylinux2014_x86_64:*"),
("pypy_x86_64", "manylinux_2_24", "quay.io/pypa/manylinux_2_24_x86_64:*"),
("pypy_x86_64", "manylinux2010", "pypywheels/manylinux2010-pypy_x86_64:*"),
("pypy_x86_64", "manylinux2014", "manylinux2014"), # Does not exist (yet)
("pypy_x86_64", "custom_image", "custom_image"),
],
)
@@ -238,40 +237,35 @@ def test_build_verbosity(
assert intercepted_build_args.args[0].build_verbosity == expected_verbosity
@pytest.mark.parametrize("option_name", ["CIBW_BUILD", "CIBW_SKIP"])
@pytest.mark.parametrize(
"selector",
"option_value, build_selector_patterns",
[
"CIBW_BUILD",
"CIBW_SKIP",
"CIBW_TEST_SKIP",
("*-manylinux1_*", ["*-manylinux_*"]),
("*-macosx_10_6_intel", ["*-macosx_x86_64"]),
("*-macosx_10_9_x86_64", ["*-macosx_x86_64"]),
("cp37-macosx_10_9_x86_64", ["cp37-macosx_x86_64"]),
],
)
@pytest.mark.parametrize(
"pattern",
[
"cp27-*",
"cp35-*",
"?p27*",
"?p2*",
"?p35*",
],
)
def test_build_selector_deprecated_error(
monkeypatch, platform, intercepted_build_args, selector, pattern, allow_empty, capsys
def test_build_selector_migrations(
intercepted_build_args,
monkeypatch,
option_name,
option_value,
build_selector_patterns,
allow_empty,
):
monkeypatch.setenv(selector, pattern)
monkeypatch.setenv(option_name, option_value)
if selector == "CIBW_BUILD":
with pytest.raises(SystemExit) as ex:
main()
assert ex.value.code == 4
main()
intercepted_build_selector = intercepted_build_args.args[0].build_selector
assert isinstance(intercepted_build_selector, BuildSelector)
if option_name == "CIBW_BUILD":
assert intercepted_build_selector.build_patterns == build_selector_patterns
else:
main()
stderr = capsys.readouterr().err
msg = f"cibuildwheel 2.x no longer supports Python < 3.6. Please use the 1.x series or update {selector}"
assert msg in stderr
assert intercepted_build_selector.skip_patterns == build_selector_patterns
@pytest.mark.parametrize("before_all", ["", None, "test text"])