chore: drop deprecated options related to CIBW_ENABLE (#2095)

* chore: drop deprecated options

* Add --enable option

* Fix pyodide tests


---------

Co-authored-by: Joe Rickerby <joerick@mac.com>
This commit is contained in:
Matthieu Darbois
2025-01-21 12:53:01 -05:00
committed by GitHub
co-authored by Joe Rickerby
parent 730b64249f
commit d134edc652
15 changed files with 123 additions and 130 deletions
+1 -2
View File
@@ -81,8 +81,7 @@ jobs:
env:
CIBW_ARCHS_MACOS: x86_64 universal2 arm64
CIBW_BUILD_FRONTEND: 'build[uv]'
CIBW_FREE_THREADED_SUPPORT: 1
CIBW_PRERELEASE_PYTHONS: 1
CIBW_ENABLE: "cpython-prerelease cpython-freethreading pypy"
- name: Run a sample build (GitHub Action, only)
uses: ./
-6
View File
@@ -119,11 +119,6 @@ properties:
description: Set environment variables on the host to pass-through to the container
during the build.
type: string_array
free-threaded-support:
type: boolean
default: false
description: The project supports free-threaded builds of Python (PEP703)
deprecated: Use the `enable` option instead.
manylinux-aarch64-image:
type: string
description: Specify alternative manylinux / musllinux container images
@@ -277,7 +272,6 @@ non_global_options = {k: {"$ref": f"#/properties/{k}"} for k in schema["properti
del non_global_options["build"]
del non_global_options["skip"]
del non_global_options["test-skip"]
del non_global_options["free-threaded-support"]
del non_global_options["enable"]
overrides["items"]["properties"]["select"]["oneOf"] = string_array
+12 -6
View File
@@ -30,6 +30,7 @@ from cibuildwheel.util import (
CIBW_CACHE_PATH,
BuildSelector,
CIProvider,
EnableGroup,
Unbuffered,
detect_ci_provider,
fix_ansi_codes_for_github_actions,
@@ -100,6 +101,17 @@ def main_inner(global_options: GlobalOptions) -> None:
""",
)
enable_groups_str = ", ".join(g.value for g in EnableGroup)
parser.add_argument(
"--enable",
action="append",
default=[],
metavar="GROUP",
help=f"""
Enable an additional category of builds. Use multiple times to select multiple groups. Choices: {enable_groups_str}.
""",
)
parser.add_argument(
"--only",
default=None,
@@ -156,12 +168,6 @@ def main_inner(global_options: GlobalOptions) -> None:
help="Do not report an error code if the build does not match any wheels.",
)
parser.add_argument(
"--prerelease-pythons",
action="store_true",
help="Enable pre-release Python versions if available.",
)
parser.add_argument(
"--debug-traceback",
action="store_true",
+12 -42
View File
@@ -29,10 +29,9 @@ from .util import (
BuildFrontendConfig,
BuildSelector,
DependencyConstraints,
EnableGroups,
EnableGroup,
TestSelector,
format_safe,
read_python_configs,
resources_dir,
selector_matches,
strtobool,
@@ -50,8 +49,8 @@ class CommandLineArguments:
package_dir: Path
print_build_identifiers: bool
allow_empty: bool
prerelease_pythons: bool
debug_traceback: bool
enable: list[str]
@staticmethod
def defaults() -> CommandLineArguments:
@@ -63,9 +62,9 @@ class CommandLineArguments:
config_file="",
output_dir=Path("wheelhouse"),
package_dir=Path("."),
prerelease_pythons=False,
print_build_identifiers=False,
debug_traceback=False,
enable=[],
)
@@ -618,28 +617,13 @@ class Options:
enable_groups = self.reader.get(
"enable", env_plat=False, option_format=ListFormat(sep=" "), env_rule=InheritRule.APPEND
)
enable = {EnableGroups(group) for group in enable_groups.split()}
free_threaded_support = strtobool(
self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True)
)
prerelease_pythons = args.prerelease_pythons or strtobool(
self.env.get("CIBW_PRERELEASE_PYTHONS", "0")
)
if free_threaded_support or prerelease_pythons:
msg = (
"free-threaded-support and prerelease-pythons should be specified by enable instead"
)
if enable:
raise OptionsReaderError(msg)
log.warning(msg)
if free_threaded_support:
enable.add(EnableGroups.CPythonFreeThreading)
if prerelease_pythons:
enable.add(EnableGroups.CPythonPrerelease)
try:
enable = {EnableGroup(group) for group in enable_groups.split()}
for command_line_group in args.enable:
enable.add(EnableGroup(command_line_group))
except ValueError as e:
msg = f"Failed to parse enable group. {e}. Valid group names are: {', '.join(g.value for g in EnableGroup)}"
raise errors.ConfigurationError(msg) from e
# This is not supported in tool.cibuildwheel, as it comes from a standard location.
# Passing this in as an environment variable will override pyproject.toml, setup.cfg, or setup.py
@@ -656,30 +640,16 @@ class Options:
build_config = args.only
skip_config = ""
architectures = Architecture.all_archs(self.platform)
enable = set(EnableGroups)
enable = set(EnableGroup)
build_selector = BuildSelector(
build_config=build_config,
skip_config=skip_config,
requires_python=requires_python,
enable=frozenset(
enable | {EnableGroups.PyPy}
), # For backwards compatibility, we are adding PyPy for now
enable=frozenset(enable),
)
test_selector = TestSelector(skip_config=test_skip)
all_configs = read_python_configs(self.platform)
all_pypy_ids = {
config["identifier"] for config in all_configs if config["identifier"].startswith("pp")
}
if (
not self._defaults
and EnableGroups.PyPy not in enable
and any(build_selector(build_id) for build_id in all_pypy_ids)
):
msg = "PyPy builds will be disabled by default in version 3. Enabling PyPy builds should be specified by enable"
log.warning(msg)
return GlobalOptions(
package_dir=package_dir,
output_dir=output_dir,
@@ -284,13 +284,6 @@
],
"title": "CIBW_ENVIRONMENT_PASS"
},
"free-threaded-support": {
"type": "boolean",
"default": false,
"description": "The project supports free-threaded builds of Python (PEP703)",
"deprecated": "Use the `enable` option instead.",
"title": "CIBW_FREE_THREADED_SUPPORT"
},
"manylinux-aarch64-image": {
"type": "string",
"description": "Specify alternative manylinux / musllinux container images",
-1
View File
@@ -2,7 +2,6 @@
build = "*"
skip = ""
test-skip = ""
free-threaded-support = false
enable = []
archs = ["auto"]
+6 -6
View File
@@ -44,7 +44,7 @@ from .typing import PathOrStr, PlatformName
__all__ = [
"MANYLINUX_ARCHS",
"EnableGroups",
"EnableGroup",
"call",
"combine_constraints",
"find_compatible_wheel",
@@ -67,7 +67,7 @@ install_certifi_script: Final[Path] = resources_dir / "install_certifi.py"
free_thread_enable_313: Final[Path] = resources_dir / "free-threaded-enable-313.xml"
class EnableGroups(enum.Enum):
class EnableGroup(enum.Enum):
"""
Groups of build selectors that are not enabled by default.
"""
@@ -278,7 +278,7 @@ class BuildSelector:
build_config: str
skip_config: str
requires_python: SpecifierSet | None = None
enable: frozenset[EnableGroups] = frozenset()
enable: frozenset[EnableGroup] = frozenset()
def __call__(self, build_id: str) -> bool:
# Filter build selectors by python_requires if set
@@ -293,15 +293,15 @@ class BuildSelector:
return False
# filter out groups that are not enabled
if EnableGroups.CPythonFreeThreading not in self.enable and selector_matches(
if EnableGroup.CPythonFreeThreading not in self.enable and selector_matches(
"cp3??t-*", build_id
):
return False
if EnableGroups.CPythonPrerelease not in self.enable and selector_matches(
if EnableGroup.CPythonPrerelease not in self.enable and selector_matches(
"cp314*", build_id
):
return False
if EnableGroups.PyPy not in self.enable and selector_matches("pp*", build_id):
if EnableGroup.PyPy not in self.enable and selector_matches("pp*", build_id):
return False
should_build = selector_matches(self.build_config, build_id)
+4 -7
View File
@@ -567,17 +567,14 @@ values are:
- `cpython-prerelease`: Enables beta versions of Pythons if any are available
(May-July, approximately). For backward compatibility, `CIBW_PRERELEASE_PYTHONS`
is also supported until cibuildwheel 3.
(May-July, approximately).
- `cpython-freethreading`: [PEP 703](https://www.python.org/dev/peps/pep-0703)
introduced variants of CPython that can be built without the Global
Interpreter Lock (GIL). Those variants are also known as free-threaded /
no-gil. This will enable building these wheels while they are experimental.
The build identifiers for those variants have a `t` suffix in their
`python_tag` (e.g. `cp313t-manylinux_x86_64`). For backward compatibility,
`CIBW_FREE_THREADED_SUPPORT` is also supported until cibuildwheel 3.
- `pypy`: Enable PyPy. For backward compatibility, this is always enabled until
cibuildwheel 3 is released.
`python_tag` (e.g. `cp313t-manylinux_x86_64`).
- `pypy`: Enable PyPy.
!!! caution
@@ -591,7 +588,7 @@ values are:
!!! note
Free threading is experimental: [Whats New In Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython)
Default: empty (`pypy` is always injected).
Default: empty.
This option doesn't support overrides or platform specific variants; it is
intended as a way to acknowledge that a project is aware that these extra
+4 -5
View File
@@ -47,11 +47,11 @@ def cibuildwheel_get_build_identifiers(
for the current platform.
"""
cmd = [sys.executable, "-m", "cibuildwheel", "--print-build-identifiers", str(project_path)]
if prerelease_pythons:
cmd.append("--prerelease-pythons")
if env is None:
env = os.environ.copy()
env.setdefault("CIBW_FREE_THREADED_SUPPORT", "1")
env["CIBW_ENABLE"] = "cpython-freethreading pypy"
if prerelease_pythons:
env["CIBW_ENABLE"] += " cpython-prerelease"
cmd_output = subprocess.run(
cmd,
@@ -115,7 +115,7 @@ def cibuildwheel_run(
_update_pip_cache_dir(env)
env.setdefault("CIBW_FREE_THREADED_SUPPORT", "1")
env["CIBW_ENABLE"] = "cpython-prerelease cpython-freethreading pypy"
if single_python:
env["CIBW_BUILD"] = "cp{}{}-*".format(*SINGLE_PYTHON_VERSION)
@@ -126,7 +126,6 @@ def cibuildwheel_run(
sys.executable,
"-m",
"cibuildwheel",
"--prerelease-pythons",
"--output-dir",
str(output_dir or tmp_output_dir),
str(package_dir),
+7 -7
View File
@@ -2,12 +2,12 @@ from __future__ import annotations
from packaging.specifiers import SpecifierSet
from cibuildwheel.util import BuildSelector, EnableGroups
from cibuildwheel.util import BuildSelector, EnableGroup
def test_build():
build_selector = BuildSelector(
build_config="cp3*-* *-manylinux*", skip_config="", enable=frozenset([EnableGroups.PyPy])
build_config="cp3*-* *-manylinux*", skip_config="", enable=frozenset([EnableGroup.PyPy])
)
assert build_selector("cp36-manylinux_x86_64")
@@ -45,7 +45,7 @@ def test_build_filter_pre():
build_selector = BuildSelector(
build_config="cp3*-* *-manylinux*",
skip_config="",
enable=frozenset([EnableGroups.CPythonPrerelease, EnableGroups.PyPy]),
enable=frozenset([EnableGroup.CPythonPrerelease, EnableGroup.PyPy]),
)
assert build_selector("cp37-manylinux_x86_64")
@@ -59,7 +59,7 @@ def test_skip():
build_selector = BuildSelector(
build_config="*",
skip_config="pp36-* cp3?-manylinux_i686 cp36-win* *-win32",
enable=frozenset([EnableGroups.PyPy]),
enable=frozenset([EnableGroup.PyPy]),
)
assert not build_selector("pp36-manylinux_x86_64")
@@ -85,7 +85,7 @@ def test_build_and_skip():
build_selector = BuildSelector(
build_config="cp36-* cp37-macosx* *-manylinux*",
skip_config="pp37-* cp37-manylinux_i686",
enable=frozenset([EnableGroups.PyPy]),
enable=frozenset([EnableGroup.PyPy]),
)
assert not build_selector("pp37-manylinux_x86_64")
@@ -119,7 +119,7 @@ def test_build_limited_python():
build_config="*",
skip_config="",
requires_python=SpecifierSet(">=3.7"),
enable=frozenset([EnableGroups.PyPy]),
enable=frozenset([EnableGroup.PyPy]),
)
assert not build_selector("cp36-manylinux_x86_64")
@@ -155,7 +155,7 @@ def test_build_limited_python_patch():
def test_build_free_threaded_python():
build_selector = BuildSelector(build_config="*", skip_config="", enable=frozenset(EnableGroups))
build_selector = BuildSelector(build_config="*", skip_config="", enable=frozenset(EnableGroup))
assert build_selector("cp313t-manylinux_x86_64")
+3 -1
View File
@@ -8,7 +8,7 @@ from pathlib import Path
import pytest
from cibuildwheel import linux, macos, util, windows
from cibuildwheel import linux, macos, pyodide, util, windows
class ArgsInterceptor:
@@ -42,6 +42,7 @@ def mock_protection(monkeypatch):
monkeypatch.setattr(windows, "build", fail_on_call)
monkeypatch.setattr(linux, "build", fail_on_call)
monkeypatch.setattr(macos, "build", fail_on_call)
monkeypatch.setattr(pyodide, "build", fail_on_call)
monkeypatch.setattr(Path, "mkdir", ignore_call)
@@ -88,6 +89,7 @@ def intercepted_build_args(monkeypatch):
monkeypatch.setattr(linux, "build", intercepted)
monkeypatch.setattr(macos, "build", intercepted)
monkeypatch.setattr(windows, "build", intercepted)
monkeypatch.setattr(pyodide, "build", intercepted)
yield intercepted
+41 -2
View File
@@ -10,7 +10,7 @@ import pytest
from cibuildwheel.__main__ import main
from cibuildwheel.environment import ParsedEnvironment
from cibuildwheel.options import BuildOptions, _get_pinned_container_images
from cibuildwheel.util import BuildSelector, resources_dir, split_config_settings
from cibuildwheel.util import BuildSelector, EnableGroup, resources_dir, split_config_settings
# CIBW_PLATFORM is tested in main_platform_test.py
@@ -126,7 +126,7 @@ def get_default_repair_command(platform: str) -> str:
return "auditwheel repair -w {dest_dir} {wheel}"
elif platform == "macos":
return "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
elif platform == "windows":
elif platform == "windows" or platform == "pyodide":
return ""
else:
msg = f"Unknown platform: {platform!r}"
@@ -368,6 +368,45 @@ def test_debug_traceback(monkeypatch, method, capfd):
assert "Traceback (most recent call last)" in err
@pytest.mark.parametrize("method", ["unset", "command_line", "env_var"])
def test_enable(method, intercepted_build_args, monkeypatch):
if method == "command_line":
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "pypy"])
elif method == "env_var":
monkeypatch.setenv("CIBW_ENABLE", "pypy")
main()
enable_groups = intercepted_build_args.args[0].globals.build_selector.enable
if method == "unset":
assert enable_groups == frozenset()
else:
assert enable_groups == frozenset([EnableGroup.PyPy])
def test_enable_arg_inherits(intercepted_build_args, monkeypatch):
monkeypatch.setenv("CIBW_ENABLE", "pypy")
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "cpython-prerelease"])
main()
enable_groups = intercepted_build_args.args[0].globals.build_selector.enable
assert enable_groups == frozenset((EnableGroup.PyPy, EnableGroup.CPythonPrerelease))
def test_enable_arg_error_message(monkeypatch, capsys):
monkeypatch.setattr(sys, "argv", [*sys.argv, "--enable", "invalid_group"])
with pytest.raises(SystemExit) as ex:
main()
assert ex.value.code == 2
_, err = capsys.readouterr()
assert "Valid group names are:" in err
def test_defaults(platform, intercepted_build_args):
main()
+2 -2
View File
@@ -6,7 +6,7 @@ import pytest
from cibuildwheel.__main__ import main
from cibuildwheel.architecture import Architecture
from cibuildwheel.util import EnableGroups
from cibuildwheel.util import EnableGroup
from ..conftest import MOCK_PACKAGE_DIR
@@ -217,7 +217,7 @@ def test_only_argument(intercepted_build_args, monkeypatch, only, plat):
assert options.globals.build_selector.skip_config == ""
assert options.platform == plat
assert options.globals.architectures == Architecture.all_archs(plat)
assert EnableGroups.PyPy in options.globals.build_selector.enable
assert EnableGroup.PyPy in options.globals.build_selector.enable
@pytest.mark.parametrize("only", ("cp311-manylxinux_x86_64", "some_linux_thing"))
+9 -22
View File
@@ -14,20 +14,8 @@ from cibuildwheel import linux, util
from cibuildwheel.__main__ import main
from cibuildwheel.oci_container import OCIPlatform
ALL_IDS = {
"cp36",
"cp37",
"cp38",
"cp39",
"cp310",
"cp311",
"cp312",
"cp313",
"pp37",
"pp38",
"pp39",
"pp310",
}
DEFAULT_IDS = {"cp36", "cp37", "cp38", "cp39", "cp310", "cp311", "cp312", "cp313"}
ALL_IDS = DEFAULT_IDS | {"cp313t", "pp37", "pp38", "pp39", "pp310"}
@pytest.fixture
@@ -77,7 +65,7 @@ def test_build_default_launches(monkeypatch):
assert kwargs["container"]["oci_platform"] == OCIPlatform.AMD64
identifiers = {x.identifier for x in kwargs["platform_configs"]}
assert identifiers == {f"{x}-manylinux_x86_64" for x in ALL_IDS}
assert identifiers == {f"{x}-manylinux_x86_64" for x in DEFAULT_IDS}
kwargs = build_in_container.call_args_list[1][1]
assert "quay.io/pypa/manylinux2014_i686" in kwargs["container"]["image"]
@@ -85,7 +73,7 @@ def test_build_default_launches(monkeypatch):
assert kwargs["container"]["oci_platform"] == OCIPlatform.i386
identifiers = {x.identifier for x in kwargs["platform_configs"]}
assert identifiers == {f"{x}-manylinux_i686" for x in ALL_IDS}
assert identifiers == {f"{x}-manylinux_i686" for x in DEFAULT_IDS}
kwargs = build_in_container.call_args_list[2][1]
assert "quay.io/pypa/musllinux_1_2_x86_64" in kwargs["container"]["image"]
@@ -93,9 +81,7 @@ def test_build_default_launches(monkeypatch):
assert kwargs["container"]["oci_platform"] == OCIPlatform.AMD64
identifiers = {x.identifier for x in kwargs["platform_configs"]}
assert identifiers == {
f"{x}-musllinux_x86_64" for x in ALL_IDS for x in ALL_IDS if "pp" not in x
}
assert identifiers == {f"{x}-musllinux_x86_64" for x in DEFAULT_IDS}
kwargs = build_in_container.call_args_list[3][1]
assert "quay.io/pypa/musllinux_1_2_i686" in kwargs["container"]["image"]
@@ -103,7 +89,7 @@ def test_build_default_launches(monkeypatch):
assert kwargs["container"]["oci_platform"] == OCIPlatform.i386
identifiers = {x.identifier for x in kwargs["platform_configs"]}
assert identifiers == {f"{x}-musllinux_i686" for x in ALL_IDS if "pp" not in x}
assert identifiers == {f"{x}-musllinux_i686" for x in DEFAULT_IDS}
@pytest.mark.usefixtures("mock_build_container")
@@ -117,6 +103,7 @@ def test_build_with_override_launches(monkeypatch, tmp_path):
[tool.cibuildwheel]
manylinux-x86_64-image = "manylinux_2_28"
musllinux-x86_64-image = "musllinux_1_2"
enable = ["pypy", "cpython-freethreading"]
# Before Python 3.10, use manylinux2014, musllinux_1_1
[[tool.cibuildwheel.overrides]]
@@ -158,7 +145,7 @@ before-all = "true"
assert identifiers == {
f"{x}-manylinux_x86_64"
for x in ALL_IDS
- {"cp36", "cp310", "cp311", "cp312", "cp313", "pp37", "pp38", "pp39", "pp310"}
- {"cp36", "cp310", "cp311", "cp312", "cp313", "cp313t", "pp37", "pp38", "pp39", "pp310"}
}
assert kwargs["options"].build_options("cp37-manylinux_x86_64").before_all == ""
@@ -169,7 +156,7 @@ before-all = "true"
identifiers = {x.identifier for x in kwargs["platform_configs"]}
assert identifiers == {
f"{x}-manylinux_x86_64"
for x in ["cp310", "cp311", "cp312", "cp313", "pp37", "pp38", "pp39", "pp310"]
for x in ["cp310", "cp311", "cp312", "cp313", "cp313t", "pp37", "pp38", "pp39", "pp310"]
}
kwargs = build_in_container.call_args_list[3][1]
+22 -14
View File
@@ -15,7 +15,7 @@ from cibuildwheel.options import (
Options,
_get_pinned_container_images,
)
from cibuildwheel.util import EnableGroups
from cibuildwheel.util import EnableGroup
PYPROJECT_1 = """
[tool.cibuildwheel]
@@ -429,24 +429,32 @@ def test_override_inherit_environment_with_references(tmp_path: Path) -> None:
@pytest.mark.parametrize(
("toml_assignment", "env", "expected_result"),
("toml_assignment", "env", "enable_args", "expected_result"),
[
("", {}, False),
("free-threaded-support = true", {}, True),
("free-threaded-support = false", {}, False),
("", {"CIBW_FREE_THREADED_SUPPORT": "0"}, False),
("", {"CIBW_FREE_THREADED_SUPPORT": "1"}, True),
("free-threaded-support = false", {"CIBW_FREE_THREADED_SUPPORT": "1"}, True),
("free-threaded-support = true", {"CIBW_FREE_THREADED_SUPPORT": "0"}, False),
("free-threaded-support = true", {"CIBW_FREE_THREADED_SUPPORT": ""}, True),
("free-threaded-support = false", {"CIBW_FREE_THREADED_SUPPORT": ""}, False),
("", {}, [], False),
("enable = ['cpython-freethreading']", {}, [], True),
("enable = []", {}, [], False),
("", {}, ["cpython-freethreading"], True),
("", {}, ["cpython-freethreading", "pypy"], True),
("", {"CIBW_ENABLE": "pypy"}, [], False),
("", {"CIBW_ENABLE": "cpython-freethreading"}, [], True),
("enable = []", {"CIBW_ENABLE": "cpython-freethreading"}, [], True),
("enable = ['cpython-freethreading']", {"CIBW_ENABLE": "pypy"}, [], True),
("enable = ['cpython-freethreading']", {}, ["pypy"], True),
("enable = ['cpython-freethreading']", {"CIBW_ENABLE": ""}, [], True),
("enable = []", {"CIBW_ENABLE": ""}, [], False),
],
)
def test_free_threaded_support(
tmp_path: Path, toml_assignment: str, env: dict[str, str], expected_result: bool
tmp_path: Path,
toml_assignment: str,
env: dict[str, str],
enable_args: list[str],
expected_result: bool,
) -> None:
args = CommandLineArguments.defaults()
args.package_dir = tmp_path
args.enable = enable_args
pyproject_toml: Path = tmp_path / "pyproject.toml"
pyproject_toml.write_text(
@@ -459,6 +467,6 @@ def test_free_threaded_support(
)
options = Options(platform="linux", command_line_arguments=args, env=env)
if expected_result:
assert EnableGroups.CPythonFreeThreading in options.globals.build_selector.enable
assert EnableGroup.CPythonFreeThreading in options.globals.build_selector.enable
else:
assert EnableGroups.CPythonFreeThreading not in options.globals.build_selector.enable
assert EnableGroup.CPythonFreeThreading not in options.globals.build_selector.enable