feat: adding enable (#2048)
* feat: adding enable Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * refactor: use recommended term Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * fix: use `cached_property` for `Options` properties * fix: warn on PyPy default --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> Co-authored-by: mayeut <mayeut@users.noreply.github.com>
This commit is contained in:
co-authored by
mayeut
parent
9459533408
commit
393e0352e8
@@ -26,6 +26,12 @@ $defs:
|
|||||||
- append
|
- append
|
||||||
default: none
|
default: none
|
||||||
description: How to inherit the parent's value.
|
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
|
additionalProperties: false
|
||||||
description: cibuildwheel's settings.
|
description: cibuildwheel's settings.
|
||||||
type: object
|
type: object
|
||||||
@@ -99,6 +105,13 @@ properties:
|
|||||||
default: pinned
|
default: pinned
|
||||||
description: Specify how cibuildwheel controls the versions of the tools it uses
|
description: Specify how cibuildwheel controls the versions of the tools it uses
|
||||||
type: string
|
type: string
|
||||||
|
enable:
|
||||||
|
description: Enable or disable certain builds.
|
||||||
|
oneOf:
|
||||||
|
- $ref: "#/$defs/enable"
|
||||||
|
- type: array
|
||||||
|
items:
|
||||||
|
$ref: "#/$defs/enable"
|
||||||
environment:
|
environment:
|
||||||
description: Set environment variables needed during the build.
|
description: Set environment variables needed during the build.
|
||||||
type: string_table
|
type: string_table
|
||||||
@@ -110,6 +123,7 @@ properties:
|
|||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
description: The project supports free-threaded builds of Python (PEP703)
|
description: The project supports free-threaded builds of Python (PEP703)
|
||||||
|
deprecated: Use the `enable` option instead.
|
||||||
manylinux-aarch64-image:
|
manylinux-aarch64-image:
|
||||||
type: string
|
type: string
|
||||||
description: Specify alternative manylinux / musllinux container images
|
description: Specify alternative manylinux / musllinux container images
|
||||||
@@ -261,6 +275,7 @@ del non_global_options["build"]
|
|||||||
del non_global_options["skip"]
|
del non_global_options["skip"]
|
||||||
del non_global_options["test-skip"]
|
del non_global_options["test-skip"]
|
||||||
del non_global_options["free-threaded-support"]
|
del non_global_options["free-threaded-support"]
|
||||||
|
del non_global_options["enable"]
|
||||||
|
|
||||||
overrides["items"]["properties"]["select"]["oneOf"] = string_array
|
overrides["items"]["properties"]["select"]["oneOf"] = string_array
|
||||||
overrides["items"]["properties"] |= non_global_options.copy()
|
overrides["items"]["properties"] |= non_global_options.copy()
|
||||||
|
|||||||
+47
-13
@@ -30,8 +30,10 @@ from .util import (
|
|||||||
BuildFrontendConfig,
|
BuildFrontendConfig,
|
||||||
BuildSelector,
|
BuildSelector,
|
||||||
DependencyConstraints,
|
DependencyConstraints,
|
||||||
|
EnableGroups,
|
||||||
TestSelector,
|
TestSelector,
|
||||||
format_safe,
|
format_safe,
|
||||||
|
read_python_configs,
|
||||||
resources_dir,
|
resources_dir,
|
||||||
selector_matches,
|
selector_matches,
|
||||||
strtobool,
|
strtobool,
|
||||||
@@ -512,6 +514,7 @@ class OptionsReader:
|
|||||||
env_plat: bool = True,
|
env_plat: bool = True,
|
||||||
option_format: OptionFormat | None = None,
|
option_format: OptionFormat | None = None,
|
||||||
ignore_empty: bool = False,
|
ignore_empty: bool = False,
|
||||||
|
env_rule: InheritRule = InheritRule.NONE,
|
||||||
) -> str:
|
) -> str:
|
||||||
"""
|
"""
|
||||||
Get and return the value for the named option from environment,
|
Get and return the value for the named option from environment,
|
||||||
@@ -543,8 +546,8 @@ class OptionsReader:
|
|||||||
(o.options.get(name), o.inherit.get(name, InheritRule.NONE))
|
(o.options.get(name), o.inherit.get(name, InheritRule.NONE))
|
||||||
for o in self.active_config_overrides
|
for o in self.active_config_overrides
|
||||||
],
|
],
|
||||||
(self.env.get(envvar), InheritRule.NONE),
|
(self.env.get(envvar), env_rule),
|
||||||
(self.env.get(plat_envvar) if env_plat else None, InheritRule.NONE),
|
(self.env.get(plat_envvar) if env_plat else None, env_rule),
|
||||||
ignore_empty=ignore_empty,
|
ignore_empty=ignore_empty,
|
||||||
option_format=option_format,
|
option_format=option_format,
|
||||||
)
|
)
|
||||||
@@ -558,14 +561,15 @@ class Options:
|
|||||||
platform: PlatformName,
|
platform: PlatformName,
|
||||||
command_line_arguments: CommandLineArguments,
|
command_line_arguments: CommandLineArguments,
|
||||||
env: Mapping[str, str],
|
env: Mapping[str, str],
|
||||||
read_config_file: bool = True,
|
defaults: bool = False,
|
||||||
):
|
):
|
||||||
self.platform = platform
|
self.platform = platform
|
||||||
self.command_line_arguments = command_line_arguments
|
self.command_line_arguments = command_line_arguments
|
||||||
self.env = env
|
self.env = env
|
||||||
|
self._defaults = defaults
|
||||||
|
|
||||||
self.reader = OptionsReader(
|
self.reader = OptionsReader(
|
||||||
self.config_file_path if read_config_file else None,
|
None if defaults else self.config_file_path,
|
||||||
platform=platform,
|
platform=platform,
|
||||||
env=env,
|
env=env,
|
||||||
disallow=DISALLOWED_OPTIONS,
|
disallow=DISALLOWED_OPTIONS,
|
||||||
@@ -578,7 +582,7 @@ class Options:
|
|||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.pyproject_toml = None
|
self.pyproject_toml = None
|
||||||
|
|
||||||
@property
|
@functools.cached_property
|
||||||
def config_file_path(self) -> Path | None:
|
def config_file_path(self) -> Path | None:
|
||||||
args = self.command_line_arguments
|
args = self.command_line_arguments
|
||||||
|
|
||||||
@@ -596,7 +600,7 @@ class Options:
|
|||||||
def package_requires_python_str(self) -> str | None:
|
def package_requires_python_str(self) -> str | None:
|
||||||
return get_requires_python_str(self.package_dir, self.pyproject_toml)
|
return get_requires_python_str(self.package_dir, self.pyproject_toml)
|
||||||
|
|
||||||
@property
|
@functools.cached_property
|
||||||
def globals(self) -> GlobalOptions:
|
def globals(self) -> GlobalOptions:
|
||||||
args = self.command_line_arguments
|
args = self.command_line_arguments
|
||||||
package_dir = args.package_dir
|
package_dir = args.package_dir
|
||||||
@@ -608,16 +612,34 @@ class Options:
|
|||||||
skip_config = self.reader.get("skip", env_plat=False, option_format=ListFormat(sep=" "))
|
skip_config = self.reader.get("skip", env_plat=False, option_format=ListFormat(sep=" "))
|
||||||
test_skip = self.reader.get("test-skip", env_plat=False, option_format=ListFormat(sep=" "))
|
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(
|
free_threaded_support = strtobool(
|
||||||
self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True)
|
self.reader.get("free-threaded-support", env_plat=False, ignore_empty=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
allow_empty = args.allow_empty or strtobool(self.env.get("CIBW_ALLOW_EMPTY", "0"))
|
|
||||||
|
|
||||||
prerelease_pythons = args.prerelease_pythons or strtobool(
|
prerelease_pythons = args.prerelease_pythons or strtobool(
|
||||||
self.env.get("CIBW_PRERELEASE_PYTHONS", "0")
|
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.
|
# 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
|
# Passing this in as an environment variable will override pyproject.toml, setup.cfg, or setup.py
|
||||||
requires_python_str: str | None = (
|
requires_python_str: str | None = (
|
||||||
@@ -633,18 +655,30 @@ class Options:
|
|||||||
build_config = args.only
|
build_config = args.only
|
||||||
skip_config = ""
|
skip_config = ""
|
||||||
architectures = Architecture.all_archs(self.platform)
|
architectures = Architecture.all_archs(self.platform)
|
||||||
prerelease_pythons = True
|
enable = set(EnableGroups)
|
||||||
free_threaded_support = True
|
|
||||||
|
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config=build_config,
|
build_config=build_config,
|
||||||
skip_config=skip_config,
|
skip_config=skip_config,
|
||||||
requires_python=requires_python,
|
requires_python=requires_python,
|
||||||
prerelease_pythons=prerelease_pythons,
|
enable=frozenset(
|
||||||
free_threaded_support=free_threaded_support,
|
enable | {EnableGroups.PyPy}
|
||||||
|
), # For backwards compatibility, we are adding PyPy for now
|
||||||
)
|
)
|
||||||
test_selector = TestSelector(skip_config=test_skip)
|
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(
|
return GlobalOptions(
|
||||||
package_dir=package_dir,
|
package_dir=package_dir,
|
||||||
output_dir=output_dir,
|
output_dir=output_dir,
|
||||||
@@ -831,7 +865,7 @@ class Options:
|
|||||||
platform=self.platform,
|
platform=self.platform,
|
||||||
command_line_arguments=CommandLineArguments.defaults(),
|
command_line_arguments=CommandLineArguments.defaults(),
|
||||||
env={},
|
env={},
|
||||||
read_config_file=False,
|
defaults=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def summary(self, identifiers: Iterable[str]) -> str:
|
def summary(self, identifiers: Iterable[str]) -> str:
|
||||||
|
|||||||
@@ -10,7 +10,16 @@
|
|||||||
],
|
],
|
||||||
"default": "none",
|
"default": "none",
|
||||||
"description": "How to inherit the parent's value."
|
"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,
|
"additionalProperties": false,
|
||||||
"description": "cibuildwheel's settings.",
|
"description": "cibuildwheel's settings.",
|
||||||
@@ -228,6 +237,21 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"title": "CIBW_DEPENDENCY_VERSIONS"
|
"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": {
|
"environment": {
|
||||||
"description": "Set environment variables needed during the build.",
|
"description": "Set environment variables needed during the build.",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ build = "*"
|
|||||||
skip = ""
|
skip = ""
|
||||||
test-skip = ""
|
test-skip = ""
|
||||||
free-threaded-support = false
|
free-threaded-support = false
|
||||||
|
enable = []
|
||||||
|
|
||||||
archs = ["auto"]
|
archs = ["auto"]
|
||||||
build-frontend = "default"
|
build-frontend = "default"
|
||||||
|
|||||||
+24
-14
@@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import enum
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
@@ -23,7 +24,7 @@ from functools import lru_cache, total_ordering
|
|||||||
from pathlib import Path, PurePath
|
from pathlib import Path, PurePath
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from time import sleep
|
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
|
from zipfile import ZipFile
|
||||||
|
|
||||||
import bracex
|
import bracex
|
||||||
@@ -41,6 +42,7 @@ from .typing import PathOrStr, PlatformName
|
|||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"MANYLINUX_ARCHS",
|
"MANYLINUX_ARCHS",
|
||||||
|
"EnableGroups",
|
||||||
"call",
|
"call",
|
||||||
"chdir",
|
"chdir",
|
||||||
"combine_constraints",
|
"combine_constraints",
|
||||||
@@ -66,6 +68,16 @@ free_thread_enable_313: Final[Path] = resources_dir / "free-threaded-enable-313.
|
|||||||
test_fail_cwd_file: Final[Path] = resources_dir / "testing_temp_dir_file.py"
|
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, ...]] = (
|
MANYLINUX_ARCHS: Final[tuple[str, ...]] = (
|
||||||
"x86_64",
|
"x86_64",
|
||||||
"i686",
|
"i686",
|
||||||
@@ -247,12 +259,7 @@ class BuildSelector:
|
|||||||
build_config: str
|
build_config: str
|
||||||
skip_config: str
|
skip_config: str
|
||||||
requires_python: SpecifierSet | None = None
|
requires_python: SpecifierSet | None = None
|
||||||
|
enable: frozenset[EnableGroups] = frozenset()
|
||||||
# a pattern that skips prerelease versions, when include_prereleases is False.
|
|
||||||
PRERELEASE_SKIP: ClassVar[str] = ""
|
|
||||||
prerelease_pythons: bool = False
|
|
||||||
|
|
||||||
free_threaded_support: bool = False
|
|
||||||
|
|
||||||
def __call__(self, build_id: str) -> bool:
|
def __call__(self, build_id: str) -> bool:
|
||||||
# Filter build selectors by python_requires if set
|
# Filter build selectors by python_requires if set
|
||||||
@@ -266,12 +273,16 @@ class BuildSelector:
|
|||||||
if not self.requires_python.contains(version):
|
if not self.requires_python.contains(version):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# filter out the prerelease pythons if self.prerelease_pythons is False
|
# filter out groups that are not enabled
|
||||||
if not self.prerelease_pythons and selector_matches(self.PRERELEASE_SKIP, build_id):
|
if EnableGroups.CPythonFreeThreading not in self.enable and selector_matches(
|
||||||
|
"cp3??t-*", build_id
|
||||||
|
):
|
||||||
return False
|
return False
|
||||||
|
if EnableGroups.CPythonPrerelease not in self.enable and selector_matches(
|
||||||
# filter out free threaded pythons if self.free_threaded_support is False
|
"cp314*", build_id
|
||||||
if not self.free_threaded_support and selector_matches("*t-*", build_id):
|
):
|
||||||
|
return False
|
||||||
|
if EnableGroups.PyPy not in self.enable and selector_matches("pp*", build_id):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
should_build = selector_matches(self.build_config, build_id)
|
should_build = selector_matches(self.build_config, build_id)
|
||||||
@@ -284,8 +295,7 @@ class BuildSelector:
|
|||||||
"build_config": self.build_config,
|
"build_config": self.build_config,
|
||||||
"skip_config": self.skip_config,
|
"skip_config": self.skip_config,
|
||||||
"requires_python": str(self.requires_python),
|
"requires_python": str(self.requires_python),
|
||||||
"prerelease_pythons": self.prerelease_pythons,
|
"enable": sorted(group.value for group in self.enable),
|
||||||
"free_threaded_support": self.free_threaded_support,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+72
-60
@@ -422,52 +422,6 @@ See the [cibuildwheel 1 documentation](https://cibuildwheel.pypa.io/en/1.x/) for
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
### `CIBW_FREE_THREADED_SUPPORT` {: #free-threaded-support}
|
|
||||||
|
|
||||||
> Choose whether free-threaded variants should be built
|
|
||||||
|
|
||||||
[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.
|
|
||||||
|
|
||||||
Building for free-threaded variants is disabled by default.
|
|
||||||
|
|
||||||
Building can be enabled by setting this option to `true`. The free-threaded compatible wheels will be built in addition to the standard wheels.
|
|
||||||
|
|
||||||
This option doesn't support overrides.
|
|
||||||
If you need to enable/disable it per platform or python version, set this option to `true` and use [`CIBW_BUILD`](#build-skip)/[`CIBW_SKIP`](#build-skip) options to filter the builds.
|
|
||||||
|
|
||||||
The build identifiers for those variants have a `t` suffix in their `python_tag` (e.g. `cp313t-manylinux_x86_64`)
|
|
||||||
|
|
||||||
!!! note
|
|
||||||
This feature is experimental: [What’s New In Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython)
|
|
||||||
|
|
||||||
#### Examples
|
|
||||||
|
|
||||||
!!! tab examples "Environment variables"
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# Enable free-threaded support
|
|
||||||
CIBW_FREE_THREADED_SUPPORT: 1
|
|
||||||
|
|
||||||
# Skip building free-threaded compatible wheels on Windows
|
|
||||||
CIBW_FREE_THREADED_SUPPORT: 1
|
|
||||||
CIBW_SKIP: *t-win*
|
|
||||||
```
|
|
||||||
|
|
||||||
It is generally recommended to use `free-threaded-support` in a config file as you can statically declare that you
|
|
||||||
support free-threaded builds.
|
|
||||||
|
|
||||||
!!! tab examples "pyproject.toml"
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[tool.cibuildwheel]
|
|
||||||
# Enable free-threaded support
|
|
||||||
free-threaded-support = true
|
|
||||||
|
|
||||||
# Skip building free-threaded compatible wheels on Windows
|
|
||||||
free-threaded-support = true
|
|
||||||
skip = "*t-win*"
|
|
||||||
```
|
|
||||||
|
|
||||||
### `CIBW_ARCHS` {: #archs}
|
### `CIBW_ARCHS` {: #archs}
|
||||||
> Change the architectures built on your machine by default.
|
> Change the architectures built on your machine by default.
|
||||||
@@ -603,24 +557,53 @@ the package is compatible with all versions of Python that it can build.
|
|||||||
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.6"
|
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.6"
|
||||||
```
|
```
|
||||||
|
|
||||||
### `CIBW_PRERELEASE_PYTHONS` {: #prerelease-pythons}
|
### `CIBW_ENABLE` {: #enable}
|
||||||
> Enable building with pre-release versions of Python if available
|
> Enable building with extra categories of selectors present.
|
||||||
|
|
||||||
|
This option lets you opt-in to non-default builds, like pre-releases and
|
||||||
|
free-threaded Python. These are not included by default to give a nice default
|
||||||
|
for new users, but can be added to the selectors available here. The allowed
|
||||||
|
values are:
|
||||||
|
|
||||||
|
|
||||||
|
- `cypython-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.
|
||||||
|
- `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.
|
||||||
|
|
||||||
During the beta period, when new versions of Python are being tested,
|
|
||||||
cibuildwheel will often gain early support for beta releases. If you would
|
|
||||||
like to test wheel building with these versions, you can enable this flag.
|
|
||||||
|
|
||||||
!!! caution
|
!!! caution
|
||||||
This option is provided for testing purposes only. It is not
|
`cpython-prerelease` is provided for testing purposes only. It is not
|
||||||
recommended to distribute wheels built when `CIBW_PRERELEASE_PYTHONS` is
|
recommended to distribute wheels built with beta releases, such as
|
||||||
set, such as uploading to PyPI. Please _do not_ upload these wheels to
|
uploading to PyPI. Please _do not_ upload these wheels to PyPI, as they are
|
||||||
PyPI, as they are not guaranteed to work with the final Python release.
|
not guaranteed to work with the final Python release. Once Python is ABI
|
||||||
Once Python is ABI stable and enters the release candidate phase, that
|
stable and enters the release candidate phase, that version of Python will
|
||||||
version of Python will become available without this flag.
|
become available without this flag.
|
||||||
|
|
||||||
Default: Off (0) if Python is available in beta phase. No effect otherwise.
|
!!! note
|
||||||
|
Free threading is experimental: [What’s New In Python 3.13](https://docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython)
|
||||||
|
|
||||||
|
Default: empty (`pypy` is always injected).
|
||||||
|
|
||||||
|
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
|
||||||
|
selectors exist. If you need to enable/disable it per platform or python
|
||||||
|
version, set this option to `true` and use
|
||||||
|
[`CIBW_BUILD`](#build-skip)/[`CIBW_SKIP`](#build-skip) options to filter the
|
||||||
|
builds.
|
||||||
|
|
||||||
|
Unlike all other cibuildwheel options, the environment variable setting will
|
||||||
|
only add to the TOML config; you can't remove an enable by setting an empty or
|
||||||
|
partial list in environment variables; use `CIBW_SKIP` instead.
|
||||||
|
|
||||||
This option can also be set using the [command-line option](#command-line) `--prerelease-pythons`. This option is not available in the `pyproject.toml` config.
|
|
||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
@@ -628,9 +611,38 @@ This option can also be set using the [command-line option](#command-line) `--pr
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# Include latest Python beta
|
# Include latest Python beta
|
||||||
CIBW_PRERELEASE_PYTHONS: True
|
CIBW_ENABLE: cpython-prerelease
|
||||||
|
|
||||||
|
# Include free-threaded support
|
||||||
|
CIBW_ENABLE: cpython-freethreading
|
||||||
|
|
||||||
|
# Include both
|
||||||
|
CIBW_ENABLE: cpython-prerelease cpython-freethreading
|
||||||
|
|
||||||
|
# Skip building free-threaded compatible wheels on Windows
|
||||||
|
CIBW_ENABLE: cpython-freethreading
|
||||||
|
CIBW_SKIP: *t-win*
|
||||||
```
|
```
|
||||||
|
|
||||||
|
It is generally recommended to use `cpython-freethreading` in a config
|
||||||
|
file as you can statically declare that you support free-threaded builds.
|
||||||
|
|
||||||
|
!!! tab examples "pyproject.toml"
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[tool.cibuildwheel]
|
||||||
|
# Enable free-threaded support
|
||||||
|
enable = ["cpython-freethreading"]
|
||||||
|
|
||||||
|
# Skip building free-threaded compatible wheels on Windows
|
||||||
|
enable = ["cpython-freethreading"]
|
||||||
|
skip = "*t-win*"
|
||||||
|
```
|
||||||
|
|
||||||
|
It is generally not recommended to use `cpython-prerelease` in a config file,
|
||||||
|
as it's intended for testing pre-releases for a 2-3 month period only.
|
||||||
|
|
||||||
|
|
||||||
### `CIBW_ALLOW_EMPTY` {: #allow-empty}
|
### `CIBW_ALLOW_EMPTY` {: #allow-empty}
|
||||||
> Suppress the error code if no wheels match the specified build identifiers
|
> Suppress the error code if no wheels match the specified build identifiers
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,13 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from packaging.specifiers import SpecifierSet
|
from packaging.specifiers import SpecifierSet
|
||||||
|
|
||||||
from cibuildwheel.util import BuildSelector
|
from cibuildwheel.util import BuildSelector, EnableGroups
|
||||||
|
|
||||||
|
|
||||||
def test_build():
|
def test_build():
|
||||||
build_selector = BuildSelector(build_config="cp3*-* *-manylinux*", skip_config="")
|
build_selector = BuildSelector(
|
||||||
|
build_config="cp3*-* *-manylinux*", skip_config="", enable=frozenset([EnableGroups.PyPy])
|
||||||
|
)
|
||||||
|
|
||||||
assert build_selector("cp36-manylinux_x86_64")
|
assert build_selector("cp36-manylinux_x86_64")
|
||||||
assert build_selector("cp37-manylinux_x86_64")
|
assert build_selector("cp37-manylinux_x86_64")
|
||||||
@@ -43,7 +45,7 @@ def test_build_filter_pre():
|
|||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="cp3*-* *-manylinux*",
|
build_config="cp3*-* *-manylinux*",
|
||||||
skip_config="",
|
skip_config="",
|
||||||
prerelease_pythons=True,
|
enable=frozenset([EnableGroups.CPythonPrerelease, EnableGroups.PyPy]),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert build_selector("cp37-manylinux_x86_64")
|
assert build_selector("cp37-manylinux_x86_64")
|
||||||
@@ -55,7 +57,9 @@ def test_build_filter_pre():
|
|||||||
|
|
||||||
def test_skip():
|
def test_skip():
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*", skip_config="pp36-* cp3?-manylinux_i686 cp36-win* *-win32"
|
build_config="*",
|
||||||
|
skip_config="pp36-* cp3?-manylinux_i686 cp36-win* *-win32",
|
||||||
|
enable=frozenset([EnableGroups.PyPy]),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert not build_selector("pp36-manylinux_x86_64")
|
assert not build_selector("pp36-manylinux_x86_64")
|
||||||
@@ -79,7 +83,9 @@ def test_skip():
|
|||||||
|
|
||||||
def test_build_and_skip():
|
def test_build_and_skip():
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="cp36-* cp37-macosx* *-manylinux*", skip_config="pp37-* cp37-manylinux_i686"
|
build_config="cp36-* cp37-macosx* *-manylinux*",
|
||||||
|
skip_config="pp37-* cp37-manylinux_i686",
|
||||||
|
enable=frozenset([EnableGroups.PyPy]),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert not build_selector("pp37-manylinux_x86_64")
|
assert not build_selector("pp37-manylinux_x86_64")
|
||||||
@@ -110,7 +116,10 @@ def test_build_braces():
|
|||||||
|
|
||||||
def test_build_limited_python():
|
def test_build_limited_python():
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(
|
||||||
build_config="*", skip_config="", requires_python=SpecifierSet(">=3.7")
|
build_config="*",
|
||||||
|
skip_config="",
|
||||||
|
requires_python=SpecifierSet(">=3.7"),
|
||||||
|
enable=frozenset([EnableGroups.PyPy]),
|
||||||
)
|
)
|
||||||
|
|
||||||
assert not build_selector("cp36-manylinux_x86_64")
|
assert not build_selector("cp36-manylinux_x86_64")
|
||||||
@@ -146,9 +155,7 @@ def test_build_limited_python_patch():
|
|||||||
|
|
||||||
|
|
||||||
def test_build_free_threaded_python():
|
def test_build_free_threaded_python():
|
||||||
build_selector = BuildSelector(
|
build_selector = BuildSelector(build_config="*", skip_config="", enable=frozenset(EnableGroups))
|
||||||
build_config="*", skip_config="", prerelease_pythons=True, free_threaded_support=True
|
|
||||||
)
|
|
||||||
|
|
||||||
assert build_selector("cp313t-manylinux_x86_64")
|
assert build_selector("cp313t-manylinux_x86_64")
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import pytest
|
|||||||
|
|
||||||
from cibuildwheel.__main__ import main
|
from cibuildwheel.__main__ import main
|
||||||
from cibuildwheel.architecture import Architecture
|
from cibuildwheel.architecture import Architecture
|
||||||
|
from cibuildwheel.util import EnableGroups
|
||||||
|
|
||||||
from ..conftest import MOCK_PACKAGE_DIR
|
from ..conftest import MOCK_PACKAGE_DIR
|
||||||
|
|
||||||
@@ -216,7 +217,7 @@ def test_only_argument(intercepted_build_args, monkeypatch, only, plat):
|
|||||||
assert options.globals.build_selector.skip_config == ""
|
assert options.globals.build_selector.skip_config == ""
|
||||||
assert options.platform == plat
|
assert options.platform == plat
|
||||||
assert options.globals.architectures == Architecture.all_archs(plat)
|
assert options.globals.architectures == Architecture.all_archs(plat)
|
||||||
assert options.globals.build_selector.prerelease_pythons is True
|
assert EnableGroups.PyPy in options.globals.build_selector.enable
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("only", ("cp311-manylxinux_x86_64", "some_linux_thing"))
|
@pytest.mark.parametrize("only", ("cp311-manylxinux_x86_64", "some_linux_thing"))
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from cibuildwheel.options import (
|
|||||||
Options,
|
Options,
|
||||||
_get_pinned_container_images,
|
_get_pinned_container_images,
|
||||||
)
|
)
|
||||||
|
from cibuildwheel.util import EnableGroups
|
||||||
|
|
||||||
PYPROJECT_1 = """
|
PYPROJECT_1 = """
|
||||||
[tool.cibuildwheel]
|
[tool.cibuildwheel]
|
||||||
@@ -454,4 +455,7 @@ def test_free_threaded_support(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
options = Options(platform="linux", command_line_arguments=args, env=env)
|
options = Options(platform="linux", command_line_arguments=args, env=env)
|
||||||
assert options.globals.build_selector.free_threaded_support is expected_result
|
if expected_result:
|
||||||
|
assert EnableGroups.CPythonFreeThreading in options.globals.build_selector.enable
|
||||||
|
else:
|
||||||
|
assert EnableGroups.CPythonFreeThreading not in options.globals.build_selector.enable
|
||||||
|
|||||||
Reference in New Issue
Block a user