chore: Add a platform_interface type to export from each platform

This avoids the repetition of the platform checks in __main__.py
by defining a dataclass with `get_python_configurations` and `build`.
This commit is contained in:
Hood Chatham
2023-04-10 13:30:23 -07:00
parent 33f642dc0b
commit 26dd3f399e
7 changed files with 54 additions and 34 deletions
+17 -29
View File
@@ -7,7 +7,7 @@ import sys
import tarfile
import textwrap
import typing
from collections.abc import Sequence, Set
from collections.abc import Set
from pathlib import Path
from tempfile import mkdtemp
@@ -19,9 +19,9 @@ import cibuildwheel.windows
from cibuildwheel.architecture import Architecture, allowed_architectures_check
from cibuildwheel.logger import log
from cibuildwheel.options import CommandLineArguments, Options, compute_options
from cibuildwheel.platform_interface import PlatformInterface
from cibuildwheel.typing import (
PLATFORMS,
GenericPythonConfiguration,
PlatformName,
assert_never,
)
@@ -244,6 +244,16 @@ def _compute_platform(args: CommandLineArguments) -> PlatformName:
return _compute_platform_ci()
def get_platform_interface(platform: PlatformName) -> PlatformInterface:
if platform == "linux": # noqa: SIM116
return cibuildwheel.linux.interface
elif platform == "windows":
return cibuildwheel.windows.interface
elif platform == "macos":
return cibuildwheel.macos.interface
assert_never(platform)
def build_in_directory(args: CommandLineArguments) -> None:
platform: PlatformName = _compute_platform(args)
options = compute_options(platform=platform, command_line_arguments=args, env=os.environ)
@@ -257,8 +267,9 @@ def build_in_directory(args: CommandLineArguments) -> None:
print(msg, file=sys.stderr)
sys.exit(2)
interface = get_platform_interface(platform)
identifiers = get_build_identifiers(
platform=platform,
interface=interface,
build_selector=options.globals.build_selector,
architectures=options.globals.architectures,
)
@@ -304,14 +315,7 @@ def build_in_directory(args: CommandLineArguments) -> None:
with cibuildwheel.util.print_new_wheels(
"\n{n} wheels produced in {m:.0f} minutes:", output_dir
):
if platform == "linux":
cibuildwheel.linux.build(options, tmp_path)
elif platform == "windows":
cibuildwheel.windows.build(options, tmp_path)
elif platform == "macos":
cibuildwheel.macos.build(options, tmp_path)
else:
assert_never(platform)
interface.build(options, tmp_path)
finally:
# avoid https://github.com/python/cpython/issues/86962 by performing
# cleanup manually
@@ -354,25 +358,9 @@ def print_preamble(platform: str, options: Options, identifiers: list[str]) -> N
def get_build_identifiers(
platform: PlatformName, build_selector: BuildSelector, architectures: Set[Architecture]
interface: PlatformInterface, build_selector: BuildSelector, architectures: Set[Architecture]
) -> list[str]:
python_configurations: Sequence[GenericPythonConfiguration]
if platform == "linux":
python_configurations = cibuildwheel.linux.get_python_configurations(
build_selector, architectures
)
elif platform == "windows":
python_configurations = cibuildwheel.windows.get_python_configurations(
build_selector, architectures
)
elif platform == "macos":
python_configurations = cibuildwheel.macos.get_python_configurations(
build_selector, architectures
)
else:
assert_never(platform)
python_configurations = interface.get_python_configurations(build_selector, architectures)
return [config.identifier for config in python_configurations]
+4
View File
@@ -12,6 +12,7 @@ from .architecture import Architecture
from .logger import log
from .oci_container import OCIContainer
from .options import Options
from .platform_interface import PlatformInterface
from .typing import OrderedDict, PathOrStr, assert_never
from .util import (
AlreadyBuiltWheelError,
@@ -483,3 +484,6 @@ def troubleshoot(options: Options, error: Exception) -> None:
print(" Files detected:")
print("\n".join(f" {f}" for f in so_files))
print()
interface = PlatformInterface(get_python_configurations=get_python_configurations, build=build)
+4
View File
@@ -19,6 +19,7 @@ from .architecture import Architecture
from .environment import ParsedEnvironment
from .logger import log
from .options import Options
from .platform_interface import PlatformInterface
from .typing import Literal, PathOrStr, assert_never
from .util import (
CIBW_CACHE_PATH,
@@ -622,3 +623,6 @@ def build(options: Options, tmp_path: Path) -> None:
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
)
sys.exit(1)
interface = PlatformInterface(get_python_configurations=get_python_configurations, build=build)
+19
View File
@@ -0,0 +1,19 @@
from __future__ import annotations
import dataclasses
from collections.abc import Callable, Sequence, Set
from pathlib import Path
from .architecture import Architecture
from .options import Options
from .typing import GenericPythonConfiguration
from .util import BuildSelector
# Can't make it frozen because we monkeypatch "build" in unit tests
@dataclasses.dataclass()
class PlatformInterface:
get_python_configurations: Callable[
[BuildSelector, Set[Architecture]], Sequence[GenericPythonConfiguration]
]
build: Callable[[Options, Path], None]
+4
View File
@@ -20,6 +20,7 @@ from .architecture import Architecture
from .environment import ParsedEnvironment
from .logger import log
from .options import Options
from .platform_interface import PlatformInterface
from .typing import PathOrStr, assert_never
from .util import (
CIBW_CACHE_PATH,
@@ -574,3 +575,6 @@ def build(options: Options, tmp_path: Path) -> None:
f"Command {error.cmd} failed with code {error.returncode}. {error.stdout}"
)
sys.exit(1)
interface = PlatformInterface(get_python_configurations=get_python_configurations, build=build)
+3 -3
View File
@@ -85,9 +85,9 @@ def platform(request, monkeypatch):
def intercepted_build_args(monkeypatch):
intercepted = ArgsInterceptor()
monkeypatch.setattr(linux, "build", intercepted)
monkeypatch.setattr(macos, "build", intercepted)
monkeypatch.setattr(windows, "build", intercepted)
monkeypatch.setattr(linux.interface, "build", intercepted)
monkeypatch.setattr(macos.interface, "build", intercepted)
monkeypatch.setattr(windows.interface, "build", intercepted)
yield intercepted
+3 -2
View File
@@ -7,7 +7,7 @@ from pathlib import Path
import pytest
from cibuildwheel.__main__ import get_build_identifiers
from cibuildwheel.__main__ import get_build_identifiers, get_platform_interface
from cibuildwheel.bashlex_eval import local_environment_executor
from cibuildwheel.environment import parse_environment
from cibuildwheel.options import (
@@ -49,8 +49,9 @@ def test_options_1(tmp_path, monkeypatch):
options = Options(platform="linux", command_line_arguments=args, env={})
interface = get_platform_interface("linux")
identifiers = get_build_identifiers(
platform="linux",
interface=interface,
build_selector=options.globals.build_selector,
architectures=options.globals.architectures,
)