diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2ae8ce95..ae21a5a8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,6 +21,7 @@ jobs: test: name: Test cibuildwheel on ${{ matrix.os }} + needs: pre-commit runs-on: ${{ matrix.os }} strategy: matrix: @@ -38,11 +39,6 @@ jobs: run: | python -m pip install -e ".[dev]" - - name: Install Visual C++ for Python 2.7 - if: runner.os == 'Windows' - run: | - choco install vcpython27 -f -y - - name: Get PR labels id: pr-labels uses: joerick/pr-labels-action@v1.0.6 @@ -70,6 +66,7 @@ jobs: test-emulated: name: Test emulated cibuildwheel using qemu + needs: pre-commit runs-on: ubuntu-latest timeout-minutes: 180 steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d7fdd5fe..bd1b6e9d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,22 +6,30 @@ repos: - id: check-case-conflict - id: check-merge-conflict - id: check-yaml + - id: check-toml + - id: debug-statements - id: end-of-file-fixer exclude: (cibuildwheel/resources/pinned_docker_images.cfg)|(.svg$) - id: mixed-line-ending - id: trailing-whitespace - repo: https://github.com/PyCQA/isort - rev: 5.7.0 + rev: 5.8.0 hooks: - id: isort - repo: https://github.com/psf/black - rev: 20.8b1 + rev: 21.4b1 hooks: - id: black files: ^bin/update_pythons.py|setup.py$ +- repo: https://github.com/asottile/setup-cfg-fmt + rev: v1.17.0 + hooks: + - id: setup-cfg-fmt + stages: [manual] + - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.812 hooks: @@ -36,20 +44,24 @@ repos: args: ["--python-version=3.7", "--ignore-missing-imports", "--scripts-are-modules"] - repo: https://github.com/asottile/pyupgrade - rev: v2.10.0 + rev: v2.13.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://gitlab.com/pycqa/flake8 - rev: 3.8.4 +- repo: https://github.com/PyCQA/flake8 + rev: 3.9.1 hooks: - id: flake8 exclude: cibuildwheel/resources/ additional_dependencies: [flake8-bugbear] - -# The original pybind11 checks for a few C++ style items - repo: local hooks: - id: disallow-caps diff --git a/.travis.yml b/.travis.yml index 1a866ea1..bd89e869 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,9 +36,9 @@ jobs: os: windows language: shell before_install: - - choco install python3 --version 3.6.8 --no-progress -y - # Update root certificates to fix SSL error; see http://www.chawn.com/RootCerts.htm - - powershell "md C:\temp\certs; CertUtil -generateSSTFromWU C:\temp\certs\RootStore.sst; Get-ChildItem -Path C:\\temp\certs\Rootstore.sst | Import-Certificate -CertStoreLocation Cert:\\LocalMachine\\Root\\ | out-null" + - choco upgrade python3 -y --version 3.6.8 --limit-output + # Update root certificates to fix SSL error; see http://www.chawn.com/RootCerts.htm + - powershell "md C:\temp\certs; CertUtil -generateSSTFromWU C:\temp\certs\RootStore.sst; Get-ChildItem -Path C:\\temp\certs\Rootstore.sst | Import-Certificate -CertStoreLocation Cert:\\LocalMachine\\Root\\ | out-null" env: - PYTHON=C:\\Python36\\python diff --git a/README.md b/README.md index 233c2855..2aa5915e 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ What does it do? | PyPy 3.6 v7.3.3 | ✅ | | | ✅ | ✅ | | | | | | PyPy 3.7 (beta) v7.3.3 | ✅ | | | ✅ | ✅ | | | | | -¹ Not supported on Travis
+¹ Only using a workaround with a newer compiler; Microsoft removed the 2008 compiler for Python 2.7 in April 2021.
- 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 @@ -161,15 +161,18 @@ Here are some repos that use cibuildwheel. | [Parselmouth][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. | | [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson | | [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS ¶ | +| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library | +| [markupsafe][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Safely add untrusted strings to HTML/XML markup. | | [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python | | [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing | | [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system | | [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system | +| [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Compute and compare MinHash signatures for DNA data sets. | | [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub | | [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 | | [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq | -| [matrixprofile][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python 3 library making time series data mining tasks, utilizing matrix profile algorithms, accessible to everyone. | | [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. | +| [matrixprofile][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python 3 library making time series data mining tasks, utilizing matrix profile algorithms, accessible to everyone. | | [CTranslate2][] | ![github icon][] | ![apple icon][] ![linux icon][] | Includes libraries from the [Intel oneAPI toolkit](https://software.intel.com/content/www/us/en/develop/tools/oneapi/base-toolkit.html). The Linux wheels also include CUDA libraries for GPU execution. | | [Tokenizer][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] | Fast and customizable text tokenization library with BPE and SentencePiece support | | [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. | @@ -182,6 +185,7 @@ Here are some repos that use cibuildwheel. | [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms | | [Imagecodecs (fork)][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] | Over 20 external dependencies in compiled libraries, custom docker image, `libomp`, `openblas` and `install_name_tool` for macOS. | | [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies | +| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. | | [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. | | [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 | @@ -209,15 +213,18 @@ Here are some repos that use cibuildwheel. [Parselmouth]: https://github.com/YannickJadoul/Parselmouth [python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson [Rtree]: https://github.com/Toblerity/rtree +[python-snappy]: https://github.com/andrix/python-snappy +[markupsafe]: https://github.com/pallets/markupsafe [KDEpy]: https://github.com/tommyod/KDEpy [cyvcf2]: https://github.com/brentp/cyvcf2 [pybind11 cmake_example]: https://github.com/pybind/cmake_example [pybind11 python_example]: https://github.com/pybind/python_example +[sourmash]: https://github.com/dib-lab/sourmash [dd-trace-py]: https://github.com/DataDog/dd-trace-py [iminuit]: https://github.com/scikit-hep/iminuit [jq.py]: https://github.com/mwilliamson/jq.py -[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile [time-machine]: https://github.com/adamchainz/time-machine +[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile [CTranslate2]: https://github.com/OpenNMT/CTranslate2 [Tokenizer]: https://github.com/OpenNMT/Tokenizer [bx-python]: https://github.com/bxlab/bx-python @@ -230,6 +237,7 @@ Here are some repos that use cibuildwheel. [fathon]: https://github.com/stfbnc/fathon [Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build [pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext +[polaroid]: https://github.com/daggy1234/polaroid [xmlstarlet]: https://github.com/dimitern/xmlstarlet [pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example @@ -243,53 +251,57 @@ Here are some repos that use cibuildwheel. [apple icon]: docs/data/readme_icons/apple.svg [linux icon]: docs/data/readme_icons/linux.svg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b144c2db..fd6b1d5e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -26,8 +26,6 @@ jobs: - task: UsePythonVersion@0 inputs: versionSpec: '3.6' - - script: choco install vcpython27 -f -y - displayName: Install Visual C++ for Python 2.7 - bash: | python -m pip install -e ".[dev]" pytest-azurepipelines python ./bin/run_tests.py @@ -39,8 +37,6 @@ jobs: - task: UsePythonVersion@0 inputs: versionSpec: '3.8' - - script: choco install vcpython27 -f -y - displayName: Install Visual C++ for Python 2.7 - bash: | python -m pip install -e ".[dev]" pytest-azurepipelines python ./bin/run_tests.py diff --git a/bin/bump_version.py b/bin/bump_version.py index 149c3a84..6f8212fc 100755 --- a/bin/bump_version.py +++ b/bin/bump_version.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 +from __future__ import annotations + import glob import os import subprocess @@ -25,24 +27,26 @@ config = [ ('setup.cfg', "version = {}"), ] +RED = "\u001b[31m" +GREEN = "\u001b[32m" +OFF = "\u001b[0m" + -# This file requires Python 3.7 -# Setting -> None will cause MyPy to notice this. @click.command() -def bump_version(): +def bump_version() -> None: current_version = cibuildwheel.__version__ try: commit_date_str = subprocess.run([ 'git', - 'show', '-s', '--pretty=format:%ci', - f'v{current_version}^{{commit}}' + 'show', '--no-patch', '--pretty=format:%ci', + f'v{current_version}^{{commit}}', ], check=True, capture_output=True, encoding='utf8').stdout - commit_date_parts = commit_date_str.split(' ') + cd_date, cd_time, cd_tz = commit_date_str.split(' ') + + url_opts = urllib.parse.urlencode({'q': f'is:pr merged:>{cd_date}T{cd_time}{cd_tz}'}) + url = f'https://github.com/joerick/cibuildwheel/pulls?{url_opts}' - url = 'https://github.com/joerick/cibuildwheel/pulls?' + urllib.parse.urlencode({ - 'q': f'is:pr merged:>{commit_date_parts[0]}T{commit_date_parts[1]}{commit_date_parts[2]}', - }) print(f'PRs merged since last release:\n {url}') print() except subprocess.CalledProcessError as e: @@ -56,8 +60,10 @@ def bump_version(): print('error: Uncommitted changes detected.') sys.exit(1) + # fmt: off print( 'Current version:', current_version) # noqa new_version = input(' New version: ').strip() + # fmt: on try: Version(new_version) @@ -72,7 +78,7 @@ def bump_version(): paths = [Path(p) for p in glob.glob(path_pattern)] if not paths: - print(f'error: Pattern {path_pattern} didn’t match any files') + print(f"error: Pattern {path_pattern} didn't match any files") sys.exit(1) find_pattern = version_pattern.format(current_version) @@ -84,11 +90,11 @@ def bump_version(): if find_pattern in contents: found_at_least_one_file_needing_update = True actions.append( - (path, find_pattern, replace_pattern) + (path, find_pattern, replace_pattern,) ) if not found_at_least_one_file_needing_update: - print(f'error: Didn’t find any occurrences of “{find_pattern}” in “{path_pattern}”') + print(f'''error: Didn't find any occurrences of "{find_pattern}" in "{path_pattern}"''') sys.exit(1) print() @@ -96,10 +102,8 @@ def bump_version(): print() for action in actions: - print('{} {red}{}{off} → {green}{}{off}'.format( - *action, - red="\u001b[31m", green="\u001b[32m", off="\u001b[0m" - )) + path, find, replace = action + print(f'{path} {RED}{find}{OFF} → {GREEN}{replace}{OFF}') print(f'Then commit, and tag as v{new_version}') @@ -123,21 +127,20 @@ def bump_version(): subprocess.run([ 'git', 'commit', - '-a', - '-m', f'Bump version: v{new_version}' + '--all', + f"--message='Bump version: v{new_version}'", ], check=True) subprocess.run([ 'git', 'tag', - '-a', - '-m', f'v{new_version}', - f'v{new_version}' + '--annotate', + f"--message='v{new_version}'", + f'v{new_version}', ], check=True) print('Done.') if __name__ == '__main__': - os.chdir(os.path.dirname(__file__)) - os.chdir('..') + os.chdir(Path(__file__).parent.parent.resolve()) bump_version() diff --git a/bin/make_dependency_update_pr.py b/bin/make_dependency_update_pr.py index 902d3f6d..e18598e7 100755 --- a/bin/make_dependency_update_pr.py +++ b/bin/make_dependency_update_pr.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from __future__ import annotations + import os import sys import textwrap @@ -49,17 +51,18 @@ def main(): return shell('git commit -a -m "Update dependencies"', check=True) - run( - [ - 'gh', 'pr', 'create', - '--repo', 'joerick/cibuildwheel', - '--base', 'master', - '--title', 'Update dependencies', - '--body', textwrap.dedent(f''' + body = textwrap.dedent(f''' Update the versions of our dependencies. PR generated by `{os.path.basename(__file__)}`. ''') + run( + [ + 'gh', 'pr', 'create', + '--repo=joerick/cibuildwheel', + '--base=master', + "--title='Update dependencies'", + f"--body='{body}'", ], check=True ) diff --git a/bin/projects.py b/bin/projects.py index c6cbbacf..fbae3a3d 100755 --- a/bin/projects.py +++ b/bin/projects.py @@ -9,14 +9,17 @@ Suggested usage: git diff """ +from __future__ import annotations + import builtins import functools +import textwrap import urllib.request import xml.dom.minidom from datetime import datetime from io import StringIO from pathlib import Path -from typing import Any, Dict, List, Optional, TextIO +from typing import Any, TextIO import click import yaml @@ -38,7 +41,7 @@ ICONS = ( class Project: NAME: int = 0 - def __init__(self, config: Dict[str, Any], github: Optional[Github] = None): + def __init__(self, config: dict[str, Any], github: Github | None = None): try: self.name: str = config["name"] self.gh: str = config["gh"] @@ -48,8 +51,8 @@ class Project: self.stars_repo: str = config.get("stars", self.gh) self.notes: str = config.get("notes", "") - self.ci: List[str] = config.get("ci", []) - self.os: List[str] = config.get("os", []) + self.ci: list[str] = config.get("ci", []) + self.os: list[str] = config.get("os", []) self.online = github is not None if github is not None: @@ -72,7 +75,7 @@ class Project: name_len = len(self.name) + 4 self.__class__.NAME = max(self.__class__.NAME, name_len) - def __lt__(self, other: "Project") -> bool: + def __lt__(self, other: Project) -> bool: if self.online: return self.num_stars < other.num_stars else: @@ -80,10 +83,9 @@ class Project: @classmethod def header(cls) -> str: - return ( - f"| {'Name':{cls.NAME}} | CI | OS | Notes |\n" - f"|{'':-^{cls.NAME+2 }}|----|----|:------|" - ) + return textwrap.dedent(f"""\ + | {'Name':{cls.NAME}} | CI | OS | Notes | + |{'':-^{cls.NAME+2 }}|----|----|:------|""") @property def namelink(self) -> str: @@ -140,7 +142,7 @@ def path_for_icon(icon_name: str) -> Path: def str_projects( - config: List[Dict[str, Any]], *, online: bool = True, auth: Optional[str] = None + config: list[dict[str, Any]], *, online: bool = True, auth: str | None = None, ) -> str: io = StringIO() print = functools.partial(builtins.print, file=io) @@ -178,7 +180,7 @@ def str_projects( @click.option("--auth", help="GitHub authentication token") @click.option("--readme", type=click.File("r+"), help="Modify a readme file if given") def projects( - input: TextIO, online: bool, auth: Optional[str], readme: Optional[TextIO] + input: TextIO, online: bool, auth: str | None, readme: TextIO | None ) -> None: config = yaml.safe_load(input) output = str_projects(config, online=online, auth=auth) diff --git a/bin/run_example_ci_configs.py b/bin/run_example_ci_configs.py index ad5f6a41..25a7cb3e 100755 --- a/bin/run_example_ci_configs.py +++ b/bin/run_example_ci_configs.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from __future__ import annotations + import os import shutil import sys @@ -123,13 +125,14 @@ def run_example_ci_configs(config_files=None): shutil.copyfile(src_config_file, dst_config_file) run(['git', 'add', example_project], check=True) - run(['git', 'commit', '--no-verify', '-m', textwrap.dedent(f''' + message = textwrap.dedent(f''' Test example minimal configs Testing files: {config_files} Generated from branch: {previous_branch} Time: {timestamp} - ''')], check=True) + ''') + run(['git', 'commit', '--no-verify', '--message', message], check=True) shell(f'git subtree --prefix={example_project} push origin {branch_name}', check=True) print('---') diff --git a/bin/sample_build.py b/bin/sample_build.py index 8fad4ed8..6a07295d 100755 --- a/bin/sample_build.py +++ b/bin/sample_build.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 +from __future__ import annotations + import argparse import os import subprocess diff --git a/bin/update_dependencies.py b/bin/update_dependencies.py index c54fc982..89d997c7 100755 --- a/bin/update_dependencies.py +++ b/bin/update_dependencies.py @@ -1,11 +1,12 @@ #!/usr/bin/env python3 +from __future__ import annotations import configparser import os import shutil import subprocess import sys -from collections import namedtuple +from typing import NamedTuple import requests @@ -25,7 +26,7 @@ if '--no-docker' in sys.argv: '--allow-unsafe', '--upgrade', 'cibuildwheel/resources/constraints.in', - '--output-file', f'cibuildwheel/resources/constraints-python{python_version}.txt' + '--output-file=cibuildwheel/resources/constraints-python{python_version}.txt', ], check=True) else: # latest manylinux2010 image with cpython 2.7 support @@ -47,14 +48,15 @@ else: ], check=True) # default constraints.txt -shutil.copyfile(f'cibuildwheel/resources/constraints-python{PYTHON_VERSIONS[-1]}.txt', 'cibuildwheel/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 -Image = namedtuple('Image', [ - 'manylinux_version', - 'platform', - 'image_name', - 'tag', -]) images = [ Image('manylinux1', 'x86_64', 'quay.io/pypa/manylinux1_x86_64', None), @@ -66,12 +68,14 @@ images = [ 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), diff --git a/bin/update_pythons.py b/bin/update_pythons.py index f787a2b9..bf801590 100755 --- a/bin/update_pythons.py +++ b/bin/update_pythons.py @@ -1,10 +1,12 @@ #!/usr/bin/env python3 +from __future__ import annotations + import copy import difflib import logging from pathlib import Path -from typing import Dict, Optional, Union +from typing import Union import click import requests @@ -80,7 +82,7 @@ class WindowsVersions: 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) -> Optional[ConfigWinCP]: + def update_version_windows(self, spec: Specifier) -> ConfigWinCP | None: 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] @@ -91,12 +93,11 @@ class WindowsVersions: version = versions[-1] identifier = f"cp{version.major}{version.minor}-{self.arch}" - result = ConfigWinCP( + return ConfigWinCP( identifier=identifier, version=str(version), arch=self.arch_str, ) - return result class PyPyVersions: @@ -171,7 +172,7 @@ class CPythonVersions: releases_info = response.json() - self.versions_dict: Dict[Version, int] = {} + self.versions_dict: dict[Version, int] = {} for release in releases_info: # Removing the prefix, Python 3.9 would use: release["name"].removeprefix("Python ") version = Version(release["name"][7:]) @@ -180,8 +181,8 @@ class CPythonVersions: uri = int(release["resource_uri"].rstrip("/").split("/")[-1]) self.versions_dict[version] = uri - def update_version_macos(self, identifier: str, spec: Specifier) -> Optional[ConfigMacOS]: - file_idents = ("macos11.0.pkg", "macosx10.9.pkg", "macosx10.6.pkg") + 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)) for version in reversed(sorted_versions): @@ -216,13 +217,13 @@ class AllVersions: self.macos_cpython = CPythonVersions() self.macos_pypy = PyPyVersions("64") - def update_config(self, config: Dict[str, str]) -> None: + def update_config(self, config: dict[str, str]) -> None: identifier = config["identifier"] version = Version(config["version"]) spec = Specifier(f"=={version.major}.{version.minor}.*") log.info(f"Reading in '{identifier}' -> {spec} @ {version}") orig_config = copy.copy(config) - config_update: Optional[AnyConfig] + config_update: AnyConfig | None # We need to use ** in update due to MyPy (probably a bug) if "macos" in identifier: diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 3ed4c383..d64f02b6 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -73,19 +73,22 @@ def main() -> None: Python. Default: auto. ''') + arch_list_str = ", ".join(a.name for a in Architecture) parser.add_argument('--archs', default=None, - help=''' + help=f''' Comma-separated list of CPU architectures to build for. When set to 'auto', builds the architectures 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, {} - '''.format(", ".join(a.name for a in Architecture))) + Choices: auto, auto64, auto32, native, all, {arch_list_str} + ''') + parser.add_argument('--output-dir', default=os.environ.get('CIBW_OUTPUT_DIR', 'wheelhouse'), help='Destination folder for the wheels.') + parser.add_argument('package_dir', default='.', nargs='?', @@ -99,6 +102,7 @@ def main() -> None: parser.add_argument('--print-build-identifiers', action='store_true', help='Print the build identifiers matched by the current invocation and exit.') + parser.add_argument('--allow-empty', action='store_true', help='Do not report an error code if the build does not match any wheels.') @@ -367,9 +371,13 @@ def detect_warnings(platform: str, build_options: BuildOptions) -> List[str]: for option_name in ['test_command', 'before_build']: option_value = getattr(build_options, option_name) - if option_value: - if '{python}' in option_value or '{pip}' in option_value: - warnings.append(option_name + ": '{python}' and '{pip}' are no longer needed, and will be removed in a future release. Simply use 'python' or 'pip' instead.") + if option_value and ('{python}' in option_value or '{pip}' in option_value): + # Reminder: in an f-string, double braces means literal single brace + msg = ( + f"{option_name}: '{{python}}' and '{{pip}}' are no longer needed, " + "and will be removed in a future release. Simply use 'python' or 'pip' instead." + ) + warnings.append(msg) return warnings diff --git a/cibuildwheel/bashlex_eval.py b/cibuildwheel/bashlex_eval.py index d82b3269..05dd46af 100644 --- a/cibuildwheel/bashlex_eval.py +++ b/cibuildwheel/bashlex_eval.py @@ -58,9 +58,8 @@ def evaluate_word_node(node: bashlex.ast.node, context: NodeExecutionContext) -> if part_string not in value: raise RuntimeError( - 'bash parse failed. part "{}" not found in "{}". Word was "{}". Full input was "{}"'.format( - part_string, value, node.word, context.input, - ) + f'bash parse failed. part "{part_string}" not found in "{value}". ' + f'Word was "{node.word}". Full input was "{context.input}"' ) value = value.replace(part_string, part_value, 1) @@ -85,9 +84,7 @@ def evaluate_nodes_as_compound_command(nodes: Sequence[bashlex.ast.node], contex if node.kind == 'command': result += evaluate_command_node(node, context=context) elif node.kind == 'operator': - if node.op == ';': - pass - else: + if node.op != ';': raise ValueError(f'Unsupported bash operator: "{node.op}"') else: raise ValueError(f'Unsupported bash node in compound command: "{node.kind}"') diff --git a/cibuildwheel/docker_container.py b/cibuildwheel/docker_container.py index e18eed8c..204a0d2a 100644 --- a/cibuildwheel/docker_container.py +++ b/cibuildwheel/docker_container.py @@ -45,10 +45,10 @@ class DockerContainer: subprocess.run( [ 'docker', 'create', - '--env', 'CIBUILDWHEEL', - '--name', self.name, - '-i', - '-v', '/:/host', # ignored on CircleCI + '--env=CIBUILDWHEEL', + f'--name={self.name}', + '--interactive', + '--volume=/:/host', # ignored on CircleCI *cwd_args, self.docker_image, *shell_args @@ -169,13 +169,15 @@ class DockerContainer: while True: line = self.bash_stdout.readline() - if line.endswith(b'%s\n' % (bytes(end_of_message, encoding='utf8'))): + if line.endswith(bytes(end_of_message, encoding='utf8') + b'\n'): + # fmt: off footer_offset = ( len(line) - 1 # newline character - len(end_of_message) # delimiter - 4 # 4 returncode decimals ) + # fmt: on returncode_str = line[footer_offset:footer_offset+4] returncode = int(returncode_str) # add the last line to output, without the footer diff --git a/cibuildwheel/extra.py b/cibuildwheel/extra.py index 3c2ef4fb..ea106130 100644 --- a/cibuildwheel/extra.py +++ b/cibuildwheel/extra.py @@ -14,11 +14,10 @@ class InlineArrayDictEncoder(toml.encoder.TomlEncoder): # type: ignore self.dump_funcs[Version] = lambda v: f'"{v}"' def dump_sections(self, o: Dict[str, Any], sup: str) -> Any: - if all(isinstance(a, list) for a in o.values()): - val = "" - for k, v in o.items(): - inner = ",\n ".join(self.dump_inline_table(d_i).strip() for d_i in v) - val += f"{k} = [\n {inner},\n]\n" - return val, self._dict() - else: + if not all(isinstance(a, list) for a in o.values()): return super().dump_sections(o, sup) + val = "" + for k, v in o.items(): + inner = ",\n ".join(self.dump_inline_table(d_i).strip() for d_i in v) + val += f"{k} = [\n {inner},\n]\n" + return val, self._dict() diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 1e4e6f73..3e99e467 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -31,7 +31,7 @@ class PythonConfiguration(NamedTuple): def get_python_configurations( build_selector: BuildSelector, - architectures: Set[Architecture] + architectures: Set[Architecture], ) -> List[PythonConfiguration]: full_python_configs = read_python_configs('linux') @@ -159,7 +159,7 @@ def build(options: BuildOptions) -> None: docker.call([ 'pip', 'wheel', container_package_dir, - '-w', built_wheel_dir, + '--wheel-dir', built_wheel_dir, '--no-deps', *get_build_verbosity_extra_flags(options.build_verbosity) ], env=env) @@ -253,5 +253,5 @@ def troubleshoot(package_dir: Path, error: Exception) -> None: '''), file=sys.stderr) print(' Files detected:') - print('\n'.join([f' {f}' for f in so_files])) + print('\n'.join(f' {f}' for f in so_files)) print('') diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index a51d0b5e..b58d8a95 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -233,6 +233,9 @@ def setup_python(python_configuration: PythonConfiguration, # 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 == '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 @@ -246,34 +249,34 @@ def setup_python(python_configuration: PythonConfiguration, # compatible back to 10.9. env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-10.9-x86_64') env.setdefault('ARCHFLAGS', '-arch x86_64') - elif python_configuration.identifier.endswith('arm64'): + elif config_is_arm64: # macOS 11 is the first OS with arm64 support, so the wheels # have that as a minimum. env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-11.0-arm64') env.setdefault('ARCHFLAGS', '-arch arm64') - elif python_configuration.identifier.endswith('universal2'): + elif config_is_universal2: if get_macos_version() < (10, 16): # we can do universal2 builds on macos 10.15, but we need to # set ARCHFLAGS otherwise CPython sets it to `-arch x86_64` env.setdefault('ARCHFLAGS', '-arch arm64 -arch x86_64') - if python_configuration.identifier.endswith('arm64') or python_configuration.identifier.endswith('universal2'): - if get_macos_version() < (10, 16) and 'SDKROOT' not in env: - # xcode 12.2 or higher can build arm64 on macos 10.15 or below, but - # needs the correct SDK selected. - sdks = get_macos_sdks() + building_arm64 = config_is_arm64 or config_is_universal2 + if building_arm64 and get_macos_version() < (10, 16) and 'SDKROOT' not in env: + # xcode 12.2 or higher can build arm64 on macos 10.15 or below, but + # needs the correct SDK selected. + sdks = get_macos_sdks() - # Different versions of Xcode contain different SDK versions... - # we're happy with anything newer than macOS 11.0 - arm64_compatible_sdks = [s for s in sdks if not s.startswith('macosx10.')] + # Different versions of Xcode contain different SDK versions... + # we're happy with anything newer than macOS 11.0 + arm64_compatible_sdks = [s for s in sdks if not s.startswith('macosx10.')] - if not arm64_compatible_sdks: - log.warning(unwrap(''' + if not arm64_compatible_sdks: + log.warning(unwrap(''' SDK for building arm64-compatible wheels not found. You need Xcode 12.2 or later to build universal2 or arm64 wheels. ''')) - else: - env.setdefault('SDKROOT', arm64_compatible_sdks[0]) + else: + env.setdefault('SDKROOT', arm64_compatible_sdks[0]) log.step('Installing build tools...') call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', 'delocate', *dependency_constraint_flags], env=env) @@ -299,6 +302,9 @@ def build(options: BuildOptions) -> None: for config in python_configurations: log.build_start(config.identifier) + config_is_arm64 = config.identifier.endswith('arm64') + config_is_universal2 = config.identifier.endswith('universal2') + dependency_constraint_flags: Sequence[PathOrStr] = [] if options.dependency_constraints: dependency_constraint_flags = [ @@ -322,7 +328,7 @@ def build(options: BuildOptions) -> None: call([ 'pip', 'wheel', options.package_dir.resolve(), - '-w', built_wheel_dir, + '--wheel-dir', built_wheel_dir, '--no-deps', *get_build_verbosity_extra_flags(options.build_verbosity) ], env=env) @@ -339,9 +345,9 @@ def build(options: BuildOptions) -> None: if options.repair_command: log.step('Repairing wheel...') - if config.identifier.endswith('universal2'): + if config_is_universal2: delocate_archs = 'x86_64,arm64' - elif config.identifier.endswith('arm64'): + elif config_is_arm64: delocate_archs = 'arm64' else: delocate_archs = 'x86_64' @@ -364,28 +370,28 @@ def build(options: BuildOptions) -> None: machine_arch = platform.machine() testing_archs: List[Literal['x86_64', 'arm64']] = [] - if config.identifier.endswith('_arm64'): + if config_is_arm64: testing_archs = ['arm64'] - elif config.identifier.endswith('_universal2'): + elif config_is_universal2: testing_archs = ['x86_64', 'arm64'] else: testing_archs = ['x86_64'] for testing_arch in testing_archs: - if config.identifier.endswith('_universal2'): + if config_is_universal2: arch_specific_identifier = f'{config.identifier}:{testing_arch}' if not options.test_selector(arch_specific_identifier): continue if machine_arch == 'x86_64' and testing_arch == 'arm64': - if config.identifier.endswith('_arm64'): + if config_is_arm64: log.warning(unwrap(''' While arm64 wheels can be built on x86_64, they cannot be tested. The ability to test the arm64 wheels will be added in a future release of cibuildwheel, once Apple Silicon CI runners are widely available. To silence this warning, set `CIBW_TEST_SKIP: *-macosx_arm64`. ''')) - elif config.identifier.endswith('_universal2'): + elif config_is_universal2: log.warning(unwrap(''' While universal2 wheels can be built on x86_64, the arm64 part of them cannot currently be tested. The ability to test the arm64 part of a @@ -440,7 +446,7 @@ def build(options: BuildOptions) -> None: call_with_arch(before_test_prepared, env=virtualenv_env, shell=True) # install the wheel - call_with_arch(['pip', 'install', str(repaired_wheel) + options.test_extras], env=virtualenv_env) + call_with_arch(['pip', 'install', f"{repaired_wheel}{options.test_extras}"], env=virtualenv_env) # test the wheel if options.test_requires: diff --git a/cibuildwheel/resources/build-platforms.toml b/cibuildwheel/resources/build-platforms.toml index 4921414c..30941c0a 100644 --- a/cibuildwheel/resources/build-platforms.toml +++ b/cibuildwheel/resources/build-platforms.toml @@ -40,10 +40,10 @@ python_configurations = [ { 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.8/python-3.8.8-macosx10.9.pkg" }, - { identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.2/python-3.9.2-macos11.pkg" }, - { identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.2/python-3.9.2-macos11.pkg" }, - { identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.2/python-3.9.2-macos11.pkg" }, + { identifier = "cp38-macosx_x86_64", version = "3.8", url = "https://www.python.org/ftp/python/3.8.9/python-3.8.9-macosx10.9.pkg" }, + { identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" }, + { identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" }, + { identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" }, { 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" }, @@ -59,10 +59,10 @@ python_configurations = [ { 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.8", arch = "32" }, - { identifier = "cp38-win_amd64", version = "3.8.8", arch = "64" }, - { identifier = "cp39-win32", version = "3.9.2", arch = "32" }, - { identifier = "cp39-win_amd64", version = "3.9.2", arch = "64" }, + { 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" }, diff --git a/cibuildwheel/resources/constraints-python27.txt b/cibuildwheel/resources/constraints-python27.txt index 95b34de7..ce5b5f03 100644 --- a/cibuildwheel/resources/constraints-python27.txt +++ b/cibuildwheel/resources/constraints-python27.txt @@ -29,7 +29,7 @@ pathlib2==2.3.5 # virtualenv scandir==1.10.0 # via pathlib2 -singledispatch==3.6.0 +singledispatch==3.6.1 # via importlib-resources six==1.15.0 # via @@ -37,7 +37,7 @@ six==1.15.0 # virtualenv typing==3.7.4.3 # via importlib-resources -virtualenv==20.4.2 +virtualenv==20.4.3 # via -r cibuildwheel/resources/constraints.in wheel==0.36.2 # via diff --git a/cibuildwheel/resources/constraints-python35.txt b/cibuildwheel/resources/constraints-python35.txt index f71a1f1c..b40e5738 100644 --- a/cibuildwheel/resources/constraints-python35.txt +++ b/cibuildwheel/resources/constraints-python35.txt @@ -18,7 +18,7 @@ importlib-resources==3.2.1 # via virtualenv six==1.15.0 # via virtualenv -virtualenv==20.4.2 +virtualenv==20.4.3 # via -r cibuildwheel/resources/constraints.in wheel==0.36.2 # via diff --git a/cibuildwheel/resources/constraints-python36.txt b/cibuildwheel/resources/constraints-python36.txt index 4e627a05..805cfd14 100644 --- a/cibuildwheel/resources/constraints-python36.txt +++ b/cibuildwheel/resources/constraints-python36.txt @@ -12,21 +12,21 @@ distlib==0.3.1 # via virtualenv filelock==3.0.12 # via virtualenv -importlib-metadata==3.4.0 +importlib-metadata==3.10.0 # via virtualenv -importlib-resources==5.1.0 +importlib-resources==5.1.2 # via virtualenv six==1.15.0 # via virtualenv typing-extensions==3.7.4.3 # via importlib-metadata -virtualenv==20.4.2 +virtualenv==20.4.3 # via -r cibuildwheel/resources/constraints.in wheel==0.36.2 # via # -r cibuildwheel/resources/constraints.in # delocate -zipp==3.4.0 +zipp==3.4.1 # via # importlib-metadata # importlib-resources @@ -34,5 +34,5 @@ zipp==3.4.0 # The following packages are considered to be unsafe in a requirements file: pip==21.0.1 # via -r cibuildwheel/resources/constraints.in -setuptools==53.0.0 +setuptools==54.2.0 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python37.txt b/cibuildwheel/resources/constraints-python37.txt index f883f852..be5e5635 100644 --- a/cibuildwheel/resources/constraints-python37.txt +++ b/cibuildwheel/resources/constraints-python37.txt @@ -12,23 +12,23 @@ distlib==0.3.1 # via virtualenv filelock==3.0.12 # via virtualenv -importlib-metadata==3.4.0 +importlib-metadata==3.10.0 # via virtualenv six==1.15.0 # via virtualenv typing-extensions==3.7.4.3 # via importlib-metadata -virtualenv==20.4.2 +virtualenv==20.4.3 # via -r cibuildwheel/resources/constraints.in wheel==0.36.2 # via # -r cibuildwheel/resources/constraints.in # delocate -zipp==3.4.0 +zipp==3.4.1 # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: pip==21.0.1 # via -r cibuildwheel/resources/constraints.in -setuptools==53.0.0 +setuptools==54.2.0 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python38.txt b/cibuildwheel/resources/constraints-python38.txt index ed2868c9..6f50b819 100644 --- a/cibuildwheel/resources/constraints-python38.txt +++ b/cibuildwheel/resources/constraints-python38.txt @@ -14,7 +14,7 @@ filelock==3.0.12 # via virtualenv six==1.15.0 # via virtualenv -virtualenv==20.4.2 +virtualenv==20.4.3 # via -r cibuildwheel/resources/constraints.in wheel==0.36.2 # via @@ -24,5 +24,5 @@ wheel==0.36.2 # The following packages are considered to be unsafe in a requirements file: pip==21.0.1 # via -r cibuildwheel/resources/constraints.in -setuptools==53.0.0 +setuptools==54.2.0 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints-python39.txt b/cibuildwheel/resources/constraints-python39.txt index ed2868c9..6f50b819 100644 --- a/cibuildwheel/resources/constraints-python39.txt +++ b/cibuildwheel/resources/constraints-python39.txt @@ -14,7 +14,7 @@ filelock==3.0.12 # via virtualenv six==1.15.0 # via virtualenv -virtualenv==20.4.2 +virtualenv==20.4.3 # via -r cibuildwheel/resources/constraints.in wheel==0.36.2 # via @@ -24,5 +24,5 @@ wheel==0.36.2 # The following packages are considered to be unsafe in a requirements file: pip==21.0.1 # via -r cibuildwheel/resources/constraints.in -setuptools==53.0.0 +setuptools==54.2.0 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/constraints.txt b/cibuildwheel/resources/constraints.txt index ed2868c9..6f50b819 100644 --- a/cibuildwheel/resources/constraints.txt +++ b/cibuildwheel/resources/constraints.txt @@ -14,7 +14,7 @@ filelock==3.0.12 # via virtualenv six==1.15.0 # via virtualenv -virtualenv==20.4.2 +virtualenv==20.4.3 # via -r cibuildwheel/resources/constraints.in wheel==0.36.2 # via @@ -24,5 +24,5 @@ wheel==0.36.2 # The following packages are considered to be unsafe in a requirements file: pip==21.0.1 # via -r cibuildwheel/resources/constraints.in -setuptools==53.0.0 +setuptools==54.2.0 # via -r cibuildwheel/resources/constraints.in diff --git a/cibuildwheel/resources/pinned_docker_images.cfg b/cibuildwheel/resources/pinned_docker_images.cfg index 88719341..df14df35 100644 --- a/cibuildwheel/resources/pinned_docker_images.cfg +++ b/cibuildwheel/resources/pinned_docker_images.cfg @@ -1,27 +1,27 @@ [x86_64] -manylinux1 = quay.io/pypa/manylinux1_x86_64:2021-02-19-3257524 +manylinux1 = quay.io/pypa/manylinux1_x86_64:2021-04-05-14df3a6 manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5 -manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-02-20-2c345f8 -manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2021-02-20-2c345f8 +manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-04-05-b4fd19d +manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2021-04-05-b4fd19d [i686] -manylinux1 = quay.io/pypa/manylinux1_i686:2021-02-19-3257524 +manylinux1 = quay.io/pypa/manylinux1_i686:2021-04-05-14df3a6 manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-02-06-3d322a5 -manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-02-20-2c345f8 -manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2021-02-20-2c345f8 +manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-04-05-b4fd19d +manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2021-04-05-b4fd19d [pypy_x86_64] manylinux2010 = pypywheels/manylinux2010-pypy_x86_64:2020-12-11-f1e0e80 [aarch64] -manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2021-02-20-2c345f8 -manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2021-02-20-2c345f8 +manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2021-04-05-b4fd19d +manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2021-04-05-b4fd19d [ppc64le] -manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2021-02-20-2c345f8 -manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2021-02-20-2c345f8 +manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2021-04-05-b4fd19d +manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2021-04-05-b4fd19d [s390x] -manylinux2014 = quay.io/pypa/manylinux2014_s390x:2021-02-20-2c345f8 -manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2021-02-20-2c345f8 +manylinux2014 = quay.io/pypa/manylinux2014_s390x:2021-04-05-b4fd19d +manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2021-04-05-b4fd19d diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index de7eb445..6ec7fe91 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -209,9 +209,7 @@ class NonPlatformWheelError(Exception): def strtobool(val: str) -> bool: - if val.lower() in ('y', 'yes', 't', 'true', 'on', '1'): - return True - return False + return val.lower() in {'y', 'yes', 't', 'true', 'on', '1'} class CIProvider(Enum): diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index fce0838b..cff10794 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -25,7 +25,6 @@ from .util import ( ) IS_RUNNING_ON_AZURE = Path('C:\\hostedtoolcache').exists() -IS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows' def call(args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None, @@ -44,7 +43,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' if version[0] == '3' else 'python2' if arch == '32': - python_name = python_name + 'x86' + python_name += 'x86' return [python_name, '-Version', version, '-OutputDirectory', 'C:\\cibw\\python'] @@ -69,10 +68,9 @@ 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 IS_RUNNING_ON_TRAVIS and not custom_compiler: - # cannot install VCForPython27.msi which is needed for compiling C software - # try with (and similar): msiexec /i VCForPython27.msi ALLUSERS=1 ACCEPT=YES /passive + if not custom_compiler: python_configurations = [c for c in python_configurations if not c.version.startswith('2.7')] # skip builds as required @@ -295,13 +293,13 @@ def build(options: BuildOptions) -> None: ]) # check that we are using the Python from the virtual environment - call(['which', 'python'], env=virtualenv_env) + call(['where', 'python'], env=virtualenv_env) if options.before_test: before_test_prepared = prepare_command( options.before_test, project='.', - package=options.package_dir + package=options.package_dir, ) shell(before_test_prepared, env=virtualenv_env) @@ -318,7 +316,7 @@ def build(options: BuildOptions) -> None: test_command_prepared = prepare_command( options.test_command, project=Path('.').resolve(), - package=options.package_dir.resolve() + package=options.package_dir.resolve(), ) shell(test_command_prepared, cwd='c:\\', env=virtualenv_env) diff --git a/docs/cpp_standards.md b/docs/cpp_standards.md index 137872cb..4887502d 100644 --- a/docs/cpp_standards.md +++ b/docs/cpp_standards.md @@ -30,11 +30,11 @@ For more details see https://en.cppreference.com/w/cpp/compiler_support, https:/ ## 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 9 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. +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 have stopped distributing it. So, by default, cibuildwheel does not attempt to build Python 2.7 extensions on Windows. +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 for this, 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. +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: diff --git a/docs/data/projects.yml b/docs/data/projects.yml index c6c7f4b8..c72f39f4 100644 --- a/docs/data/projects.yml +++ b/docs/data/projects.yml @@ -2,6 +2,7 @@ # name: required, printed name # gh: GitHub repo (eventually a url: could be added for non-github projects) # stars: GitHub repo (optional, if different from package, such as for Twisted) +# pypi: The pypi name, if different from the GitHub package name # os: Operating system list, [windows, apple, linux] (optional) # ci: [appveyor, github, azurepipelines, circleci, gitlab, travisci] (optional) # notes: (text, optional) @@ -29,6 +30,7 @@ - name: Parselmouth gh: YannickJadoul/Parselmouth + pypi: praat-parselmouth notes: A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. ci: [github] os: [windows, apple, linux] @@ -82,6 +84,7 @@ - name: PyAV gh: PyAV-Org/PyAV + pypi: av ci: [github] os: [windows, apple, linux] notes: Pythonic bindings for FFmpeg's libraries. @@ -109,6 +112,7 @@ - name: etebase-py gh: etesync/etebase-py + pypi: etebase notes: Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. ci: [travisci] os: [linux] @@ -175,6 +179,7 @@ - name: jq.py gh: mwilliamson/jq.py + pypi: jq ci: [travisci] os: [apple, linux] @@ -226,6 +231,7 @@ - name: Dependency Injector gh: ets-labs/python-dependency-injector + pypi: dependency-injector ci: [travisci] os: [windows, apple, linux] notes: Dependency injection framework for Python, uses Windows TravisCI @@ -237,11 +243,13 @@ - name: PyTables gh: PyTables/PyTables + pypi: tables ci: [github] os: [windows, apple, linux] - name: dd-trace-py gh: DataDog/dd-trace-py + pypi: ddtrace ci: [github] os: [windows, apple, linux] notes: Uses custom alternate arch emulation on GitHub @@ -270,6 +278,7 @@ - name: MyPy gh: mypyc/mypy_mypyc-wheels stars: python/mypy + pypi: mypy ci: [github] os: [apple, linux, windows] notes: MyPyC, the compiled component of MyPy. @@ -277,6 +286,7 @@ - name: Imagecodecs (fork) gh: czaki/imagecodecs_build stars: cgohlke/imagecodecs + pypi: imagecodecs ci: [azurepipelines] ci_config: azure-pipelines.yaml os: [apple, linux] @@ -293,3 +303,24 @@ ci: [github] os: [apple, linux, windows] notes: Time mocking library using only the CPython C API. + +- name: polaroid + gh: daggy1234/polaroid + ci: [github] + os: [apple, linux, windows] + notes: Full range of wheels for setuptools rust, with auto release and PyPI deploy. + +- name: python-snappy + gh: andrix/python-snappy + ci: [github] + os: [apple, linux, windows] + +- name: sourmash + gh: dib-lab/sourmash + ci: [github] + os: [apple, linux, windows] + +- name: markupsafe + gh: pallets/markupsafe + ci: [github] + os: [apple, linux, windows] diff --git a/docs/faq.md b/docs/faq.md index b1b6bb48..2d8b834f 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -18,7 +18,7 @@ If your wheel didn't compile, check the list below for some debugging tips. 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: -- Programs and libraries cannot be installed on the Travis CI Ubuntu host with `apt-get`, but can be installed inside of the Docker image using `yum` or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [the options docs](options.md#build-environment) for details on these options. +- Programs and libraries are not installed on the Travis CI Ubuntu host, but rather should be installed inside of the Docker image (using `yum` for `manylinux2010` or `manylinux2014`, and `apt-get` for `manylinux_2_24`) or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [the options docs](options.md#build-environment) for details on these options. - The project directory is mounted in the running Docker instance as `/project`, the output directory for the wheels as `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that this is not available on CircleCI due to their Docker policies. diff --git a/docs/options.md b/docs/options.md index edea4d36..a8aa125c 100644 --- a/docs/options.md +++ b/docs/options.md @@ -365,6 +365,11 @@ CIBW_BEFORE_ALL: make -C third_party_lib CIBW_BEFORE_ALL_LINUX: yum install -y libffi-dev ``` +Note that manylinux2_24 builds occur inside a Debian9 docker, where +manylinux2010 and manylinux2014 builds occur inside a CentOS one. So for +`manylinux2_24` the `CIBW_BEFORE_ALL_LINUX` command must use `apt-get -y` +instead. + ### `CIBW_BEFORE_BUILD` {: #before-build} > Execute a shell command preparing each wheel's build diff --git a/docs/setup.md b/docs/setup.md index 2ac9512f..fa7017cd 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -45,10 +45,6 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/ steps: - uses: actions/checkout@v2 - - name: Install Visual C++ for Python 2.7 - if: runner.os == 'Windows' - run: choco install vcpython27 -f -y - - name: Build wheels run: pipx run cibuildwheel==1.10.0 @@ -87,10 +83,6 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/ - name: Install cibuildwheel run: python -m pip install cibuildwheel==1.10.0 - - name: Install Visual C++ for Python 2.7 - if: runner.os == 'Windows' - run: choco install vcpython27 -f -y - - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse diff --git a/examples/azure-pipelines-minimal.yml b/examples/azure-pipelines-minimal.yml index 742af4b4..40a89f34 100644 --- a/examples/azure-pipelines-minimal.yml +++ b/examples/azure-pipelines-minimal.yml @@ -31,8 +31,6 @@ jobs: pool: {vmImage: 'vs2017-win2016'} steps: - task: UsePythonVersion@0 - - script: choco install vcpython27 -f -y - displayName: Install Visual C++ for Python 2.7 - bash: | set -o errexit python -m pip install --upgrade pip diff --git a/examples/github-deploy.yml b/examples/github-deploy.yml index 249ce138..e362a292 100644 --- a/examples/github-deploy.yml +++ b/examples/github-deploy.yml @@ -26,10 +26,6 @@ jobs: with: python-version: '3.8' - - name: Install Visual C++ for Python 2.7 - if: runner.os == 'Windows' - run: choco install vcpython27 -f -y - - name: Build wheels uses: joerick/cibuildwheel@v1.10.0 diff --git a/examples/github-minimal.yml b/examples/github-minimal.yml index 0ac6b853..68f582f8 100644 --- a/examples/github-minimal.yml +++ b/examples/github-minimal.yml @@ -13,10 +13,6 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Install Visual C++ for Python 2.7 - if: runner.os == 'Windows' - run: choco install vcpython27 -f -y - - name: Build wheels uses: joerick/cibuildwheel@v1.10.0 # to supply options, put them in 'env', like: diff --git a/examples/github-with-qemu.yml b/examples/github-with-qemu.yml index a49b8120..544da85d 100644 --- a/examples/github-with-qemu.yml +++ b/examples/github-with-qemu.yml @@ -18,10 +18,6 @@ jobs: with: python-version: '3.7' - - name: Install Visual C++ for Python 2.7 - if: runner.os == 'Windows' - run: choco install vcpython27 -f -y - - name: Set up QEMU if: runner.os == 'Linux' uses: docker/setup-qemu-action@v1 diff --git a/examples/travis-ci-deploy.yml b/examples/travis-ci-deploy.yml index 1658575e..a1598768 100644 --- a/examples/travis-ci-deploy.yml +++ b/examples/travis-ci-deploy.yml @@ -14,7 +14,7 @@ jobs: - os: windows language: shell before_install: - - choco install python --version 3.8.6 + - choco upgrade python -y --version 3.8.6 - export PATH="/c/Python38:/c/Python38/Scripts:$PATH" # make sure it's on PATH as 'python3' - ln -s /c/Python38/python.exe /c/Python38/python3.exe diff --git a/examples/travis-ci-minimal.yml b/examples/travis-ci-minimal.yml index a3a2a330..7fbc1889 100644 --- a/examples/travis-ci-minimal.yml +++ b/examples/travis-ci-minimal.yml @@ -20,7 +20,7 @@ jobs: - os: windows language: shell before_install: - - choco install python --version 3.8.6 + - choco upgrade python -y --version 3.8.6 - export PATH="/c/Python38:/c/Python38/Scripts:$PATH" # make sure it's on PATH as 'python3' - ln -s /c/Python38/python.exe /c/Python38/python3.exe diff --git a/examples/travis-ci-test-and-deploy.yml b/examples/travis-ci-test-and-deploy.yml index 7c8e22db..ec4deeca 100644 --- a/examples/travis-ci-test-and-deploy.yml +++ b/examples/travis-ci-test-and-deploy.yml @@ -14,7 +14,7 @@ python: before_install: - | if [[ "$TRAVIS_OS_NAME" = windows ]]; then - choco install python --version 3.8.6 + choco upgrade python -y --version 3.8.6 export PATH="/c/Python38:/c/Python38/Scripts:$PATH" # make sure it's on PATH as 'python3' ln -s /c/Python38/python.exe /c/Python38/python3.exe diff --git a/mkdocs.yml b/mkdocs.yml index 59f6a290..b6d51244 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,3 +39,4 @@ markdown_extensions: plugins: - include-markdown + - search diff --git a/pyproject.toml b/pyproject.toml index 6e9a2f33..979c4888 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,4 +8,5 @@ build-backend = "setuptools.build_meta" [tool.black] line-length = 120 -target-version = ['py36'] +target-version = ['py36', 'py37', 'py38'] +skip-string-normalization = true diff --git a/setup.cfg b/setup.cfg index 34bc30ab..14eafb35 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,39 +1,48 @@ [metadata] - name = cibuildwheel version = 1.10.0 description = Build Python wheels on CI with minimal configuration. long_description = file: README.md long_description_content_type = text/markdown +url = https://github.com/joerick/cibuildwheel author = Joe Rickerby author_email = joerick@mac.com -url = https://github.com/joerick/cibuildwheel license = BSD +license_file = LICENSE classifiers = + Development Status :: 5 - Production/Stable Intended Audience :: Developers + License :: OSI Approved :: BSD License Natural Language :: English Programming Language :: Python :: 3 - Development Status :: 5 - Production/Stable - License :: OSI Approved :: BSD License + Programming Language :: Python :: 3 :: Only + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Programming Language :: Python :: Implementation :: CPython Topic :: Software Development :: Build Tools +keywords = ci,wheel,packaging,pypi,travis,appveyor,macos,linux,windows project_urls = Changelog=https://github.com/joerick/cibuildwheel#changelog Documentation=https://cibuildwheel.readthedocs.io/ -keywords = ci,wheel,packaging,pypi,travis,appveyor,macos,linux,windows [options] packages = find: -zip_safe = False -include_package_data = True -python_requires = >=3.6 install_requires = bashlex!=0.13 - toml - certifi bracex + certifi packaging - typing_extensions; python_version < '3.8' + toml + typing_extensions;python_version < '3.8' +python_requires = >=3.6 +include_package_data = True +zip_safe = False + +[options.entry_points] +console_scripts = + cibuildwheel = cibuildwheel.__main__:main [options.package_data] cibuildwheel = resources/* @@ -42,28 +51,26 @@ cibuildwheel = resources/* include = cibuildwheel -[options.entry_points] -console_scripts = - cibuildwheel = cibuildwheel.__main__:main - - [flake8] ignore = E501,W503,E741,E226,B950 select = C,E,F,W,B,B9 application-import-names = cibuildwheel exclude = - cibuildwheel/resources/, - dist/, - build/, - .git/, - env/, - env2/, - env??/, - .venv/, - site/ + cibuildwheel/resources/, + dist/, + build/, + .git/, + env/, + env2/, + env??/, + .venv/, + site/ [tool:pytest] -junit_family=xunit2 +junit_family = xunit2 +testpaths = + test + unit_test [mypy] python_version = 3.7 @@ -110,5 +117,5 @@ ignore_missing_imports = True ignore_missing_imports = True [tool:isort] -profile=black -multi_line_output=3 +profile = black +multi_line_output = 3 diff --git a/test/test_before_all.py b/test/test_before_all.py index 1b9ff240..2306fb27 100644 --- a/test/test_before_all.py +++ b/test/test_before_all.py @@ -31,7 +31,7 @@ def test(tmp_path): # write python version information to a temporary file, this is # checked in setup.py 'CIBW_BEFORE_ALL': before_all_command, - 'CIBW_BEFORE_ALL_LINUX': before_all_command + ''' && python -c "import sys; assert sys.version_info >= (3, 6)"''', + 'CIBW_BEFORE_ALL_LINUX': f'{before_all_command} && python -c "import sys; assert sys.version_info >= (3, 6)"', 'CIBW_ENVIRONMENT': "TEST_VAL='123'" }) diff --git a/test/test_dependency_versions.py b/test/test_dependency_versions.py index 72c10597..e41e6bf2 100644 --- a/test/test_dependency_versions.py +++ b/test/test_dependency_versions.py @@ -40,11 +40,10 @@ VERSION_REGEX = r'([\w-]+)==([^\s]+)' def get_versions_from_constraint_file(constraint_file): constraint_file_text = constraint_file.read_text(encoding='utf8') - versions = {} - for package, version in re.findall(VERSION_REGEX, constraint_file_text): - versions[package] = version - - return versions + return { + package: version + for package, version in re.findall(VERSION_REGEX, constraint_file_text) + } @pytest.mark.parametrize('python_version', ['2.7', '3.5', '3.6', '3.8']) @@ -52,8 +51,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.IS_WINDOWS_RUNNING_ON_TRAVIS and python_version == '2.7': - pytest.skip('Windows + Travis CI requires a workaround') + if utils.platform == 'windows' and python_version == '2.7': + pytest.skip('Windows requires a workaround') is_running_on_macos_11_or_later = ( utils.platform == 'macos' and utils.get_macos_version() >= (10, 16) @@ -91,7 +90,7 @@ def test_pinned_versions(tmp_path, python_version): build_environment[env_name] = constraint_versions[package] cibw_environment_option = ' '.join( - [f'{k}={v}' for k, v in build_environment.items()] + f'{k}={v}' for k, v in build_environment.items() ) # build and test the wheels @@ -124,7 +123,7 @@ 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.IS_WINDOWS_RUNNING_ON_TRAVIS and python_version == '2.7': + if utils.platform == 'windows' and python_version == '2.7': pytest.skip('Windows + Travis CI requires a workaround') project_dir = tmp_path / 'project' @@ -154,7 +153,7 @@ def test_dependency_constraints_file(tmp_path, python_version): build_environment[env_name] = version cibw_environment_option = ' '.join( - [f'{k}={v}' for k, v in build_environment.items()] + f'{k}={v}' for k, v in build_environment.items() ) # build and test the wheels diff --git a/test/utils.py b/test/utils.py index dc87f638..bd9270b9 100644 --- a/test/utils.py +++ b/test/utils.py @@ -12,7 +12,18 @@ import sys from contextlib import contextmanager from tempfile import mkdtemp -IS_WINDOWS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows' +platform: str + +if 'CIBW_PLATFORM' in os.environ: + platform = os.environ['CIBW_PLATFORM'] +elif sys.platform.startswith('linux'): + platform = 'linux' +elif sys.platform.startswith('darwin'): + platform = 'macos' +elif sys.platform in ['win32', 'cygwin']: + platform = 'windows' +else: + raise Exception('Unsupported platform') # Python 2 does not have a tempfile.TemporaryDirectory context manager @@ -91,7 +102,7 @@ def _get_arm64_macosx_deployment_target(macosx_deployment_target: str) -> str: def expected_wheels(package_name, package_version, manylinux_versions=None, macosx_deployment_target='10.9', machine_arch=None, *, - exclude_27=IS_WINDOWS_RUNNING_ON_TRAVIS): + exclude_27=platform == 'windows'): ''' Returns a list of expected wheels from a run of cibuildwheel. ''' @@ -187,17 +198,3 @@ def get_macos_version(): ''' version_str, _, _ = pm.mac_ver() return tuple(map(int, version_str.split(".")[:2])) - - -platform = None - -if 'CIBW_PLATFORM' in os.environ: - platform = os.environ['CIBW_PLATFORM'] -elif sys.platform.startswith('linux'): - platform = 'linux' -elif sys.platform.startswith('darwin'): - platform = 'macos' -elif sys.platform in ['win32', 'cygwin']: - platform = 'windows' -else: - raise Exception('Unsupported platform') diff --git a/unit_test/docker_container_test.py b/unit_test/docker_container_test.py index 22771ed2..bd07b50b 100644 --- a/unit_test/docker_container_test.py +++ b/unit_test/docker_container_test.py @@ -94,7 +94,7 @@ def test_binary_output(): data = bytes(output, encoding='utf8', errors='surrogateescape') - for i in range(0, 512): + for i in range(512): assert data[i] == i % 256 # check that environment variables can carry binary data, except null characters diff --git a/unit_test/main_tests/main_options_test.py b/unit_test/main_tests/main_options_test.py index 24559489..dbfc7539 100644 --- a/unit_test/main_tests/main_options_test.py +++ b/unit_test/main_tests/main_options_test.py @@ -134,7 +134,7 @@ def test_repair_command(repair_command, platform_specific, platform, intercepted ]) @pytest.mark.parametrize('platform_specific', [False, True]) def test_environment(environment, platform_specific, platform, intercepted_build_args, monkeypatch): - env_string = ' '.join([f'{k}={v}' for k, v in environment.items()]) + env_string = ' '.join(f'{k}={v}' for k, v in environment.items()) if platform_specific: monkeypatch.setenv('CIBW_ENVIRONMENT_' + platform.upper(), env_string) monkeypatch.setenv('CIBW_ENVIRONMENT', 'overwritten') diff --git a/unit_test/main_tests/main_platform_test.py b/unit_test/main_tests/main_platform_test.py index 1b37663e..45fe7d1e 100644 --- a/unit_test/main_tests/main_platform_test.py +++ b/unit_test/main_tests/main_platform_test.py @@ -123,12 +123,10 @@ def test_archs_platform_native(platform, intercepted_build_args, monkeypatch): main() build_options = intercepted_build_args.args[0] - if platform == 'linux': + if platform in {'linux', 'macos'}: assert build_options.architectures == {Architecture.x86_64} elif platform == 'windows': assert build_options.architectures == {Architecture.AMD64} - elif platform == 'macos': - assert build_options.architectures == {Architecture.x86_64} def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch): @@ -137,12 +135,10 @@ def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch): main() build_options = intercepted_build_args.args[0] - if platform == 'linux': + if platform in {'linux', 'macos'}: assert build_options.architectures == {Architecture.x86_64} elif platform == 'windows': assert build_options.architectures == {Architecture.AMD64} - elif platform == 'macos': - assert build_options.architectures == {Architecture.x86_64} def test_archs_platform_auto32(platform, intercepted_build_args, monkeypatch):