refactor: pull arch out into separate file

This commit is contained in:
Henry Schreiner
2021-01-22 13:02:51 -05:00
parent f5b84797e5
commit ff8f881098
6 changed files with 94 additions and 91 deletions
+2 -3
View File
@@ -11,16 +11,15 @@ import cibuildwheel
import cibuildwheel.linux import cibuildwheel.linux
import cibuildwheel.macos import cibuildwheel.macos
import cibuildwheel.windows import cibuildwheel.windows
from cibuildwheel.architecture import Architecture, allowed_architectures_check
from cibuildwheel.environment import EnvironmentParseError, parse_environment from cibuildwheel.environment import EnvironmentParseError, parse_environment
from cibuildwheel.typing import PLATFORMS, PlatformName, assert_never from cibuildwheel.typing import PLATFORMS, PlatformName, assert_never
from cibuildwheel.util import ( from cibuildwheel.util import (
Architecture,
BuildOptions, BuildOptions,
BuildSelector, BuildSelector,
DependencyConstraints, DependencyConstraints,
TestSelector, TestSelector,
Unbuffered, Unbuffered,
allowed_architectures_check,
detect_ci_provider, detect_ci_provider,
resources_dir, resources_dir,
) )
@@ -259,7 +258,7 @@ def main() -> None:
print_preamble(platform, build_options) print_preamble(platform, build_options)
try: try:
allowed_architectures_check(platform, build_options) allowed_architectures_check(platform, build_options.architectures)
except ValueError as err: except ValueError as err:
print("cibuildwheel:", *err.args, file=sys.stderr) print("cibuildwheel:", *err.args, file=sys.stderr)
sys.exit(4) sys.exit(4)
+86
View File
@@ -0,0 +1,86 @@
import functools
import platform as platform_module
import re
from enum import Enum
from typing import Set
from .typing import PlatformName, assert_never
PRETTY_NAMES = {'linux': 'Linux', 'macos': 'macOS', 'windows': 'Windows'}
@functools.total_ordering
class Architecture(Enum):
value: str
# mac/linux archs
x86_64 = 'x86_64'
i686 = 'i686'
aarch64 = 'aarch64'
ppc64le = 'ppc64le'
s390x = 's390x'
# windows archs
x86 = 'x86'
AMD64 = 'AMD64'
# Allow this to be sorted
def __lt__(self, other: "Architecture") -> bool:
return self.value < other.value
@staticmethod
def parse_config(config: str, platform: PlatformName) -> 'Set[Architecture]':
result = set()
for arch_str in re.split(r'[\s,]+', config):
if arch_str == 'auto':
result |= Architecture.auto_archs(platform=platform)
elif arch_str == 'native':
result.add(Architecture(platform_module.machine()))
elif arch_str == 'all':
result |= Architecture.all_archs(platform=platform)
else:
result.add(Architecture(arch_str))
return result
@staticmethod
def auto_archs(platform: PlatformName) -> 'Set[Architecture]':
native_architecture = Architecture(platform_module.machine())
result = {native_architecture}
if platform == 'linux' and native_architecture == Architecture.x86_64:
# x86_64 machines can run i686 docker containers
result.add(Architecture.i686)
if platform == 'windows' and native_architecture == Architecture.AMD64:
result.add(Architecture.x86)
return result
@staticmethod
def all_archs(platform: PlatformName) -> 'Set[Architecture]':
if platform == 'linux':
return {Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x}
elif platform == 'macos':
return {Architecture.x86_64}
elif platform == 'windows':
return {Architecture.x86, Architecture.AMD64}
else:
assert_never(platform)
def allowed_architectures_check(
platform: PlatformName,
architectures: Set[Architecture],
) -> None:
allowed_architectures = Architecture.all_archs(platform)
msg = f'{PRETTY_NAMES[platform]} only supports {sorted(allowed_architectures)} at the moment.'
if platform != 'linux':
msg += ' If you want to set emulation architectures on Linux, use CIBW_ARCHS_LINUX instead.'
if not architectures <= allowed_architectures:
msg = f'Invalid archs option {architectures}. ' + msg
raise ValueError(msg)
if not architectures:
msg = 'Empty archs option set. ' + msg
raise ValueError(msg)
+1 -1
View File
@@ -4,11 +4,11 @@ import textwrap
from pathlib import Path, PurePath from pathlib import Path, PurePath
from typing import List, NamedTuple, Set from typing import List, NamedTuple, Set
from .architecture import Architecture
from .docker_container import DockerContainer from .docker_container import DockerContainer
from .logger import log from .logger import log
from .typing import PathOrStr from .typing import PathOrStr
from .util import ( from .util import (
Architecture,
BuildOptions, BuildOptions,
BuildSelector, BuildSelector,
NonPlatformWheelError, NonPlatformWheelError,
+2 -84
View File
@@ -1,9 +1,6 @@
import fnmatch import fnmatch
import functools
import itertools import itertools
import os import os
import platform as platform_module
import re
import ssl import ssl
import sys import sys
import textwrap import textwrap
@@ -17,8 +14,9 @@ import bracex
import certifi import certifi
import toml import toml
from .architecture import Architecture
from .environment import ParsedEnvironment from .environment import ParsedEnvironment
from .typing import PathOrStr, PlatformName, assert_never from .typing import PathOrStr, PlatformName
if sys.version_info < (3, 9): if sys.version_info < (3, 9):
from importlib_resources import files from importlib_resources import files
@@ -163,62 +161,6 @@ class DependencyConstraints:
return f'{self.__class__.__name__}{self.base_file_path!r})' return f'{self.__class__.__name__}{self.base_file_path!r})'
@functools.total_ordering
class Architecture(Enum):
value: str
# mac/linux archs
x86_64 = 'x86_64'
i686 = 'i686'
aarch64 = 'aarch64'
ppc64le = 'ppc64le'
s390x = 's390x'
# windows archs
x86 = 'x86'
AMD64 = 'AMD64'
# Allow this to be sorted
def __lt__(self, other: "Architecture") -> bool:
return self.value < other.value
@staticmethod
def parse_config(config: str, platform: PlatformName) -> 'Set[Architecture]':
result = set()
for arch_str in re.split(r'[\s,]+', config):
if arch_str == 'auto':
result |= Architecture.auto_archs(platform=platform)
elif arch_str == 'native':
result.add(Architecture(platform_module.machine()))
elif arch_str == 'all':
result |= Architecture.all_archs(platform=platform)
else:
result.add(Architecture(arch_str))
return result
@staticmethod
def auto_archs(platform: PlatformName) -> 'Set[Architecture]':
native_architecture = Architecture(platform_module.machine())
result = {native_architecture}
if platform == 'linux' and native_architecture == Architecture.x86_64:
# x86_64 machines can run i686 docker containers
result.add(Architecture.i686)
if platform == 'windows' and native_architecture == Architecture.AMD64:
result.add(Architecture.x86)
return result
@staticmethod
def all_archs(platform: PlatformName) -> 'Set[Architecture]':
if platform == 'linux':
return {Architecture.x86_64, Architecture.i686, Architecture.aarch64, Architecture.ppc64le, Architecture.s390x}
elif platform == 'macos':
return {Architecture.x86_64}
elif platform == 'windows':
return {Architecture.x86, Architecture.AMD64}
else:
assert_never(platform)
class BuildOptions(NamedTuple): class BuildOptions(NamedTuple):
package_dir: Path package_dir: Path
output_dir: Path output_dir: Path
@@ -286,27 +228,3 @@ def detect_ci_provider() -> Optional[CIProvider]:
return CIProvider.other return CIProvider.other
else: else:
return None return None
PRETTY_NAMES = {'linux': 'Linux', 'macos': 'macOS', 'windows': 'Windows'}
def allowed_architectures_check(
platform: PlatformName,
options: BuildOptions,
) -> None:
allowed_architectures = Architecture.all_archs(platform)
msg = f'{PRETTY_NAMES[platform]} only supports {sorted(allowed_architectures)} at the moment.'
if platform != 'linux':
msg += ' If you want to set emulation architectures on Linux, use CIBW_ARCHS_LINUX instead.'
if not options.architectures <= allowed_architectures:
msg = f'Invalid archs option {options.architectures}. ' + msg
raise ValueError(msg)
if not options.architectures:
msg = 'Empty archs option set. ' + msg
raise ValueError(msg)
+1 -1
View File
@@ -9,11 +9,11 @@ from zipfile import ZipFile
import toml import toml
from .architecture import Architecture
from .environment import ParsedEnvironment from .environment import ParsedEnvironment
from .logger import log from .logger import log
from .typing import PathOrStr from .typing import PathOrStr
from .util import ( from .util import (
Architecture,
BuildOptions, BuildOptions,
BuildSelector, BuildSelector,
NonPlatformWheelError, NonPlatformWheelError,
+2 -2
View File
@@ -89,9 +89,9 @@ def test_archs_argument(platform, intercepted_build_args, monkeypatch, use_env_v
monkeypatch.setattr(sys, 'argv', sys.argv + ['--archs', 'ppc64le']) monkeypatch.setattr(sys, 'argv', sys.argv + ['--archs', 'ppc64le'])
if platform in {'macos', 'windows'}: if platform in {'macos', 'windows'}:
with pytest.raises(SystemExit) as err: with pytest.raises(SystemExit) as exit:
main() main()
assert err.value.args == (4,) assert exit.value.args == (4,)
else: else:
main() main()