Compare commits

...
42 Commits
Author SHA1 Message Date
Joe Rickerby 0b6307072a Bump version: v2.5.0 2022-04-29 14:46:08 +01:00
Joe Rickerby 61bcac854e Merge pull request #1091 from mayeut/abi3
feature: add support for ABI3 wheels
2022-04-29 14:31:27 +01:00
Joe Rickerby 75998410e0 Add tips+tricks entry for ABI3 building 2022-04-29 14:16:00 +01:00
Joe Rickerby 46702f581d Space out the log statements a little 2022-04-29 13:32:03 +01:00
Joe Rickerby acc079675b Merge remote-tracking branch 'origin/main' into abi3 2022-04-29 11:57:20 +01:00
Joe Rickerby f324c9ad61 Merge pull request #1096 from henryiii/henryiii/feat/sdist
feat: SDist builds
2022-04-29 11:52:08 +01:00
Henry Schreiner de44c88c75 docs: add some projects (#1097)
* docs: add some projects

* chore: update docs
2022-04-28 19:18:49 -04:00
Henry Schreiner 35054666bb refactor: review comments 2022-04-27 17:18:01 -04:00
Henry Schreiner b1e8549bb1 fix: minor cleanup 2022-04-27 14:55:30 -04:00
Henry Schreiner 958a7c32c1 refactor: use single entry for SDist builds
Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
2022-04-27 09:37:17 -04:00
Joe Rickerby 91fae8268e Add prog arguments to ArgumentParser to prevent the wrong inferred name
when calling like 'python -m cibuildwheel', we get errors like

usage: __main__.py [-h] [--platform {auto,linux,macos,windows}] [--archs ARCHS] [--output-dir OUTPUT_DIR] [--config-file CONFIG_FILE]
                   [--print-build-identifiers] [--allow-empty] [--prerelease-pythons]
                   [package_dir]
__main__.py: error: unrecognized arguments: --sad

With this change, we get error outputs like:

usage: cibuildwheel [-h] [--platform {auto,linux,macos,windows}] [--archs ARCHS] [--output-dir OUTPUT_DIR] [--config-file CONFIG_FILE]
                    [--print-build-identifiers] [--allow-empty] [--prerelease-pythons]
                    [package_dir]
cibuildwheel: error: unrecognized arguments: --asda
2022-04-27 01:01:31 -04:00
Joe Rickerby 8c77d5ed41 Tidy ups, bug fixes 2022-04-27 01:01:31 -04:00
Joe Rickerby 898dd62022 Add test for argument passthrough 2022-04-27 01:01:31 -04:00
Joe Rickerby c6c5e6e59b Add test for cibuildwheel.from-sdist 2022-04-27 01:01:31 -04:00
Joe Rickerby e887d4bbf8 Add entrypoint 2022-04-27 01:01:31 -04:00
Joe Rickerby 763cd15ae2 Add from_sdist script 2022-04-27 01:01:31 -04:00
mayeut e3ff027131 feature: add support for ABI3 wheels 2022-04-26 22:38:17 +02:00
Matthieu Darbois de07370930 fix: extract project as current user on linux (#1095)
This allows git to work properly, e.g., `versioneer`/`setuptools_scm` with latest git versions.
c.f. https://github.com/pypa/manylinux/issues/1309
2022-04-26 13:29:00 -04:00
Henry Schreiner 986a50f8a0 docs: two minor additions (#1093)
* docs: mention when msvcd140_1.dll is included in cpython

* docs: mention maturin-action
2022-04-26 00:29:32 -04:00
Joe Rickerby dff69251ee Merge pull request #1086 from pauldmccarthy/bf/allow-empty
fix: Don't error if no new wheels were built
2022-04-22 10:47:56 +01:00
Paul McCarthy f08f08c04d style: spurious comma 2022-04-21 10:34:11 +01:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 496ea9bd56 [pre-commit.ci] pre-commit autoupdate (#1092)
updates:
- [github.com/hadialqattan/pycln: v1.2.5 → v1.3.1](https://github.com/hadialqattan/pycln/compare/v1.2.5...v1.3.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-04-19 13:35:44 -04:00
Paul McCarthy abedb68783 test: build_frontend_env fixture not required for --allow-empy test. Small
style tweak
2022-04-19 16:02:23 +01:00
Paul McCarthy baf3ead650 style: exit early to reduce indentation 2022-04-19 16:00:12 +01:00
pre-commit-ci[bot] 30627ae04f [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2022-04-19 15:52:06 +01:00
Paul McCarthy 945d4f6635 test: don't modify build_frontend_env, as it appears to be global 2022-04-19 15:52:06 +01:00
pre-commit-ci[bot] d061fc7967 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2022-04-19 15:52:06 +01:00
Paul McCarthy be9a635f9b fix: don't assume that any configurations are active 2022-04-19 15:52:06 +01:00
Paul McCarthy bb2d5bdab6 TEST: Actually evaluate test outcome 2022-04-19 15:52:06 +01:00
pre-commit-ci[bot] 82c3d4a4b7 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2022-04-19 15:52:06 +01:00
Paul McCarthy 1f52f30fcf TEST: Sanity check test for --allow-empty flag 2022-04-19 15:52:06 +01:00
Paul McCarthy 1e176a021b RF: Remove unnecessary message 2022-04-19 15:52:06 +01:00
pre-commit-ci[bot] 07013d6baf [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2022-04-19 15:52:06 +01:00
Paul McCarthy fe97589390 fix: Don't error if no new wheels were built (this may happen if --allow-empty is active) 2022-04-19 15:52:06 +01:00
Shantanuandhauntsaninja <> 6d4431306e chore: use tomllib on Python 3.11 (#1047)
* Use tomllib on Python 3.11

* delint

Co-authored-by: hauntsaninja <>
2022-04-16 00:00:57 -04:00
pre-commit-ci[bot]pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>Henry Schreiner
9ae6ae2756 [pre-commit.ci] pre-commit autoupdate (#1084)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/pre-commit/pre-commit-hooks: v4.1.0 → v4.2.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.1.0...v4.2.0)
- [github.com/asottile/pyupgrade: v2.31.1 → v2.32.0](https://github.com/asottile/pyupgrade/compare/v2.31.1...v2.32.0)

* chore: fix minor style msg

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

* chore: use extend on flake8

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

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
2022-04-13 15:33:49 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 00ba73bf21 chore(deps): bump actions/upload-artifact from 2 to 3 (#1082)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2...v3)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-12 15:15:01 -04:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 75fd65fcf7 chore(deps): bump actions/download-artifact from 2 to 3 (#1081)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v2...v3)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-12 15:14:45 -04:00
Joe Rickerby 68b8cd8ee5 Merge pull request #1083 from DiddiLeija/fix-docs-py-block 2022-04-12 20:13:09 +01:00
Diego Ramirez a7271b2750 Fix a badly-formatted Python block in the docs
The whole block is indented, though a code block with Python formatting is there.
2022-04-11 12:45:38 -05:00
cibuildwheel-bot[bot]andmayeut 5824aecc5c Update dependencies (#1073)
Co-authored-by: mayeut <mayeut@users.noreply.github.com>
2022-04-05 00:53:56 -04:00
pre-commit-ci[bot]andpre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> 989f21de16 [pre-commit.ci] pre-commit autoupdate (#1074)
updates:
- [github.com/asottile/setup-cfg-fmt: v1.20.0 → v1.20.1](https://github.com/asottile/setup-cfg-fmt/compare/v1.20.0...v1.20.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-04-05 00:53:33 -04:00
52 changed files with 1006 additions and 458 deletions
+2 -2
View File
@@ -16,7 +16,7 @@ jobs:
- name: Build SDist and wheel - name: Build SDist and wheel
run: pipx run build run: pipx run build
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
path: dist/* path: dist/*
@@ -29,7 +29,7 @@ jobs:
if: github.event_name == 'release' && github.event.action == 'published' if: github.event_name == 'release' && github.event.action == 'published'
steps: steps:
- uses: actions/download-artifact@v2 - uses: actions/download-artifact@v3
with: with:
name: artifact name: artifact
path: dist path: dist
+1 -1
View File
@@ -61,7 +61,7 @@ jobs:
env: env:
CIBW_ARCHS_MACOS: x86_64 universal2 arm64 CIBW_ARCHS_MACOS: x86_64 universal2 arm64
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v3
with: with:
name: sample_wheels name: sample_wheels
path: wheelhouse path: wheelhouse
+4 -4
View File
@@ -1,7 +1,7 @@
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0 rev: v4.2.0
hooks: hooks:
- id: check-case-conflict - id: check-case-conflict
- id: check-merge-conflict - id: check-merge-conflict
@@ -14,7 +14,7 @@ repos:
- id: trailing-whitespace - id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v2.31.1 rev: v2.32.0
hooks: hooks:
- id: pyupgrade - id: pyupgrade
name: PyUpgrade 3.6+ name: PyUpgrade 3.6+
@@ -27,7 +27,7 @@ repos:
# Autoremoves unused imports # Autoremoves unused imports
- repo: https://github.com/hadialqattan/pycln - repo: https://github.com/hadialqattan/pycln
rev: v1.2.5 rev: v1.3.1
hooks: hooks:
- id: pycln - id: pycln
args: [--all] args: [--all]
@@ -44,7 +44,7 @@ repos:
- id: black - id: black
- repo: https://github.com/asottile/setup-cfg-fmt - repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.20.0 rev: v1.20.1
hooks: hooks:
- id: setup-cfg-fmt - id: setup-cfg-fmt
+22 -19
View File
@@ -87,7 +87,7 @@ jobs:
- uses: actions/setup-python@v2 - uses: actions/setup-python@v2
- name: Install cibuildwheel - name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.4.0 run: python -m pip install cibuildwheel==2.5.0
- name: Build wheels - name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse run: python -m cibuildwheel --output-dir wheelhouse
@@ -142,25 +142,25 @@ Here are some repos that use cibuildwheel.
|-----------------------------------|----|----|:------| |-----------------------------------|----|----|:------|
| [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. | | [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. |
| [Tornado][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. | | [Tornado][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. |
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. | | [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions | | [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | MyPyC, the compiled component of MyPy. | | [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
| [pydantic][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Data parsing and validation using Python type hints | | [pydantic][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Data parsing and validation using Python type hints |
| [uvloop][] | ![github icon][] | ![apple icon][] ![linux icon][] | Ultra fast asyncio event loop. |
| [psutil][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Cross-platform lib for process and system monitoring in Python |
| [vaex][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Out-of-Core hybrid Apache Arrow/NumPy DataFrame for Python, ML, visualization and exploration of big tabular data at a billion rows per second 🚀 |
| [Google Benchmark][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A microbenchmark support library |
[scikit-learn]: https://github.com/scikit-learn/scikit-learn [scikit-learn]: https://github.com/scikit-learn/scikit-learn
[Tornado]: https://github.com/tornadoweb/tornado [Tornado]: https://github.com/tornadoweb/tornado
[NumPy]: https://github.com/numpy/numpy
[pytorch-fairseq]: https://github.com/pytorch/fairseq [pytorch-fairseq]: https://github.com/pytorch/fairseq
[Matplotlib]: https://github.com/matplotlib/matplotlib [Matplotlib]: https://github.com/matplotlib/matplotlib
[Kivy]: https://github.com/kivy/kivy
[NCNN]: https://github.com/Tencent/ncnn
[Prophet]: https://github.com/facebook/prophet
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels [MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
[pydantic]: https://github.com/samuelcolvin/pydantic [pydantic]: https://github.com/samuelcolvin/pydantic
[uvloop]: https://github.com/MagicStack/uvloop
[psutil]: https://github.com/giampaolo/psutil
[vaex]: https://github.com/vaexio/vaex
[Google Benchmark]: https://github.com/google/benchmark
[appveyor icon]: docs/data/readme_icons/appveyor.svg [appveyor icon]: docs/data/readme_icons/appveyor.svg
[github icon]: docs/data/readme_icons/github.svg [github icon]: docs/data/readme_icons/github.svg
@@ -192,6 +192,16 @@ Changelog
<!-- this section was generated by bin/update_readme_changelog.py -- do not edit manually --> <!-- this section was generated by bin/update_readme_changelog.py -- do not edit manually -->
### v2.5.0
_29 April 2022_
- ✨ Added support for building ABI3 wheels. cibuildwheel will now recognise when an ABI3 wheel was produced, and skip subsequent build steps where the previously built wheel is compatible. Tests still will run on all selected versions of Python, using the ABI3 wheel. (#1091)
- ✨ You can now build wheels directly from sdist archives, in addition to source directories. Just call cibuildwheel with an sdist argument on the command line, like `cibuildwheel mypackage-1.0.0.tar.gz` (#1096)
- 🐛 Fix a bug where cibuildwheel would crash when no builds are selected and `--allow-empty` is passed (#1086)
- 🐛 Workaround a permissions issue on Linux relating to newer versions of git and setuptools_scm (#1095)
- 📚 Minor docs improvements
### v2.4.0 ### v2.4.0
_2 April 2022_ _2 April 2022_
@@ -231,13 +241,6 @@ _26 October 2021_
- 🐛 Fix bug in the GitHub Action step causing a syntax error (#895) - 🐛 Fix bug in the GitHub Action step causing a syntax error (#895)
### v2.2.1
_26 October 2021_
- 🛠 Added a `config-file` option on the GitHub Action to specify something other than pyproject.toml in your GitHub Workflow file. (#883)
- 🐛 Fix missing resources in sdist and released wheel on PyPI. We've also made some internal changes to our release processes to make them more reliable. (#893, #894)
<!-- END bin/update_readme_changelog.py --> <!-- END bin/update_readme_changelog.py -->
--- ---
@@ -283,6 +286,6 @@ Massive props also to-
See also See also
======== ========
If you'd like to keep wheel building separate from the package itself, check out [astrofrog/autowheel](https://github.com/astrofrog/autowheel). It builds packages using cibuildwheel from source distributions on PyPI.
Another very similar tool to consider is [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild). `multibuild` is a shell script toolbox for building a wheel on various platforms. It is used as a basis to build some of the big data science tools, like SciPy. Another very similar tool to consider is [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild). `multibuild` is a shell script toolbox for building a wheel on various platforms. It is used as a basis to build some of the big data science tools, like SciPy.
If you are building Rust wheels, you can get by without some of the tricks required to make GLIBC work via manylinux; this is especially relevant for cross-compiling, which is easy with Rust. See [maturin-action](https://github.com/messense/maturin-action) for a tool that is optimized for building Rust wheels and cross-compiling.
+8 -2
View File
@@ -5,13 +5,19 @@ from __future__ import annotations
import copy import copy
import difflib import difflib
import logging import logging
import sys
from pathlib import Path from pathlib import Path
from typing import Any, Union from typing import Any, Union
import click import click
import requests import requests
import rich import rich
import tomli
if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
from packaging.specifiers import Specifier from packaging.specifiers import Specifier
from packaging.version import Version from packaging.version import Version
from rich.logging import RichHandler from rich.logging import RichHandler
@@ -296,7 +302,7 @@ def update_pythons(force: bool, level: str) -> None:
original_toml = toml_file_path.read_text() original_toml = toml_file_path.read_text()
with toml_file_path.open("rb") as f: with toml_file_path.open("rb") as f:
configs = tomli.load(f) configs = tomllib.load(f)
for config in configs["windows"]["python_configurations"]: for config in configs["windows"]["python_configurations"]:
all_versions.update_config(config) all_versions.update_config(config)
+8 -2
View File
@@ -5,12 +5,18 @@ from __future__ import annotations
import difflib import difflib
import logging import logging
import subprocess import subprocess
import sys
from pathlib import Path from pathlib import Path
from typing import NamedTuple from typing import NamedTuple
import click import click
import rich import rich
import tomli
if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
from packaging.version import InvalidVersion, Version from packaging.version import InvalidVersion, Version
from rich.logging import RichHandler from rich.logging import RichHandler
from rich.syntax import Syntax from rich.syntax import Syntax
@@ -78,7 +84,7 @@ def update_virtualenv(force: bool, level: str) -> None:
original_toml = toml_file_path.read_text() original_toml = toml_file_path.read_text()
with toml_file_path.open("rb") as f: with toml_file_path.open("rb") as f:
loaded_file = tomli.load(f) loaded_file = tomllib.load(f)
version = str(loaded_file["version"]) version = str(loaded_file["version"])
versions = git_ls_remote_versions(GET_VIRTUALENV_GITHUB) versions = git_ls_remote_versions(GET_VIRTUALENV_GITHUB)
if versions[0].version > Version(version): if versions[0].version > Version(version):
+1 -1
View File
@@ -1 +1 @@
__version__ = "2.4.0" __version__ = "2.5.0"
+50 -9
View File
@@ -2,6 +2,8 @@ import argparse
import os import os
import shutil import shutil
import sys import sys
import tarfile
import tempfile
import textwrap import textwrap
from pathlib import Path from pathlib import Path
from tempfile import mkdtemp from tempfile import mkdtemp
@@ -20,13 +22,12 @@ from cibuildwheel.util import (
CIBW_CACHE_PATH, CIBW_CACHE_PATH,
BuildSelector, BuildSelector,
Unbuffered, Unbuffered,
chdir,
detect_ci_provider, detect_ci_provider,
) )
def main() -> None: def main() -> None:
platform: PlatformName
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Build wheels for all the platforms.", description="Build wheels for all the platforms.",
epilog=""" epilog="""
@@ -65,6 +66,8 @@ def main() -> None:
parser.add_argument( parser.add_argument(
"--output-dir", "--output-dir",
type=Path,
default=Path(os.environ.get("CIBW_OUTPUT_DIR", "wheelhouse")),
help="Destination folder for the wheels. Default: wheelhouse.", help="Destination folder for the wheels. Default: wheelhouse.",
) )
@@ -72,20 +75,26 @@ def main() -> None:
"--config-file", "--config-file",
default="", default="",
help=""" help="""
TOML config file. Default: "", meaning {package}/pyproject.toml, TOML config file. Default: "", meaning {package}/pyproject.toml, if
if it exists. it exists. To refer to a project inside your project, use {package};
this matters if you build from an SDist.
""", """,
) )
parser.add_argument( parser.add_argument(
"package_dir", "package_dir",
default=".", metavar="PACKAGE",
default=Path("."),
type=Path,
nargs="?", nargs="?",
help=""" help="""
Path to the package that you want wheels for. Must be a subdirectory of Path to the package that you want wheels for. Default: the working
the working directory. When set, the working directory is still directory. Can be a directory inside the working directory, or an
considered the 'project' and is copied into the Docker container on sdist. When set to a directory, the working directory is still
Linux. Default: the working directory. considered the 'project' and is copied into the Docker container
on Linux. When set to a tar.gz sdist file, --config-file
and --output-dir are relative to the current directory, and other
paths are relative to the expanded SDist directory.
""", """,
) )
@@ -109,6 +118,38 @@ def main() -> None:
args = parser.parse_args(namespace=CommandLineArguments()) args = parser.parse_args(namespace=CommandLineArguments())
args.package_dir = args.package_dir.resolve()
# This are always relative to the base directory, even in SDist builds
args.output_dir = args.output_dir.resolve()
# Standard builds if a directory or non-existent path is given
if not args.package_dir.is_file() and not args.package_dir.name.endswith("tar.gz"):
build_in_directory(args)
return
# Tarfile builds require extraction and changing the directory
with tempfile.TemporaryDirectory(prefix="cibw-sdist-") as temp_dir_str:
temp_dir = Path(temp_dir_str)
with tarfile.open(args.package_dir) as tar:
tar.extractall(path=temp_dir)
# The extract directory is now the project dir
try:
(project_dir,) = temp_dir.iterdir()
except ValueError:
raise SystemExit("invalid sdist: didn't contain a single dir") from None
# This is now the new package dir
args.package_dir = project_dir.resolve()
with chdir(temp_dir):
build_in_directory(args)
def build_in_directory(args: CommandLineArguments) -> None:
platform: PlatformName
if args.platform != "auto": if args.platform != "auto":
platform = args.platform platform = args.platform
else: else:
+1 -1
View File
@@ -122,7 +122,7 @@ class DockerContainer:
if from_path.is_dir(): if from_path.is_dir():
self.call(["mkdir", "-p", to_path]) self.call(["mkdir", "-p", to_path])
subprocess.run( subprocess.run(
f"tar cf - . | docker exec -i {self.name} tar -xC {shell_quote(to_path)} -f -", f"tar cf - . | docker exec -i {self.name} tar --no-same-owner -xC {shell_quote(to_path)} -f -",
shell=True, shell=True,
check=True, check=True,
cwd=from_path, cwd=from_path,
-1
View File
@@ -51,7 +51,6 @@ class EnvironmentAssignment(Protocol):
executor: Optional[bashlex_eval.EnvironmentExecutor] = None, executor: Optional[bashlex_eval.EnvironmentExecutor] = None,
) -> str: ) -> str:
"""Returns the value of this assignment, as evaluated in the environment""" """Returns the value of this assignment, as evaluated in the environment"""
...
class EnvironmentAssignmentRaw: class EnvironmentAssignmentRaw:
+79 -63
View File
@@ -12,6 +12,7 @@ from .typing import OrderedDict, PathOrStr, assert_never
from .util import ( from .util import (
BuildSelector, BuildSelector,
NonPlatformWheelError, NonPlatformWheelError,
find_compatible_abi3_wheel,
get_build_verbosity_extra_flags, get_build_verbosity_extra_flags,
prepare_command, prepare_command,
read_python_configs, read_python_configs,
@@ -132,6 +133,8 @@ def build_on_docker(
) )
docker.call(["sh", "-c", before_all_prepared], env=env) docker.call(["sh", "-c", before_all_prepared], env=env)
built_wheels: List[PurePath] = []
for config in platform_configs: for config in platform_configs:
log.build_start(config.identifier) log.build_start(config.identifier)
build_options = options.build_options(config.identifier) build_options = options.build_options(config.identifier)
@@ -174,74 +177,83 @@ def build_on_docker(
) )
sys.exit(1) sys.exit(1)
if build_options.before_build: abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
log.step("Running before_build...") if abi3_wheel:
before_build_prepared = prepare_command( log.step_end()
build_options.before_build, print(
project=container_project_path, f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
package=container_package_dir,
)
docker.call(["sh", "-c", before_build_prepared], env=env)
log.step("Building wheel...")
temp_dir = PurePath("/tmp/cibuildwheel")
built_wheel_dir = temp_dir / "built_wheel"
docker.call(["rm", "-rf", built_wheel_dir])
docker.call(["mkdir", "-p", built_wheel_dir])
verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
if build_options.build_frontend == "pip":
docker.call(
[
"python",
"-m",
"pip",
"wheel",
container_package_dir,
f"--wheel-dir={built_wheel_dir}",
"--no-deps",
*verbosity_flags,
],
env=env,
)
elif build_options.build_frontend == "build":
config_setting = " ".join(verbosity_flags)
docker.call(
[
"python",
"-m",
"build",
container_package_dir,
"--wheel",
f"--outdir={built_wheel_dir}",
f"--config-setting={config_setting}",
],
env=env,
) )
repaired_wheels = [abi3_wheel]
else: else:
assert_never(build_options.build_frontend)
built_wheel = docker.glob(built_wheel_dir, "*.whl")[0] if build_options.before_build:
log.step("Running before_build...")
before_build_prepared = prepare_command(
build_options.before_build,
project=container_project_path,
package=container_package_dir,
)
docker.call(["sh", "-c", before_build_prepared], env=env)
repaired_wheel_dir = temp_dir / "repaired_wheel" log.step("Building wheel...")
docker.call(["rm", "-rf", repaired_wheel_dir])
docker.call(["mkdir", "-p", repaired_wheel_dir])
if built_wheel.name.endswith("none-any.whl"): temp_dir = PurePath("/tmp/cibuildwheel")
raise NonPlatformWheelError() built_wheel_dir = temp_dir / "built_wheel"
docker.call(["rm", "-rf", built_wheel_dir])
docker.call(["mkdir", "-p", built_wheel_dir])
if build_options.repair_command: verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
log.step("Repairing wheel...")
repair_command_prepared = prepare_command(
build_options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir
)
docker.call(["sh", "-c", repair_command_prepared], env=env)
else:
docker.call(["mv", built_wheel, repaired_wheel_dir])
repaired_wheels = docker.glob(repaired_wheel_dir, "*.whl") if build_options.build_frontend == "pip":
docker.call(
[
"python",
"-m",
"pip",
"wheel",
container_package_dir,
f"--wheel-dir={built_wheel_dir}",
"--no-deps",
*verbosity_flags,
],
env=env,
)
elif build_options.build_frontend == "build":
config_setting = " ".join(verbosity_flags)
docker.call(
[
"python",
"-m",
"build",
container_package_dir,
"--wheel",
f"--outdir={built_wheel_dir}",
f"--config-setting={config_setting}",
],
env=env,
)
else:
assert_never(build_options.build_frontend)
built_wheel = docker.glob(built_wheel_dir, "*.whl")[0]
repaired_wheel_dir = temp_dir / "repaired_wheel"
docker.call(["rm", "-rf", repaired_wheel_dir])
docker.call(["mkdir", "-p", repaired_wheel_dir])
if built_wheel.name.endswith("none-any.whl"):
raise NonPlatformWheelError()
if build_options.repair_command:
log.step("Repairing wheel...")
repair_command_prepared = prepare_command(
build_options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir
)
docker.call(["sh", "-c", repair_command_prepared], env=env)
else:
docker.call(["mv", built_wheel, repaired_wheel_dir])
repaired_wheels = docker.glob(repaired_wheel_dir, "*.whl")
if build_options.test_command and build_options.test_selector(config.identifier): if build_options.test_command and build_options.test_selector(config.identifier):
log.step("Testing wheel...") log.step("Testing wheel...")
@@ -292,8 +304,12 @@ def build_on_docker(
docker.call(["rm", "-rf", venv_dir]) docker.call(["rm", "-rf", venv_dir])
# move repaired wheels to output # move repaired wheels to output
docker.call(["mkdir", "-p", container_output_dir]) if abi3_wheel is None:
docker.call(["mv", *repaired_wheels, container_output_dir]) docker.call(["mkdir", "-p", container_output_dir])
docker.call(["mv", *repaired_wheels, container_output_dir])
built_wheels.extend(
container_output_dir / repaired_wheel.name for repaired_wheel in repaired_wheels
)
log.build_end() log.build_end()
+88 -70
View File
@@ -23,6 +23,7 @@ from .util import (
call, call,
detect_ci_provider, detect_ci_provider,
download, download,
find_compatible_abi3_wheel,
get_build_verbosity_extra_flags, get_build_verbosity_extra_flags,
get_pip_version, get_pip_version,
install_certifi_script, install_certifi_script,
@@ -275,6 +276,9 @@ def build(options: Options, tmp_path: Path) -> None:
options.globals.build_selector, options.globals.architectures options.globals.build_selector, options.globals.architectures
) )
if len(python_configurations) == 0:
return
try: try:
before_all_options_identifier = python_configurations[0].identifier before_all_options_identifier = python_configurations[0].identifier
before_all_options = options.build_options(before_all_options_identifier) before_all_options = options.build_options(before_all_options_identifier)
@@ -288,6 +292,8 @@ def build(options: Options, tmp_path: Path) -> None:
) )
shell(before_all_prepared, env=env) shell(before_all_prepared, env=env)
built_wheels: List[Path] = []
for config in python_configurations: for config in python_configurations:
build_options = options.build_options(config.identifier) build_options = options.build_options(config.identifier)
log.build_start(config.identifier) log.build_start(config.identifier)
@@ -315,84 +321,94 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.build_frontend, build_options.build_frontend,
) )
if build_options.before_build: abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
log.step("Running before_build...") if abi3_wheel:
before_build_prepared = prepare_command( log.step_end()
build_options.before_build, project=".", package=build_options.package_dir print(
f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
) )
shell(before_build_prepared, env=env) repaired_wheel = abi3_wheel
else:
log.step("Building wheel...") if build_options.before_build:
built_wheel_dir.mkdir() log.step("Running before_build...")
before_build_prepared = prepare_command(
verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity) build_options.before_build, project=".", package=build_options.package_dir
if build_options.build_frontend == "pip":
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/pypa/cibuildwheel/pull/369
call(
"python",
"-m",
"pip",
"wheel",
build_options.package_dir.resolve(),
f"--wheel-dir={built_wheel_dir}",
"--no-deps",
*verbosity_flags,
env=env,
)
elif build_options.build_frontend == "build":
config_setting = " ".join(verbosity_flags)
build_env = env.copy()
if build_options.dependency_constraints:
constraint_path = build_options.dependency_constraints.get_for_python_version(
config.version
) )
build_env["PIP_CONSTRAINT"] = constraint_path.as_uri() shell(before_build_prepared, env=env)
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
call(
"python",
"-m",
"build",
build_options.package_dir,
"--wheel",
f"--outdir={built_wheel_dir}",
f"--config-setting={config_setting}",
env=build_env,
)
else:
assert_never(build_options.build_frontend)
built_wheel = next(built_wheel_dir.glob("*.whl")) log.step("Building wheel...")
built_wheel_dir.mkdir()
repaired_wheel_dir.mkdir() verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
if built_wheel.name.endswith("none-any.whl"): if build_options.build_frontend == "pip":
raise NonPlatformWheelError() # Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/pypa/cibuildwheel/pull/369
if build_options.repair_command: call(
log.step("Repairing wheel...") "python",
"-m",
if config_is_universal2: "pip",
delocate_archs = "x86_64,arm64" "wheel",
elif config_is_arm64: build_options.package_dir.resolve(),
delocate_archs = "arm64" f"--wheel-dir={built_wheel_dir}",
"--no-deps",
*verbosity_flags,
env=env,
)
elif build_options.build_frontend == "build":
config_setting = " ".join(verbosity_flags)
build_env = env.copy()
if build_options.dependency_constraints:
constraint_path = (
build_options.dependency_constraints.get_for_python_version(
config.version
)
)
build_env["PIP_CONSTRAINT"] = constraint_path.as_uri()
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
call(
"python",
"-m",
"build",
build_options.package_dir,
"--wheel",
f"--outdir={built_wheel_dir}",
f"--config-setting={config_setting}",
env=build_env,
)
else: else:
delocate_archs = "x86_64" assert_never(build_options.build_frontend)
repair_command_prepared = prepare_command( built_wheel = next(built_wheel_dir.glob("*.whl"))
build_options.repair_command,
wheel=built_wheel,
dest_dir=repaired_wheel_dir,
delocate_archs=delocate_archs,
)
shell(repair_command_prepared, env=env)
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
repaired_wheel = next(repaired_wheel_dir.glob("*.whl")) repaired_wheel_dir.mkdir()
log.step_end() if built_wheel.name.endswith("none-any.whl"):
raise NonPlatformWheelError()
if build_options.repair_command:
log.step("Repairing wheel...")
if config_is_universal2:
delocate_archs = "x86_64,arm64"
elif config_is_arm64:
delocate_archs = "arm64"
else:
delocate_archs = "x86_64"
repair_command_prepared = prepare_command(
build_options.repair_command,
wheel=built_wheel,
dest_dir=repaired_wheel_dir,
delocate_archs=delocate_archs,
)
shell(repair_command_prepared, env=env)
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
log.step_end()
if build_options.test_command and build_options.test_selector(config.identifier): if build_options.test_command and build_options.test_selector(config.identifier):
machine_arch = platform.machine() machine_arch = platform.machine()
@@ -518,7 +534,9 @@ def build(options: Options, tmp_path: Path) -> None:
) )
# we're all done here; move it to output (overwrite existing) # we're all done here; move it to output (overwrite existing)
shutil.move(str(repaired_wheel), build_options.output_dir) if abi3_wheel is None:
shutil.move(str(repaired_wheel), build_options.output_dir)
built_wheels.append(build_options.output_dir / repaired_wheel.name)
# clean up # clean up
shutil.rmtree(identifier_tmp_dir) shutil.rmtree(identifier_tmp_dir)
+14 -13
View File
@@ -8,7 +8,7 @@ from pathlib import Path
from typing import ( from typing import (
Any, Any,
Dict, Dict,
Iterator, Generator,
List, List,
Mapping, Mapping,
NamedTuple, NamedTuple,
@@ -18,7 +18,11 @@ from typing import (
Union, Union,
) )
import tomli if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
from packaging.specifiers import SpecifierSet from packaging.specifiers import SpecifierSet
from .architecture import Architecture from .architecture import Architecture
@@ -33,6 +37,7 @@ from .util import (
DependencyConstraints, DependencyConstraints,
TestSelector, TestSelector,
cached_property, cached_property,
format_safe,
resources_dir, resources_dir,
selector_matches, selector_matches,
strtobool, strtobool,
@@ -43,9 +48,9 @@ from .util import (
class CommandLineArguments: class CommandLineArguments:
platform: Literal["auto", "linux", "macos", "windows"] platform: Literal["auto", "linux", "macos", "windows"]
archs: Optional[str] archs: Optional[str]
output_dir: Optional[str] output_dir: Path
config_file: str config_file: str
package_dir: str package_dir: Path
print_build_identifiers: bool print_build_identifiers: bool
allow_empty: bool allow_empty: bool
prerelease_pythons: bool prerelease_pythons: bool
@@ -244,7 +249,7 @@ class OptionsReader:
Load a toml file, returns global and platform as separate dicts. Load a toml file, returns global and platform as separate dicts.
""" """
with filename.open("rb") as f: with filename.open("rb") as f:
config = tomli.load(f) config = tomllib.load(f)
global_options = config.get("tool", {}).get("cibuildwheel", {}) global_options = config.get("tool", {}).get("cibuildwheel", {})
platform_options = global_options.get(self.platform, {}) platform_options = global_options.get(self.platform, {})
@@ -260,7 +265,7 @@ class OptionsReader:
] ]
@contextmanager @contextmanager
def identifier(self, identifier: Optional[str]) -> Iterator[None]: def identifier(self, identifier: Optional[str]) -> Generator[None, None, None]:
self.current_identifier = identifier self.current_identifier = identifier
try: try:
yield yield
@@ -341,7 +346,7 @@ class Options:
args = self.command_line_arguments args = self.command_line_arguments
if args.config_file: if args.config_file:
return Path(args.config_file.format(package=args.package_dir)) return Path(format_safe(args.config_file, package=args.package_dir))
# return pyproject.toml, if it's available # return pyproject.toml, if it's available
pyproject_toml_path = Path(args.package_dir) / "pyproject.toml" pyproject_toml_path = Path(args.package_dir) / "pyproject.toml"
@@ -358,12 +363,8 @@ class Options:
@property @property
def globals(self) -> GlobalOptions: def globals(self) -> GlobalOptions:
args = self.command_line_arguments args = self.command_line_arguments
package_dir = Path(args.package_dir) package_dir = args.package_dir
output_dir = Path( output_dir = args.output_dir
args.output_dir
if args.output_dir is not None
else os.environ.get("CIBW_OUTPUT_DIR", "wheelhouse")
)
build_config = self.reader.get("build", env_plat=False, sep=" ") or "*" build_config = self.reader.get("build", env_plat=False, sep=" ") or "*"
skip_config = self.reader.get("skip", env_plat=False, sep=" ") skip_config = self.reader.get("skip", env_plat=False, sep=" ")
+5 -2
View File
@@ -4,7 +4,10 @@ from configparser import ConfigParser
from pathlib import Path from pathlib import Path
from typing import Any, Optional from typing import Any, Optional
import tomli if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
if sys.version_info < (3, 8): if sys.version_info < (3, 8):
Constant = ast.Str Constant = ast.Str
@@ -56,7 +59,7 @@ def get_requires_python_str(package_dir: Path) -> Optional[str]:
# Read in from pyproject.toml:project.requires-python # Read in from pyproject.toml:project.requires-python
try: try:
with (package_dir / "pyproject.toml").open("rb") as f1: with (package_dir / "pyproject.toml").open("rb") as f1:
info = tomli.load(f1) info = tomllib.load(f1)
return str(info["project"]["requires-python"]) return str(info["project"]["requires-python"])
except (FileNotFoundError, KeyError, IndexError, TypeError): except (FileNotFoundError, KeyError, IndexError, TypeError):
pass pass
@@ -26,5 +26,5 @@ wheel==0.37.1
# The following packages are considered to be unsafe in a requirements file: # The following packages are considered to be unsafe in a requirements file:
pip==22.0.4 pip==22.0.4
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
setuptools==61.3.0 setuptools==61.3.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
@@ -26,11 +26,11 @@ wheel==0.37.1
# via # via
# -r cibuildwheel/resources/constraints.in # -r cibuildwheel/resources/constraints.in
# delocate # delocate
zipp==3.7.0 zipp==3.8.0
# via importlib-metadata # via importlib-metadata
# The following packages are considered to be unsafe in a requirements file: # The following packages are considered to be unsafe in a requirements file:
pip==22.0.4 pip==22.0.4
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
setuptools==61.3.0 setuptools==61.3.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
@@ -26,5 +26,5 @@ wheel==0.37.1
# The following packages are considered to be unsafe in a requirements file: # The following packages are considered to be unsafe in a requirements file:
pip==22.0.4 pip==22.0.4
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
setuptools==61.3.0 setuptools==61.3.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
@@ -26,5 +26,5 @@ wheel==0.37.1
# The following packages are considered to be unsafe in a requirements file: # The following packages are considered to be unsafe in a requirements file:
pip==22.0.4 pip==22.0.4
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
setuptools==61.3.0 setuptools==61.3.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
+1 -1
View File
@@ -26,5 +26,5 @@ wheel==0.37.1
# The following packages are considered to be unsafe in a requirements file: # The following packages are considered to be unsafe in a requirements file:
pip==22.0.4 pip==22.0.4
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
setuptools==61.3.0 setuptools==61.3.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
+27 -27
View File
@@ -1,43 +1,43 @@
[x86_64] [x86_64]
manylinux1 = quay.io/pypa/manylinux1_x86_64:2022-03-31-9afae1d manylinux1 = quay.io/pypa/manylinux1_x86_64:2022-04-03-9524524
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-03-31-361e6b6 manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-04-03-da6ecb3
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-04-03-da6ecb3
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2022-03-31-361e6b6 musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2022-04-03-da6ecb3
[i686] [i686]
manylinux1 = quay.io/pypa/manylinux1_i686:2022-03-31-9afae1d manylinux1 = quay.io/pypa/manylinux1_i686:2022-04-03-9524524
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-03-31-361e6b6 manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-04-03-da6ecb3
manylinux2014 = quay.io/pypa/manylinux2014_i686:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_i686:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-04-03-da6ecb3
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2022-03-31-361e6b6 musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2022-04-03-da6ecb3
[pypy_x86_64] [pypy_x86_64]
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-03-31-361e6b6 manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-04-03-da6ecb3
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-04-03-da6ecb3
[pypy_i686] [pypy_i686]
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-03-31-361e6b6 manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-04-03-da6ecb3
manylinux2014 = quay.io/pypa/manylinux2014_i686:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_i686:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-04-03-da6ecb3
[aarch64] [aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-04-03-da6ecb3
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2022-03-31-361e6b6 musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2022-04-03-da6ecb3
[ppc64le] [ppc64le]
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-04-03-da6ecb3
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2022-03-31-361e6b6 musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2022-04-03-da6ecb3
[s390x] [s390x]
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_s390x:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-04-03-da6ecb3
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2022-03-31-361e6b6 musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2022-04-03-da6ecb3
[pypy_aarch64] [pypy_aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2022-03-31-361e6b6 manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2022-04-03-da6ecb3
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-03-31-361e6b6 manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-04-03-da6ecb3
+69 -6
View File
@@ -13,29 +13,37 @@ import time
import urllib.request import urllib.request
from enum import Enum from enum import Enum
from functools import lru_cache from functools import lru_cache
from pathlib import Path from pathlib import Path, PurePath
from time import sleep from time import sleep
from typing import ( from typing import (
Any, Any,
ClassVar, ClassVar,
Dict, Dict,
Generator,
Iterable, Iterable,
Iterator,
List, List,
NamedTuple, NamedTuple,
Optional, Optional,
Sequence, Sequence,
TextIO, TextIO,
TypeVar,
Union,
cast, cast,
overload, overload,
) )
import bracex import bracex
import certifi import certifi
import tomli
if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
from filelock import FileLock from filelock import FileLock
from packaging.requirements import InvalidRequirement, Requirement from packaging.requirements import InvalidRequirement, Requirement
from packaging.specifiers import SpecifierSet from packaging.specifiers import SpecifierSet
from packaging.utils import parse_wheel_filename
from packaging.version import Version from packaging.version import Version
from platformdirs import user_cache_path from platformdirs import user_cache_path
@@ -46,6 +54,7 @@ __all__ = [
"MANYLINUX_ARCHS", "MANYLINUX_ARCHS",
"call", "call",
"shell", "shell",
"find_compatible_abi3_wheel",
"format_safe", "format_safe",
"prepare_command", "prepare_command",
"get_build_verbosity_extra_flags", "get_build_verbosity_extra_flags",
@@ -53,6 +62,7 @@ __all__ = [
"selector_matches", "selector_matches",
"strtobool", "strtobool",
"cached_property", "cached_property",
"chdir",
] ]
resources_dir: Final = Path(__file__).parent / "resources" resources_dir: Final = Path(__file__).parent / "resources"
@@ -203,7 +213,7 @@ def get_build_verbosity_extra_flags(level: int) -> List[str]:
def read_python_configs(config: PlatformName) -> List[Dict[str, str]]: def read_python_configs(config: PlatformName) -> List[Dict[str, str]]:
input_file = resources_dir / "build-platforms.toml" input_file = resources_dir / "build-platforms.toml"
with input_file.open("rb") as f: with input_file.open("rb") as f:
loaded_file = tomli.load(f) loaded_file = tomllib.load(f)
results: List[Dict[str, str]] = list(loaded_file[config]["python_configurations"]) results: List[Dict[str, str]] = list(loaded_file[config]["python_configurations"])
return results return results
@@ -409,7 +419,7 @@ def unwrap(text: str) -> str:
@contextlib.contextmanager @contextlib.contextmanager
def print_new_wheels(msg: str, output_dir: Path) -> Iterator[None]: def print_new_wheels(msg: str, output_dir: Path) -> Generator[None, None, None]:
""" """
Prints the new items in a directory upon exiting. The message to display Prints the new items in a directory upon exiting. The message to display
can include {n} for number of wheels, {s} for total number of seconds, can include {n} for number of wheels, {s} for total number of seconds,
@@ -430,6 +440,10 @@ def print_new_wheels(msg: str, output_dir: Path) -> Iterator[None]:
FileReport(wheel.name, f"{(wheel.stat().st_size + 1023) // 1024:,d}") FileReport(wheel.name, f"{(wheel.stat().st_size + 1023) // 1024:,d}")
for wheel in final_contents - existing_contents for wheel in final_contents - existing_contents
] ]
if len(new_contents) == 0:
return
max_name_len = max(len(f.name) for f in new_contents) max_name_len = max(len(f.name) for f in new_contents)
max_size_len = max(len(f.size) for f in new_contents) max_size_len = max(len(f.size) for f in new_contents)
n = len(new_contents) n = len(new_contents)
@@ -460,7 +474,7 @@ def get_pip_version(env: Dict[str, str]) -> str:
def _ensure_virtualenv() -> Path: def _ensure_virtualenv() -> Path:
input_file = resources_dir / "virtualenv.toml" input_file = resources_dir / "virtualenv.toml"
with input_file.open("rb") as f: with input_file.open("rb") as f:
loaded_file = tomli.load(f) loaded_file = tomllib.load(f)
version = str(loaded_file["version"]) version = str(loaded_file["version"])
url = str(loaded_file["url"]) url = str(loaded_file["url"])
path = CIBW_CACHE_PATH / f"virtualenv-{version}.pyz" path = CIBW_CACHE_PATH / f"virtualenv-{version}.pyz"
@@ -557,7 +571,56 @@ def virtualenv(
return env return env
T = TypeVar("T", bound=PurePath)
def find_compatible_abi3_wheel(wheels: Sequence[T], identifier: str) -> Optional[T]:
"""
Finds an ABI3 wheel in `wheels` compatible with the Python interpreter
specified by `identifier`.
"""
interpreter, platform = identifier.split("-")
if not interpreter.startswith("cp3"):
return None
for wheel in wheels:
_, _, _, tags = parse_wheel_filename(wheel.name)
for tag in tags:
if tag.abi != "abi3":
continue
if not tag.interpreter.startswith("cp3"):
continue
if int(tag.interpreter[3:]) > int(interpreter[3:]):
continue
if platform.startswith(("manylinux", "musllinux", "macosx")):
# Linux, macOS
os_, arch = platform.split("_", 1)
if not tag.platform.startswith(os_):
continue
if not tag.platform.endswith("_" + arch):
continue
else:
# Windows
if not tag.platform == platform:
continue
return wheel
return None
if sys.version_info >= (3, 8): if sys.version_info >= (3, 8):
from functools import cached_property from functools import cached_property
else: else:
from .functools_cached_property_38 import cached_property from .functools_cached_property_38 import cached_property
# Can be replaced by contextlib.chdir in Python 3.11
@contextlib.contextmanager
def chdir(new_path: Union[Path, str]) -> Generator[None, None, None]:
"""Non thread-safe context manager to change the current working directory."""
cwd = os.getcwd()
try:
os.chdir(new_path)
yield
finally:
os.chdir(cwd)
+84 -66
View File
@@ -22,6 +22,7 @@ from .util import (
NonPlatformWheelError, NonPlatformWheelError,
call, call,
download, download,
find_compatible_abi3_wheel,
get_build_verbosity_extra_flags, get_build_verbosity_extra_flags,
get_pip_version, get_pip_version,
prepare_command, prepare_command,
@@ -234,6 +235,9 @@ def build(options: Options, tmp_path: Path) -> None:
options.globals.build_selector, options.globals.architectures options.globals.build_selector, options.globals.architectures
) )
if len(python_configurations) == 0:
return
try: try:
before_all_options_identifier = python_configurations[0].identifier before_all_options_identifier = python_configurations[0].identifier
before_all_options = options.build_options(before_all_options_identifier) before_all_options = options.build_options(before_all_options_identifier)
@@ -246,6 +250,8 @@ def build(options: Options, tmp_path: Path) -> None:
) )
shell(before_all_prepared, env=env) shell(before_all_prepared, env=env)
built_wheels: List[Path] = []
for config in python_configurations: for config in python_configurations:
build_options = options.build_options(config.identifier) build_options = options.build_options(config.identifier)
log.build_start(config.identifier) log.build_start(config.identifier)
@@ -271,83 +277,93 @@ def build(options: Options, tmp_path: Path) -> None:
build_options.build_frontend, build_options.build_frontend,
) )
# run the before_build command abi3_wheel = find_compatible_abi3_wheel(built_wheels, config.identifier)
if build_options.before_build: if abi3_wheel:
log.step("Running before_build...") log.step_end()
before_build_prepared = prepare_command( print(
build_options.before_build, project=".", package=options.globals.package_dir f"\nFound previously built wheel {abi3_wheel.name}, that's compatible with {config.identifier}. Skipping build step..."
) )
shell(before_build_prepared, env=env) repaired_wheel = abi3_wheel
else:
log.step("Building wheel...") # run the before_build command
built_wheel_dir.mkdir() if build_options.before_build:
log.step("Running before_build...")
verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity) before_build_prepared = prepare_command(
build_options.before_build, project=".", package=options.globals.package_dir
if build_options.build_frontend == "pip":
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/pypa/cibuildwheel/pull/369
call(
"python",
"-m",
"pip",
"wheel",
options.globals.package_dir.resolve(),
f"--wheel-dir={built_wheel_dir}",
"--no-deps",
*get_build_verbosity_extra_flags(build_options.build_verbosity),
env=env,
)
elif build_options.build_frontend == "build":
config_setting = " ".join(verbosity_flags)
build_env = env.copy()
if build_options.dependency_constraints:
constraints_path = build_options.dependency_constraints.get_for_python_version(
config.version
) )
# Bug in pip <= 21.1.3 - we can't have a space in the shell(before_build_prepared, env=env)
# constraints file, and pip doesn't support drive letters
# in uhi. After probably pip 21.2, we can use uri. For
# now, use a temporary file.
if " " in str(constraints_path):
assert " " not in str(identifier_tmp_dir)
tmp_file = identifier_tmp_dir / "constraints.txt"
tmp_file.write_bytes(constraints_path.read_bytes())
constraints_path = tmp_file
build_env["PIP_CONSTRAINT"] = str(constraints_path) log.step("Building wheel...")
build_env["VIRTUALENV_PIP"] = get_pip_version(env) built_wheel_dir.mkdir()
verbosity_flags = get_build_verbosity_extra_flags(build_options.build_verbosity)
if build_options.build_frontend == "pip":
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
# see https://github.com/pypa/cibuildwheel/pull/369
call( call(
"python", "python",
"-m", "-m",
"build", "pip",
build_options.package_dir, "wheel",
"--wheel", options.globals.package_dir.resolve(),
f"--outdir={built_wheel_dir}", f"--wheel-dir={built_wheel_dir}",
f"--config-setting={config_setting}", "--no-deps",
env=build_env, *get_build_verbosity_extra_flags(build_options.build_verbosity),
env=env,
) )
else: elif build_options.build_frontend == "build":
assert_never(build_options.build_frontend) config_setting = " ".join(verbosity_flags)
build_env = env.copy()
if build_options.dependency_constraints:
constraints_path = (
build_options.dependency_constraints.get_for_python_version(
config.version
)
)
# Bug in pip <= 21.1.3 - we can't have a space in the
# constraints file, and pip doesn't support drive letters
# in uhi. After probably pip 21.2, we can use uri. For
# now, use a temporary file.
if " " in str(constraints_path):
assert " " not in str(identifier_tmp_dir)
tmp_file = identifier_tmp_dir / "constraints.txt"
tmp_file.write_bytes(constraints_path.read_bytes())
constraints_path = tmp_file
built_wheel = next(built_wheel_dir.glob("*.whl")) build_env["PIP_CONSTRAINT"] = str(constraints_path)
build_env["VIRTUALENV_PIP"] = get_pip_version(env)
call(
"python",
"-m",
"build",
build_options.package_dir,
"--wheel",
f"--outdir={built_wheel_dir}",
f"--config-setting={config_setting}",
env=build_env,
)
else:
assert_never(build_options.build_frontend)
# repair the wheel built_wheel = next(built_wheel_dir.glob("*.whl"))
repaired_wheel_dir.mkdir()
if built_wheel.name.endswith("none-any.whl"): # repair the wheel
raise NonPlatformWheelError() repaired_wheel_dir.mkdir()
if build_options.repair_command: if built_wheel.name.endswith("none-any.whl"):
log.step("Repairing wheel...") raise NonPlatformWheelError()
repair_command_prepared = prepare_command(
build_options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir
)
shell(repair_command_prepared, env=env)
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
repaired_wheel = next(repaired_wheel_dir.glob("*.whl")) if build_options.repair_command:
log.step("Repairing wheel...")
repair_command_prepared = prepare_command(
build_options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir
)
shell(repair_command_prepared, env=env)
else:
shutil.move(str(built_wheel), repaired_wheel_dir)
repaired_wheel = next(repaired_wheel_dir.glob("*.whl"))
if build_options.test_command and options.globals.test_selector(config.identifier): if build_options.test_command and options.globals.test_selector(config.identifier):
log.step("Testing wheel...") log.step("Testing wheel...")
@@ -402,7 +418,9 @@ def build(options: Options, tmp_path: Path) -> None:
shell(test_command_prepared, cwd="c:\\", env=virtualenv_env) shell(test_command_prepared, cwd="c:\\", env=virtualenv_env)
# we're all done here; move it to output (remove if already exists) # we're all done here; move it to output (remove if already exists)
shutil.move(str(repaired_wheel), build_options.output_dir) if abi3_wheel is None:
shutil.move(str(repaired_wheel), build_options.output_dir)
built_wheels.append(build_options.output_dir / repaired_wheel.name)
# clean up # clean up
# (we ignore errors because occasionally Windows fails to unlink a file and we # (we ignore errors because occasionally Windows fails to unlink a file and we
+10
View File
@@ -2,6 +2,16 @@
title: Changelog title: Changelog
--- ---
### v2.5.0
_29 April 2022_
- ✨ Added support for building ABI3 wheels. cibuildwheel will now recognise when an ABI3 wheel was produced, and skip subsequent build steps where the previously built wheel is compatible. Tests still will run on all selected versions of Python, using the ABI3 wheel. (#1091)
- ✨ You can now build wheels directly from sdist archives, in addition to source directories. Just call cibuildwheel with an sdist argument on the command line, like `cibuildwheel mypackage-1.0.0.tar.gz` (#1096)
- 🐛 Fix a bug where cibuildwheel would crash when no builds are selected and `--allow-empty` is passed (#1086)
- 🐛 Workaround a permissions issue on Linux relating to newer versions of git and setuptools_scm (#1095)
- 📚 Minor docs improvements
### v2.4.0 ### v2.4.0
_2 April 2022_ _2 April 2022_
+1 -1
View File
@@ -14,7 +14,7 @@ The old `manylinux1` image (based on CentOS 5) contains a version of GCC and lib
OS X/macOS allows you to specify a so-called "deployment target" version that will ensure backwards compatibility with older versions of macOS. One way to do this is by setting the `MACOSX_DEPLOYMENT_TARGET` environment variable. OS X/macOS allows you to specify a so-called "deployment target" version that will ensure backwards compatibility with older versions of macOS. One way to do this is by setting the `MACOSX_DEPLOYMENT_TARGET` environment variable.
However, to enable modern C++ standards, the deploment target needs to be set high enough (since older OS X/macOS versions did not have the necessary modern C++ standard library). However, to enable modern C++ standards, the deployment target needs to be set high enough (since older OS X/macOS versions did not have the necessary modern C++ standard library).
To get C++11 and C++14 support, `MACOSX_DEPLOYMENT_TARGET` needs to be set to (at least) `"10.9"`. By default, `cibuildwheel` already does this, building 64-bit-only wheels for macOS 10.9 and later. To get C++11 and C++14 support, `MACOSX_DEPLOYMENT_TARGET` needs to be set to (at least) `"10.9"`. By default, `cibuildwheel` already does this, building 64-bit-only wheels for macOS 10.9 and later.
+63 -2
View File
@@ -287,7 +287,7 @@
pypi: mypy pypi: mypy
ci: [github] ci: [github]
os: [apple, linux, windows] os: [apple, linux, windows]
notes: MyPyC, the compiled component of MyPy. notes: The compiled version of MyPy using MyPyC.
- name: Imagecodecs (fork) - name: Imagecodecs (fork)
gh: czaki/imagecodecs_build gh: czaki/imagecodecs_build
@@ -521,10 +521,71 @@
gh: arbor-sim/arbor gh: arbor-sim/arbor
ci: [github] ci: [github]
os: [apple, linux] os: [apple, linux]
pypi: arbor
notes: > notes: >
Arbor is a multi-compartment neuron simulation library; compatible with Arbor is a multi-compartment neuron simulation library; compatible with
next-generation accelerators; best-practices applied to research software; next-generation accelerators; best-practices applied to research software;
focused on community-driven development. Includes a focused on community-driven development. Includes a
[small script](https://github.com/arbor-sim/arbor/blob/master/scripts/patchwheel.py) [small script](https://github.com/arbor-sim/arbor/blob/master/scripts/patchwheel.py)
patching `rpath` in bundled libraries. patching `rpath` in bundled libraries.
- name: Kivy
gh: kivy/kivy
ci: [github]
os: [windows, apple, linux]
- name: NCNN
gh: Tencent/ncnn
ci: [github]
os: [windows, apple, linux]
- name: Prophet
gh: facebook/prophet
ci: [github]
os: [windows, apple, linux]
- name: MemRay
gh: bloomberg/memray
ci: [github]
os: [linux]
- name: PyGame
gh: pygame/pygame
ci: [github]
os: [apple, linux]
- name: UltraJSON
gh: ultrajson/ultrajson
ci: [github]
os: [windows, apple, linux]
- name: NumPy
gh: numpy/numpy
ci: [github, travisci]
os: [windows, apple, linux]
- name: Wrapt
gh: GrahamDumpleton/wrapt
ci: [github]
os: [windows, apple, linux]
- name: SimpleJSON
gh: simplejson/simplejson
ci: [github]
os: [windows, apple, linux]
- name: Implicit
gh: benfred/implicit
ci: [github]
os: [windows, apple, linux]
notes: Includes GPU support for linux wheels
- name: power-grid-model
gh: alliander-opensource/power-grid-model
ci: [github]
os: [windows, apple, linux]
notes: Python/C++ library for distribution power system analysis
- name: Python-WebRTC
gh: MarshalX/python-webrtc
ci: [github]
os: [windows, apple, linux]
+26 -20
View File
@@ -103,6 +103,12 @@ Linux), and the other architectures are emulated automatically.
{% include "../examples/github-with-qemu.yml" %} {% include "../examples/github-with-qemu.yml" %}
``` ```
### Building CPython ABI3 wheels (Limited API) {: #abi3}
The CPython Limited API is a subset of the Python C Extension API that's declared to be forward-compatible, meaning you can compile wheels for one version of Python, and they'll be compatible with future versions. Wheels that use the Limited API are known as ABI3 wheels.
To create a package that builds ABI3 wheels, you'll need to configure your build backend to compile libraries correctly create wheels with the right tags. [Check this repo](https://github.com/joerick/python-abi3-package-sample) for an example of how to do this with setuptools.
### Building packages with optional C extensions ### Building packages with optional C extensions
`cibuildwheel` defines the environment variable `CIBUILDWHEEL` to the value `1` allowing projects for which the C extension is optional to make it mandatory when building wheels. `cibuildwheel` defines the environment variable `CIBUILDWHEEL` to the value `1` allowing projects for which the C extension is optional to make it mandatory when building wheels.
@@ -127,7 +133,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: If you use GitHub Actions for builds, you can use cibuildwheel as an action:
```yaml ```yaml
uses: pypa/cibuildwheel@v2.4.0 uses: pypa/cibuildwheel@v2.5.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. 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.
@@ -153,7 +159,7 @@ The second option, and the only one that supports other CI systems, is using a `
```bash ```bash
# requirements-cibw.txt # requirements-cibw.txt
cibuildwheel==2.4.0 cibuildwheel==2.5.0
``` ```
Then your install step would have `python -m pip install -r requirements-cibw.txt` in it. Your `.github/dependabot.yml` file could look like this: Then your install step would have `python -m pip install -r requirements-cibw.txt` in it. Your `.github/dependabot.yml` file could look like this:
@@ -179,7 +185,7 @@ package 'sdist' will also benefit.
#### Missing build dependencies {: #cibw-options-alternatives-deps} #### Missing build dependencies {: #cibw-options-alternatives-deps}
If your build needs Python dependencies, rather than using CIBW_BEFORE_BUILD, it's best to add these to the If your build needs Python dependencies, rather than using `CIBW_BEFORE_BUILD`, it's best to add these to the
[`build-system.requires`](https://www.python.org/dev/peps/pep-0518/#build-system-table) [`build-system.requires`](https://www.python.org/dev/peps/pep-0518/#build-system-table)
section of your pyproject.toml. For example, if your project requires Cython section of your pyproject.toml. For example, if your project requires Cython
to build, your pyproject.toml might include a section like this: to build, your pyproject.toml might include a section like this:
@@ -201,35 +207,35 @@ You might need to run some other commands before building, like running a
script that performs codegen or downloading some data that's not stored in script that performs codegen or downloading some data that's not stored in
your source tree. your source tree.
Rather than using CIBW_BEFORE_ALL or CIBW_BEFORE_BUILD, you could incorporate Rather than using `CIBW_BEFORE_ALL` or `CIBW_BEFORE_BUILD`, you could incorporate
these steps into your package's build process. For example, if you're using these steps into your package's build process. For example, if you're using
setuptools, you can add steps to your package's `setup.py` using a structure setuptools, you can add steps to your package's `setup.py` using a structure
like this: like this:
```python ```python
import subprocess import subprocess
import setuptools import setuptools
import setuptools.command.build_py import setuptools.command.build_py
class BuildPyCommand(setuptools.command.build_py.build_py): class BuildPyCommand(setuptools.command.build_py.build_py):
"""Custom build command.""" """Custom build command."""
def run(self): def run(self):
# your custom build steps here # your custom build steps here
# e.g. # e.g.
# subprocess.run(['python', 'scripts/my_custom_script.py'], check=True) # subprocess.run(['python', 'scripts/my_custom_script.py'], check=True)
setuptools.command.build_py.build_py.run(self) setuptools.command.build_py.build_py.run(self)
setuptools.setup( setuptools.setup(
cmdclass={ cmdclass={
'build_py': BuildPyCommand, 'build_py': BuildPyCommand,
}, },
# Usual setup() args. # Usual setup() args.
# ... # ...
) )
``` ```
#### Compiler flags #### Compiler flags
@@ -309,7 +315,7 @@ See [#816](https://github.com/pypa/cibuildwheel/issues/816), thanks to @phoeriou
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 C extension with a newer compiler.
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). 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). CPython 3.8.3 and all versions after it have this extra DLL, so it is only needed for 3.8 and earlier.
To add the `/d2FH4-` flag to a standard `setup.py` using `setuptools`, the `extra_compile_args` option can be used: To add the `/d2FH4-` flag to a standard `setup.py` using `setuptools`, the `extra_compile_args` option can be used:
+2 -2
View File
@@ -183,7 +183,7 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Build wheels - name: Build wheels
run: pipx run cibuildwheel==2.4.0 run: pipx run cibuildwheel==2.5.0
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
@@ -218,7 +218,7 @@ To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/
- uses: actions/setup-python@v2 - uses: actions/setup-python@v2
- name: Install cibuildwheel - name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.4.0 run: python -m pip install cibuildwheel==2.5.0
- name: Build wheels - name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse run: python -m cibuildwheel --output-dir wheelhouse
+138 -102
View File
@@ -10,22 +10,29 @@ title: Working examples
|-----------------------------------|----|----|:------| |-----------------------------------|----|----|:------|
| [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. | | [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The machine learning library. A complex but clean config using many of cibuildwheel's features to build a large project with Cython and C++ extensions. |
| [Tornado][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. | | [Tornado][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. |
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. | | [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions | | [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | MyPyC, the compiled component of MyPy. | | [Kivy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Open source UI framework written in Python, running on Windows, Linux, macOS, Android and iOS |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
| [MyPy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | The compiled version of MyPy using MyPyC. |
| [pydantic][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Data parsing and validation using Python type hints | | [pydantic][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Data parsing and validation using Python type hints |
| [uvloop][] | ![github icon][] | ![apple icon][] ![linux icon][] | Ultra fast asyncio event loop. | | [uvloop][] | ![github icon][] | ![apple icon][] ![linux icon][] | Ultra fast asyncio event loop. |
| [psutil][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Cross-platform lib for process and system monitoring in Python | | [psutil][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Cross-platform lib for process and system monitoring in Python |
| [MemRay][] | ![github icon][] | ![linux icon][] | Memray is a memory profiler for Python |
| [vaex][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Out-of-Core hybrid Apache Arrow/NumPy DataFrame for Python, ML, visualization and exploration of big tabular data at a billion rows per second 🚀 | | [vaex][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Out-of-Core hybrid Apache Arrow/NumPy DataFrame for Python, ML, visualization and exploration of big tabular data at a billion rows per second 🚀 |
| [Google Benchmark][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A microbenchmark support library | | [Google Benchmark][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A microbenchmark support library |
| [Apache Beam][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Apache Beam is a unified programming model for Batch and Streaming | | [Apache Beam][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Apache Beam is a unified programming model for Batch and Streaming data processing. |
| [asyncpg][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A fast PostgreSQL Database Client Library for Python/asyncio. | | [asyncpg][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A fast PostgreSQL Database Client Library for Python/asyncio. |
| [scikit-image][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Image processing library. Uses cibuildwheel to build and test a project that uses Cython with platform-native code. | | [scikit-image][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Image processing library. Uses cibuildwheel to build and test a project that uses Cython with platform-native code. |
| [cmake][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an in-process SQL OLAP Database Management System | | [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an in-process SQL OLAP Database Management System |
| [PyGame][] | ![github icon][] | ![apple icon][] ![linux icon][] | pygame (the library) is a Free and Open Source python programming language library for making multimedia applications like games built on top of the excellent SDL library. C, Python, Native, OpenGL. |
| [cmake][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
| [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. | | [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. |
| [websockets][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Library for building WebSocket servers and clients. Mostly written in Python, with a small C 'speedups' extension module. | | [websockets][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Library for building WebSocket servers and clients. Mostly written in Python, with a small C 'speedups' extension module. |
| [cvxpy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A Python-embedded modeling language for convex optimization problems. | | [cvxpy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A Python-embedded modeling language for convex optimization problems. |
| [UltraJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Ultra fast JSON decoder and encoder written in C with Python bindings |
| [PyOxidizer][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A modern Python application packaging and distribution tool | | [PyOxidizer][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A modern Python application packaging and distribution tool |
| [Triton][] | ![github icon][] | ![linux icon][] | Self hosted runners | | [Triton][] | ![github icon][] | ![linux icon][] | Self hosted runners |
| [River][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 🌊 Online machine learning in Python | | [River][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 🌊 Online machine learning in Python |
@@ -33,6 +40,7 @@ title: Working examples
| [pyzmq][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python bindings for zeromq, the networking library. Uses Cython and CFFI. | | [pyzmq][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python bindings for zeromq, the networking library. Uses Cython and CFFI. |
| [aiortc][] | ![github icon][] | ![apple icon][] ![linux icon][] | WebRTC and ORTC implementation for Python using asyncio. | | [aiortc][] | ![github icon][] | ![apple icon][] ![linux icon][] | WebRTC and ORTC implementation for Python using asyncio. |
| [vispy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Main repository for Vispy | | [vispy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Main repository for Vispy |
| [Implicit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes GPU support for linux wheels |
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` | | [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
| [tinyobjloader][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Tiny but powerful single file wavefront obj loader | | [tinyobjloader][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Tiny but powerful single file wavefront obj loader |
| [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI | | [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI |
@@ -41,12 +49,14 @@ title: Working examples
| [PyYAML][] | ![github icon][] | ![apple icon][] | Canonical source repository for PyYAML | | [PyYAML][] | ![github icon][] | ![apple icon][] | Canonical source repository for PyYAML |
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, PyTables, pandas, bcolz and more | | [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, PyTables, pandas, bcolz and more |
| [h5py][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | HDF5 for Python -- The h5py package is a Pythonic interface to the HDF5 binary data format. | | [h5py][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | HDF5 for Python -- The h5py package is a Pythonic interface to the HDF5 binary data format. |
| [Wrapt][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python module for decorators, wrappers and monkey patching. |
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. | | [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
| [OpenColorIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A color management framework for visual effects and animation. | | [OpenColorIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A color management framework for visual effects and animation. |
| [Line Profiler][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Line-by-line profiling for Python | | [Line Profiler][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Line-by-line profiling for Python |
| [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data | | [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data |
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
| [pikepdf][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by qpdf | | [pikepdf][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by qpdf |
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. | | [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python | | [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
| [DeepForest][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | An Efficient, Scalable and Optimized Python Framework for Deep Forest (2021.2.1) | | [DeepForest][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | An Efficient, Scalable and Optimized Python Framework for Deep Forest (2021.2.1) |
@@ -55,8 +65,8 @@ title: Working examples
| [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. | | [Parselmouth][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. |
| [AutoPy][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. | | [AutoPy][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [H3-py][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for H3, a hierarchical hexagonal geospatial indexing system | | [H3-py][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for H3, a hierarchical hexagonal geospatial indexing system |
| [markupsafe][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Safely add untrusted strings to HTML/XML markup. |
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS ¶ | | [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS ¶ |
| [markupsafe][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Safely add untrusted strings to HTML/XML markup. |
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson | | [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library | | [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
| [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system | | [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system |
@@ -65,10 +75,10 @@ title: Working examples
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system | | [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
| [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub | | [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub |
| [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing | | [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing |
| [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Quickly search, compare, and analyze genomic and metagenomic data sets. |
| [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. | | [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. |
| [abess][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A fast best-subset selection library. It uses cibuildwheel to build a large project with C++ extensions. | | [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Quickly search, compare, and analyze genomic and metagenomic data sets. |
| [CTranslate2][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes libraries from the [Intel oneAPI toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit.html) and CUDA kernels compiled for multiple GPU architectures. | | [CTranslate2][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes libraries from the [Intel oneAPI toolkit](https://www.intel.com/content/www/us/en/developer/tools/oneapi/base-toolkit.html) and CUDA kernels compiled for multiple GPU architectures. |
| [abess][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A fast best-subset selection library. It uses cibuildwheel to build a large project with C++ extensions. |
| [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. | | [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. |
| [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq | | [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq |
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 | | [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 |
@@ -78,6 +88,7 @@ title: Working examples
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. | | [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. |
| [iDynTree][] | ![github icon][] | ![linux icon][] | Uses manylinux_2_24 | | [iDynTree][] | ![github icon][] | ![linux icon][] | Uses manylinux_2_24 |
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. | | [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [Python-WebRTC][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | a Python extension that provides bindings to WebRTC M92 |
| [pybase64][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast Base64 encoding/decoding in Python | | [pybase64][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast Base64 encoding/decoding in Python |
| [Arbor][] | ![github icon][] | ![apple icon][] ![linux icon][] | Arbor is a multi-compartment neuron simulation library; compatible with next-generation accelerators; best-practices applied to research software; focused on community-driven development. Includes a [small script](https://github.com/arbor-sim/arbor/blob/master/scripts/patchwheel.py) patching `rpath` in bundled libraries. | | [Arbor][] | ![github icon][] | ![apple icon][] ![linux icon][] | Arbor is a multi-compartment neuron simulation library; compatible with next-generation accelerators; best-practices applied to research software; focused on community-driven development. Includes a [small script](https://github.com/arbor-sim/arbor/blob/master/scripts/patchwheel.py) patching `rpath` in bundled libraries. |
| [etebase-py][] | ![travisci icon][] | ![linux icon][] | Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. | | [etebase-py][] | ![travisci icon][] | ![linux icon][] | Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. |
@@ -85,10 +96,11 @@ title: Working examples
| [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. | | [Imagecodecs (fork)][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] | Over 20 external dependencies in compiled libraries, custom docker image, `libomp`, `openblas` and `install_name_tool` for macOS. |
| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. | | [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. |
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy | | [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy |
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
| [clang-format][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Scikit-build wrapper around LLVM's CMake, all platforms, generic wheels. | | [clang-format][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Scikit-build wrapper around LLVM's CMake, all platforms, generic wheels. |
| [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. | | [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 | | [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
| [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. | | [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
| [pillow-heif][] | ![github icon][] | ![apple icon][] ![linux icon][] | Python CFFI binding to libheif library with third party dependencies like `libde265`, `x265`, `libaom` with test & publishing on PyPi. | | [pillow-heif][] | ![github icon][] | ![apple icon][] ![linux icon][] | Python CFFI binding to libheif library with third party dependencies like `libde265`, `x265`, `libaom` with test & publishing on PyPi. |
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies | | [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
@@ -98,22 +110,29 @@ title: Working examples
[scikit-learn]: https://github.com/scikit-learn/scikit-learn [scikit-learn]: https://github.com/scikit-learn/scikit-learn
[Tornado]: https://github.com/tornadoweb/tornado [Tornado]: https://github.com/tornadoweb/tornado
[NumPy]: https://github.com/numpy/numpy
[pytorch-fairseq]: https://github.com/pytorch/fairseq [pytorch-fairseq]: https://github.com/pytorch/fairseq
[Matplotlib]: https://github.com/matplotlib/matplotlib [Matplotlib]: https://github.com/matplotlib/matplotlib
[Kivy]: https://github.com/kivy/kivy
[NCNN]: https://github.com/Tencent/ncnn
[Prophet]: https://github.com/facebook/prophet
[MyPy]: https://github.com/mypyc/mypy_mypyc-wheels [MyPy]: https://github.com/mypyc/mypy_mypyc-wheels
[pydantic]: https://github.com/samuelcolvin/pydantic [pydantic]: https://github.com/samuelcolvin/pydantic
[uvloop]: https://github.com/MagicStack/uvloop [uvloop]: https://github.com/MagicStack/uvloop
[psutil]: https://github.com/giampaolo/psutil [psutil]: https://github.com/giampaolo/psutil
[MemRay]: https://github.com/bloomberg/memray
[vaex]: https://github.com/vaexio/vaex [vaex]: https://github.com/vaexio/vaex
[Google Benchmark]: https://github.com/google/benchmark [Google Benchmark]: https://github.com/google/benchmark
[Apache Beam]: https://github.com/apache/beam [Apache Beam]: https://github.com/apache/beam
[asyncpg]: https://github.com/MagicStack/asyncpg [asyncpg]: https://github.com/MagicStack/asyncpg
[scikit-image]: https://github.com/scikit-image/scikit-image [scikit-image]: https://github.com/scikit-image/scikit-image
[cmake]: https://github.com/scikit-build/cmake-python-distributions
[duckdb]: https://github.com/duckdb/duckdb [duckdb]: https://github.com/duckdb/duckdb
[PyGame]: https://github.com/pygame/pygame
[cmake]: https://github.com/scikit-build/cmake-python-distributions
[twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport [twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport
[websockets]: https://github.com/aaugustin/websockets [websockets]: https://github.com/aaugustin/websockets
[cvxpy]: https://github.com/cvxpy/cvxpy [cvxpy]: https://github.com/cvxpy/cvxpy
[UltraJSON]: https://github.com/ultrajson/ultrajson
[PyOxidizer]: https://github.com/indygreg/PyOxidizer [PyOxidizer]: https://github.com/indygreg/PyOxidizer
[Triton]: https://github.com/openai/triton [Triton]: https://github.com/openai/triton
[River]: https://github.com/online-ml/river [River]: https://github.com/online-ml/river
@@ -121,6 +140,7 @@ title: Working examples
[pyzmq]: https://github.com/zeromq/pyzmq [pyzmq]: https://github.com/zeromq/pyzmq
[aiortc]: https://github.com/aiortc/aiortc [aiortc]: https://github.com/aiortc/aiortc
[vispy]: https://github.com/vispy/vispy [vispy]: https://github.com/vispy/vispy
[Implicit]: https://github.com/benfred/implicit
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python [Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
[tinyobjloader]: https://github.com/tinyobjloader/tinyobjloader [tinyobjloader]: https://github.com/tinyobjloader/tinyobjloader
[Dependency Injector]: https://github.com/ets-labs/python-dependency-injector [Dependency Injector]: https://github.com/ets-labs/python-dependency-injector
@@ -129,12 +149,14 @@ title: Working examples
[PyYAML]: https://github.com/yaml/pyyaml [PyYAML]: https://github.com/yaml/pyyaml
[numexpr]: https://github.com/pydata/numexpr [numexpr]: https://github.com/pydata/numexpr
[h5py]: https://github.com/h5py/h5py [h5py]: https://github.com/h5py/h5py
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
[PyAV]: https://github.com/PyAV-Org/PyAV [PyAV]: https://github.com/PyAV-Org/PyAV
[SimpleJSON]: https://github.com/simplejson/simplejson
[OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO [OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO
[Line Profiler]: https://github.com/pyutils/line_profiler [Line Profiler]: https://github.com/pyutils/line_profiler
[PyTables]: https://github.com/PyTables/PyTables [PyTables]: https://github.com/PyTables/PyTables
[OpenTimelineIO]: https://github.com/PixarAnimationStudios/OpenTimelineIO
[pikepdf]: https://github.com/pikepdf/pikepdf [pikepdf]: https://github.com/pikepdf/pikepdf
[OpenTimelineIO]: https://github.com/PixarAnimationStudios/OpenTimelineIO
[ruptures]: https://github.com/deepcharles/ruptures [ruptures]: https://github.com/deepcharles/ruptures
[aioquic]: https://github.com/aiortc/aioquic [aioquic]: https://github.com/aiortc/aioquic
[DeepForest]: https://github.com/LAMDA-NJU/Deep-Forest [DeepForest]: https://github.com/LAMDA-NJU/Deep-Forest
@@ -143,8 +165,8 @@ title: Working examples
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth [Parselmouth]: https://github.com/YannickJadoul/Parselmouth
[AutoPy]: https://github.com/autopilot-rs/autopy [AutoPy]: https://github.com/autopilot-rs/autopy
[H3-py]: https://github.com/uber/h3-py [H3-py]: https://github.com/uber/h3-py
[markupsafe]: https://github.com/pallets/markupsafe
[Rtree]: https://github.com/Toblerity/rtree [Rtree]: https://github.com/Toblerity/rtree
[markupsafe]: https://github.com/pallets/markupsafe
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson [python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
[python-snappy]: https://github.com/andrix/python-snappy [python-snappy]: https://github.com/andrix/python-snappy
[pybind11 cmake_example]: https://github.com/pybind/cmake_example [pybind11 cmake_example]: https://github.com/pybind/cmake_example
@@ -153,10 +175,10 @@ title: Working examples
[pybind11 python_example]: https://github.com/pybind/python_example [pybind11 python_example]: https://github.com/pybind/python_example
[dd-trace-py]: https://github.com/DataDog/dd-trace-py [dd-trace-py]: https://github.com/DataDog/dd-trace-py
[cyvcf2]: https://github.com/brentp/cyvcf2 [cyvcf2]: https://github.com/brentp/cyvcf2
[sourmash]: https://github.com/dib-lab/sourmash
[time-machine]: https://github.com/adamchainz/time-machine [time-machine]: https://github.com/adamchainz/time-machine
[abess]: https://github.com/abess-team/abess [sourmash]: https://github.com/dib-lab/sourmash
[CTranslate2]: https://github.com/OpenNMT/CTranslate2 [CTranslate2]: https://github.com/OpenNMT/CTranslate2
[abess]: https://github.com/abess-team/abess
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile [matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
[jq.py]: https://github.com/mwilliamson/jq.py [jq.py]: https://github.com/mwilliamson/jq.py
[iminuit]: https://github.com/scikit-hep/iminuit [iminuit]: https://github.com/scikit-hep/iminuit
@@ -166,6 +188,7 @@ title: Working examples
[boost-histogram]: https://github.com/scikit-hep/boost-histogram [boost-histogram]: https://github.com/scikit-hep/boost-histogram
[iDynTree]: https://github.com/robotology/idyntree [iDynTree]: https://github.com/robotology/idyntree
[TgCrypto]: https://github.com/pyrogram/tgcrypto [TgCrypto]: https://github.com/pyrogram/tgcrypto
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
[pybase64]: https://github.com/mayeut/pybase64 [pybase64]: https://github.com/mayeut/pybase64
[Arbor]: https://github.com/arbor-sim/arbor [Arbor]: https://github.com/arbor-sim/arbor
[etebase-py]: https://github.com/etesync/etebase-py [etebase-py]: https://github.com/etesync/etebase-py
@@ -173,10 +196,11 @@ title: Working examples
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build [Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
[polaroid]: https://github.com/daggy1234/polaroid [polaroid]: https://github.com/daggy1234/polaroid
[numpythia]: https://github.com/scikit-hep/numpythia [numpythia]: https://github.com/scikit-hep/numpythia
[pyjet]: https://github.com/scikit-hep/pyjet
[clang-format]: https://github.com/ssciwr/clang-format-wheel [clang-format]: https://github.com/ssciwr/clang-format-wheel
[ninja]: https://github.com/scikit-build/ninja-python-distributions [pyjet]: https://github.com/scikit-hep/pyjet
[power-grid-model]: https://github.com/alliander-opensource/power-grid-model
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example [pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
[ninja]: https://github.com/scikit-build/ninja-python-distributions
[GSD]: https://github.com/glotzerlab/gsd [GSD]: https://github.com/glotzerlab/gsd
[pillow-heif]: https://github.com/bigcat88/pillow_heif [pillow-heif]: https://github.com/bigcat88/pillow_heif
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext [pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
@@ -194,93 +218,105 @@ title: Working examples
[apple icon]: data/readme_icons/apple.svg [apple icon]: data/readme_icons/apple.svg
[linux icon]: data/readme_icons/linux.svg [linux icon]: data/readme_icons/linux.svg
<!-- scikit-learn: 49555, last pushed 0 days ago --> <!-- scikit-learn: 49827, last pushed 0 days ago -->
<!-- Tornado: 20477, last pushed 1 days ago --> <!-- Tornado: 20521, last pushed 2 days ago -->
<!-- pytorch-fairseq: 16526, last pushed 2 days ago --> <!-- NumPy: 20265, last pushed 0 days ago -->
<!-- Matplotlib: 15257, last pushed 0 days ago --> <!-- pytorch-fairseq: 16785, last pushed 0 days ago -->
<!-- MyPy: 12783, last pushed 0 days ago --> <!-- Matplotlib: 15401, last pushed 0 days ago -->
<!-- pydantic: 9538, last pushed 3 days ago --> <!-- Kivy: 14554, last pushed 2 days ago -->
<!-- uvloop: 8496, last pushed 85 days ago --> <!-- NCNN: 14371, last pushed 0 days ago -->
<!-- psutil: 8240, last pushed 3 days ago --> <!-- Prophet: 14355, last pushed 16 days ago -->
<!-- vaex: 6968, last pushed 0 days ago --> <!-- MyPy: 12962, last pushed 0 days ago -->
<!-- Google Benchmark: 6312, last pushed 0 days ago --> <!-- pydantic: 9748, last pushed 2 days ago -->
<!-- Apache Beam: 5409, last pushed 0 days ago --> <!-- uvloop: 8562, last pushed 111 days ago -->
<!-- asyncpg: 5394, last pushed 4 days ago --> <!-- psutil: 8332, last pushed 2 days ago -->
<!-- scikit-image: 4842, last pushed 0 days ago --> <!-- MemRay: 7309, last pushed 0 days ago -->
<!-- cmake: 4616, last pushed 0 days ago --> <!-- vaex: 7014, last pushed 1 days ago -->
<!-- duckdb: 4607, last pushed 0 days ago --> <!-- Google Benchmark: 6408, last pushed 16 days ago -->
<!-- twisted-iocpsupport: 4550, last pushed 0 days ago --> <!-- Apache Beam: 5467, last pushed 0 days ago -->
<!-- websockets: 3862, last pushed 0 days ago --> <!-- asyncpg: 5434, last pushed 31 days ago -->
<!-- cvxpy: 3840, last pushed 5 days ago --> <!-- scikit-image: 4877, last pushed 0 days ago -->
<!-- PyOxidizer: 3571, last pushed 0 days ago --> <!-- duckdb: 4808, last pushed 0 days ago -->
<!-- Triton: 3552, last pushed 0 days ago --> <!-- PyGame: 4731, last pushed 0 days ago -->
<!-- River: 3261, last pushed 0 days ago --> <!-- cmake: 4701, last pushed 0 days ago -->
<!-- OpenSpiel: 3129, last pushed 3 days ago --> <!-- twisted-iocpsupport: 4574, last pushed 0 days ago -->
<!-- pyzmq: 3057, last pushed 3 days ago --> <!-- websockets: 3903, last pushed 3 days ago -->
<!-- aiortc: 2857, last pushed 2 days ago --> <!-- cvxpy: 3881, last pushed 0 days ago -->
<!-- vispy: 2836, last pushed 0 days ago --> <!-- UltraJSON: 3662, last pushed 0 days ago -->
<!-- Confluent client for Kafka: 2699, last pushed 0 days ago --> <!-- PyOxidizer: 3628, last pushed 0 days ago -->
<!-- tinyobjloader: 2460, last pushed 95 days ago --> <!-- Triton: 3590, last pushed 0 days ago -->
<!-- Dependency Injector: 1986, last pushed 2 days ago --> <!-- River: 3327, last pushed 0 days ago -->
<!-- coverage.py: 1972, last pushed 3 days ago --> <!-- OpenSpiel: 3163, last pushed 1 days ago -->
<!-- PyCryptodome: 1961, last pushed 2 days ago --> <!-- pyzmq: 3069, last pushed 2 days ago -->
<!-- PyYAML: 1785, last pushed 9 days ago --> <!-- aiortc: 2887, last pushed 1 days ago -->
<!-- numexpr: 1741, last pushed 2 days ago --> <!-- vispy: 2858, last pushed 0 days ago -->
<!-- h5py: 1703, last pushed 0 days ago --> <!-- Implicit: 2753, last pushed 1 days ago -->
<!-- PyAV: 1503, last pushed 0 days ago --> <!-- Confluent client for Kafka: 2731, last pushed 0 days ago -->
<!-- OpenColorIO: 1275, last pushed 0 days ago --> <!-- tinyobjloader: 2492, last pushed 121 days ago -->
<!-- Line Profiler: 1140, last pushed 0 days ago --> <!-- Dependency Injector: 2061, last pushed 10 days ago -->
<!-- PyTables: 1113, last pushed 6 days ago --> <!-- coverage.py: 2013, last pushed 2 days ago -->
<!-- OpenTimelineIO: 1023, last pushed 0 days ago --> <!-- PyCryptodome: 1981, last pushed 11 days ago -->
<!-- pikepdf: 982, last pushed 2 days ago --> <!-- PyYAML: 1810, last pushed 11 days ago -->
<!-- ruptures: 930, last pushed 3 days ago --> <!-- numexpr: 1750, last pushed 7 days ago -->
<!-- aioquic: 893, last pushed 2 days ago --> <!-- h5py: 1716, last pushed 21 days ago -->
<!-- DeepForest: 737, last pushed 252 days ago --> <!-- Wrapt: 1662, last pushed 40 days ago -->
<!-- google neuroglancer: 725, last pushed 3 days ago --> <!-- PyAV: 1538, last pushed 0 days ago -->
<!-- Psycopg 3: 638, last pushed 0 days ago --> <!-- SimpleJSON: 1481, last pushed 5 days ago -->
<!-- Parselmouth: 634, last pushed 0 days ago --> <!-- OpenColorIO: 1299, last pushed 0 days ago -->
<!-- AutoPy: 629, last pushed 97 days ago --> <!-- Line Profiler: 1173, last pushed 0 days ago -->
<!-- H3-py: 498, last pushed 2 days ago --> <!-- PyTables: 1120, last pushed 8 days ago -->
<!-- markupsafe: 459, last pushed 17 days ago --> <!-- pikepdf: 1042, last pushed 8 days ago -->
<!-- Rtree: 456, last pushed 1 days ago --> <!-- OpenTimelineIO: 1035, last pushed 5 days ago -->
<!-- python-rapidjson: 447, last pushed 23 days ago --> <!-- ruptures: 945, last pushed 12 days ago -->
<!-- python-snappy: 426, last pushed 15 days ago --> <!-- aioquic: 906, last pushed 0 days ago -->
<!-- pybind11 cmake_example: 380, last pushed 2 days ago --> <!-- DeepForest: 743, last pushed 278 days ago -->
<!-- KDEpy: 356, last pushed 50 days ago --> <!-- google neuroglancer: 731, last pushed 7 days ago -->
<!-- tgcalls: 346, last pushed 83 days ago --> <!-- Psycopg 3: 654, last pushed 0 days ago -->
<!-- pybind11 python_example: 312, last pushed 81 days ago --> <!-- Parselmouth: 649, last pushed 23 days ago -->
<!-- dd-trace-py: 300, last pushed 0 days ago --> <!-- AutoPy: 634, last pushed 123 days ago -->
<!-- cyvcf2: 294, last pushed 17 days ago --> <!-- H3-py: 514, last pushed 0 days ago -->
<!-- sourmash: 281, last pushed 0 days ago --> <!-- Rtree: 473, last pushed 8 days ago -->
<!-- time-machine: 274, last pushed 3 days ago --> <!-- markupsafe: 465, last pushed 23 days ago -->
<!-- abess: 258, last pushed 6 days ago --> <!-- python-rapidjson: 449, last pushed 50 days ago -->
<!-- CTranslate2: 254, last pushed 0 days ago --> <!-- python-snappy: 430, last pushed 42 days ago -->
<!-- matrixprofile: 250, last pushed 279 days ago --> <!-- pybind11 cmake_example: 392, last pushed 16 days ago -->
<!-- jq.py: 206, last pushed 54 days ago --> <!-- KDEpy: 365, last pushed 76 days ago -->
<!-- iminuit: 197, last pushed 2 days ago --> <!-- tgcalls: 347, last pushed 109 days ago -->
<!-- Tokenizer: 169, last pushed 25 days ago --> <!-- pybind11 python_example: 320, last pushed 16 days ago -->
<!-- PyGLM: 133, last pushed 3 days ago --> <!-- dd-trace-py: 315, last pushed 0 days ago -->
<!-- bx-python: 113, last pushed 86 days ago --> <!-- cyvcf2: 295, last pushed 43 days ago -->
<!-- boost-histogram: 107, last pushed 1 days ago --> <!-- time-machine: 292, last pushed 0 days ago -->
<!-- iDynTree: 98, last pushed 4 days ago --> <!-- sourmash: 286, last pushed 0 days ago -->
<!-- TgCrypto: 94, last pushed 28 days ago --> <!-- CTranslate2: 263, last pushed 0 days ago -->
<!-- abess: 261, last pushed 2 days ago -->
<!-- matrixprofile: 256, last pushed 306 days ago -->
<!-- jq.py: 212, last pushed 80 days ago -->
<!-- iminuit: 199, last pushed 6 days ago -->
<!-- Tokenizer: 174, last pushed 51 days ago -->
<!-- PyGLM: 138, last pushed 30 days ago -->
<!-- bx-python: 113, last pushed 112 days ago -->
<!-- boost-histogram: 110, last pushed 9 days ago -->
<!-- iDynTree: 103, last pushed 16 days ago -->
<!-- TgCrypto: 96, last pushed 54 days ago -->
<!-- Python-WebRTC: 88, last pushed 48 days ago -->
<!-- pybase64: 82, last pushed 2 days ago --> <!-- pybase64: 82, last pushed 2 days ago -->
<!-- Arbor: 70, last pushed 0 days ago --> <!-- Arbor: 72, last pushed 0 days ago -->
<!-- etebase-py: 56, last pushed 95 days ago --> <!-- etebase-py: 56, last pushed 121 days ago -->
<!-- fathon: 43, last pushed 134 days ago --> <!-- fathon: 44, last pushed 161 days ago -->
<!-- Imagecodecs (fork): 41, last pushed 32 days ago --> <!-- Imagecodecs (fork): 42, last pushed 58 days ago -->
<!-- polaroid: 35, last pushed 110 days ago --> <!-- polaroid: 35, last pushed 137 days ago -->
<!-- numpythia: 33, last pushed 34 days ago --> <!-- numpythia: 33, last pushed 23 days ago -->
<!-- pyjet: 32, last pushed 34 days ago --> <!-- clang-format: 33, last pushed 1 days ago -->
<!-- clang-format: 32, last pushed 38 days ago --> <!-- pyjet: 32, last pushed 23 days ago -->
<!-- ninja: 23, last pushed 10 days ago --> <!-- power-grid-model: 31, last pushed 0 days ago -->
<!-- pybind11 scikit_build_example: 21, last pushed 51 days ago --> <!-- pybind11 scikit_build_example: 23, last pushed 16 days ago -->
<!-- GSD: 19, last pushed 87 days ago --> <!-- ninja: 23, last pushed 3 days ago -->
<!-- pillow-heif: 16, last pushed 0 days ago --> <!-- GSD: 19, last pushed 12 days ago -->
<!-- pyinstrument_cext: 10, last pushed 175 days ago --> <!-- pillow-heif: 18, last pushed 2 days ago -->
<!-- xmlstarlet: 8, last pushed 11 days ago --> <!-- pyinstrument_cext: 10, last pushed 201 days ago -->
<!-- CorrectionLib: 8, last pushed 0 days ago --> <!-- xmlstarlet: 9, last pushed 16 days ago -->
<!-- SiPM: 5, last pushed 1 days ago --> <!-- CorrectionLib: 8, last pushed 7 days ago -->
<!-- SiPM: 6, last pushed 8 days ago -->
<!-- END bin/projects.py --> <!-- END bin/projects.py -->
+1 -1
View File
@@ -12,7 +12,7 @@ stack: python 3.7
init: init:
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH% - cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
install: python -m pip install cibuildwheel==2.4.0 install: python -m pip install cibuildwheel==2.5.0
build_script: python -m cibuildwheel --output-dir wheelhouse build_script: python -m cibuildwheel --output-dir wheelhouse
+3 -3
View File
@@ -6,7 +6,7 @@ jobs:
- bash: | - bash: |
set -o errexit set -o errexit
python3 -m pip install --upgrade pip python3 -m pip install --upgrade pip
pip3 install cibuildwheel==2.4.0 pip3 install cibuildwheel==2.5.0
displayName: Install dependencies displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse . - bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels displayName: Build wheels
@@ -20,7 +20,7 @@ jobs:
- bash: | - bash: |
set -o errexit set -o errexit
python3 -m pip install --upgrade pip python3 -m pip install --upgrade pip
python3 -m pip install cibuildwheel==2.4.0 python3 -m pip install cibuildwheel==2.5.0
displayName: Install dependencies displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse . - bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels displayName: Build wheels
@@ -34,7 +34,7 @@ jobs:
- bash: | - bash: |
set -o errexit set -o errexit
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install cibuildwheel==2.4.0 pip install cibuildwheel==2.5.0
displayName: Install dependencies displayName: Install dependencies
- bash: cibuildwheel --output-dir wheelhouse . - bash: cibuildwheel --output-dir wheelhouse .
displayName: Build wheels displayName: Build wheels
+2 -2
View File
@@ -11,7 +11,7 @@ jobs:
- run: - run:
name: Build the Linux wheels. name: Build the Linux wheels.
command: | command: |
pip3 install --user cibuildwheel==2.4.0 pip3 install --user cibuildwheel==2.5.0
cibuildwheel --output-dir wheelhouse cibuildwheel --output-dir wheelhouse
- store_artifacts: - store_artifacts:
path: wheelhouse/ path: wheelhouse/
@@ -25,7 +25,7 @@ jobs:
- run: - run:
name: Build the OS X wheels. name: Build the OS X wheels.
command: | command: |
pip3 install cibuildwheel==2.4.0 pip3 install cibuildwheel==2.5.0
cibuildwheel --output-dir wheelhouse cibuildwheel --output-dir wheelhouse
- store_artifacts: - store_artifacts:
path: wheelhouse/ path: wheelhouse/
+1 -1
View File
@@ -10,7 +10,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Build wheels - name: Build wheels
uses: pypa/cibuildwheel@v2.4.0 uses: pypa/cibuildwheel@v2.5.0
env: env:
CIBW_ARCHS_MACOS: x86_64 universal2 CIBW_ARCHS_MACOS: x86_64 universal2
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Build wheels - name: Build wheels
uses: pypa/cibuildwheel@v2.4.0 uses: pypa/cibuildwheel@v2.5.0
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Build wheels - name: Build wheels
uses: pypa/cibuildwheel@v2.4.0 uses: pypa/cibuildwheel@v2.5.0
# to supply options, put them in 'env', like: # to supply options, put them in 'env', like:
# env: # env:
# CIBW_SOME_OPTION: value # CIBW_SOME_OPTION: value
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
platforms: all platforms: all
- name: Build wheels - name: Build wheels
uses: pypa/cibuildwheel@v2.4.0 uses: pypa/cibuildwheel@v2.5.0
env: env:
# configure cibuildwheel to build native archs ('auto'), and some # configure cibuildwheel to build native archs ('auto'), and some
# emulated ones # emulated ones
+1 -1
View File
@@ -12,7 +12,7 @@ linux:
DOCKER_TLS_CERTDIR: "" DOCKER_TLS_CERTDIR: ""
script: script:
- curl -sSL https://get.docker.com/ | sh - curl -sSL https://get.docker.com/ | sh
- python -m pip install cibuildwheel==2.4.0 - python -m pip install cibuildwheel==2.5.0
- cibuildwheel --output-dir wheelhouse - cibuildwheel --output-dir wheelhouse
artifacts: artifacts:
paths: paths:
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
- ln -s /c/Python38/python.exe /c/Python38/python3.exe - ln -s /c/Python38/python.exe /c/Python38/python3.exe
install: install:
- python3 -m pip install cibuildwheel==2.4.0 - python3 -m pip install cibuildwheel==2.5.0
script: script:
# build the wheels, put them into './dist' # build the wheels, put them into './dist'
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
- ln -s /c/Python38/python.exe /c/Python38/python3.exe - ln -s /c/Python38/python.exe /c/Python38/python3.exe
install: install:
- python3 -m pip install cibuildwheel==2.4.0 - python3 -m pip install cibuildwheel==2.5.0
script: script:
# build the wheels, put them into './wheelhouse' # build the wheels, put them into './wheelhouse'
+2 -2
View File
@@ -55,7 +55,7 @@ jobs:
- stage: deploy - stage: deploy
name: Build and deploy Linux wheels name: Build and deploy Linux wheels
services: docker services: docker
install: python3 -m pip install cibuildwheel==2.4.0 twine install: python3 -m pip install cibuildwheel==2.5.0 twine
script: python3 -m cibuildwheel --output-dir wheelhouse script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
# Deploy on windows # Deploy on windows
@@ -63,7 +63,7 @@ jobs:
name: Build and deploy Windows wheels name: Build and deploy Windows wheels
os: windows os: windows
language: shell language: shell
install: python3 -m pip install cibuildwheel==2.4.0 twine install: python3 -m pip install cibuildwheel==2.5.0 twine
script: python3 -m cibuildwheel --output-dir wheelhouse script: python3 -m cibuildwheel --output-dir wheelhouse
after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl after_success: python3 -m twine upload --skip-existing wheelhouse/*.whl
+5 -5
View File
@@ -1,6 +1,6 @@
[metadata] [metadata]
name = cibuildwheel name = cibuildwheel
version = 2.4.0 version = 2.5.0
description = Build Python wheels on CI with minimal configuration. description = Build Python wheels on CI with minimal configuration.
long_description = file: README.md long_description = file: README.md
long_description_content_type = text/markdown long_description_content_type = text/markdown
@@ -35,10 +35,10 @@ install_requires =
bracex bracex
certifi certifi
filelock filelock
packaging packaging>=20.9
platformdirs platformdirs
tomli
dataclasses;python_version < '3.7' dataclasses;python_version < '3.7'
tomli;python_version < '3.11'
typing-extensions>=3.10.0.0;python_version < '3.8' typing-extensions>=3.10.0.0;python_version < '3.8'
python_requires = >=3.6 python_requires = >=3.6
include_package_data = True include_package_data = True
@@ -56,8 +56,8 @@ console_scripts =
cibuildwheel = resources/* cibuildwheel = resources/*
[flake8] [flake8]
ignore = E501,W503,E741,E226,B950,E203 extend-ignore = E203,E501,B950
select = C,E,F,W,B,B9 extend-select = B,B9
application-import-names = cibuildwheel application-import-names = cibuildwheel
exclude = exclude =
cibuildwheel/resources/, cibuildwheel/resources/,
+1
View File
@@ -13,6 +13,7 @@ extras = {
"pytest>=6", "pytest>=6",
"pytest-timeout", "pytest-timeout",
"pytest-xdist", "pytest-xdist",
"build",
], ],
"bin": [ "bin": [
"click", "click",
+16
View File
@@ -59,3 +59,19 @@ def test_build_identifiers(tmp_path):
assert len(expected_wheels) == len( assert len(expected_wheels) == len(
build_identifiers build_identifiers
), f"{expected_wheels} vs {build_identifiers}" ), f"{expected_wheels} vs {build_identifiers}"
def test_allow_empty(tmp_path):
project_dir = tmp_path / "project"
basic_project.generate(project_dir)
# Sanity check - --allow-empty should cause a no-op build to complete
# without error
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env={"CIBW_BUILD": "BUILD_NOTHING_AT_ALL"},
add_args=["--allow-empty"],
)
# check that nothing was built
assert len(actual_wheels) == 0
+173
View File
@@ -0,0 +1,173 @@
import os
import subprocess
import sys
import textwrap
from pathlib import Path
from tempfile import TemporaryDirectory
from test.test_projects.base import TestProject
from . import test_projects, utils
# utilities
def make_sdist(project: TestProject, working_dir: Path) -> Path:
project_dir = working_dir / "project"
project_dir.mkdir(parents=True, exist_ok=True)
project.generate(project_dir)
sdist_dir = working_dir / "sdist"
subprocess.run(
[sys.executable, "-m", "build", "--sdist", "--outdir", str(sdist_dir), str(project_dir)],
check=True,
)
return next(sdist_dir.glob("*.tar.gz"))
def cibuildwheel_from_sdist_run(sdist_path, add_env=None, config_file=None):
env = os.environ.copy()
if add_env:
env.update(add_env)
with TemporaryDirectory() as tmp_output_dir:
subprocess.run(
[
sys.executable,
"-m",
"cibuildwheel",
*(["--config-file", config_file] if config_file else []),
"--output-dir",
str(tmp_output_dir),
str(sdist_path),
],
env=env,
check=True,
)
return os.listdir(tmp_output_dir)
# tests
def test_simple(tmp_path):
basic_project = test_projects.new_c_project()
# make an sdist of the project
sdist_dir = tmp_path / "sdist"
sdist_dir.mkdir()
sdist_path = make_sdist(basic_project, sdist_dir)
# build the wheels from sdist
actual_wheels = cibuildwheel_from_sdist_run(
sdist_path,
add_env={"CIBW_BUILD": "cp39-*"},
)
# check that the expected wheels are produced
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w]
assert set(actual_wheels) == set(expected_wheels)
def test_external_config_file_argument(tmp_path, capfd):
basic_project = test_projects.new_c_project()
# make an sdist of the project
sdist_dir = tmp_path / "sdist"
sdist_dir.mkdir()
sdist_path = make_sdist(basic_project, sdist_dir)
# add a config file
config_file = tmp_path / "config.toml"
config_file.write_text(
textwrap.dedent(
"""
[tool.cibuildwheel]
before-all = 'echo "test log statement from before-all"'
"""
)
)
# build the wheels from sdist
actual_wheels = cibuildwheel_from_sdist_run(
sdist_path,
add_env={"CIBW_BUILD": "cp39-*"},
config_file=str(config_file),
)
# check that the expected wheels are produced
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w]
assert set(actual_wheels) == set(expected_wheels)
# check that before-all was run
captured = capfd.readouterr()
assert "test log statement from before-all" in captured.out
def test_config_in_pyproject_toml(tmp_path, capfd):
# make a project with a pyproject.toml
project = test_projects.new_c_project()
project.files["pyproject.toml"] = textwrap.dedent(
"""
[tool.cibuildwheel]
before-build = 'echo "test log statement from before-build 8419"'
"""
)
# make an sdist of the project
sdist_dir = tmp_path / "sdist"
sdist_dir.mkdir()
sdist_path = make_sdist(project, sdist_dir)
# build the wheels from sdist
actual_wheels = cibuildwheel_from_sdist_run(
sdist_path,
add_env={"CIBW_BUILD": "cp39-*"},
)
# check that the expected wheels are produced
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w]
assert set(actual_wheels) == set(expected_wheels)
# check that before-build was run
captured = capfd.readouterr()
assert "test log statement from before-build 8419" in captured.out
def test_internal_config_file_argument(tmp_path, capfd):
# make a project with a config file inside
project = test_projects.new_c_project(
setup_cfg_add="include_package_data = True",
)
project.files["wheel_build_config.toml"] = textwrap.dedent(
"""
[tool.cibuildwheel]
before-all = 'echo "test log statement from before-all 1829"'
"""
)
project.files["MANIFEST.in"] = textwrap.dedent(
"""
include wheel_build_config.toml
"""
)
# make an sdist of the project
sdist_dir = tmp_path / "sdist"
sdist_dir.mkdir()
sdist_path = make_sdist(project, sdist_dir)
# build the wheels from sdist, referencing the config file inside
actual_wheels = cibuildwheel_from_sdist_run(
sdist_path,
add_env={"CIBW_BUILD": "cp39-*"},
config_file="{package}/wheel_build_config.toml",
)
# check that the expected wheels are produced
expected_wheels = [w for w in utils.expected_wheels("spam", "0.1.0") if "cp39" in w]
assert set(actual_wheels) == set(expected_wheels)
# check that before-all was run
captured = capfd.readouterr()
assert "test log statement from before-all 1829" in captured.out
+50
View File
@@ -0,0 +1,50 @@
import textwrap
from . import test_projects, utils
limited_api_project = test_projects.new_c_project(
setup_py_add=textwrap.dedent(
r"""
cmdclass = {}
extension_kwargs = {}
if sys.version_info[:2] >= (3, 8):
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
class bdist_wheel_abi3(_bdist_wheel):
def finalize_options(self):
_bdist_wheel.finalize_options(self)
self.root_is_pure = False
def get_tag(self):
python, abi, plat = _bdist_wheel.get_tag(self)
return python, "abi3", plat
cmdclass["bdist_wheel"] = bdist_wheel_abi3
extension_kwargs["define_macros"] = [("Py_LIMITED_API", "0x03080000")]
extension_kwargs["py_limited_api"] = True
"""
),
setup_py_extension_args_add="**extension_kwargs",
setup_py_setup_args_add="cmdclass=cmdclass",
)
def test(tmp_path):
project_dir = tmp_path / "project"
limited_api_project.generate(project_dir)
# build the wheels
actual_wheels = utils.cibuildwheel_run(
project_dir,
add_env={
"CIBW_SKIP": "pp* ", # PyPy does not have a Py_LIMITED_API equivalent
},
)
# check that the expected wheels are produced
expected_wheels = [
w.replace("cp38-cp38", "cp38-abi3")
for w in utils.expected_wheels("spam", "0.1.0")
if "-pp" not in w and "-cp39" not in w and "-cp310" not in w
]
assert set(actual_wheels) == set(expected_wheels)
+3
View File
@@ -54,6 +54,7 @@ setup(
'spam', 'spam',
sources=['spam.c'], sources=['spam.c'],
libraries=libraries, libraries=libraries,
{{ setup_py_extension_args_add | indent(8) }}
)], )],
{{ setup_py_setup_args_add | indent(4) }} {{ setup_py_setup_args_add | indent(4) }}
) )
@@ -73,6 +74,7 @@ def new_c_project(
spam_c_top_level_add="", spam_c_top_level_add="",
spam_c_function_add="", spam_c_function_add="",
setup_py_add="", setup_py_add="",
setup_py_extension_args_add="",
setup_py_setup_args_add="", setup_py_setup_args_add="",
setup_cfg_add="", setup_cfg_add="",
): ):
@@ -91,6 +93,7 @@ def new_c_project(
"spam_c_top_level_add": spam_c_top_level_add, "spam_c_top_level_add": spam_c_top_level_add,
"spam_c_function_add": spam_c_function_add, "spam_c_function_add": spam_c_function_add,
"setup_py_add": setup_py_add, "setup_py_add": setup_py_add,
"setup_py_extension_args_add": setup_py_extension_args_add,
"setup_py_setup_args_add": setup_py_setup_args_add, "setup_py_setup_args_add": setup_py_setup_args_add,
"setup_cfg_add": setup_cfg_add, "setup_cfg_add": setup_cfg_add,
} }
+8 -1
View File
@@ -44,7 +44,9 @@ def cibuildwheel_get_build_identifiers(project_path, env=None, *, prerelease_pyt
return cmd_output.strip().split("\n") return cmd_output.strip().split("\n")
def cibuildwheel_run(project_path, package_dir=".", env=None, add_env=None, output_dir=None): def cibuildwheel_run(
project_path, package_dir=".", env=None, add_env=None, output_dir=None, add_args=None
):
""" """
Runs cibuildwheel as a subprocess, building the project at project_path. Runs cibuildwheel as a subprocess, building the project at project_path.
@@ -57,6 +59,7 @@ def cibuildwheel_run(project_path, package_dir=".", env=None, add_env=None, outp
:param add_env: environment used to update env :param add_env: environment used to update env
:param output_dir: directory where wheels are saved. If None, a temporary :param output_dir: directory where wheels are saved. If None, a temporary
directory will be used for the duration of the command. directory will be used for the duration of the command.
:param add_args: Additional command-line arguments to pass to cibuildwheel.
:return: list of built wheels (file names). :return: list of built wheels (file names).
""" """
if env is None: if env is None:
@@ -64,6 +67,9 @@ def cibuildwheel_run(project_path, package_dir=".", env=None, add_env=None, outp
# If present in the host environment, remove the MACOSX_DEPLOYMENT_TARGET for consistency # If present in the host environment, remove the MACOSX_DEPLOYMENT_TARGET for consistency
env.pop("MACOSX_DEPLOYMENT_TARGET", None) env.pop("MACOSX_DEPLOYMENT_TARGET", None)
if add_args is None:
add_args = []
if add_env is not None: if add_env is not None:
env.update(add_env) env.update(add_env)
@@ -77,6 +83,7 @@ def cibuildwheel_run(project_path, package_dir=".", env=None, add_env=None, outp
"--output-dir", "--output-dir",
str(output_dir or tmp_output_dir), str(output_dir or tmp_output_dir),
str(package_dir), str(package_dir),
*add_args,
], ],
env=env, env=env,
cwd=project_path, cwd=project_path,
+7 -2
View File
@@ -1,6 +1,11 @@
import sys
from typing import Dict, List from typing import Dict, List
import tomli if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
from packaging.version import Version from packaging.version import Version
from cibuildwheel.extra import Printable, dump_python_configurations from cibuildwheel.extra import Printable, dump_python_configurations
@@ -12,7 +17,7 @@ def test_compare_configs():
txt = f1.read() txt = f1.read()
with open(resources_dir / "build-platforms.toml", "rb") as f2: with open(resources_dir / "build-platforms.toml", "rb") as f2:
dict_txt = tomli.load(f2) dict_txt = tomllib.load(f2)
new_txt = dump_python_configurations(dict_txt) new_txt = dump_python_configurations(dict_txt)
print(new_txt) print(new_txt)
+1 -1
View File
@@ -32,7 +32,7 @@ def fake_package_dir(monkeypatch):
real_path_exists = Path.exists real_path_exists = Path.exists
def mock_path_exists(path): def mock_path_exists(path):
if path == MOCK_PACKAGE_DIR / "setup.py": if str(path).endswith(str(MOCK_PACKAGE_DIR / "setup.py")):
return True return True
else: else:
return real_path_exists(path) return real_path_exists(path)
+9 -5
View File
@@ -3,7 +3,11 @@ from fnmatch import fnmatch
from pathlib import Path from pathlib import Path
import pytest import pytest
import tomli
if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
from cibuildwheel.__main__ import main from cibuildwheel.__main__ import main
from cibuildwheel.environment import ParsedEnvironment from cibuildwheel.environment import ParsedEnvironment
@@ -20,13 +24,13 @@ def test_output_dir(platform, intercepted_build_args, monkeypatch):
main() main()
assert intercepted_build_args.args[0].globals.output_dir == OUTPUT_DIR assert intercepted_build_args.args[0].globals.output_dir == OUTPUT_DIR.resolve()
def test_output_dir_default(platform, intercepted_build_args, monkeypatch): def test_output_dir_default(platform, intercepted_build_args, monkeypatch):
main() main()
assert intercepted_build_args.args[0].globals.output_dir == Path("wheelhouse") assert intercepted_build_args.args[0].globals.output_dir == Path("wheelhouse").resolve()
@pytest.mark.parametrize("also_set_environment", [False, True]) @pytest.mark.parametrize("also_set_environment", [False, True])
@@ -39,7 +43,7 @@ def test_output_dir_argument(also_set_environment, platform, intercepted_build_a
main() main()
assert intercepted_build_args.args[0].globals.output_dir == OUTPUT_DIR assert intercepted_build_args.args[0].globals.output_dir == OUTPUT_DIR.resolve()
def test_build_selector(platform, intercepted_build_args, monkeypatch, allow_empty): def test_build_selector(platform, intercepted_build_args, monkeypatch, allow_empty):
@@ -314,7 +318,7 @@ def test_defaults(platform, intercepted_build_args):
build_options: BuildOptions = intercepted_build_args.args[0].build_options(identifier=None) build_options: BuildOptions = intercepted_build_args.args[0].build_options(identifier=None)
defaults_config_path = resources_dir / "defaults.toml" defaults_config_path = resources_dir / "defaults.toml"
with defaults_config_path.open("rb") as f: with defaults_config_path.open("rb") as f:
defaults_toml = tomli.load(f) defaults_toml = tomllib.load(f)
root_defaults = defaults_toml["tool"]["cibuildwheel"] root_defaults = defaults_toml["tool"]["cibuildwheel"]
platform_defaults = defaults_toml["tool"]["cibuildwheel"][platform] platform_defaults = defaults_toml["tool"]["cibuildwheel"][platform]
+2 -2
View File
@@ -60,14 +60,14 @@ def test_platform_argument(platform, intercepted_build_args, monkeypatch):
options = intercepted_build_args.args[0] options = intercepted_build_args.args[0]
assert options.globals.package_dir == MOCK_PACKAGE_DIR assert options.globals.package_dir == MOCK_PACKAGE_DIR.resolve()
def test_platform_environment(platform, intercepted_build_args, monkeypatch): def test_platform_environment(platform, intercepted_build_args, monkeypatch):
main() main()
options = intercepted_build_args.args[0] options = intercepted_build_args.args[0]
assert options.globals.package_dir == MOCK_PACKAGE_DIR assert options.globals.package_dir == MOCK_PACKAGE_DIR.resolve()
def test_archs_default(platform, intercepted_build_args, monkeypatch): def test_archs_default(platform, intercepted_build_args, monkeypatch):
+3 -3
View File
@@ -34,7 +34,7 @@ def test_options_1(tmp_path, monkeypatch):
f.write(PYPROJECT_1) f.write(PYPROJECT_1)
args = get_default_command_line_arguments() args = get_default_command_line_arguments()
args.package_dir = str(tmp_path) args.package_dir = tmp_path
monkeypatch.setattr(platform_module, "machine", lambda: "x86_64") monkeypatch.setattr(platform_module, "machine", lambda: "x86_64")
@@ -77,7 +77,7 @@ def test_passthrough(tmp_path, monkeypatch):
f.write(PYPROJECT_1) f.write(PYPROJECT_1)
args = get_default_command_line_arguments() args = get_default_command_line_arguments()
args.package_dir = str(tmp_path) args.package_dir = tmp_path
monkeypatch.setattr(platform_module, "machine", lambda: "x86_64") monkeypatch.setattr(platform_module, "machine", lambda: "x86_64")
monkeypatch.setenv("EXAMPLE_ENV", "ONE") monkeypatch.setenv("EXAMPLE_ENV", "ONE")
@@ -105,7 +105,7 @@ def test_passthrough(tmp_path, monkeypatch):
) )
def test_passthrough_evil(tmp_path, monkeypatch, env_var_value): def test_passthrough_evil(tmp_path, monkeypatch, env_var_value):
args = get_default_command_line_arguments() args = get_default_command_line_arguments()
args.package_dir = str(tmp_path) args.package_dir = tmp_path
monkeypatch.setattr(platform_module, "machine", lambda: "x86_64") monkeypatch.setattr(platform_module, "machine", lambda: "x86_64")
monkeypatch.setenv("CIBW_ENVIRONMENT_PASS_LINUX", "ENV_VAR") monkeypatch.setenv("CIBW_ENVIRONMENT_PASS_LINUX", "ENV_VAR")
+4 -2
View File
@@ -1,3 +1,5 @@
from pathlib import Path
from cibuildwheel.options import CommandLineArguments from cibuildwheel.options import CommandLineArguments
@@ -8,8 +10,8 @@ def get_default_command_line_arguments() -> CommandLineArguments:
defaults.allow_empty = False defaults.allow_empty = False
defaults.archs = None defaults.archs = None
defaults.config_file = "" defaults.config_file = ""
defaults.output_dir = None defaults.output_dir = Path("wheelhouse")
defaults.package_dir = "." defaults.package_dir = Path(".")
defaults.prerelease_pythons = False defaults.prerelease_pythons = False
defaults.print_build_identifiers = False defaults.print_build_identifiers = False