Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50fef6ffbf | ||
|
|
b1ed7bb3bc | ||
|
|
ca08f5fbcf | ||
|
|
229029e112 | ||
|
|
3294577c17 | ||
|
|
8f51efbc3e | ||
|
|
ebdbb3cbd5 | ||
|
|
3a30bec9ef | ||
|
|
126b81916d | ||
|
|
9abea5b73b | ||
|
|
170e7aaeb9 | ||
|
|
5b570a2451 | ||
|
|
ffd7dddcc7 | ||
|
|
b0b13d3a16 | ||
|
|
b1781e4606 | ||
|
|
3580374b18 | ||
|
|
c6dd39bd83 | ||
|
|
dd8fe86308 | ||
|
|
2e12f05d5e |
@@ -43,7 +43,7 @@ jobs:
|
||||
merge-multiple: true
|
||||
|
||||
- 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:
|
||||
subject-path: "dist/cibuildwheel-*"
|
||||
|
||||
|
||||
@@ -52,17 +52,6 @@ jobs:
|
||||
|
||||
- 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
|
||||
- name: Clean docker images
|
||||
if: runner.os == 'Linux'
|
||||
|
||||
@@ -5,7 +5,6 @@ linux:
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
command: ["dockerd-entrypoint.sh"]
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_DRIVER: overlay2
|
||||
# See https://github.com/docker-library/docker/pull/166
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
|
||||
@@ -14,14 +14,14 @@ repos:
|
||||
- id: trailing-whitespace
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.5.5
|
||||
rev: v0.6.3
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: ["--fix", "--show-fixes"]
|
||||
- id: ruff-format
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.11.0
|
||||
rev: v1.11.2
|
||||
hooks:
|
||||
- id: mypy
|
||||
name: mypy 3.8 on cibuildwheel/
|
||||
@@ -77,7 +77,7 @@ repos:
|
||||
|
||||
|
||||
- repo: https://github.com/python-jsonschema/check-jsonschema
|
||||
rev: 0.29.1
|
||||
rev: 0.29.2
|
||||
hooks:
|
||||
- id: check-dependabot
|
||||
- id: check-github-actions
|
||||
|
||||
+4
-1
@@ -44,6 +44,7 @@ jobs:
|
||||
python: 3.9
|
||||
services: docker
|
||||
arch: s390x
|
||||
allow_failure: True
|
||||
env: PYTHON=python
|
||||
|
||||
install:
|
||||
@@ -56,5 +57,7 @@ script: |
|
||||
(while true; do echo "travis_keep_alive"; sleep 300; done) &
|
||||
SPINNER_PID=$!
|
||||
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}
|
||||
test ${result} -eq 0
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
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 |
|
||||
|---------|----------------------------------------------|-----------|-----------|---------|--------------------------------------|
|
||||
| Linux | AppVeyor¹ / Azure Pipelines / GitHub Actions | Travis CI | Cirrus CI | | CircleCI¹ / GitHub Actions / GitLab¹ |
|
||||
| macOS | AppVeyor¹ / Azure Pipelines | | Cirrus CI | GitLab¹ | CircleCI¹ / GitHub Actions |
|
||||
| Windows | AppVeyor¹ / Azure Pipelines | Travis CI | Cirrus CI | | GitHub Actions / GitLab¹ |
|
||||
| | 3.8 | 3.9 | 3.10 | 3.11 | 3.12 |
|
||||
|---------|----------------------------------|-----------|-----------|---------|--------------------------------------------------|
|
||||
| Linux | Azure Pipelines / GitHub Actions | Travis CI | Cirrus CI | | AppVeyor¹ / CircleCI¹ / GitHub Actions / GitLab¹ |
|
||||
| macOS | Azure Pipelines | | Cirrus CI | GitLab¹ | AppVeyor¹ /CircleCI¹ / GitHub Actions |
|
||||
| Windows | Azure Pipelines | Travis CI | Cirrus CI | | AppVeyor¹ / GitHub Actions / GitLab¹ |
|
||||
|
||||
> ¹ Runs a reduced set of tests to reduce CI load
|
||||
|
||||
|
||||
@@ -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. |
|
||||
| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
|
||||
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
|
||||
| [Tornado][] | ![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 |
|
||||
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
|
||||
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
|
||||
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
|
||||
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
|
||||
@@ -172,8 +172,8 @@ Here are some repos that use cibuildwheel.
|
||||
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
|
||||
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
|
||||
[NumPy]: https://github.com/numpy/numpy
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[NCNN]: https://github.com/Tencent/ncnn
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
|
||||
+11
-11
@@ -1,26 +1,26 @@
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu
|
||||
APPVEYOR_JOB_NAME: "python38-x64-ubuntu"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
APPVEYOR_JOB_NAME: "python38-x64-vs2015"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos
|
||||
APPVEYOR_JOB_NAME: "python38-x64-macos"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204
|
||||
APPVEYOR_JOB_NAME: "python312-x64-ubuntu"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
APPVEYOR_JOB_NAME: "python312-x64-vs2022"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
|
||||
APPVEYOR_JOB_NAME: "python312-x64-macos"
|
||||
|
||||
stack: python 3.8
|
||||
stack: python 3.12
|
||||
|
||||
build: off
|
||||
|
||||
init:
|
||||
- cmd: set PATH=C:\Python38;C:\Python38\Scripts;%PATH%
|
||||
- ps: |
|
||||
$BRANCH = if ($env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH) { $env:APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH } else { $env:APPVEYOR_REPO_BRANCH }
|
||||
if (-not ($BRANCH -eq 'main' -or $BRANCH.ToLower().StartsWith('appveyor-'))) {
|
||||
$env:PYTEST_ADDOPTS='-k "unit_test or test_0_basic" --suppress-no-test-exit-code'
|
||||
$env:PYTEST_ADDOPTS = '-k "unit_test or test_0_basic" --suppress-no-test-exit-code'
|
||||
}
|
||||
python -m pip install -U pip
|
||||
|
||||
install: python -m pip install -e ".[dev]" pytest-custom-exit-code
|
||||
install:
|
||||
- python -m pip install -U pip
|
||||
- python -m pip install -e ".[dev]" pytest-custom-exit-code
|
||||
|
||||
# the '-u' flag is required so the output is in the correct order.
|
||||
# See https://github.com/pypa/cibuildwheel/pull/24 for more info.
|
||||
|
||||
@@ -240,7 +240,7 @@ def _compute_platform_auto() -> 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:
|
||||
msg = "--platform cannot be specified with --only, it is computed from --only"
|
||||
|
||||
+179
-93
@@ -9,15 +9,15 @@ import enum
|
||||
import functools
|
||||
import shlex
|
||||
import textwrap
|
||||
from collections.abc import Callable, Generator, Iterable, Iterator, Set
|
||||
from collections.abc import Generator, Iterable, Set
|
||||
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 . import errors
|
||||
from ._compat import tomllib
|
||||
from ._compat.typing import NotRequired, assert_never
|
||||
from ._compat.typing import assert_never
|
||||
from .architecture import Architecture
|
||||
from .environment import EnvironmentParseError, ParsedEnvironment, parse_environment
|
||||
from .logger import log
|
||||
@@ -118,13 +118,16 @@ class BuildOptions:
|
||||
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)
|
||||
class Override:
|
||||
select_pattern: str
|
||||
options: dict[str, Setting]
|
||||
options: dict[str, SettingValue]
|
||||
inherit: dict[str, InheritRule]
|
||||
|
||||
|
||||
@@ -137,22 +140,123 @@ DISALLOWED_OPTIONS = {
|
||||
}
|
||||
|
||||
|
||||
class TableFmt(TypedDict):
|
||||
# a format string, used with '.format', with `k` and `v` parameters
|
||||
# e.g. "{k}={v}"
|
||||
item: str
|
||||
# the string that is inserted between items
|
||||
# e.g. " "
|
||||
sep: str
|
||||
# a quoting function that, if supplied, is called to quote each value
|
||||
# e.g. shlex.quote
|
||||
quote: NotRequired[Callable[[str], str]]
|
||||
|
||||
|
||||
class ConfigOptionError(KeyError):
|
||||
class OptionsReaderError(errors.ConfigurationError):
|
||||
pass
|
||||
|
||||
|
||||
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):
|
||||
NONE = enum.auto()
|
||||
APPEND = enum.auto()
|
||||
@@ -160,10 +264,9 @@ class InheritRule(enum.Enum):
|
||||
|
||||
|
||||
def _resolve_cascade(
|
||||
*pairs: tuple[Setting | None, InheritRule],
|
||||
*pairs: tuple[SettingValue | None, InheritRule],
|
||||
ignore_empty: bool = False,
|
||||
list_sep: str | None = None,
|
||||
table_format: TableFmt | None = None,
|
||||
option_format: OptionFormat | None = None,
|
||||
) -> str:
|
||||
"""
|
||||
Given a cascade of values with inherit rules, resolve them into a single
|
||||
@@ -186,13 +289,6 @@ def _resolve_cascade(
|
||||
|
||||
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:
|
||||
if value is None:
|
||||
continue
|
||||
@@ -200,14 +296,9 @@ def _resolve_cascade(
|
||||
if ignore_empty and not value and value is not False:
|
||||
continue
|
||||
|
||||
value_string = _stringify_setting(value, list_sep, table_format)
|
||||
value_string = _stringify_setting(value, option_format=option_format)
|
||||
|
||||
result = _merge_values(
|
||||
result,
|
||||
value_string,
|
||||
rule=rule,
|
||||
merge_sep=merge_sep,
|
||||
)
|
||||
result = _apply_inherit_rule(result, value_string, rule=rule, option_format=option_format)
|
||||
|
||||
if result is None:
|
||||
msg = "a setting should at least have a default value"
|
||||
@@ -217,7 +308,9 @@ def _resolve_cascade(
|
||||
|
||||
|
||||
# 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:
|
||||
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
|
||||
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}"
|
||||
raise ConfigOptionError(msg)
|
||||
raise OptionsReaderError(msg)
|
||||
|
||||
if rule == InheritRule.APPEND:
|
||||
return f"{before}{merge_sep}{after}"
|
||||
return option_format.merge_values(before, after)
|
||||
elif rule == InheritRule.PREPEND:
|
||||
return f"{after}{merge_sep}{before}"
|
||||
return option_format.merge_values(after, before)
|
||||
else:
|
||||
assert_never(rule)
|
||||
|
||||
|
||||
def _stringify_setting(
|
||||
setting: Setting, list_sep: str | None, table_format: TableFmt | None
|
||||
setting: SettingValue,
|
||||
option_format: OptionFormat | None,
|
||||
) -> str:
|
||||
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"
|
||||
raise ConfigOptionError(msg)
|
||||
return table_format["sep"].join(
|
||||
item for k, v in setting.items() for item in _inner_fmt(k, v, table_format)
|
||||
)
|
||||
raise OptionsReaderError(msg) from None
|
||||
|
||||
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"
|
||||
raise ConfigOptionError(msg)
|
||||
return list_sep.join(setting)
|
||||
raise OptionsReaderError(msg) from None
|
||||
|
||||
if isinstance(setting, (bool, int)):
|
||||
return str(setting)
|
||||
@@ -323,14 +421,14 @@ class OptionsReader:
|
||||
if config_overrides is not None:
|
||||
if not isinstance(config_overrides, list):
|
||||
msg = "'tool.cibuildwheel.overrides' must be a list"
|
||||
raise ConfigOptionError(msg)
|
||||
raise OptionsReaderError(msg)
|
||||
|
||||
for config_override in config_overrides:
|
||||
select = config_override.pop("select", None)
|
||||
|
||||
if not select:
|
||||
msg = "'select' must be set in an override"
|
||||
raise ConfigOptionError(msg)
|
||||
raise OptionsReaderError(msg)
|
||||
|
||||
if isinstance(select, list):
|
||||
select = " ".join(select)
|
||||
@@ -340,7 +438,7 @@ class OptionsReader:
|
||||
i in {"none", "append", "prepend"} for i in inherit.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()}
|
||||
|
||||
@@ -358,7 +456,7 @@ class OptionsReader:
|
||||
matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7)
|
||||
if matches:
|
||||
msg += f" Perhaps you meant {matches[0]!r}?"
|
||||
raise ConfigOptionError(msg)
|
||||
raise OptionsReaderError(msg)
|
||||
|
||||
def _validate_platform_option(self, name: str) -> None:
|
||||
"""
|
||||
@@ -368,7 +466,7 @@ class OptionsReader:
|
||||
disallowed_platform_options = self.disallow.get(self.platform, set())
|
||||
if name in disallowed_platform_options:
|
||||
msg = f"{name!r} is not allowed in {disallowed_platform_options}"
|
||||
raise ConfigOptionError(msg)
|
||||
raise OptionsReaderError(msg)
|
||||
|
||||
allowed_option_names = self.default_options.keys() | self.default_platform_options.keys()
|
||||
|
||||
@@ -377,7 +475,7 @@ class OptionsReader:
|
||||
matches = difflib.get_close_matches(name, allowed_option_names, 1, 0.7)
|
||||
if matches:
|
||||
msg += f" Perhaps you meant {matches[0]!r}?"
|
||||
raise ConfigOptionError(msg)
|
||||
raise OptionsReaderError(msg)
|
||||
|
||||
def _load_file(self, filename: Path) -> tuple[dict[str, Any], dict[str, Any]]:
|
||||
"""
|
||||
@@ -412,8 +510,7 @@ class OptionsReader:
|
||||
name: str,
|
||||
*,
|
||||
env_plat: bool = True,
|
||||
list_sep: str | None = None,
|
||||
table_format: TableFmt | None = None,
|
||||
option_format: OptionFormat | None = None,
|
||||
ignore_empty: bool = False,
|
||||
) -> str:
|
||||
"""
|
||||
@@ -429,7 +526,7 @@ class OptionsReader:
|
||||
|
||||
if name not in self.default_options and name not in self.default_platform_options:
|
||||
msg = f"{name!r} must be in cibuildwheel/resources/defaults.toml file to be accessed."
|
||||
raise ConfigOptionError(msg)
|
||||
raise OptionsReaderError(msg)
|
||||
|
||||
# Environment variable form
|
||||
envvar = f"CIBW_{name.upper().replace('-', '_')}"
|
||||
@@ -449,26 +546,10 @@ class OptionsReader:
|
||||
(self.env.get(envvar), InheritRule.NONE),
|
||||
(self.env.get(plat_envvar) if env_plat else None, InheritRule.NONE),
|
||||
ignore_empty=ignore_empty,
|
||||
list_sep=list_sep,
|
||||
table_format=table_format,
|
||||
option_format=option_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:
|
||||
def __init__(
|
||||
self,
|
||||
@@ -513,9 +594,11 @@ class Options:
|
||||
package_dir = args.package_dir
|
||||
output_dir = args.output_dir
|
||||
|
||||
build_config = self.reader.get("build", env_plat=False, list_sep=" ") or "*"
|
||||
skip_config = self.reader.get("skip", env_plat=False, list_sep=" ")
|
||||
test_skip = self.reader.get("test-skip", env_plat=False, list_sep=" ")
|
||||
build_config = (
|
||||
self.reader.get("build", env_plat=False, option_format=ListFormat(sep=" ")) or "*"
|
||||
)
|
||||
skip_config = self.reader.get("skip", env_plat=False, option_format=ListFormat(sep=" "))
|
||||
test_skip = self.reader.get("test-skip", env_plat=False, option_format=ListFormat(sep=" "))
|
||||
|
||||
free_threaded_support = strtobool(
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
# Process `--only`
|
||||
@@ -569,30 +652,33 @@ class Options:
|
||||
"""
|
||||
|
||||
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", table_format={"item": '{k}="{v}"', "sep": " "}
|
||||
environment_config = self.reader.get("environment", option_format=EnvironmentFormat())
|
||||
environment_pass = self.reader.get(
|
||||
"environment-pass", option_format=ListFormat(sep=" ")
|
||||
).split()
|
||||
before_build = self.reader.get("before-build", option_format=ListFormat(sep=" && "))
|
||||
repair_command = self.reader.get(
|
||||
"repair-wheel-command", option_format=ListFormat(sep=" && ")
|
||||
)
|
||||
environment_pass = self.reader.get("environment-pass", 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",
|
||||
table_format={"item": "{k}={v}", "sep": " ", "quote": shlex.quote},
|
||||
"config-settings", option_format=ShlexTableFormat(sep=" ", pair_sep="=")
|
||||
)
|
||||
|
||||
dependency_versions = self.reader.get("dependency-versions")
|
||||
test_command = self.reader.get("test-command", list_sep=" && ")
|
||||
before_test = self.reader.get("before-test", list_sep=" && ")
|
||||
test_requires = self.reader.get("test-requires", list_sep=" ").split()
|
||||
test_extras = self.reader.get("test-extras", list_sep=",")
|
||||
test_command = self.reader.get("test-command", option_format=ListFormat(sep=" && "))
|
||||
before_test = self.reader.get("before-test", option_format=ListFormat(sep=" && "))
|
||||
test_requires = self.reader.get(
|
||||
"test-requires", option_format=ListFormat(sep=" ")
|
||||
).split()
|
||||
test_extras = self.reader.get("test-extras", option_format=ListFormat(sep=","))
|
||||
build_verbosity_str = self.reader.get("build-verbosity")
|
||||
|
||||
build_frontend_str = self.reader.get(
|
||||
"build-frontend",
|
||||
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
|
||||
if not build_frontend_str or build_frontend_str == "default":
|
||||
@@ -674,7 +760,7 @@ class Options:
|
||||
|
||||
container_engine_str = self.reader.get(
|
||||
"container-engine",
|
||||
table_format={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
||||
option_format=ShlexTableFormat(sep="; ", pair_sep=":", allow_merge=False),
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -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_arm64", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
|
||||
{ identifier = "cp311-macosx_universal2", version = "3.11", url = "https://www.python.org/ftp/python/3.11.9/python-3.11.9-macos11.pkg" },
|
||||
{ identifier = "cp312-macosx_x86_64", version = "3.12", url = "https://www.python.org/ftp/python/3.12.4/python-3.12.4-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_universal2", 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.5/python-3.12.5-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_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" },
|
||||
@@ -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 = "pp39-macosx_x86_64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_x86_64.tar.bz2" },
|
||||
{ identifier = "pp39-macosx_arm64", version = "3.9", url = "https://downloads.python.org/pypy/pypy3.9-v7.3.16-macos_arm64.tar.bz2" },
|
||||
{ identifier = "pp310-macosx_x86_64", version = "3.10", url = "https://downloads.python.org/pypy/pypy3.10-v7.3.16-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_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.17-macos_arm64.tar.bz2" },
|
||||
]
|
||||
|
||||
[windows]
|
||||
@@ -152,8 +152,8 @@ python_configurations = [
|
||||
{ identifier = "cp310-win_amd64", version = "3.10.11", arch = "64" },
|
||||
{ identifier = "cp311-win32", version = "3.11.9", arch = "32" },
|
||||
{ identifier = "cp311-win_amd64", version = "3.11.9", arch = "64" },
|
||||
{ identifier = "cp312-win32", version = "3.12.4", arch = "32" },
|
||||
{ identifier = "cp312-win_amd64", version = "3.12.4", arch = "64" },
|
||||
{ identifier = "cp312-win32", version = "3.12.5", arch = "32" },
|
||||
{ identifier = "cp312-win_amd64", version = "3.12.5", arch = "64" },
|
||||
{ identifier = "cp313-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" },
|
||||
@@ -161,13 +161,13 @@ python_configurations = [
|
||||
{ identifier = "cp39-win_arm64", version = "3.9.10", arch = "ARM64" },
|
||||
{ identifier = "cp310-win_arm64", version = "3.10.11", arch = "ARM64" },
|
||||
{ identifier = "cp311-win_arm64", version = "3.11.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 = "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 = "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 = "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]
|
||||
|
||||
@@ -10,7 +10,7 @@ build==1.2.1
|
||||
# via
|
||||
# -r .nox/update_constraints/tmp/constraints-pyodide.in
|
||||
# pyodide-build
|
||||
certifi==2024.7.4
|
||||
certifi==2024.8.30
|
||||
# via
|
||||
# httpcore
|
||||
# httpx
|
||||
@@ -21,7 +21,7 @@ click==8.1.7
|
||||
# via typer
|
||||
cloudpickle==3.0.0
|
||||
# via loky
|
||||
cmake==3.30.1
|
||||
cmake==3.30.2
|
||||
# via pyodide-build
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
@@ -31,9 +31,9 @@ h11==0.14.0
|
||||
# via httpcore
|
||||
httpcore==1.0.5
|
||||
# via httpx
|
||||
httpx==0.27.0
|
||||
httpx==0.27.2
|
||||
# via unearth
|
||||
idna==3.7
|
||||
idna==3.8
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
@@ -74,13 +74,13 @@ pyodide-lock==0.1.0a6
|
||||
# via pyodide-build
|
||||
pyproject-hooks==1.1.0
|
||||
# via build
|
||||
pyyaml==6.0.1
|
||||
pyyaml==6.0.2
|
||||
# via pyodide-build
|
||||
requests==2.32.3
|
||||
# via pyodide-build
|
||||
resolvelib==1.0.1
|
||||
# via pyodide-build
|
||||
rich==13.7.1
|
||||
rich==13.8.0
|
||||
# via
|
||||
# pyodide-build
|
||||
# pyodide-cli
|
||||
@@ -95,7 +95,7 @@ sniffio==1.3.1
|
||||
# via
|
||||
# anyio
|
||||
# httpx
|
||||
typer==0.12.3
|
||||
typer==0.12.5
|
||||
# via
|
||||
# auditwheel-emscripten
|
||||
# pyodide-build
|
||||
@@ -107,7 +107,7 @@ typing-extensions==4.12.2
|
||||
# pydantic
|
||||
# pydantic-core
|
||||
# typer
|
||||
unearth==0.16.1
|
||||
unearth==0.17.2
|
||||
# via pyodide-build
|
||||
urllib3==2.2.2
|
||||
# via
|
||||
@@ -117,7 +117,7 @@ virtualenv==20.26.3
|
||||
# via
|
||||
# build
|
||||
# pyodide-build
|
||||
wheel==0.43.0
|
||||
wheel==0.44.0
|
||||
# via
|
||||
# auditwheel-emscripten
|
||||
# pyodide-build
|
||||
|
||||
@@ -4,13 +4,13 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
importlib-metadata==8.2.0
|
||||
importlib-metadata==8.4.0
|
||||
# via build
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
@@ -30,5 +30,5 @@ typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
zipp==3.19.2
|
||||
zipp==3.20.1
|
||||
# via importlib-metadata
|
||||
|
||||
@@ -4,7 +4,7 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
|
||||
@@ -4,7 +4,7 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
|
||||
@@ -4,7 +4,7 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
|
||||
@@ -4,7 +4,7 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.1.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
|
||||
@@ -4,13 +4,13 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
importlib-metadata==8.2.0
|
||||
importlib-metadata==8.4.0
|
||||
# via build
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
@@ -30,5 +30,5 @@ typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
zipp==3.19.2
|
||||
zipp==3.20.1
|
||||
# via importlib-metadata
|
||||
|
||||
@@ -4,13 +4,13 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
filelock==3.15.4
|
||||
# via virtualenv
|
||||
importlib-metadata==8.2.0
|
||||
importlib-metadata==8.4.0
|
||||
# via build
|
||||
macholib==1.16.3
|
||||
# via delocate
|
||||
@@ -30,5 +30,5 @@ typing-extensions==4.12.2
|
||||
# via delocate
|
||||
virtualenv==20.26.3
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
zipp==3.19.2
|
||||
zipp==3.20.1
|
||||
# via importlib-metadata
|
||||
|
||||
@@ -4,7 +4,7 @@ altgraph==0.17.4
|
||||
# via macholib
|
||||
build==1.2.1
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
delocate==0.11.0
|
||||
delocate==0.12.0
|
||||
# via -r cibuildwheel/resources/constraints.in
|
||||
distlib==0.3.8
|
||||
# via virtualenv
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
url = "https://nodejs.org/dist/"
|
||||
v20 = "v20.16.0"
|
||||
v20 = "v20.17.0"
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
[x86_64]
|
||||
manylinux1 = quay.io/pypa/manylinux1_x86_64:2024-04-29-76807b8
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64: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_28 = quay.io/pypa/manylinux_2_28_x86_64:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_x86_64:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_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.09.01-2
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_x86_64:2024.09.01-2
|
||||
|
||||
[i686]
|
||||
manylinux1 = quay.io/pypa/manylinux1_i686:2024-04-29-76807b8
|
||||
manylinux2010 = quay.io/pypa/manylinux2010_i686:2022-08-05-4535177
|
||||
manylinux2014 = quay.io/pypa/manylinux2014_i686: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
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_i686:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_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.09.01-2
|
||||
|
||||
[pypy_x86_64]
|
||||
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_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]
|
||||
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
|
||||
|
||||
[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_28 = quay.io/pypa/manylinux_2_28_aarch64:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_aarch64:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_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.09.01-2
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_aarch64:2024.09.01-2
|
||||
|
||||
[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_28 = quay.io/pypa/manylinux_2_28_ppc64le:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_ppc64le:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_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.09.01-2
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_ppc64le:2024.09.01-2
|
||||
|
||||
[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_28 = quay.io/pypa/manylinux_2_28_s390x:2024.08.03-1
|
||||
musllinux_1_1 = quay.io/pypa/musllinux_1_1_s390x:2024.08.03-1
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_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.09.01-2
|
||||
musllinux_1_2 = quay.io/pypa/musllinux_1_2_s390x:2024.09.01-2
|
||||
|
||||
[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_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
@@ -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. |
|
||||
| [pytorch-fairseq][] | ![github icon][] | ![apple icon][] ![linux icon][] | Facebook AI Research Sequence-to-Sequence Toolkit written in Python. |
|
||||
| [NumPy][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The fundamental package for scientific computing with Python. |
|
||||
| [Tornado][] | ![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 |
|
||||
| [Tornado][] | ![github icon][] | ![linux icon][] ![apple icon][] ![windows icon][] | Tornado is a Python web framework and asynchronous networking library. Uses stable ABI for a small C extension. |
|
||||
| [NCNN][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | ncnn is a high-performance neural network inference framework optimized for the mobile platform |
|
||||
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
|
||||
| [Prophet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Tool for producing high quality forecasts for time series data that has multiple seasonality with linear or non-linear growth. |
|
||||
@@ -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. |
|
||||
| [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. |
|
||||
| [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 |
|
||||
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
|
||||
| [SimpleJSON][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | simplejson is a simple, fast, extensible JSON encoder/decoder for Python |
|
||||
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
|
||||
| [OpenTimelineIO][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Open Source API and interchange format for editorial timeline information. |
|
||||
| [PyTables][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python package to manage extremely large amounts of data |
|
||||
@@ -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 |
|
||||
| [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. |
|
||||
| [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 |
|
||||
| [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 |
|
||||
| [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 |
|
||||
@@ -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. |
|
||||
| [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 |
|
||||
| [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. |
|
||||
| [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 |
|
||||
| [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. |
|
||||
| [GSD][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Cython and NumPy project with 64-bit wheels. |
|
||||
| [aalink][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Async Python interface for Ableton Link. |
|
||||
| [CorrectionLib][] | ![github icon][] | ![apple icon][] ![linux icon][] | Structured JSON powered correction library for HEP, designed for the CMS experiment at CERN. |
|
||||
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
|
||||
@@ -121,8 +121,8 @@ title: Working examples
|
||||
[scikit-learn]: https://github.com/scikit-learn/scikit-learn
|
||||
[pytorch-fairseq]: https://github.com/facebookresearch/fairseq
|
||||
[NumPy]: https://github.com/numpy/numpy
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[duckdb]: https://github.com/duckdb/duckdb
|
||||
[Tornado]: https://github.com/tornadoweb/tornado
|
||||
[NCNN]: https://github.com/Tencent/ncnn
|
||||
[Matplotlib]: https://github.com/matplotlib/matplotlib
|
||||
[Prophet]: https://github.com/facebook/prophet
|
||||
@@ -165,9 +165,9 @@ title: Working examples
|
||||
[Wrapt]: https://github.com/GrahamDumpleton/wrapt
|
||||
[envd]: https://github.com/tensorchord/envd
|
||||
[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
|
||||
[aioquic]: https://github.com/aiortc/aioquic
|
||||
[SimpleJSON]: https://github.com/simplejson/simplejson
|
||||
[ruptures]: https://github.com/deepcharles/ruptures
|
||||
[OpenTimelineIO]: https://github.com/AcademySoftwareFoundation/OpenTimelineIO
|
||||
[PyTables]: https://github.com/PyTables/PyTables
|
||||
@@ -203,8 +203,8 @@ title: Working examples
|
||||
[streaming-form-data]: https://github.com/siddhantgoel/streaming-form-data
|
||||
[bx-python]: https://github.com/bxlab/bx-python
|
||||
[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
|
||||
[Python-WebRTC]: https://github.com/MarshalX/python-webrtc
|
||||
[pybase64]: https://github.com/mayeut/pybase64
|
||||
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
|
||||
[fathon]: https://github.com/stfbnc/fathon
|
||||
@@ -214,13 +214,13 @@ title: Working examples
|
||||
[clang-format]: https://github.com/ssciwr/clang-format-wheel
|
||||
[etebase-py]: https://github.com/etesync/etebase-py
|
||||
[cf-units]: https://github.com/SciTools/cf-units
|
||||
[Confluent client for Kafka]: https://github.com/confluentinc/confluent-kafka-python
|
||||
[ninja]: https://github.com/scikit-build/ninja-python-distributions
|
||||
[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
|
||||
[ril]: https://github.com/Cryptex-github/ril-py
|
||||
[GSD]: https://github.com/glotzerlab/gsd
|
||||
[SiPM]: https://github.com/EdoPro98/SimSiPM
|
||||
[GSD]: https://github.com/glotzerlab/gsd
|
||||
[aalink]: https://github.com/artfwo/aalink
|
||||
[CorrectionLib]: https://github.com/cms-nanoAOD/correctionlib
|
||||
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu
|
||||
APPVEYOR_JOB_NAME: "python37-x64-ubuntu"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
APPVEYOR_JOB_NAME: "python37-x64-vs2015"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos
|
||||
APPVEYOR_JOB_NAME: "python37-x64-macos"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2204
|
||||
APPVEYOR_JOB_NAME: "linux-x64"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
APPVEYOR_JOB_NAME: "windows-x64"
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: macos-sonoma
|
||||
APPVEYOR_JOB_NAME: "macos-x64"
|
||||
|
||||
stack: python 3.7
|
||||
|
||||
init:
|
||||
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
|
||||
stack: python 3.12
|
||||
|
||||
install: python -m pip install cibuildwheel==2.20.0
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ linux:
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
command: ["dockerd-entrypoint.sh"]
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_DRIVER: overlay2
|
||||
# See https://github.com/docker-library/docker/pull/166
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
|
||||
@@ -6,7 +6,6 @@ linux:
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
command: ["dockerd-entrypoint.sh"]
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_DRIVER: overlay2
|
||||
# See https://github.com/docker-library/docker/pull/166
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
|
||||
@@ -184,10 +184,8 @@ messages_control.disable = [
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py38"
|
||||
line-length = 100
|
||||
|
||||
|
||||
[tool.ruff.lint]
|
||||
extend-select = [
|
||||
"B", # flake8-bugbear
|
||||
|
||||
+2
-2
@@ -37,7 +37,7 @@ def build_frontend_env_nouv(request: pytest.FixtureRequest) -> dict[str, str]:
|
||||
return {"CIBW_BUILD_FRONTEND": frontend}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def build_frontend_env(build_frontend_env_nouv: dict[str, str]) -> dict[str, str]:
|
||||
frontend = build_frontend_env_nouv["CIBW_BUILD_FRONTEND"]
|
||||
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]"}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def docker_cleanup() -> Generator[None, None, None]:
|
||||
def get_images() -> set[str]:
|
||||
if detect_ci_provider() is None or platform != "linux":
|
||||
|
||||
@@ -6,7 +6,7 @@ import textwrap
|
||||
|
||||
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
|
||||
|
||||
@@ -49,6 +49,9 @@ def test_pyodide_build(tmp_path, use_pyproject_toml):
|
||||
if not shutil.which("python3.12"):
|
||||
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:
|
||||
basic_project.files["pyproject.toml"] = textwrap.dedent(
|
||||
"""
|
||||
|
||||
+4
-5
@@ -23,15 +23,14 @@ EMULATED_ARCHS: Final[list[str]] = sorted(
|
||||
)
|
||||
SINGLE_PYTHON_VERSION: Final[tuple[int, int]] = (3, 12)
|
||||
|
||||
platform: str
|
||||
|
||||
if "CIBW_PLATFORM" in os.environ:
|
||||
platform = os.environ["CIBW_PLATFORM"]
|
||||
platform = os.environ.get("CIBW_PLATFORM", "")
|
||||
if platform:
|
||||
pass
|
||||
elif sys.platform.startswith("linux"):
|
||||
platform = "linux"
|
||||
elif sys.platform.startswith("darwin"):
|
||||
platform = "macos"
|
||||
elif sys.platform in ["win32", "cygwin"]:
|
||||
elif sys.platform.startswith(("win32", "cygwin")):
|
||||
platform = "windows"
|
||||
else:
|
||||
msg = f"Unsupported platform {sys.platform!r}"
|
||||
|
||||
@@ -19,7 +19,7 @@ def pytest_addoption(parser):
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def fake_package_dir(tmp_path, monkeypatch):
|
||||
"""
|
||||
Monkey-patch enough for the main() function to run
|
||||
|
||||
@@ -47,7 +47,7 @@ def mock_protection(monkeypatch):
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def fake_package_dir_autouse(fake_package_dir): # noqa: ARG001
|
||||
def fake_package_dir_autouse(fake_package_dir):
|
||||
pass
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ def disable_print_wheels(monkeypatch):
|
||||
monkeypatch.setattr(util, "print_new_wheels", empty_cm)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def allow_empty(monkeypatch, fake_package_dir):
|
||||
monkeypatch.setattr(sys, "argv", [*fake_package_dir, "--allow-empty"])
|
||||
|
||||
@@ -81,7 +81,7 @@ def platform(request, monkeypatch):
|
||||
return platform_value
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def intercepted_build_args(monkeypatch):
|
||||
intercepted = ArgsInterceptor()
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from cibuildwheel.architecture import Architecture
|
||||
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):
|
||||
if option_value is None:
|
||||
monkeypatch.delenv("CIBW_PLATFORM", raising=False)
|
||||
|
||||
@@ -29,7 +29,7 @@ ALL_IDS = {
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@pytest.fixture
|
||||
def mock_build_container(monkeypatch):
|
||||
def fail_on_call(*args, **kwargs):
|
||||
msg = "This should never be called"
|
||||
|
||||
@@ -10,7 +10,6 @@ import pytest
|
||||
from cibuildwheel import errors
|
||||
from cibuildwheel.__main__ import get_build_identifiers, get_platform_module
|
||||
from cibuildwheel.bashlex_eval import local_environment_executor
|
||||
from cibuildwheel.environment import parse_environment
|
||||
from cibuildwheel.options import (
|
||||
CommandLineArguments,
|
||||
Options,
|
||||
@@ -66,7 +65,7 @@ def test_options_1(tmp_path, monkeypatch):
|
||||
|
||||
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()
|
||||
pinned_x86_64_container_image = all_pinned_container_images["x86_64"]
|
||||
|
||||
@@ -4,7 +4,15 @@ from pathlib import Path
|
||||
|
||||
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 = """
|
||||
[tool.cibuildwheel]
|
||||
@@ -37,42 +45,32 @@ def test_simple_settings(tmp_path, platform, fname):
|
||||
|
||||
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("archs", list_sep=" ") == "auto"
|
||||
assert options_reader.get("archs", option_format=ListFormat(" ")) == "auto"
|
||||
assert (
|
||||
options_reader.get("test-requires", list_sep=" ")
|
||||
options_reader.get("test-requires", option_format=ListFormat(" "))
|
||||
== {"windows": "something", "macos": "else", "linux": "other many"}[platform]
|
||||
)
|
||||
|
||||
# Also testing options for support for both lists and tables
|
||||
assert (
|
||||
options_reader.get("environment", table_format={"item": '{k}="{v}"', "sep": " "})
|
||||
options_reader.get("environment", option_format=EnvironmentFormat())
|
||||
== 'THING="OTHER" FOO="BAR"'
|
||||
)
|
||||
assert (
|
||||
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("test-extras", option_format=ListFormat(",")) == "one,two"
|
||||
|
||||
assert options_reader.get("manylinux-x86_64-image") == "manylinux1"
|
||||
assert options_reader.get("manylinux-i686-image") == "manylinux2014"
|
||||
|
||||
with pytest.raises(ConfigOptionError):
|
||||
options_reader.get("environment", list_sep=" ")
|
||||
with pytest.raises(OptionsReaderError):
|
||||
# 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):
|
||||
options_reader.get("test-extras", table_format={"item": '{k}="{v}"', "sep": " "})
|
||||
with pytest.raises(OptionsReaderError):
|
||||
# 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):
|
||||
@@ -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-i686-image") == "manylinux2014"
|
||||
|
||||
assert (
|
||||
options_reader.get("test-requires", list_sep=" ")
|
||||
options_reader.get("test-requires", option_format=ListFormat(" "))
|
||||
== {"windows": "docs", "macos": "docs", "linux": "scod"}[platform]
|
||||
)
|
||||
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={})
|
||||
|
||||
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={})
|
||||
|
||||
assert "repair-wheel-command" in str(excinfo.value)
|
||||
@@ -205,7 +203,7 @@ def test_unexpected_table(tmp_path):
|
||||
repair-wheel-command = "repair-project-linux"
|
||||
"""
|
||||
)
|
||||
with pytest.raises(ConfigOptionError):
|
||||
with pytest.raises(OptionsReaderError):
|
||||
OptionsReader(pyproject_toml, platform="linux", env={})
|
||||
|
||||
|
||||
@@ -219,8 +217,8 @@ build = ["1", "2"]
|
||||
)
|
||||
options_reader = OptionsReader(pyproject_toml, platform="linux", env={})
|
||||
|
||||
assert options_reader.get("build", list_sep=", ") == "1, 2"
|
||||
with pytest.raises(ConfigOptionError):
|
||||
assert options_reader.get("build", option_format=ListFormat(", ")) == "1, 2"
|
||||
with pytest.raises(OptionsReaderError):
|
||||
options_reader.get("build")
|
||||
|
||||
|
||||
@@ -234,7 +232,7 @@ manylinux-x86_64-image = "manylinux1"
|
||||
)
|
||||
disallow = {"windows": {"manylinux-x86_64-image"}}
|
||||
OptionsReader(pyproject_toml, platform="linux", disallow=disallow, env={})
|
||||
with pytest.raises(ConfigOptionError):
|
||||
with pytest.raises(OptionsReaderError):
|
||||
OptionsReader(pyproject_toml, platform="windows", disallow=disallow, env={})
|
||||
|
||||
|
||||
@@ -305,7 +303,7 @@ def test_resolve_cascade_merge_list(ignore_empty, rule):
|
||||
(["b1", "b2"], rule),
|
||||
(None, InheritRule.NONE),
|
||||
ignore_empty=ignore_empty,
|
||||
list_sep=" ",
|
||||
option_format=ListFormat(" "),
|
||||
)
|
||||
|
||||
if not ignore_empty:
|
||||
@@ -326,24 +324,34 @@ def test_resolve_cascade_merge_dict(rule):
|
||||
(None, InheritRule.NONE),
|
||||
({"value": "override"}, rule),
|
||||
(None, InheritRule.NONE),
|
||||
table_format={"item": "{k}={v}", "sep": " "},
|
||||
option_format=ShlexTableFormat(),
|
||||
)
|
||||
|
||||
if rule == InheritRule.PREPEND:
|
||||
assert answer == "value=override value=a1 base=b1"
|
||||
assert answer == "value=a1 base=b1"
|
||||
elif rule == InheritRule.NONE:
|
||||
assert answer == "value=override"
|
||||
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():
|
||||
answer = _resolve_cascade(
|
||||
({"value": "a1", "base": "b1"}, InheritRule.NONE),
|
||||
("value=a1 base=b1", InheritRule.NONE),
|
||||
({"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 = """
|
||||
@@ -387,28 +395,28 @@ def test_pyproject_2(tmp_path, platform):
|
||||
pyproject_toml.write_text(PYPROJECT_2)
|
||||
|
||||
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"):
|
||||
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"):
|
||||
assert (
|
||||
options_reader.get("test-command", list_sep=" && ")
|
||||
options_reader.get("test-command", option_format=ListFormat(" && "))
|
||||
== "pyproject-override && override2 && pyproject"
|
||||
)
|
||||
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"'
|
||||
)
|
||||
|
||||
with options_reader.identifier("cp37-final"):
|
||||
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"
|
||||
)
|
||||
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"'
|
||||
)
|
||||
|
||||
@@ -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={})
|
||||
|
||||
|
||||
@@ -442,8 +450,8 @@ other = ["two", "three"]
|
||||
|
||||
options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={})
|
||||
assert (
|
||||
options_reader.get("config-settings", table_format={"item": '{k}="{v}"', "sep": " "})
|
||||
== 'example="one" other="two" other="three"'
|
||||
options_reader.get("config-settings", option_format=ShlexTableFormat(pair_sep="=", sep=" "))
|
||||
== "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={})
|
||||
assert (
|
||||
options_reader.get(
|
||||
"config-settings", table_format={"item": "--config-settings='{k}=\"{v}\"'", "sep": " "}
|
||||
)
|
||||
== "--config-settings='--build-option=\"--use-mypyc\"'"
|
||||
options_reader.get("config-settings", option_format=ShlexTableFormat(sep=" ", pair_sep="="))
|
||||
== "--build-option=--use-mypyc"
|
||||
)
|
||||
|
||||
|
||||
@@ -471,12 +477,16 @@ def test_overrides_inherit(tmp_path):
|
||||
"""\
|
||||
[tool.cibuildwheel]
|
||||
before-all = ["before-all"]
|
||||
config-settings = {key1="value1", key2="value2", empty=""}
|
||||
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "cp37*"
|
||||
inherit.before-all = "append"
|
||||
before-all = ["override1"]
|
||||
|
||||
inherit.config-settings = "append"
|
||||
config-settings = {key3="value3", key2="override2"}
|
||||
|
||||
[[tool.cibuildwheel.overrides]]
|
||||
select = "cp37*"
|
||||
inherit.before-all = "prepend"
|
||||
@@ -486,9 +496,17 @@ before-all = ["override2"]
|
||||
|
||||
options_reader = OptionsReader(config_file_path=pyproject_toml, platform="linux", env={})
|
||||
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"):
|
||||
assert (
|
||||
options_reader.get("before-all", list_sep=" && ")
|
||||
options_reader.get("before-all", option_format=ListFormat(" && "))
|
||||
== "override2 && before-all && override1"
|
||||
)
|
||||
assert (
|
||||
options_reader.get("config-settings", option_format=ShlexTableFormat())
|
||||
== "key1=value1 key2=override2 empty='' key3=value3"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user