Compare commits

..
Author SHA1 Message Date
Joe Rickerby 50fef6ffbf Remove the DOCKER_HOST variable from gitlab configs 2024-09-06 13:26:01 +01:00
cibuildwheel-bot[bot]andcibuildwheel-bot[bot] <83877280+cibuildwheel-bot[bot]@users.noreply.github.com> b1ed7bb3bc [Bot] Update dependencies (#1993)
Update dependencies

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

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

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


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

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

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

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

---------

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

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

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


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

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

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

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

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

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

* chore: ruff python-version not needed

---------

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

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

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

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

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


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

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

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

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

* fix: support empty CIBW_PLATFORM

* Add test

---------

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

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

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

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


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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-07 16:07:28 -04:00
36 changed files with 370 additions and 281 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ jobs:
merge-multiple: true merge-multiple: true
- name: Generate artifact attestation for sdist and wheel - name: Generate artifact attestation for sdist and wheel
uses: actions/attest-build-provenance@5e9cb68e95676991667494a6a4e59b8a2f13e1d0 # v1.3.3 uses: actions/attest-build-provenance@6149ea5740be74af77f260b9db67e633f6b0a9a1 # v1.4.2
with: with:
subject-path: "dist/cibuildwheel-*" subject-path: "dist/cibuildwheel-*"
-11
View File
@@ -52,17 +52,6 @@ jobs:
- uses: yezz123/setup-uv@v4 - uses: yezz123/setup-uv@v4
# Install podman on this CI instance for podman tests on linux
# Snippet from: https://github.com/redhat-actions/podman-login/blob/main/.github/workflows/example.yml
- name: Install latest podman
if: runner.os == 'Linux'
run: |
. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -sSfL "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" | sudo apt-key add -
sudo apt-get update
sudo apt-get -y install podman
# free some space to prevent reaching GHA disk space limits # free some space to prevent reaching GHA disk space limits
- name: Clean docker images - name: Clean docker images
if: runner.os == 'Linux' if: runner.os == 'Linux'
-1
View File
@@ -5,7 +5,6 @@ linux:
entrypoint: ["env", "-u", "DOCKER_HOST"] entrypoint: ["env", "-u", "DOCKER_HOST"]
command: ["dockerd-entrypoint.sh"] command: ["dockerd-entrypoint.sh"]
variables: variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2 DOCKER_DRIVER: overlay2
# See https://github.com/docker-library/docker/pull/166 # See https://github.com/docker-library/docker/pull/166
DOCKER_TLS_CERTDIR: "" DOCKER_TLS_CERTDIR: ""
+3 -3
View File
@@ -14,14 +14,14 @@ repos:
- id: trailing-whitespace - id: trailing-whitespace
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.5.5 rev: v0.6.3
hooks: hooks:
- id: ruff - id: ruff
args: ["--fix", "--show-fixes"] args: ["--fix", "--show-fixes"]
- id: ruff-format - id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.0 rev: v1.11.2
hooks: hooks:
- id: mypy - id: mypy
name: mypy 3.8 on cibuildwheel/ name: mypy 3.8 on cibuildwheel/
@@ -77,7 +77,7 @@ repos:
- repo: https://github.com/python-jsonschema/check-jsonschema - repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.29.1 rev: 0.29.2
hooks: hooks:
- id: check-dependabot - id: check-dependabot
- id: check-github-actions - id: check-github-actions
+4 -1
View File
@@ -44,6 +44,7 @@ jobs:
python: 3.9 python: 3.9
services: docker services: docker
arch: s390x arch: s390x
allow_failure: True
env: PYTHON=python env: PYTHON=python
install: install:
@@ -56,5 +57,7 @@ script: |
(while true; do echo "travis_keep_alive"; sleep 300; done) & (while true; do echo "travis_keep_alive"; sleep 300; done) &
SPINNER_PID=$! SPINNER_PID=$!
disown disown
$PYTHON ./bin/run_tests.py --num-processes 2 result=0
$PYTHON ./bin/run_tests.py --num-processes 2 || result=1
kill -9 ${SPINNER_PID} kill -9 ${SPINNER_PID}
test ${result} -eq 0
+5 -5
View File
@@ -1,10 +1,10 @@
This is a summary of the host Python versions and platforms covered by the different CI platforms: This is a summary of the host Python versions and platforms covered by the different CI platforms:
| | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 | | | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 |
|---------|----------------------------------------------|-----------|-----------|---------|--------------------------------------| |---------|----------------------------------|-----------|-----------|---------|--------------------------------------------------|
| Linux | AppVeyor¹ / Azure Pipelines / GitHub Actions | Travis CI | Cirrus CI | | CircleCI¹ / GitHub Actions / GitLab¹ | | Linux | Azure Pipelines / GitHub Actions | Travis CI | Cirrus CI | | AppVeyor¹ / CircleCI¹ / GitHub Actions / GitLab¹ |
| macOS | AppVeyor¹ / Azure Pipelines | | Cirrus CI | GitLab¹ | CircleCI¹ / GitHub Actions | | macOS | Azure Pipelines | | Cirrus CI | GitLab¹ | AppVeyor¹ /CircleCI¹ / GitHub Actions |
| Windows | AppVeyor¹ / Azure Pipelines | Travis CI | Cirrus CI | | GitHub Actions / GitLab¹ | | Windows | Azure Pipelines | Travis CI | Cirrus CI | | AppVeyor¹ / GitHub Actions / GitLab¹ |
> ¹ Runs a reduced set of tests to reduce CI load > ¹ Runs a reduced set of tests to reduce CI load
+2 -2
View File
@@ -161,8 +161,8 @@ 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. |
| [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. |
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. | | [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system | | [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform | | [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions | | [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. | | [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. |
@@ -172,8 +172,8 @@ Here are some repos that use cibuildwheel.
[scikit-learn]: https://github.com/scikit-learn/scikit-learn [scikit-learn]: https://github.com/scikit-learn/scikit-learn
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq [pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy [NumPy]: https://github.com/numpy/numpy
[Tornado]: https://github.com/tornadoweb/tornado
[duckdb]: https://github.com/duckdb/duckdb [duckdb]: https://github.com/duckdb/duckdb
[Tornado]: https://github.com/tornadoweb/tornado
[NCNN]: https://github.com/Tencent/ncnn [NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib [Matplotlib]: https://github.com/matplotlib/matplotlib
[Prophet]: https://github.com/facebook/prophet [Prophet]: https://github.com/facebook/prophet
+11 -11
View File
@@ -1,26 +1,26 @@
environment: environment:
matrix: matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204
APPVEYOR_JOB_NAME: "python38-x64-ubuntu" APPVEYOR_JOB_NAME: "python312-x64-ubuntu"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: "python38-x64-vs2015" APPVEYOR_JOB_NAME: "python312-x64-vs2022"
- APPVEYOR_BUILD_WORKER_IMAGE: macos - APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
APPVEYOR_JOB_NAME: "python38-x64-macos" APPVEYOR_JOB_NAME: "python312-x64-macos"
stack: python 3.8 stack: python 3.12
build: off build: off
init: init:
- cmd: set PATH=C:\Python38;C:\Python38\Scripts;%PATH%
- ps: | - ps: |
$BRANCH = if ($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH) { $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH } else { $env:APPVEYOR_REPO_BRANCH } $BRANCH = if ($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH) { $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH } else { $env:APPVEYOR_REPO_BRANCH }
if (-not ($BRANCH -eq 'main' -or $BRANCH.ToLower().StartsWith('appveyor-'))) { if (-not ($BRANCH -eq 'main' -or $BRANCH.ToLower().StartsWith('appveyor-'))) {
$env:PYTEST_ADDOPTS='-k "unit_test or test_0_basic" --suppress-no-test-exit-code' $env:PYTEST_ADDOPTS = '-k "unit_test or test_0_basic" --suppress-no-test-exit-code'
} }
python -m pip install -U pip
install: python -m pip install -e ".[dev]" pytest-custom-exit-code install:
- python -m pip install -U pip
- python -m pip install -e ".[dev]" pytest-custom-exit-code
# the '-u' flag is required so the output is in the correct order. # the '-u' flag is required so the output is in the correct order.
# See https://github.com/pypa/cibuildwheel/pull/24 for more info. # See https://github.com/pypa/cibuildwheel/pull/24 for more info.
+1 -1
View File
@@ -240,7 +240,7 @@ def _compute_platform_auto() -> PlatformName:
def _compute_platform(args: CommandLineArguments) -> PlatformName: def _compute_platform(args: CommandLineArguments) -> PlatformName:
platform_option_value = args.platform or os.environ.get("CIBW_PLATFORM", "auto") platform_option_value = args.platform or os.environ.get("CIBW_PLATFORM", "") or "auto"
if args.only and args.platform is not None: if args.only and args.platform is not None:
msg = "--platform cannot be specified with --only, it is computed from --only" msg = "--platform cannot be specified with --only, it is computed from --only"
+179 -93
View File
@@ -9,15 +9,15 @@ import enum
import functools import functools
import shlex import shlex
import textwrap import textwrap
from collections.abc import Callable, Generator, Iterable, Iterator, Set from collections.abc import Generator, Iterable, Set
from pathlib import Path from pathlib import Path
from typing import Any, Literal, Mapping, Sequence, TypedDict, Union # noqa: TID251 from typing import Any, Literal, Mapping, Sequence, Union # noqa: TID251
from packaging.specifiers import SpecifierSet from packaging.specifiers import SpecifierSet
from . import errors from . import errors
from ._compat import tomllib from ._compat import tomllib
from ._compat.typing import NotRequired, assert_never from ._compat.typing import assert_never
from .architecture import Architecture from .architecture import Architecture
from .environment import EnvironmentParseError, ParsedEnvironment, parse_environment from .environment import EnvironmentParseError, ParsedEnvironment, parse_environment
from .logger import log from .logger import log
@@ -118,13 +118,16 @@ class BuildOptions:
return self.globals.architectures return self.globals.architectures
Setting = Union[Mapping[str, str], Sequence[str], str, int, bool] SettingLeaf = Union[str, int, bool]
SettingList = Sequence[SettingLeaf]
SettingTable = Mapping[str, Union[SettingLeaf, SettingList]]
SettingValue = Union[SettingTable, SettingList, SettingLeaf]
@dataclasses.dataclass(frozen=True) @dataclasses.dataclass(frozen=True)
class Override: class Override:
select_pattern: str select_pattern: str
options: dict[str, Setting] options: dict[str, SettingValue]
inherit: dict[str, InheritRule] inherit: dict[str, InheritRule]
@@ -137,22 +140,123 @@ DISALLOWED_OPTIONS = {
} }
class TableFmt(TypedDict): class OptionsReaderError(errors.ConfigurationError):
# a format string, used with '.format', with `k` and `v` parameters
# e.g. "{k}={v}"
item: str
# the string that is inserted between items
# e.g. " "
sep: str
# a quoting function that, if supplied, is called to quote each value
# e.g. shlex.quote
quote: NotRequired[Callable[[str], str]]
class ConfigOptionError(KeyError):
pass pass
class OptionFormat:
"""
Base class for option format specifiers. These objects describe how values
can be parsed from rich TOML values and how they're merged together.
"""
class NotSupported(Exception):
pass
def format_list(self, value: SettingList) -> str: # noqa: ARG002
raise OptionFormat.NotSupported
def format_table(self, table: SettingTable) -> str: # noqa: ARG002
raise OptionFormat.NotSupported
def merge_values(self, before: str, after: str) -> str: # noqa: ARG002
raise OptionFormat.NotSupported
class ListFormat(OptionFormat):
"""
A format that joins lists with a separator.
"""
def __init__(self, sep: str) -> None:
self.sep = sep
def format_list(self, value: SettingList) -> str:
return self.sep.join(str(v) for v in value)
def merge_values(self, before: str, after: str) -> str:
return f"{before}{self.sep}{after}"
class ShlexTableFormat(OptionFormat):
"""
The standard table format uses shlex.quote to quote values and shlex.split
to unquote and split them. When merging values, keys in before are
replaced by keys in after.
"""
def __init__(self, sep: str = " ", pair_sep: str = "=", allow_merge: bool = True) -> None:
self.sep = sep
self.pair_sep = pair_sep
self.allow_merge = allow_merge
def format_table(self, table: SettingTable) -> str:
assignments: list[tuple[str, str]] = []
for k, v in table.items():
if shlex.split(k) != [k]:
msg = f"Invalid table key: {k}"
raise OptionsReaderError(msg)
if isinstance(v, str):
assignments.append((k, v))
elif isinstance(v, Sequence):
for inner_v in v:
assignments.append((k, str(inner_v)))
else:
assignments.append((k, str(v)))
return self.sep.join(f"{k}{self.pair_sep}{shlex.quote(v)}" for k, v in assignments)
def merge_values(self, before: str, after: str) -> str:
if not self.allow_merge:
raise OptionFormat.NotSupported
before_dict = self.parse_table(before)
after_dict = self.parse_table(after)
return self.format_table({**before_dict, **after_dict})
def parse_table(self, table: str) -> Mapping[str, str | Sequence[str]]:
assignments: list[tuple[str, str]] = []
for assignment_str in shlex.split(table):
key, sep, value = assignment_str.partition(self.pair_sep)
if not sep:
msg = f"malformed option with value {assignment_str!r}"
raise OptionsReaderError(msg)
assignments.append((key, value))
result: dict[str, str | list[str]] = {}
for key, value in assignments:
if key in result:
existing_value = result[key]
if isinstance(existing_value, list):
result[key] = [*existing_value, value]
else:
result[key] = [existing_value, value]
else:
result[key] = value
return result
class EnvironmentFormat(OptionFormat):
"""
The environment format accepts a table of environment variables, where the
values may contain variables or command substitutions.
"""
def format_table(self, table: SettingTable) -> str:
return " ".join(f'{k}="{v}"' for k, v in table.items())
def merge_values(self, before: str, after: str) -> str:
return f"{before} {after}"
class InheritRule(enum.Enum): class InheritRule(enum.Enum):
NONE = enum.auto() NONE = enum.auto()
APPEND = enum.auto() APPEND = enum.auto()
@@ -160,10 +264,9 @@ class InheritRule(enum.Enum):
def _resolve_cascade( def _resolve_cascade(
*pairs: tuple[Setting | None, InheritRule], *pairs: tuple[SettingValue | None, InheritRule],
ignore_empty: bool = False, ignore_empty: bool = False,
list_sep: str | None = None, option_format: OptionFormat | None = None,
table_format: TableFmt | None = None,
) -> str: ) -> str:
""" """
Given a cascade of values with inherit rules, resolve them into a single Given a cascade of values with inherit rules, resolve them into a single
@@ -186,13 +289,6 @@ def _resolve_cascade(
result: str | None = None result: str | None = None
if table_format is not None:
merge_sep = table_format["sep"]
elif list_sep is not None:
merge_sep = list_sep
else:
merge_sep = None
for value, rule in pairs: for value, rule in pairs:
if value is None: if value is None:
continue continue
@@ -200,14 +296,9 @@ def _resolve_cascade(
if ignore_empty and not value and value is not False: if ignore_empty and not value and value is not False:
continue continue
value_string = _stringify_setting(value, list_sep, table_format) value_string = _stringify_setting(value, option_format=option_format)
result = _merge_values( result = _apply_inherit_rule(result, value_string, rule=rule, option_format=option_format)
result,
value_string,
rule=rule,
merge_sep=merge_sep,
)
if result is None: if result is None:
msg = "a setting should at least have a default value" msg = "a setting should at least have a default value"
@@ -217,7 +308,9 @@ def _resolve_cascade(
# pylint: disable-next=inconsistent-return-statements # pylint: disable-next=inconsistent-return-statements
def _merge_values(before: str | None, after: str, rule: InheritRule, merge_sep: str | None) -> str: def _apply_inherit_rule(
before: str | None, after: str, rule: InheritRule, option_format: OptionFormat | None
) -> str:
if rule == InheritRule.NONE: if rule == InheritRule.NONE:
return after return after
@@ -230,34 +323,39 @@ def _merge_values(before: str | None, after: str, rule: InheritRule, merge_sep:
# if after is an empty string, we shouldn't add any separator # if after is an empty string, we shouldn't add any separator
return before return before
if not merge_sep: if not option_format:
msg = f"Don't know how to merge {before!r} and {after!r} with {rule}" msg = f"Don't know how to merge {before!r} and {after!r} with {rule}"
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
if rule == InheritRule.APPEND: if rule == InheritRule.APPEND:
return f"{before}{merge_sep}{after}" return option_format.merge_values(before, after)
elif rule == InheritRule.PREPEND: elif rule == InheritRule.PREPEND:
return f"{after}{merge_sep}{before}" return option_format.merge_values(after, before)
else: else:
assert_never(rule) assert_never(rule)
def _stringify_setting( def _stringify_setting(
setting: Setting, list_sep: str | None, table_format: TableFmt | None setting: SettingValue,
option_format: OptionFormat | None,
) -> str: ) -> str:
if isinstance(setting, Mapping): if isinstance(setting, Mapping):
if table_format is None: try:
if option_format is None:
raise OptionFormat.NotSupported
return option_format.format_table(setting)
except OptionFormat.NotSupported:
msg = f"Error converting {setting!r} to a string: this setting doesn't accept a table" msg = f"Error converting {setting!r} to a string: this setting doesn't accept a table"
raise ConfigOptionError(msg) raise OptionsReaderError(msg) from None
return table_format["sep"].join(
item for k, v in setting.items() for item in _inner_fmt(k, v, table_format)
)
if not isinstance(setting, str) and isinstance(setting, Sequence): if not isinstance(setting, str) and isinstance(setting, Sequence):
if list_sep is None: try:
if option_format is None:
raise OptionFormat.NotSupported
return option_format.format_list(setting)
except OptionFormat.NotSupported:
msg = f"Error converting {setting!r} to a string: this setting doesn't accept a list" msg = f"Error converting {setting!r} to a string: this setting doesn't accept a list"
raise ConfigOptionError(msg) raise OptionsReaderError(msg) from None
return list_sep.join(setting)
if isinstance(setting, (bool, int)): if isinstance(setting, (bool, int)):
return str(setting) return str(setting)
@@ -323,14 +421,14 @@ class OptionsReader:
if config_overrides is not None: if config_overrides is not None:
if not isinstance(config_overrides, list): if not isinstance(config_overrides, list):
msg = "'tool.cibuildwheel.overrides' must be a list" msg = "'tool.cibuildwheel.overrides' must be a list"
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
for config_override in config_overrides: for config_override in config_overrides:
select = config_override.pop("select", None) select = config_override.pop("select", None)
if not select: if not select:
msg = "'select' must be set in an override" msg = "'select' must be set in an override"
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
if isinstance(select, list): if isinstance(select, list):
select = " ".join(select) select = " ".join(select)
@@ -340,7 +438,7 @@ class OptionsReader:
i in {"none", "append", "prepend"} for i in inherit.values() i in {"none", "append", "prepend"} for i in inherit.values()
): ):
msg = "'inherit' must be a dict containing only {'none', 'append', 'prepend'} values" msg = "'inherit' must be a dict containing only {'none', 'append', 'prepend'} values"
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
inherit_enum = {k: InheritRule[v.upper()] for k, v in inherit.items()} inherit_enum = {k: InheritRule[v.upper()] for k, v in inherit.items()}
@@ -358,7 +456,7 @@ class OptionsReader:
matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7) matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7)
if matches: if matches:
msg += f" Perhaps you meant {matches[0]!r}?" msg += f" Perhaps you meant {matches[0]!r}?"
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
def _validate_platform_option(self, name: str) -> None: def _validate_platform_option(self, name: str) -> None:
""" """
@@ -368,7 +466,7 @@ class OptionsReader:
disallowed_platform_options = self.disallow.get(self.platform, set()) disallowed_platform_options = self.disallow.get(self.platform, set())
if name in disallowed_platform_options: if name in disallowed_platform_options:
msg = f"{name!r} is not allowed in {disallowed_platform_options}" msg = f"{name!r} is not allowed in {disallowed_platform_options}"
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
allowed_option_names = self.default_options.keys() | self.default_platform_options.keys() allowed_option_names = self.default_options.keys() | self.default_platform_options.keys()
@@ -377,7 +475,7 @@ class OptionsReader:
matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7) matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7)
if matches: if matches:
msg += f" Perhaps you meant {matches[0]!r}?" msg += f" Perhaps you meant {matches[0]!r}?"
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
def _load_file(self, filename: Path) -> tuple[dict[str, Any], dict[str, Any]]: def _load_file(self, filename: Path) -> tuple[dict[str, Any], dict[str, Any]]:
""" """
@@ -412,8 +510,7 @@ class OptionsReader:
name: str, name: str,
*, *,
env_plat: bool = True, env_plat: bool = True,
list_sep: str | None = None, option_format: OptionFormat | None = None,
table_format: TableFmt | None = None,
ignore_empty: bool = False, ignore_empty: bool = False,
) -> str: ) -> str:
""" """
@@ -429,7 +526,7 @@ class OptionsReader:
if name not in self.default_options and name not in self.default_platform_options: if name not in self.default_options and name not in self.default_platform_options:
msg = f"{name!r} must be in cibuildwheel/resources/defaults.toml file to be accessed." msg = f"{name!r} must be in cibuildwheel/resources/defaults.toml file to be accessed."
raise ConfigOptionError(msg) raise OptionsReaderError(msg)
# Environment variable form # Environment variable form
envvar = f"CIBW_{name.upper().replace('-', '_')}" envvar = f"CIBW_{name.upper().replace('-', '_')}"
@@ -449,26 +546,10 @@ class OptionsReader:
(self.env.get(envvar), InheritRule.NONE), (self.env.get(envvar), InheritRule.NONE),
(self.env.get(plat_envvar) if env_plat else None, InheritRule.NONE), (self.env.get(plat_envvar) if env_plat else None, InheritRule.NONE),
ignore_empty=ignore_empty, ignore_empty=ignore_empty,
list_sep=list_sep, option_format=option_format,
table_format=table_format,
) )
def _inner_fmt(k: str, v: Any, table: TableFmt) -> Iterator[str]:
quote_function = table.get("quote", lambda a: a)
if isinstance(v, list):
for inner_v in v:
qv = quote_function(inner_v)
yield table["item"].format(k=k, v=qv)
elif isinstance(v, bool):
qv = quote_function(str(v))
yield table["item"].format(k=k, v=qv)
else:
qv = quote_function(v)
yield table["item"].format(k=k, v=qv)
class Options: class Options:
def __init__( def __init__(
self, self,
@@ -513,9 +594,11 @@ class Options:
package_dir = args.package_dir package_dir = args.package_dir
output_dir = args.output_dir output_dir = args.output_dir
build_config = self.reader.get("build", env_plat=False, list_sep=" ") or "*" build_config = (
skip_config = self.reader.get("skip", env_plat=False, list_sep=" ") self.reader.get("build", env_plat=False, option_format=ListFormat(sep=" ")) or "*"
test_skip = self.reader.get("test-skip", env_plat=False, list_sep=" ") )
skip_config = self.reader.get("skip", env_plat=False, option_format=ListFormat(sep=" "))
test_skip = self.reader.get("test-skip", env_plat=False, option_format=ListFormat(sep=" "))
free_threaded_support = strtobool( free_threaded_support = strtobool(
self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True) self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True)
@@ -534,7 +617,7 @@ class Options:
) )
requires_python = None if requires_python_str is None else SpecifierSet(requires_python_str) requires_python = None if requires_python_str is None else SpecifierSet(requires_python_str)
archs_config_str = args.archs or self.reader.get("archs", list_sep=" ") archs_config_str = args.archs or self.reader.get("archs", option_format=ListFormat(sep=" "))
architectures = Architecture.parse_config(archs_config_str, platform=self.platform) architectures = Architecture.parse_config(archs_config_str, platform=self.platform)
# Process `--only` # Process `--only`
@@ -569,30 +652,33 @@ class Options:
""" """
with self.reader.identifier(identifier): with self.reader.identifier(identifier):
before_all = self.reader.get("before-all", list_sep=" && ") before_all = self.reader.get("before-all", option_format=ListFormat(sep=" && "))
environment_config = self.reader.get( environment_config = self.reader.get("environment", option_format=EnvironmentFormat())
"environment", table_format={"item": '{k}="{v}"', "sep": " "} environment_pass = self.reader.get(
"environment-pass", option_format=ListFormat(sep=" ")
).split()
before_build = self.reader.get("before-build", option_format=ListFormat(sep=" && "))
repair_command = self.reader.get(
"repair-wheel-command", option_format=ListFormat(sep=" && ")
) )
environment_pass = self.reader.get("environment-pass", list_sep=" ").split()
before_build = self.reader.get("before-build", list_sep=" && ")
repair_command = self.reader.get("repair-wheel-command", list_sep=" && ")
config_settings = self.reader.get( config_settings = self.reader.get(
"config-settings", "config-settings", option_format=ShlexTableFormat(sep=" ", pair_sep="=")
table_format={"item": "{k}={v}", "sep": " ", "quote": shlex.quote},
) )
dependency_versions = self.reader.get("dependency-versions") dependency_versions = self.reader.get("dependency-versions")
test_command = self.reader.get("test-command", list_sep=" && ") test_command = self.reader.get("test-command", option_format=ListFormat(sep=" && "))
before_test = self.reader.get("before-test", list_sep=" && ") before_test = self.reader.get("before-test", option_format=ListFormat(sep=" && "))
test_requires = self.reader.get("test-requires", list_sep=" ").split() test_requires = self.reader.get(
test_extras = self.reader.get("test-extras", list_sep=",") "test-requires", option_format=ListFormat(sep=" ")
).split()
test_extras = self.reader.get("test-extras", option_format=ListFormat(sep=","))
build_verbosity_str = self.reader.get("build-verbosity") build_verbosity_str = self.reader.get("build-verbosity")
build_frontend_str = self.reader.get( build_frontend_str = self.reader.get(
"build-frontend", "build-frontend",
env_plat=False, env_plat=False,
table_format={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote}, option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
) )
build_frontend: BuildFrontendConfig | None build_frontend: BuildFrontendConfig | None
if not build_frontend_str or build_frontend_str == "default": if not build_frontend_str or build_frontend_str == "default":
@@ -674,7 +760,7 @@ class Options:
container_engine_str = self.reader.get( container_engine_str = self.reader.get(
"container-engine", "container-engine",
table_format={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote}, option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
) )
try: try:
+9 -9
View File
@@ -120,9 +120,9 @@ python_configurations = [
{ identifier = "cp311-macosx_x86_64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" }, { identifier = "cp311-macosx_x86_64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
{ identifier = "cp311-macosx_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" }, { identifier = "cp311-macosx_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
{ identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" }, { identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
{ identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.4/python-3.12.4-macos11.pkg" }, { identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.5/python-3.12.5-macos11.pkg" },
{ identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.4/python-3.12.4-macos11.pkg" }, { identifier = "cp312-macosx_arm64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.5/python-3.12.5-macos11.pkg" },
{ identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.4/python-3.12.4-macos11.pkg" }, { identifier = "cp312-macosx_universal2", version = "3.12", url = "https://www.python.org/ftp/python/3.12.5/python-3.12.5-macos11.pkg" },
{ identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" }, { identifier = "cp313-macosx_x86_64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
{ identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" }, { identifier = "cp313-macosx_arm64", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
{ identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" }, { identifier = "cp313-macosx_universal2", version = "3.13", url = "https://www.python.org/ftp/python/3.13.0/python-3.13.0rc1-macos11.pkg" },
@@ -134,8 +134,8 @@ python_configurations = [
{ identifier = "pp38-macosx_arm64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_arm64.tar.bz2" }, { identifier = "pp38-macosx_arm64", version = "3.8", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-macos_arm64.tar.bz2" },
{ identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" }, { identifier = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" },
{ identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2" }, { identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2" },
{ identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.16-macos_x86_64.tar.bz2" }, { identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.17-macos_x86_64.tar.bz2" },
{ identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.16-macos_arm64.tar.bz2" }, { identifier = "pp310-macosx_arm64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.17-macos_arm64.tar.bz2" },
] ]
[windows] [windows]
@@ -152,8 +152,8 @@ python_configurations = [
{ identifier = "cp310-win_amd64", version = "3.10.11", arch = "64" }, { identifier = "cp310-win_amd64", version = "3.10.11", arch = "64" },
{ identifier = "cp311-win32", version = "3.11.9", arch = "32" }, { identifier = "cp311-win32", version = "3.11.9", arch = "32" },
{ identifier = "cp311-win_amd64", version = "3.11.9", arch = "64" }, { identifier = "cp311-win_amd64", version = "3.11.9", arch = "64" },
{ identifier = "cp312-win32", version = "3.12.4", arch = "32" }, { identifier = "cp312-win32", version = "3.12.5", arch = "32" },
{ identifier = "cp312-win_amd64", version = "3.12.4", arch = "64" }, { identifier = "cp312-win_amd64", version = "3.12.5", arch = "64" },
{ identifier = "cp313-win32", version = "3.13.0-rc1", arch = "32" }, { identifier = "cp313-win32", version = "3.13.0-rc1", arch = "32" },
{ identifier = "cp313t-win32", version = "3.13.0-rc1", arch = "32" }, { identifier = "cp313t-win32", version = "3.13.0-rc1", arch = "32" },
{ identifier = "cp313-win_amd64", version = "3.13.0-rc1", arch = "64" }, { identifier = "cp313-win_amd64", version = "3.13.0-rc1", arch = "64" },
@@ -161,13 +161,13 @@ python_configurations = [
{ identifier = "cp39-win_arm64", version = "3.9.10", arch = "ARM64" }, { identifier = "cp39-win_arm64", version = "3.9.10", arch = "ARM64" },
{ identifier = "cp310-win_arm64", version = "3.10.11", arch = "ARM64" }, { identifier = "cp310-win_arm64", version = "3.10.11", arch = "ARM64" },
{ identifier = "cp311-win_arm64", version = "3.11.9", arch = "ARM64" }, { identifier = "cp311-win_arm64", version = "3.11.9", arch = "ARM64" },
{ identifier = "cp312-win_arm64", version = "3.12.4", arch = "ARM64" }, { identifier = "cp312-win_arm64", version = "3.12.5", arch = "ARM64" },
{ identifier = "cp313-win_arm64", version = "3.13.0-rc1", arch = "ARM64" }, { identifier = "cp313-win_arm64", version = "3.13.0-rc1", arch = "ARM64" },
{ identifier = "cp313t-win_arm64", version = "3.13.0-rc1", arch = "ARM64" }, { identifier = "cp313t-win_arm64", version = "3.13.0-rc1", arch = "ARM64" },
{ identifier = "pp37-win_amd64", version = "3.7", arch = "64", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.9-win64.zip" }, { identifier = "pp37-win_amd64", version = "3.7", arch = "64", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.9-win64.zip" },
{ identifier = "pp38-win_amd64", version = "3.8", arch = "64", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" }, { identifier = "pp38-win_amd64", version = "3.8", arch = "64", url = "https://downloads.python.org/pypy/pypy3.8-v7.3.11-win64.zip" },
{ identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" }, { identifier = "pp39-win_amd64", version = "3.9", arch = "64", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-win64.zip" },
{ identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.16-win64.zip" }, { identifier = "pp310-win_amd64", version = "3.10", arch = "64", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.17-win64.zip" },
] ]
[pyodide] [pyodide]
@@ -10,7 +10,7 @@ build==1.2.1
# via # via
# -r .nox/update_constraints/tmp/constraints-pyodide.in # -r .nox/update_constraints/tmp/constraints-pyodide.in
# pyodide-build # pyodide-build
certifi==2024.7.4 certifi==2024.8.30
# via # via
# httpcore # httpcore
# httpx # httpx
@@ -21,7 +21,7 @@ click==8.1.7
# via typer # via typer
cloudpickle==3.0.0 cloudpickle==3.0.0
# via loky # via loky
cmake==3.30.1 cmake==3.30.2
# via pyodide-build # via pyodide-build
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
@@ -31,9 +31,9 @@ h11==0.14.0
# via httpcore # via httpcore
httpcore==1.0.5 httpcore==1.0.5
# via httpx # via httpx
httpx==0.27.0 httpx==0.27.2
# via unearth # via unearth
idna==3.7 idna==3.8
# via # via
# anyio # anyio
# httpx # httpx
@@ -74,13 +74,13 @@ pyodide-lock==0.1.0a6
# via pyodide-build # via pyodide-build
pyproject-hooks==1.1.0 pyproject-hooks==1.1.0
# via build # via build
pyyaml==6.0.1 pyyaml==6.0.2
# via pyodide-build # via pyodide-build
requests==2.32.3 requests==2.32.3
# via pyodide-build # via pyodide-build
resolvelib==1.0.1 resolvelib==1.0.1
# via pyodide-build # via pyodide-build
rich==13.7.1 rich==13.8.0
# via # via
# pyodide-build # pyodide-build
# pyodide-cli # pyodide-cli
@@ -95,7 +95,7 @@ sniffio==1.3.1
# via # via
# anyio # anyio
# httpx # httpx
typer==0.12.3 typer==0.12.5
# via # via
# auditwheel-emscripten # auditwheel-emscripten
# pyodide-build # pyodide-build
@@ -107,7 +107,7 @@ typing-extensions==4.12.2
# pydantic # pydantic
# pydantic-core # pydantic-core
# typer # typer
unearth==0.16.1 unearth==0.17.2
# via pyodide-build # via pyodide-build
urllib3==2.2.2 urllib3==2.2.2
# via # via
@@ -117,7 +117,7 @@ virtualenv==20.26.3
# via # via
# build # build
# pyodide-build # pyodide-build
wheel==0.43.0 wheel==0.44.0
# via # via
# auditwheel-emscripten # auditwheel-emscripten
# pyodide-build # pyodide-build
@@ -4,13 +4,13 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.2.1 build==1.2.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
filelock==3.15.4 filelock==3.15.4
# via virtualenv # via virtualenv
importlib-metadata==8.2.0 importlib-metadata==8.4.0
# via build # via build
macholib==1.16.3 macholib==1.16.3
# via delocate # via delocate
@@ -30,5 +30,5 @@ typing-extensions==4.12.2
# via delocate # via delocate
virtualenv==20.26.3 virtualenv==20.26.3
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
zipp==3.19.2 zipp==3.20.1
# via importlib-metadata # via importlib-metadata
@@ -4,7 +4,7 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.2.1 build==1.2.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
@@ -4,7 +4,7 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.2.1 build==1.2.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
@@ -4,7 +4,7 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.2.1 build==1.2.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
@@ -4,7 +4,7 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.1.1 build==1.1.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
@@ -4,13 +4,13 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.2.1 build==1.2.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
filelock==3.15.4 filelock==3.15.4
# via virtualenv # via virtualenv
importlib-metadata==8.2.0 importlib-metadata==8.4.0
# via build # via build
macholib==1.16.3 macholib==1.16.3
# via delocate # via delocate
@@ -30,5 +30,5 @@ typing-extensions==4.12.2
# via delocate # via delocate
virtualenv==20.26.3 virtualenv==20.26.3
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
zipp==3.19.2 zipp==3.20.1
# via importlib-metadata # via importlib-metadata
@@ -4,13 +4,13 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.2.1 build==1.2.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
filelock==3.15.4 filelock==3.15.4
# via virtualenv # via virtualenv
importlib-metadata==8.2.0 importlib-metadata==8.4.0
# via build # via build
macholib==1.16.3 macholib==1.16.3
# via delocate # via delocate
@@ -30,5 +30,5 @@ typing-extensions==4.12.2
# via delocate # via delocate
virtualenv==20.26.3 virtualenv==20.26.3
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
zipp==3.19.2 zipp==3.20.1
# via importlib-metadata # via importlib-metadata
+1 -1
View File
@@ -4,7 +4,7 @@ altgraph==0.17.4
# via macholib # via macholib
build==1.2.1 build==1.2.1
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
delocate==0.11.0 delocate==0.12.0
# via -r cibuildwheel/resources/constraints.in # via -r cibuildwheel/resources/constraints.in
distlib==0.3.8 distlib==0.3.8
# via virtualenv # via virtualenv
+1 -1
View File
@@ -1,2 +1,2 @@
url = "https://nodejs.org/dist/" url = "https://nodejs.org/dist/"
v20 = "v20.16.0" v20 = "v20.17.0"
+24 -24
View File
@@ -1,54 +1,54 @@
[x86_64] [x86_64]
manylinux1 = quay.io/pypa/manylinux1_x86_64:2024-04-29-76807b8 manylinux1 = quay.io/pypa/manylinux1_x86_64:2024-04-29-76807b8
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177 manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2024.08.03-1 manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2024.09.01-2
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2024.08.03-1 musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2024.09.01-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2024.08.03-1 musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2024.09.01-2
[i686] [i686]
manylinux1 = quay.io/pypa/manylinux1_i686:2024-04-29-76807b8 manylinux1 = quay.io/pypa/manylinux1_i686:2024-04-29-76807b8
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177 manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_i686:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_i686:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2024.08.03-1 musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2024.09.01-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2024.08.03-1 musllinux_1_2 = quay.io/pypa/musllinux_1_2_i686:2024.09.01-2
[pypy_x86_64] [pypy_x86_64]
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177 manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2024.08.03-1 manylinux_2_28 = quay.io/pypa/manylinux_2_28_x86_64:2024.09.01-2
[pypy_i686] [pypy_i686]
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177 manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
manylinux2014 = quay.io/pypa/manylinux2014_i686:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_i686:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2022-12-26-0d38463
[aarch64] [aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.08.03-1 manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.09.01-2
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2024.08.03-1 musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2024.09.01-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2024.08.03-1 musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2024.09.01-2
[ppc64le] [ppc64le]
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2024.08.03-1 manylinux_2_28 = quay.io/pypa/manylinux_2_28_ppc64le:2024.09.01-2
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2024.08.03-1 musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2024.09.01-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2024.08.03-1 musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2024.09.01-2
[s390x] [s390x]
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_s390x:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2024.08.03-1 manylinux_2_28 = quay.io/pypa/manylinux_2_28_s390x:2024.09.01-2
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2024.08.03-1 musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2024.09.01-2
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2024.08.03-1 musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2024.09.01-2
[pypy_aarch64] [pypy_aarch64]
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2024.08.03-1 manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2024.09.01-2
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463 manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2022-12-26-0d38463
manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.08.03-1 manylinux_2_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.09.01-2
+12 -12
View File
@@ -11,8 +11,8 @@ 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. |
| [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. |
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. | | [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
| [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system | | [duckdb][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | DuckDB is an analytical in-process SQL database management system |
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform | | [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions | | [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. | | [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. |
@@ -55,9 +55,9 @@ title: Working examples
| [Wrapt][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python module for decorators, wrappers and monkey patching. | | [Wrapt][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python module for decorators, wrappers and monkey patching. |
| [envd][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A machine learning development environment build tool | | [envd][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A machine learning development environment build tool |
| [OpenColorIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A color management framework for visual effects and animation. | | [OpenColorIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | A color management framework for visual effects and animation. |
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
| [Psycopg 3][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A modern implementation of a PostgreSQL adapter for Python | | [Psycopg 3][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A modern implementation of a PostgreSQL adapter for Python |
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. | | [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. | | [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
| [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data | | [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data |
@@ -93,8 +93,8 @@ title: Working examples
| [streaming-form-data][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Streaming parser for multipart/form-data written in Cython | | [streaming-form-data][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Streaming parser for multipart/form-data written in Cython |
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. | | [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
| [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. |
| [Python-WebRTC][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | a Python extension that provides bindings to WebRTC M92 |
| [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis | | [power-grid-model][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python/C++ library for distribution power system analysis |
| [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 |
| [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. |
| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms | | [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
@@ -104,13 +104,13 @@ title: Working examples
| [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. |
| [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. |
| [cf-units][] | ![github icon][] | ![apple icon][] ![linux icon][] | Units of measure as required by the Climate and Forecast (CF) Metadata Conventions | | [cf-units][] | ![github icon][] | ![apple icon][] ![linux icon][] | Units of measure as required by the Climate and Forecast (CF) Metadata Conventions |
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
| [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. | | [ninja][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Multitagged binary builds for all supported platforms, using cibw 2 config configuration. |
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy | | [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy |
| [Confluent client for Kafka][] | ![travisci icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | setup in `tools/wheels/build-wheels.bat` |
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy | | [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
| [ril][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A python binding to Rust Imaging library using maturin and Pyo3, utilizes Github Action cache to improve speed. Builds abi3 wheels. | | [ril][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A python binding to Rust Imaging library using maturin and Pyo3, utilizes Github Action cache to improve speed. Builds abi3 wheels. |
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
| [SiPM][] | ![github icon][] | ![apple icon][] ![linux icon][] | High performance library for SiPM detectors simulation using C++17, OpenMP and AVX2 intrinsics. | | [SiPM][] | ![github icon][] | ![apple icon][] ![linux icon][] | High performance library for SiPM detectors simulation using C++17, OpenMP and AVX2 intrinsics. |
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
| [aalink][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Async Python interface for Ableton Link. | | [aalink][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Async Python interface for Ableton Link. |
| [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. | | [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. |
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. | | [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
@@ -121,8 +121,8 @@ title: Working examples
[scikit-learn]: https://github.com/scikit-learn/scikit-learn [scikit-learn]: https://github.com/scikit-learn/scikit-learn
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq [pytorch-fairseq]: https://github.com/facebookresearch/fairseq
[NumPy]: https://github.com/numpy/numpy [NumPy]: https://github.com/numpy/numpy
[Tornado]: https://github.com/tornadoweb/tornado
[duckdb]: https://github.com/duckdb/duckdb [duckdb]: https://github.com/duckdb/duckdb
[Tornado]: https://github.com/tornadoweb/tornado
[NCNN]: https://github.com/Tencent/ncnn [NCNN]: https://github.com/Tencent/ncnn
[Matplotlib]: https://github.com/matplotlib/matplotlib [Matplotlib]: https://github.com/matplotlib/matplotlib
[Prophet]: https://github.com/facebook/prophet [Prophet]: https://github.com/facebook/prophet
@@ -165,9 +165,9 @@ title: Working examples
[Wrapt]: https://github.com/GrahamDumpleton/wrapt [Wrapt]: https://github.com/GrahamDumpleton/wrapt
[envd]: https://github.com/tensorchord/envd [envd]: https://github.com/tensorchord/envd
[OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO [OpenColorIO]: https://github.com/AcademySoftwareFoundation/OpenColorIO
[SimpleJSON]: https://github.com/simplejson/simplejson
[aioquic]: https://github.com/aiortc/aioquic
[Psycopg 3]: https://github.com/psycopg/psycopg [Psycopg 3]: https://github.com/psycopg/psycopg
[aioquic]: https://github.com/aiortc/aioquic
[SimpleJSON]: https://github.com/simplejson/simplejson
[ruptures]: https://github.com/deepcharles/ruptures [ruptures]: https://github.com/deepcharles/ruptures
[OpenTimelineIO]: https://github.com/AcademySoftwareFoundation/OpenTimelineIO [OpenTimelineIO]: https://github.com/AcademySoftwareFoundation/OpenTimelineIO
[PyTables]: https://github.com/PyTables/PyTables [PyTables]: https://github.com/PyTables/PyTables
@@ -203,8 +203,8 @@ title: Working examples
[streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data [streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data
[bx-python]: https://github.com/bxlab/bx-python [bx-python]: https://github.com/bxlab/bx-python
[boost-histogram]: https://github.com/scikit-hep/boost-histogram [boost-histogram]: https://github.com/scikit-hep/boost-histogram
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
[power-grid-model]: https://github.com/PowerGridModel/power-grid-model [power-grid-model]: https://github.com/PowerGridModel/power-grid-model
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
[pybase64]: https://github.com/mayeut/pybase64 [pybase64]: https://github.com/mayeut/pybase64
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build [Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
[fathon]: https://github.com/stfbnc/fathon [fathon]: https://github.com/stfbnc/fathon
@@ -214,13 +214,13 @@ title: Working examples
[clang-format]: https://github.com/ssciwr/clang-format-wheel [clang-format]: https://github.com/ssciwr/clang-format-wheel
[etebase-py]: https://github.com/etesync/etebase-py [etebase-py]: https://github.com/etesync/etebase-py
[cf-units]: https://github.com/SciTools/cf-units [cf-units]: https://github.com/SciTools/cf-units
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
[ninja]: https://github.com/scikit-build/ninja-python-distributions [ninja]: https://github.com/scikit-build/ninja-python-distributions
[numpythia]: https://github.com/scikit-hep/numpythia [numpythia]: https://github.com/scikit-hep/numpythia
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
[pyjet]: https://github.com/scikit-hep/pyjet [pyjet]: https://github.com/scikit-hep/pyjet
[ril]: https://github.com/Cryptex-github/ril-py [ril]: https://github.com/Cryptex-github/ril-py
[GSD]: https://github.com/glotzerlab/gsd
[SiPM]: https://github.com/EdoPro98/SimSiPM [SiPM]: https://github.com/EdoPro98/SimSiPM
[GSD]: https://github.com/glotzerlab/gsd
[aalink]: https://github.com/artfwo/aalink [aalink]: https://github.com/artfwo/aalink
[CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib [CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib
[xmlstarlet]: https://github.com/dimitern/xmlstarlet [xmlstarlet]: https://github.com/dimitern/xmlstarlet
+7 -10
View File
@@ -1,16 +1,13 @@
environment: environment:
matrix: matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204
APPVEYOR_JOB_NAME: "python37-x64-ubuntu" APPVEYOR_JOB_NAME: "linux-x64"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
APPVEYOR_JOB_NAME: "python37-x64-vs2015" APPVEYOR_JOB_NAME: "windows-x64"
- APPVEYOR_BUILD_WORKER_IMAGE: macos - APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
APPVEYOR_JOB_NAME: "python37-x64-macos" APPVEYOR_JOB_NAME: "macos-x64"
stack: python 3.7 stack: python 3.12
init:
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
install: python -m pip install cibuildwheel==2.20.0 install: python -m pip install cibuildwheel==2.20.0
-1
View File
@@ -6,7 +6,6 @@ linux:
entrypoint: ["env", "-u", "DOCKER_HOST"] entrypoint: ["env", "-u", "DOCKER_HOST"]
command: ["dockerd-entrypoint.sh"] command: ["dockerd-entrypoint.sh"]
variables: variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2 DOCKER_DRIVER: overlay2
# See https://github.com/docker-library/docker/pull/166 # See https://github.com/docker-library/docker/pull/166
DOCKER_TLS_CERTDIR: "" DOCKER_TLS_CERTDIR: ""
-1
View File
@@ -6,7 +6,6 @@ linux:
entrypoint: ["env", "-u", "DOCKER_HOST"] entrypoint: ["env", "-u", "DOCKER_HOST"]
command: ["dockerd-entrypoint.sh"] command: ["dockerd-entrypoint.sh"]
variables: variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2 DOCKER_DRIVER: overlay2
# See https://github.com/docker-library/docker/pull/166 # See https://github.com/docker-library/docker/pull/166
DOCKER_TLS_CERTDIR: "" DOCKER_TLS_CERTDIR: ""
-2
View File
@@ -184,10 +184,8 @@ messages_control.disable = [
] ]
[tool.ruff] [tool.ruff]
target-version = "py38"
line-length = 100 line-length = 100
[tool.ruff.lint] [tool.ruff.lint]
extend-select = [ extend-select = [
"B", # flake8-bugbear "B", # flake8-bugbear
+2 -2
View File
@@ -37,7 +37,7 @@ def build_frontend_env_nouv(request: pytest.FixtureRequest) -> dict[str, str]:
return {"CIBW_BUILD_FRONTEND": frontend} return {"CIBW_BUILD_FRONTEND": frontend}
@pytest.fixture() @pytest.fixture
def build_frontend_env(build_frontend_env_nouv: dict[str, str]) -> dict[str, str]: def build_frontend_env(build_frontend_env_nouv: dict[str, str]) -> dict[str, str]:
frontend = build_frontend_env_nouv["CIBW_BUILD_FRONTEND"] frontend = build_frontend_env_nouv["CIBW_BUILD_FRONTEND"]
if frontend != "build" or platform == "pyodide" or find_uv() is None: if frontend != "build" or platform == "pyodide" or find_uv() is None:
@@ -46,7 +46,7 @@ def build_frontend_env(build_frontend_env_nouv: dict[str, str]) -> dict[str, str
return {"CIBW_BUILD_FRONTEND": "build[uv]"} return {"CIBW_BUILD_FRONTEND": "build[uv]"}
@pytest.fixture() @pytest.fixture
def docker_cleanup() -> Generator[None, None, None]: def docker_cleanup() -> Generator[None, None, None]:
def get_images() -> set[str]: def get_images() -> set[str]:
if detect_ci_provider() is None or platform != "linux": if detect_ci_provider() is None or platform != "linux":
+4 -1
View File
@@ -6,7 +6,7 @@ import textwrap
import pytest import pytest
from cibuildwheel.util import CIBW_CACHE_PATH from cibuildwheel.util import CIBW_CACHE_PATH, CIProvider, detect_ci_provider
from . import test_projects, utils from . import test_projects, utils
@@ -49,6 +49,9 @@ def test_pyodide_build(tmp_path, use_pyproject_toml):
if not shutil.which("python3.12"): if not shutil.which("python3.12"):
pytest.skip("Python 3.12 not installed") pytest.skip("Python 3.12 not installed")
if detect_ci_provider() == CIProvider.travis_ci:
pytest.skip("Python 3.12 is just a non-working pyenv shim")
if use_pyproject_toml: if use_pyproject_toml:
basic_project.files["pyproject.toml"] = textwrap.dedent( basic_project.files["pyproject.toml"] = textwrap.dedent(
""" """
+4 -5
View File
@@ -23,15 +23,14 @@ EMULATED_ARCHS: Final[list[str]] = sorted(
) )
SINGLE_PYTHON_VERSION: Final[tuple[int, int]] = (3, 12) SINGLE_PYTHON_VERSION: Final[tuple[int, int]] = (3, 12)
platform: str platform = os.environ.get("CIBW_PLATFORM", "")
if platform:
if "CIBW_PLATFORM" in os.environ: pass
platform = os.environ["CIBW_PLATFORM"]
elif sys.platform.startswith("linux"): elif sys.platform.startswith("linux"):
platform = "linux" platform = "linux"
elif sys.platform.startswith("darwin"): elif sys.platform.startswith("darwin"):
platform = "macos" platform = "macos"
elif sys.platform in ["win32", "cygwin"]: elif sys.platform.startswith(("win32", "cygwin")):
platform = "windows" platform = "windows"
else: else:
msg = f"Unsupported platform {sys.platform!r}" msg = f"Unsupported platform {sys.platform!r}"
+1 -1
View File
@@ -19,7 +19,7 @@ def pytest_addoption(parser):
) )
@pytest.fixture() @pytest.fixture
def fake_package_dir(tmp_path, monkeypatch): def fake_package_dir(tmp_path, monkeypatch):
""" """
Monkey-patch enough for the main() function to run Monkey-patch enough for the main() function to run
+3 -3
View File
@@ -47,7 +47,7 @@ def mock_protection(monkeypatch):
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def fake_package_dir_autouse(fake_package_dir): # noqa: ARG001 def fake_package_dir_autouse(fake_package_dir):
pass pass
@@ -60,7 +60,7 @@ def disable_print_wheels(monkeypatch):
monkeypatch.setattr(util, "print_new_wheels", empty_cm) monkeypatch.setattr(util, "print_new_wheels", empty_cm)
@pytest.fixture() @pytest.fixture
def allow_empty(monkeypatch, fake_package_dir): def allow_empty(monkeypatch, fake_package_dir):
monkeypatch.setattr(sys, "argv", [*fake_package_dir, "--allow-empty"]) monkeypatch.setattr(sys, "argv", [*fake_package_dir, "--allow-empty"])
@@ -81,7 +81,7 @@ def platform(request, monkeypatch):
return platform_value return platform_value
@pytest.fixture() @pytest.fixture
def intercepted_build_args(monkeypatch): def intercepted_build_args(monkeypatch):
intercepted = ArgsInterceptor() intercepted = ArgsInterceptor()
+1 -1
View File
@@ -10,7 +10,7 @@ from cibuildwheel.architecture import Architecture
from ..conftest import MOCK_PACKAGE_DIR from ..conftest import MOCK_PACKAGE_DIR
@pytest.mark.parametrize("option_value", [None, "auto"]) @pytest.mark.parametrize("option_value", [None, "auto", ""])
def test_platform_unset_or_auto(monkeypatch, intercepted_build_args, option_value): def test_platform_unset_or_auto(monkeypatch, intercepted_build_args, option_value):
if option_value is None: if option_value is None:
monkeypatch.delenv("CIBW_PLATFORM", raising=False) monkeypatch.delenv("CIBW_PLATFORM", raising=False)
+1 -1
View File
@@ -29,7 +29,7 @@ ALL_IDS = {
} }
@pytest.fixture() @pytest.fixture
def mock_build_container(monkeypatch): def mock_build_container(monkeypatch):
def fail_on_call(*args, **kwargs): def fail_on_call(*args, **kwargs):
msg = "This should never be called" msg = "This should never be called"
+1 -2
View File
@@ -10,7 +10,6 @@ import pytest
from cibuildwheel import errors from cibuildwheel import errors
from cibuildwheel.__main__ import get_build_identifiers, get_platform_module from cibuildwheel.__main__ import get_build_identifiers, get_platform_module
from cibuildwheel.bashlex_eval import local_environment_executor from cibuildwheel.bashlex_eval import local_environment_executor
from cibuildwheel.environment import parse_environment
from cibuildwheel.options import ( from cibuildwheel.options import (
CommandLineArguments, CommandLineArguments,
Options, Options,
@@ -66,7 +65,7 @@ def test_options_1(tmp_path, monkeypatch):
default_build_options = options.build_options(identifier=None) default_build_options = options.build_options(identifier=None)
assert default_build_options.environment == parse_environment('FOO="BAR"') assert default_build_options.environment.as_dictionary(prev_environment={}) == {"FOO": "BAR"}
all_pinned_container_images = _get_pinned_container_images() all_pinned_container_images = _get_pinned_container_images()
pinned_x86_64_container_image = all_pinned_container_images["x86_64"] pinned_x86_64_container_image = all_pinned_container_images["x86_64"]
+71 -53
View File
@@ -4,7 +4,15 @@ from pathlib import Path
import pytest import pytest
from cibuildwheel.options import ConfigOptionError, InheritRule, OptionsReader, _resolve_cascade from cibuildwheel.options import (
EnvironmentFormat,
InheritRule,
ListFormat,
OptionsReader,
OptionsReaderError,
ShlexTableFormat,
_resolve_cascade,
)
PYPROJECT_1 = """ PYPROJECT_1 = """
[tool.cibuildwheel] [tool.cibuildwheel]
@@ -37,42 +45,32 @@ def test_simple_settings(tmp_path, platform, fname):
options_reader = OptionsReader(config_file_path, platform=platform, env={}) options_reader = OptionsReader(config_file_path, platform=platform, env={})
assert options_reader.get("build", env_plat=False, list_sep=" ") == "cp39*" assert options_reader.get("build", option_format=ListFormat(" "), env_plat=False) == "cp39*"
assert options_reader.get("test-command") == "pyproject" assert options_reader.get("test-command") == "pyproject"
assert options_reader.get("archs", list_sep=" ") == "auto" assert options_reader.get("archs", option_format=ListFormat(" ")) == "auto"
assert ( assert (
options_reader.get("test-requires", list_sep=" ") options_reader.get("test-requires", option_format=ListFormat(" "))
== {"windows": "something", "macos": "else", "linux": "other many"}[platform] == {"windows": "something", "macos": "else", "linux": "other many"}[platform]
) )
# Also testing options for support for both lists and tables # Also testing options for support for both lists and tables
assert ( assert (
options_reader.get("environment", table_format={"item": '{k}="{v}"', "sep": " "}) options_reader.get("environment", option_format=EnvironmentFormat())
== 'THING="OTHER" FOO="BAR"' == 'THING="OTHER" FOO="BAR"'
) )
assert ( assert options_reader.get("test-extras", option_format=ListFormat(",")) == "one,two"
options_reader.get(
"environment", list_sep="x", table_format={"item": '{k}="{v}"', "sep": " "}
)
== 'THING="OTHER" FOO="BAR"'
)
assert options_reader.get("test-extras", list_sep=",") == "one,two"
assert (
options_reader.get(
"test-extras", list_sep=",", table_format={"item": '{k}="{v}"', "sep": " "}
)
== "one,two"
)
assert options_reader.get("manylinux-x86_64-image") == "manylinux1" assert options_reader.get("manylinux-x86_64-image") == "manylinux1"
assert options_reader.get("manylinux-i686-image") == "manylinux2014" assert options_reader.get("manylinux-i686-image") == "manylinux2014"
with pytest.raises(ConfigOptionError): with pytest.raises(OptionsReaderError):
options_reader.get("environment", list_sep=" ") # fails because the option is a table and the option_format only works with lists
options_reader.get("environment", option_format=ListFormat(" "))
with pytest.raises(ConfigOptionError): with pytest.raises(OptionsReaderError):
options_reader.get("test-extras", table_format={"item": '{k}="{v}"', "sep": " "}) # fails because the option is a list and the option_format only works with tables
options_reader.get("test-extras", option_format=ShlexTableFormat())
def test_envvar_override(tmp_path, platform): def test_envvar_override(tmp_path, platform):
@@ -91,14 +89,14 @@ def test_envvar_override(tmp_path, platform):
}, },
) )
assert options_reader.get("archs", list_sep=" ") == "auto" assert options_reader.get("archs", option_format=ListFormat(" ")) == "auto"
assert options_reader.get("build", list_sep=" ") == "cp38*" assert options_reader.get("build") == "cp38*"
assert options_reader.get("manylinux-x86_64-image") == "manylinux_2_24" assert options_reader.get("manylinux-x86_64-image") == "manylinux_2_24"
assert options_reader.get("manylinux-i686-image") == "manylinux2014" assert options_reader.get("manylinux-i686-image") == "manylinux2014"
assert ( assert (
options_reader.get("test-requires", list_sep=" ") options_reader.get("test-requires", option_format=ListFormat(" "))
== {"windows": "docs", "macos": "docs", "linux": "scod"}[platform] == {"windows": "docs", "macos": "docs", "linux": "scod"}[platform]
) )
assert options_reader.get("test-command") == "mytest" assert options_reader.get("test-command") == "mytest"
@@ -174,7 +172,7 @@ repairs-wheel-command = "repair-project-linux"
""" """
) )
with pytest.raises(ConfigOptionError) as excinfo: with pytest.raises(OptionsReaderError) as excinfo:
OptionsReader(pyproject_toml, platform="linux", env={}) OptionsReader(pyproject_toml, platform="linux", env={})
assert "repair-wheel-command" in str(excinfo.value) assert "repair-wheel-command" in str(excinfo.value)
@@ -191,7 +189,7 @@ repair_wheel_command = "repair-project-linux"
""" """
) )
with pytest.raises(ConfigOptionError) as excinfo: with pytest.raises(OptionsReaderError) as excinfo:
OptionsReader(pyproject_toml, platform="linux", env={}) OptionsReader(pyproject_toml, platform="linux", env={})
assert "repair-wheel-command" in str(excinfo.value) assert "repair-wheel-command" in str(excinfo.value)
@@ -205,7 +203,7 @@ def test_unexpected_table(tmp_path):
repair-wheel-command = "repair-project-linux" repair-wheel-command = "repair-project-linux"
""" """
) )
with pytest.raises(ConfigOptionError): with pytest.raises(OptionsReaderError):
OptionsReader(pyproject_toml, platform="linux", env={}) OptionsReader(pyproject_toml, platform="linux", env={})
@@ -219,8 +217,8 @@ build = ["1", "2"]
) )
options_reader = OptionsReader(pyproject_toml, platform="linux", env={}) options_reader = OptionsReader(pyproject_toml, platform="linux", env={})
assert options_reader.get("build", list_sep=", ") == "1, 2" assert options_reader.get("build", option_format=ListFormat(", ")) == "1, 2"
with pytest.raises(ConfigOptionError): with pytest.raises(OptionsReaderError):
options_reader.get("build") options_reader.get("build")
@@ -234,7 +232,7 @@ manylinux-x86_64-image = "manylinux1"
) )
disallow = {"windows": {"manylinux-x86_64-image"}} disallow = {"windows": {"manylinux-x86_64-image"}}
OptionsReader(pyproject_toml, platform="linux", disallow=disallow, env={}) OptionsReader(pyproject_toml, platform="linux", disallow=disallow, env={})
with pytest.raises(ConfigOptionError): with pytest.raises(OptionsReaderError):
OptionsReader(pyproject_toml, platform="windows", disallow=disallow, env={}) OptionsReader(pyproject_toml, platform="windows", disallow=disallow, env={})
@@ -305,7 +303,7 @@ def test_resolve_cascade_merge_list(ignore_empty, rule):
(["b1", "b2"], rule), (["b1", "b2"], rule),
(None, InheritRule.NONE), (None, InheritRule.NONE),
ignore_empty=ignore_empty, ignore_empty=ignore_empty,
list_sep=" ", option_format=ListFormat(" "),
) )
if not ignore_empty: if not ignore_empty:
@@ -326,24 +324,34 @@ def test_resolve_cascade_merge_dict(rule):
(None, InheritRule.NONE), (None, InheritRule.NONE),
({"value": "override"}, rule), ({"value": "override"}, rule),
(None, InheritRule.NONE), (None, InheritRule.NONE),
table_format={"item": "{k}={v}", "sep": " "}, option_format=ShlexTableFormat(),
) )
if rule == InheritRule.PREPEND: if rule == InheritRule.PREPEND:
assert answer == "value=override value=a1 base=b1" assert answer == "value=a1 base=b1"
elif rule == InheritRule.NONE: elif rule == InheritRule.NONE:
assert answer == "value=override" assert answer == "value=override"
elif rule == InheritRule.APPEND: elif rule == InheritRule.APPEND:
assert answer == "value=a1 base=b1 value=override" assert answer == "value=override base=b1"
def test_resolve_cascade_merge_strings():
answer = _resolve_cascade(
("value=a1 base=b1", InheritRule.NONE),
("value=override", InheritRule.APPEND),
option_format=ShlexTableFormat(),
)
assert answer == "value=override base=b1"
def test_resolve_cascade_merge_different_types(): def test_resolve_cascade_merge_different_types():
answer = _resolve_cascade( answer = _resolve_cascade(
({"value": "a1", "base": "b1"}, InheritRule.NONE), ("value=a1 base=b1", InheritRule.NONE),
({"value": "override"}, InheritRule.APPEND), ({"value": "override"}, InheritRule.APPEND),
table_format={"item": "{k}={v}", "sep": " "}, ("extra_string_var=c1", InheritRule.APPEND),
option_format=ShlexTableFormat(),
) )
assert answer == "value=a1 base=b1 value=override" assert answer == "value=override base=b1 extra_string_var=c1"
PYPROJECT_2 = """ PYPROJECT_2 = """
@@ -387,28 +395,28 @@ def test_pyproject_2(tmp_path, platform):
pyproject_toml.write_text(PYPROJECT_2) pyproject_toml.write_text(PYPROJECT_2)
options_reader = OptionsReader(config_file_path=pyproject_toml, platform=platform, env={}) options_reader = OptionsReader(config_file_path=pyproject_toml, platform=platform, env={})
assert options_reader.get("test-command", list_sep=" && ") == "pyproject" assert options_reader.get("test-command", option_format=ListFormat(" && ")) == "pyproject"
with options_reader.identifier("random"): with options_reader.identifier("random"):
assert options_reader.get("test-command", list_sep=" && ") == "pyproject" assert options_reader.get("test-command", option_format=ListFormat(" && ")) == "pyproject"
with options_reader.identifier("cp37-something"): with options_reader.identifier("cp37-something"):
assert ( assert (
options_reader.get("test-command", list_sep=" && ") options_reader.get("test-command", option_format=ListFormat(" && "))
== "pyproject-override && override2 && pyproject" == "pyproject-override && override2 && pyproject"
) )
assert ( assert (
options_reader.get("environment", table_format={"item": '{k}="{v}"', "sep": " "}) options_reader.get("environment", option_format=EnvironmentFormat())
== 'FOO="BAR" HAM="EGGS" FOO="BAZ" PYTHON="MONTY"' == 'FOO="BAR" HAM="EGGS" FOO="BAZ" PYTHON="MONTY"'
) )
with options_reader.identifier("cp37-final"): with options_reader.identifier("cp37-final"):
assert ( assert (
options_reader.get("test-command", list_sep=" && ") options_reader.get("test-command", option_format=ListFormat(" && "))
== "extra-prepend && pyproject-override && override2 && pyproject && pyproject-finalize && finalize2 && extra-finalize" == "extra-prepend && pyproject-override && override2 && pyproject && pyproject-finalize && finalize2 && extra-finalize"
) )
assert ( assert (
options_reader.get("environment", table_format={"item": '{k}="{v}"', "sep": " "}) options_reader.get("environment", option_format=EnvironmentFormat())
== 'FOO="BAR" HAM="EGGS" FOO="BAZ" PYTHON="MONTY"' == 'FOO="BAR" HAM="EGGS" FOO="BAZ" PYTHON="MONTY"'
) )
@@ -426,7 +434,7 @@ test-command = "pyproject-override"
""" """
) )
with pytest.raises(ConfigOptionError): with pytest.raises(OptionsReaderError):
OptionsReader(config_file_path=pyproject_toml, platform=platform, env={}) OptionsReader(config_file_path=pyproject_toml, platform=platform, env={})
@@ -442,8 +450,8 @@ other = ["two", "three"]
options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={}) options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={})
assert ( assert (
options_reader.get("config-settings", table_format={"item": '{k}="{v}"', "sep": " "}) options_reader.get("config-settings", option_format=ShlexTableFormat(pair_sep="=", sep=" "))
== 'example="one" other="two" other="three"' == "example=one other=two other=three"
) )
@@ -458,10 +466,8 @@ def test_pip_config_settings(tmp_path):
options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={}) options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={})
assert ( assert (
options_reader.get( options_reader.get("config-settings", option_format=ShlexTableFormat(sep=" ", pair_sep="="))
"config-settings", table_format={"item": "--config-settings='{k}=\"{v}\"'", "sep": " "} == "--build-option=--use-mypyc"
)
== "--config-settings='--build-option=\"--use-mypyc\"'"
) )
@@ -471,12 +477,16 @@ def test_overrides_inherit(tmp_path):
"""\ """\
[tool.cibuildwheel] [tool.cibuildwheel]
before-all = ["before-all"] before-all = ["before-all"]
config-settings = {key1="value1", key2="value2", empty=""}
[[tool.cibuildwheel.overrides]] [[tool.cibuildwheel.overrides]]
select = "cp37*" select = "cp37*"
inherit.before-all = "append" inherit.before-all = "append"
before-all = ["override1"] before-all = ["override1"]
inherit.config-settings = "append"
config-settings = {key3="value3", key2="override2"}
[[tool.cibuildwheel.overrides]] [[tool.cibuildwheel.overrides]]
select = "cp37*" select = "cp37*"
inherit.before-all = "prepend" inherit.before-all = "prepend"
@@ -486,9 +496,17 @@ before-all = ["override2"]
options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={}) options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={})
with options_reader.identifier("cp38-something"): with options_reader.identifier("cp38-something"):
assert options_reader.get("before-all", list_sep=" && ") == "before-all" assert options_reader.get("before-all", option_format=ListFormat(" && ")) == "before-all"
assert (
options_reader.get("config-settings", option_format=ShlexTableFormat())
== "key1=value1 key2=value2 empty=''"
)
with options_reader.identifier("cp37-something"): with options_reader.identifier("cp37-something"):
assert ( assert (
options_reader.get("before-all", list_sep=" && ") options_reader.get("before-all", option_format=ListFormat(" && "))
== "override2 && before-all && override1" == "override2 && before-all && override1"
) )
assert (
options_reader.get("config-settings", option_format=ShlexTableFormat())
== "key1=value1 key2=override2 empty='' key3=value3"
)