Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adding enable #2048

Merged
merged 4 commits into from
Nov 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions bin/generate_schema.py
Original file line number Diff line number Diff line change
@@ -26,6 +26,12 @@
- append
default: none
description: How to inherit the parent's value.
enable:
enum:
- cpython-freethreading
- cpython-prerelease
- pypy
description: A Python version or flavor to enable.
additionalProperties: false
description: cibuildwheel's settings.
type: object
@@ -99,6 +105,13 @@
default: pinned
description: Specify how cibuildwheel controls the versions of the tools it uses
type: string
enable:
description: Enable or disable certain builds.
oneOf:
- $ref: "#/$defs/enable"
- type: array
items:
$ref: "#/$defs/enable"
environment:
description: Set environment variables needed during the build.
type: string_table
@@ -110,6 +123,7 @@
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
@@ -261,6 +275,7 @@
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
overrides["items"]["properties"] |= non_global_options.copy()
60 changes: 47 additions & 13 deletions cibuildwheel/options.py
Original file line number Diff line number Diff line change
@@ -30,8 +30,10 @@
BuildFrontendConfig,
BuildSelector,
DependencyConstraints,
EnableGroups,
TestSelector,
format_safe,
read_python_configs,
resources_dir,
selector_matches,
strtobool,
@@ -512,6 +514,7 @@ def get(
env_plat: bool = True,
option_format: OptionFormat | None = None,
ignore_empty: bool = False,
env_rule: InheritRule = InheritRule.NONE,
) -> str:
"""
Get and return the value for the named option from environment,
@@ -543,8 +546,8 @@ def get(
(o.options.get(name), o.inherit.get(name, InheritRule.NONE))
for o in self.active_config_overrides
],
(self.env.get(envvar), InheritRule.NONE),
(self.env.get(plat_envvar) if env_plat else None, InheritRule.NONE),
(self.env.get(envvar), env_rule),
(self.env.get(plat_envvar) if env_plat else None, env_rule),
ignore_empty=ignore_empty,
option_format=option_format,
)
@@ -558,14 +561,15 @@ def __init__(
platform: PlatformName,
command_line_arguments: CommandLineArguments,
env: Mapping[str, str],
read_config_file: bool = True,
defaults: bool = False,
):
self.platform = platform
self.command_line_arguments = command_line_arguments
self.env = env
self._defaults = defaults

self.reader = OptionsReader(
self.config_file_path if read_config_file else None,
None if defaults else self.config_file_path,
platform=platform,
env=env,
disallow=DISALLOWED_OPTIONS,
@@ -578,7 +582,7 @@ def __init__(
except FileNotFoundError:
self.pyproject_toml = None

@property
@functools.cached_property
def config_file_path(self) -> Path | None:
args = self.command_line_arguments

@@ -596,7 +600,7 @@ def config_file_path(self) -> Path | None:
def package_requires_python_str(self) -> str | None:
return get_requires_python_str(self.package_dir, self.pyproject_toml)

@property
@functools.cached_property
def globals(self) -> GlobalOptions:
args = self.command_line_arguments
package_dir = args.package_dir
@@ -608,16 +612,34 @@ def globals(self) -> GlobalOptions:
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=" "))

allow_empty = args.allow_empty or strtobool(self.env.get("CIBW_ALLOW_EMPTY", "0"))

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)
)

allow_empty = args.allow_empty or strtobool(self.env.get("CIBW_ALLOW_EMPTY", "0"))

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)

# 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
requires_python_str: str | None = (
@@ -633,18 +655,30 @@ def globals(self) -> GlobalOptions:
build_config = args.only
skip_config = ""
architectures = Architecture.all_archs(self.platform)
prerelease_pythons = True
free_threaded_support = True
enable = set(EnableGroups)

build_selector = BuildSelector(
build_config=build_config,
skip_config=skip_config,
requires_python=requires_python,
prerelease_pythons=prerelease_pythons,
free_threaded_support=free_threaded_support,
enable=frozenset(
enable | {EnableGroups.PyPy}
), # For backwards compatibility, we are adding PyPy for now
)
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,
@@ -831,7 +865,7 @@ def defaults(self) -> Options:
platform=self.platform,
command_line_arguments=CommandLineArguments.defaults(),
env={},
read_config_file=False,
defaults=True,
)

def summary(self, identifiers: Iterable[str]) -> str:
26 changes: 25 additions & 1 deletion cibuildwheel/resources/cibuildwheel.schema.json
Original file line number Diff line number Diff line change
@@ -10,7 +10,16 @@
],
"default": "none",
"description": "How to inherit the parent's value."
}
},
"enable": {
"enum": [
"cpython-eol",
"cpython-freethreading",
"cpython-prerelease",
"pypy-eol"
]
},
"description": "A Python version or flavor to enable."
},
"additionalProperties": false,
"description": "cibuildwheel's settings.",
@@ -228,6 +237,21 @@
"type": "string",
"title": "CIBW_DEPENDENCY_VERSIONS"
},
"enable": {
"description": "Enable or disable certain builds.",
"oneOf": [
{
"$ref": "#/$defs/enable"
},
{
"type": "array",
"items": {
"$ref": "#/$defs/enable"
}
}
],
"title": "CIBW_ENABLE"
},
"environment": {
"description": "Set environment variables needed during the build.",
"oneOf": [
1 change: 1 addition & 0 deletions cibuildwheel/resources/defaults.toml
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ build = "*"
skip = ""
test-skip = ""
free-threaded-support = false
enable = []

archs = ["auto"]
build-frontend = "default"
38 changes: 24 additions & 14 deletions cibuildwheel/util.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import annotations

import contextlib
import enum
import fnmatch
import itertools
import os
@@ -23,7 +24,7 @@
from pathlib import Path, PurePath
from tempfile import TemporaryDirectory
from time import sleep
from typing import Any, ClassVar, Final, Literal, TextIO, TypeVar
from typing import Any, Final, Literal, TextIO, TypeVar
from zipfile import ZipFile

import bracex
@@ -41,6 +42,7 @@

__all__ = [
"MANYLINUX_ARCHS",
"EnableGroups",
"call",
"chdir",
"combine_constraints",
@@ -66,6 +68,16 @@
test_fail_cwd_file: Final[Path] = resources_dir / "testing_temp_dir_file.py"


class EnableGroups(enum.Enum):
"""
Groups of build selectors that are not enabled by default.
"""

CPythonFreeThreading = "cpython-freethreading"
CPythonPrerelease = "cpython-prerelease"
PyPy = "pypy"


MANYLINUX_ARCHS: Final[tuple[str, ...]] = (
"x86_64",
"i686",
@@ -247,12 +259,7 @@ class BuildSelector:
build_config: str
skip_config: str
requires_python: SpecifierSet | None = None

# a pattern that skips prerelease versions, when include_prereleases is False.
PRERELEASE_SKIP: ClassVar[str] = ""
prerelease_pythons: bool = False

free_threaded_support: bool = False
enable: frozenset[EnableGroups] = frozenset()

def __call__(self, build_id: str) -> bool:
# Filter build selectors by python_requires if set
@@ -266,12 +273,16 @@ def __call__(self, build_id: str) -> bool:
if not self.requires_python.contains(version):
return False

# filter out the prerelease pythons if self.prerelease_pythons is False
if not self.prerelease_pythons and selector_matches(self.PRERELEASE_SKIP, build_id):
# filter out groups that are not enabled
if EnableGroups.CPythonFreeThreading not in self.enable and selector_matches(
"cp3??t-*", build_id
):
return False

# filter out free threaded pythons if self.free_threaded_support is False
if not self.free_threaded_support and selector_matches("*t-*", build_id):
if EnableGroups.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):
return False

should_build = selector_matches(self.build_config, build_id)
@@ -284,8 +295,7 @@ def options_summary(self) -> Any:
"build_config": self.build_config,
"skip_config": self.skip_config,
"requires_python": str(self.requires_python),
"prerelease_pythons": self.prerelease_pythons,
"free_threaded_support": self.free_threaded_support,
"enable": sorted(group.value for group in self.enable),
}


Loading