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

chore: Simplify host platform logic #1498

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
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
28 changes: 13 additions & 15 deletions cibuildwheel/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from cibuildwheel.typing import PLATFORMS, GenericPythonConfiguration, PlatformName
from cibuildwheel.util import (
CIBW_CACHE_PATH,
HOST_IS_WINDOWS,
HOST_PLATFORM,
BuildSelector,
CIProvider,
Unbuffered,
Expand Down Expand Up @@ -164,7 +166,7 @@ def main() -> None:
finally:
# avoid https://github.com/python/cpython/issues/86962 by performing
# cleanup manually
shutil.rmtree(temp_dir, ignore_errors=sys.platform.startswith("win"))
shutil.rmtree(temp_dir, ignore_errors=HOST_IS_WINDOWS)
if temp_dir.exists():
log.warning(f"Can't delete temporary folder '{temp_dir}'")

Expand Down Expand Up @@ -197,19 +199,15 @@ def _compute_platform_ci() -> PlatformName:
file=sys.stderr,
)
sys.exit(2)
if sys.platform.startswith("linux"):
return "linux"
elif sys.platform == "darwin":
return "macos"
elif sys.platform == "win32":
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to say sys.platform == "win32" but this changes it to startswith("win"). Am I introducing a bug with this behavior change? If so I'd like to add a comment explaining why we use == "win32" here but in architecture we use startswith("win").

return "windows"
else:
print(
'cibuildwheel: Unable to detect platform from "sys.platform" in a CI environment. You can run '
"cibuildwheel using the --platform argument. Check --help output for more information.",
file=sys.stderr,
)
sys.exit(2)
if HOST_PLATFORM:
return HOST_PLATFORM

print(
'cibuildwheel: Unable to detect platform from "sys.platform" in a CI environment. You can run '
"cibuildwheel using the --platform argument. Check --help output for more information.",
file=sys.stderr,
)
sys.exit(2)


def _compute_platform(args: CommandLineArguments) -> PlatformName:
Expand Down Expand Up @@ -328,7 +326,7 @@ def build_in_directory(args: CommandLineArguments) -> None:
finally:
# avoid https://github.com/python/cpython/issues/86962 by performing
# cleanup manually
shutil.rmtree(tmp_path, ignore_errors=sys.platform.startswith("win"))
shutil.rmtree(tmp_path, ignore_errors=HOST_IS_WINDOWS)
if tmp_path.exists():
log.warning(f"Can't delete temporary folder '{tmp_path}'")

Expand Down
14 changes: 4 additions & 10 deletions cibuildwheel/architecture.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import functools
import platform as platform_module
import re
import sys
from collections.abc import Set
from enum import Enum

from ._compat.typing import Final, Literal, assert_never
from .typing import PlatformName
from .util import HOST_PLATFORM

PRETTY_NAMES: Final[dict[PlatformName, str]] = {
"linux": "Linux",
Expand Down Expand Up @@ -74,20 +74,14 @@ def parse_config(config: str, platform: PlatformName) -> set[Architecture]:
def auto_archs(platform: PlatformName) -> set[Architecture]:
native_machine = platform_module.machine()

# Cross-platform support. Used for --print-build-identifiers or docker builds.
host_platform: PlatformName = (
"windows"
if sys.platform.startswith("win")
else ("macos" if sys.platform.startswith("darwin") else "linux")
)
Comment on lines -78 to -82
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this PR because it was bothering me that the logic here does not exactly match the logic in _compute_platform_ci().


assert HOST_PLATFORM
native_architecture = Architecture(native_machine)

# we might need to rename the native arch to the machine we're running
# on, as the same arch can have different names on different platforms
if host_platform != platform:
if platform != HOST_PLATFORM:
for arch_synonym in ARCH_SYNONYMS:
if native_machine == arch_synonym.get(host_platform):
if native_machine == arch_synonym.get(HOST_PLATFORM):
synonym = arch_synonym[platform]

if synonym is None:
Expand Down
7 changes: 3 additions & 4 deletions cibuildwheel/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import IO, AnyStr, Tuple

from ._compat.typing import Final
from .util import CIProvider, detect_ci_provider
from .util import HOST_IS_WIN32, CIProvider, detect_ci_provider

FoldPattern = Tuple[str, str]
DEFAULT_FOLD_PATTERN: Final[FoldPattern] = ("{name}", "")
Expand Down Expand Up @@ -48,7 +48,7 @@ class Logger:
active_fold_group_name: str | None = None

def __init__(self) -> None:
if sys.platform == "win32" and hasattr(sys.stdout, "reconfigure"):
if HOST_IS_WIN32 and hasattr(sys.stdout, "reconfigure"):
# the encoding on Windows can be a 1-byte charmap, but all CIs
# support utf8, so we hardcode that
sys.stdout.reconfigure(encoding="utf8")
Expand Down Expand Up @@ -253,8 +253,7 @@ def file_supports_color(file_obj: IO[AnyStr]) -> bool:
"""
Returns True if the running system's terminal supports color.
"""
plat = sys.platform
supported_platform = plat != "win32" or "ANSICON" in os.environ
supported_platform = HOST_IS_WIN32 or "ANSICON" in os.environ

is_a_tty = file_is_a_tty(file_obj)

Expand Down
25 changes: 21 additions & 4 deletions cibuildwheel/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,24 @@ def build_frontend_or_default(
os.environ.get("CIBW_CACHE_PATH", DEFAULT_CIBW_CACHE_PATH)
).resolve()

IS_WIN: Final[bool] = sys.platform.startswith("win")

def get_host_platform() -> PlatformName | None:
# Cross-platform support. Used for --print-build-identifiers or docker builds.
if sys.platform.startswith("linux"):
return "linux"
elif sys.platform.startswith("darwin"):
return "macos"
elif sys.platform.startswith("win"):
return "windows"
else:
return None


HOST_PLATFORM: Final[PlatformName | None] = get_host_platform()

HOST_IS_WINDOWS: Final[bool] = get_host_platform() == "windows"

HOST_IS_WIN32: Final[bool] = sys.platform == "win32"
Comment on lines +111 to +113
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a bit excessive but I think it makes the intended distinction between these two checks 100% clear.



@typing.overload
Expand Down Expand Up @@ -135,7 +152,7 @@ def call(
if capture_stdout:
kwargs["universal_newlines"] = True
kwargs["stdout"] = subprocess.PIPE
result = subprocess.run(args_, check=True, shell=IS_WIN, env=env, cwd=cwd, **kwargs)
result = subprocess.run(args_, check=True, shell=HOST_IS_WINDOWS, env=env, cwd=cwd, **kwargs)
if not capture_stdout:
return None
return typing.cast(str, result.stdout)
Expand Down Expand Up @@ -585,7 +602,7 @@ def virtualenv(
# version of pip that will end-up installed.
# c.f. https://virtualenv.pypa.io/en/latest/cli_interface.html#section-seeder
if (
not IS_WIN
not HOST_IS_WINDOWS
and constraints["pip"] != "embed"
and Version(constraints["pip"]) >= Version("19.3")
):
Expand All @@ -602,7 +619,7 @@ def virtualenv(
python,
venv_path,
)
if IS_WIN:
if HOST_IS_WINDOWS:
paths = [str(venv_path), str(venv_path / "Scripts")]
else:
paths = [str(venv_path / "bin")]
Expand Down
3 changes: 3 additions & 0 deletions unit_test/architecture_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

import pytest

from cibuildwheel import architecture
from cibuildwheel.architecture import Architecture
from cibuildwheel.util import get_host_platform


@pytest.fixture(
Expand All @@ -24,6 +26,7 @@ def platform_machine(request, monkeypatch):
platform_name, platform_value, machine_value, machine_name = request.param
monkeypatch.setattr(sys, "platform", platform_value)
monkeypatch.setattr(platform_module, "machine", lambda: machine_value)
monkeypatch.setattr(architecture, "HOST_PLATFORM", get_host_platform())
return platform_name, machine_name


Expand Down
3 changes: 3 additions & 0 deletions unit_test/main_tests/main_platform_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

import pytest

from cibuildwheel import __main__
from cibuildwheel.__main__ import main
from cibuildwheel.architecture import Architecture
from cibuildwheel.util import get_host_platform

from ..conftest import MOCK_PACKAGE_DIR

Expand Down Expand Up @@ -35,6 +37,7 @@ def test_unknown_platform_on_ci(monkeypatch, capsys):
monkeypatch.setenv("CI", "true")
monkeypatch.setattr(sys, "platform", "nonexistent")
monkeypatch.delenv("CIBW_PLATFORM", raising=False)
monkeypatch.setattr(__main__, "HOST_PLATFORM", get_host_platform())

with pytest.raises(SystemExit) as exit:
main()
Expand Down