feat: use python3.11+ for cibuildwheel driver (#1912)

* chore: use SPEC 0 schedule for cibuildwheel

* remove support for {python} and {pip} in commands

* Remove specific Python versions from the update-dependencies job

The requirements pinning is done by uv now, so we don't need to
run the versions of Python to do the pinning anymore.

---------

Co-authored-by: Joe Rickerby <joerick@mac.com>
This commit is contained in:
Matthieu Darbois
2025-01-16 10:45:18 -05:00
committed by GitHub
co-authored by Joe Rickerby
parent 1608f7567e
commit a96545b729
33 changed files with 117 additions and 166 deletions
+6 -7
View File
@@ -1,6 +1,7 @@
from __future__ import annotations
import argparse
import contextlib
import dataclasses
import os
import shutil
@@ -12,7 +13,7 @@ import typing
from collections.abc import Iterable, Sequence, Set
from pathlib import Path
from tempfile import mkdtemp
from typing import Protocol
from typing import Protocol, assert_never
import cibuildwheel
import cibuildwheel.linux
@@ -21,7 +22,6 @@ import cibuildwheel.pyodide
import cibuildwheel.util
import cibuildwheel.windows
from cibuildwheel import errors
from cibuildwheel._compat.typing import assert_never
from cibuildwheel.architecture import Architecture, allowed_architectures_check
from cibuildwheel.logger import log
from cibuildwheel.options import CommandLineArguments, Options, compute_options
@@ -31,7 +31,6 @@ from cibuildwheel.util import (
BuildSelector,
CIProvider,
Unbuffered,
chdir,
detect_ci_provider,
fix_ansi_codes_for_github_actions,
strtobool,
@@ -200,7 +199,7 @@ def main_inner(global_options: GlobalOptions) -> None:
# This is now the new package dir
args.package_dir = project_dir.resolve()
with chdir(project_dir):
with contextlib.chdir(project_dir):
build_in_directory(args)
finally:
# avoid https://github.com/python/cpython/issues/86962 by performing
@@ -418,10 +417,10 @@ def detect_warnings(*, options: Options, identifiers: Iterable[str]) -> list[str
if any(o and ("{python}" in o or "{pip}" in o) for o in option_values):
# Reminder: in an f-string, double braces means literal single brace
msg = (
f"{option_name}: '{{python}}' and '{{pip}}' are no longer needed, "
"and will be removed in cibuildwheel 3. Simply use 'python' or 'pip' instead."
f"{option_name}: '{{python}}' and '{{pip}}' are no longer supported "
"and have been removed in cibuildwheel 3. Simply use 'python' or 'pip' instead."
)
warnings.append(msg)
raise errors.ConfigurationError(msg)
return warnings
-1
View File
@@ -1 +0,0 @@
from __future__ import annotations
-10
View File
@@ -1,10 +0,0 @@
from __future__ import annotations
import sys
if sys.version_info >= (3, 11):
from tomllib import load, loads
else:
from tomli import load, loads
__all__ = ["load", "loads"]
-14
View File
@@ -1,14 +0,0 @@
from __future__ import annotations
import sys
if sys.version_info < (3, 11):
from typing_extensions import NotRequired, Self, assert_never
else:
from typing import NotRequired, Self, assert_never
__all__ = (
"NotRequired",
"Self",
"assert_never",
)
+1 -2
View File
@@ -6,9 +6,8 @@ import re
import sys
from collections.abc import Set
from enum import Enum
from typing import Final, Literal
from typing import Final, Literal, assert_never
from ._compat.typing import assert_never
from .typing import PlatformName
PRETTY_NAMES: Final[dict[PlatformName, str]] = {
+7 -3
View File
@@ -1,14 +1,18 @@
from __future__ import annotations
import subprocess
from collections.abc import Iterable, Mapping, Sequence
from collections.abc import (
Callable,
Iterable,
Mapping,
Sequence,
)
from dataclasses import dataclass
from typing import Callable, Dict, List # noqa: TID251
import bashlex
# a function that takes a command and the environment, and returns the result
EnvironmentExecutor = Callable[[List[str], Dict[str, str]], str]
EnvironmentExecutor = Callable[[list[str], dict[str, str]], str]
def local_environment_executor(command: Sequence[str], env: Mapping[str, str]) -> str:
+3 -3
View File
@@ -4,15 +4,15 @@ import contextlib
import subprocess
import sys
import textwrap
from collections import OrderedDict
from collections.abc import Iterable, Iterator, Sequence, Set
from dataclasses import dataclass
from pathlib import Path, PurePath, PurePosixPath
from typing import OrderedDict, Tuple
from typing import assert_never
from packaging.version import Version
from . import errors
from ._compat.typing import assert_never
from .architecture import Architecture
from .logger import log
from .oci_container import OCIContainer, OCIContainerEngineConfig, OCIPlatform
@@ -104,7 +104,7 @@ def get_build_steps(
Groups PythonConfigurations into BuildSteps. Each BuildStep represents a
separate container instance.
"""
steps = OrderedDict[Tuple[str, str, str, OCIContainerEngineConfig], BuildStep]()
steps = OrderedDict[tuple[str, str, str, OCIContainerEngineConfig], BuildStep]()
for config in python_configurations:
_, platform_tag = config.identifier.split("-", 1)
+2 -2
View File
@@ -5,11 +5,11 @@ import os
import re
import sys
import time
from typing import IO, AnyStr, Final, Tuple
from typing import IO, AnyStr, Final
from .util import CIProvider, detect_ci_provider
FoldPattern = Tuple[str, str]
FoldPattern = tuple[str, str]
DEFAULT_FOLD_PATTERN: Final[FoldPattern] = ("{name}", "")
FOLD_PATTERNS: Final[dict[str, FoldPattern]] = {
"azure": ("##[group]{name}", "##[endgroup]"),
+4 -5
View File
@@ -12,13 +12,12 @@ import typing
from collections.abc import Sequence, Set
from dataclasses import dataclass
from pathlib import Path
from typing import Literal, Tuple
from typing import Literal, assert_never
from filelock import FileLock
from packaging.version import Version
from . import errors
from ._compat.typing import assert_never
from .architecture import Architecture
from .environment import ParsedEnvironment
from .logger import log
@@ -50,7 +49,7 @@ from .util import (
)
@functools.lru_cache(maxsize=None)
@functools.cache
def get_macos_version() -> tuple[int, int]:
"""
Returns the macOS major/minor version, as a tuple, e.g. (10, 15) or (11, 0)
@@ -74,10 +73,10 @@ def get_macos_version() -> tuple[int, int]:
capture_stdout=True,
)
version = tuple(map(int, version_str.split(".")[:2]))
return typing.cast(Tuple[int, int], version)
return typing.cast(tuple[int, int], version)
@functools.lru_cache(maxsize=None)
@functools.cache
def get_test_macosx_deployment_target() -> str:
version = get_macos_version()
if version >= (11, 0):
+2 -3
View File
@@ -16,9 +16,8 @@ from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path, PurePath, PurePosixPath
from types import TracebackType
from typing import IO, Dict, Literal
from typing import IO, Literal, Self, assert_never
from ._compat.typing import Self, assert_never
from .errors import OCIEngineTooOldError
from .logger import log
from .typing import PathOrStr, PopenBytes
@@ -489,7 +488,7 @@ class OCIContainer:
capture_output=True,
)
)
return typing.cast(Dict[str, str], env)
return typing.cast(dict[str, str], env)
def environment_executor(self, command: Sequence[str], environment: dict[str, str]) -> str:
# used as an EnvironmentExecutor to evaluate commands and capture output
+8 -9
View File
@@ -9,15 +9,14 @@ import enum
import functools
import shlex
import textwrap
from collections.abc import Callable, Generator, Iterable, Set
import tomllib
from collections.abc import Callable, Generator, Iterable, Mapping, Sequence, Set
from pathlib import Path
from typing import Any, Literal, Mapping, Sequence, Union # noqa: TID251
from typing import Any, Literal, assert_never
from packaging.specifiers import SpecifierSet
from . import errors
from ._compat import tomllib
from ._compat.typing import assert_never
from .architecture import Architecture
from .environment import EnvironmentParseError, ParsedEnvironment, parse_environment
from .logger import log
@@ -122,10 +121,10 @@ class BuildOptions:
return self.globals.architectures
SettingLeaf = Union[str, int, bool]
SettingLeaf = str | int | bool
SettingList = Sequence[SettingLeaf]
SettingTable = Mapping[str, Union[SettingLeaf, SettingList]]
SettingValue = Union[SettingTable, SettingList, SettingLeaf]
SettingTable = Mapping[str, SettingLeaf | SettingList]
SettingValue = SettingTable | SettingList | SettingLeaf
@dataclasses.dataclass(frozen=True)
@@ -361,7 +360,7 @@ def _stringify_setting(
msg = f"Error converting {setting!r} to a string: this setting doesn't accept a list"
raise OptionsReaderError(msg) from None
if isinstance(setting, (bool, int)):
if isinstance(setting, bool | int):
return str(setting)
return setting
@@ -984,7 +983,7 @@ def compute_options(
return options
@functools.lru_cache(maxsize=None)
@functools.cache
def _get_pinned_container_images() -> Mapping[str, Mapping[str, str]]:
"""
This looks like a dict of dicts, e.g.
+1 -1
View File
@@ -15,7 +15,7 @@ __all__ = (
if typing.TYPE_CHECKING:
PopenBytes = subprocess.Popen[bytes]
PathOrStr = Union[str, os.PathLike[str]]
PathOrStr = str | os.PathLike[str]
else:
PopenBytes = subprocess.Popen
PathOrStr = Union[str, "os.PathLike[str]"]
+6 -20
View File
@@ -14,13 +14,14 @@ import sys
import tarfile
import textwrap
import time
import tomllib
import typing
import urllib.request
from collections import defaultdict
from collections.abc import Callable, Generator, Iterable, Mapping, MutableMapping, Sequence
from dataclasses import dataclass
from enum import Enum
from functools import lru_cache, total_ordering
from functools import cache, total_ordering
from pathlib import Path, PurePath
from tempfile import TemporaryDirectory
from time import sleep
@@ -37,7 +38,6 @@ from packaging.version import Version
from platformdirs import user_cache_path
from . import errors
from ._compat import tomllib
from .architecture import Architecture
from .errors import FatalError
from .typing import PathOrStr, PlatformName
@@ -46,7 +46,6 @@ __all__ = [
"MANYLINUX_ARCHS",
"EnableGroups",
"call",
"chdir",
"combine_constraints",
"find_compatible_wheel",
"find_uv",
@@ -219,12 +218,12 @@ def format_safe(template: str, **kwargs: str | os.PathLike[str]) -> str:
def prepare_command(command: str, **kwargs: PathOrStr) -> str:
"""
Preprocesses a command by expanding variables like {python}.
Preprocesses a command by expanding variables like {project}.
For example, used in the test_command option to specify the path to the
project's root. Unmatched syntax will mostly be allowed through.
"""
return format_safe(command, python="python", pip="pip", **kwargs)
return format_safe(command, **kwargs)
def get_build_verbosity_extra_flags(level: int) -> list[str]:
@@ -631,7 +630,7 @@ def get_pip_version(env: Mapping[str, str]) -> str:
return pip_version
@lru_cache(maxsize=None)
@cache
def ensure_node(major_version: str) -> Path:
input_file = resources_dir / "nodejs.toml"
with input_file.open("rb") as f:
@@ -663,7 +662,7 @@ def ensure_node(major_version: str) -> Path:
return path
@lru_cache(maxsize=None)
@cache
def _ensure_virtualenv(version: str) -> Path:
version_parts = version.split(".")
key = f"py{version_parts[0]}{version_parts[1]}"
@@ -839,19 +838,6 @@ def find_compatible_wheel(wheels: Sequence[T], identifier: str) -> T | None:
return None
# Can be replaced by contextlib.chdir in Python 3.11
@contextlib.contextmanager
def chdir(new_path: Path | str) -> Generator[None, None, None]:
"""Non thread-safe context manager to change the current working directory."""
cwd = os.getcwd()
try:
os.chdir(new_path)
yield
finally:
os.chdir(cwd)
def fix_ansi_codes_for_github_actions(text: str) -> str:
"""
Github Actions forgets the current ANSI style on every new line. This
+3 -3
View File
@@ -7,14 +7,14 @@ import subprocess
import textwrap
from collections.abc import MutableMapping, Sequence, Set
from dataclasses import dataclass
from functools import lru_cache
from functools import cache
from pathlib import Path
from typing import assert_never
from filelock import FileLock
from packaging.version import Version
from . import errors
from ._compat.typing import assert_never
from .architecture import Architecture
from .environment import ParsedEnvironment
from .logger import log
@@ -96,7 +96,7 @@ def get_python_configurations(
return python_configurations
@lru_cache(maxsize=None)
@cache
def _ensure_nuget() -> Path:
nuget = CIBW_CACHE_PATH / "nuget.exe"
with FileLock(str(nuget) + ".lock"):