diff --git a/.gitignore b/.gitignore index bf26a7624..ee089f1bc 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ __pycache__/ /compatible-tox-hack/compatible_tox_hack.egg-info/ /dist/ /docs/_static_dynamic/ +/pex/windows/stubs/ diff --git a/build-backend/pex_build/setuptools/build.py b/build-backend/pex_build/setuptools/build.py index ddf60f8bf..8c80e05ec 100644 --- a/build-backend/pex_build/setuptools/build.py +++ b/build-backend/pex_build/setuptools/build.py @@ -1,7 +1,7 @@ # Copyright 2024 Pex project contributors. # Licensed under the Apache License, Version 2.0 (see LICENSE). -from __future__ import absolute_import +from __future__ import absolute_import, print_function import hashlib import os.path @@ -15,8 +15,8 @@ # We re-export all setuptools' PEP-517 build backend hooks here for the build frontend to call. from setuptools.build_meta import * # NOQA -from pex import hashing, requirements -from pex.common import open_zip, temporary_dir +from pex import hashing, requirements, windows +from pex.common import open_zip, safe_copy, safe_mkdir, temporary_dir from pex.orderedset import OrderedSet from pex.pep_376 import Hash, InstalledFile, Record from pex.version import __version__ @@ -48,12 +48,33 @@ def build_wheel( wheel = setuptools.build_meta.build_wheel( wheel_directory, config_settings=config_settings, metadata_directory=metadata_directory ) # type: str - if pex_build.INCLUDE_DOCS: - wheel_path = os.path.join(wheel_directory, wheel) - with temporary_dir() as chroot: - with open_zip(wheel_path) as zip_fp: - zip_fp.extractall(chroot) + wheel_path = os.path.join(wheel_directory, wheel) + with temporary_dir() as chroot: + with open_zip(wheel_path) as zip_fp: + zip_fp.extractall(chroot) + + dist_info_dir = "pex-{version}.dist-info".format(version=__version__) + record_path = os.path.join(chroot, dist_info_dir, "RECORD") + with open(record_path) as fp: + installed_files = list(Record.read(fp)) + + for stub in windows.fetch_all_stubs(): + stub_relpath = os.path.relpath( + stub.path, os.path.dirname(os.path.dirname(os.path.dirname(windows.__file__))) + ) + stub_dst = os.path.join(chroot, stub_relpath) + safe_mkdir(os.path.dirname(stub_dst)) + safe_copy(stub.path, stub_dst) + installed_files.append( + InstalledFile( + path=stub_relpath, + hash=Hash.create(hashlib.sha256(stub.data)), + size=len(stub.data), + ) + ) + print("Embedded Windows script stub", stub.path, file=sys.stderr) + if pex_build.INCLUDE_DOCS: out_dir = os.path.join(chroot, "pex", "docs") subprocess.check_call( args=[ @@ -63,10 +84,6 @@ def build_wheel( out_dir, ] ) - dist_info_dir = "pex-{version}.dist-info".format(version=__version__) - record_path = os.path.join(chroot, dist_info_dir, "RECORD") - with open(record_path) as fp: - installed_files = list(Record.read(fp)) for root, _, files in os.walk(out_dir): for f in files: src = os.path.join(root, f) @@ -76,21 +93,22 @@ def build_wheel( installed_files.append( InstalledFile(path=dst, hash=Hash.create(hasher), size=os.path.getsize(src)) ) - Record.write(record_path, installed_files) - with open_zip(wheel_path, "w", compression=ZIP_DEFLATED) as zip_fp: - - def add_top_level_dir(name): - # type: (str) -> None - top = os.path.join(chroot, name) - zip_fp.write(top, name + "/") - for root, dirs, files in os.walk(top): - dirs[:] = sorted(dirs) - for path in sorted(files) + dirs: - src = os.path.join(root, path) - dst = os.path.relpath(src, chroot) - zip_fp.write(src, dst) - - add_top_level_dir("pex") - add_top_level_dir(dist_info_dir) + + Record.write(record_path, installed_files) + with open_zip(wheel_path, "w", compression=ZIP_DEFLATED) as zip_fp: + + def add_top_level_dir(name): + # type: (str) -> None + top = os.path.join(chroot, name) + zip_fp.write(top, name + "/") + for root, dirs, files in os.walk(top): + dirs[:] = sorted(dirs) + for path in sorted(files) + dirs: + src = os.path.join(root, path) + dst = os.path.relpath(src, chroot) + zip_fp.write(src, dst) + + add_top_level_dir("pex") + add_top_level_dir(dist_info_dir) return wheel diff --git a/pex/os.py b/pex/os.py index 1796d0a5b..4c96c93b9 100644 --- a/pex/os.py +++ b/pex/os.py @@ -6,15 +6,49 @@ import os import sys +from pex.enum import Enum from pex.typing import TYPE_CHECKING if TYPE_CHECKING: from typing import Any, List, NoReturn, Text, Tuple, Union + +class _CurrentOs(object): + def __get__(self, obj, objtype=None): + # type: (...) -> Os.Value + if not hasattr(self, "_current"): + # N.B.: Python 2.7 uses "linux2". + if sys.platform.startswith("linux"): + self._current = Os.LINUX + elif sys.platform == "darwin": + self._current = Os.MACOS + elif sys.platform == "win32": + self._current = Os.WINDOWS + if not hasattr(self, "_current"): + raise ValueError( + "The current operating system is not supported!: {system}".format( + system=sys.platform + ) + ) + return self._current + + +class Os(Enum["Os.Value"]): + class Value(Enum.Value): + pass + + LINUX = Value("linux") + MACOS = Value("macos") + WINDOWS = Value("windows") + CURRENT = _CurrentOs() + + +Os.seal() + # N.B.: Python 2.7 uses "linux2". -LINUX = sys.platform.startswith("linux") -MAC = sys.platform == "darwin" -WINDOWS = sys.platform == "win32" +LINUX = Os.CURRENT is Os.LINUX +MAC = Os.CURRENT is Os.MACOS +WINDOWS = Os.CURRENT is Os.WINDOWS HOME_ENV_VAR = "USERPROFILE" if WINDOWS else "HOME" diff --git a/pex/scie/__init__.py b/pex/scie/__init__.py index b128c5020..594fd85fe 100644 --- a/pex/scie/__init__.py +++ b/pex/scie/__init__.py @@ -23,11 +23,11 @@ ScieConfiguration, ScieInfo, ScieOptions, - SciePlatform, ScieStyle, Url, ) from pex.scie.science import SCIENCE_RELEASES_URL, SCIENCE_REQUIREMENT +from pex.sysconfig import SysPlatform from pex.typing import TYPE_CHECKING, cast from pex.variables import ENV, Variables @@ -40,7 +40,6 @@ "ScieConfiguration", "ScieInfo", "ScieOptions", - "SciePlatform", "ScieStyle", "build", "extract_options", @@ -162,11 +161,11 @@ def register_options(parser): dest="scie_platforms", default=[], action="append", - type=SciePlatform.parse, + type=SysPlatform.parse, choices=[ platform - for platform in SciePlatform.values() - if platform not in (SciePlatform.WINDOWS_AARCH64, SciePlatform.WINDOWS_X86_64) + for platform in SysPlatform.values() + if platform not in (SysPlatform.WINDOWS_AARCH64, SysPlatform.WINDOWS_X86_64) ], help=( "The platform to produce the native PEX scie executable for. Can be specified multiple " diff --git a/pex/scie/model.py b/pex/scie/model.py index 505dc0056..dabbc91ee 100644 --- a/pex/scie/model.py +++ b/pex/scie/model.py @@ -4,8 +4,6 @@ from __future__ import absolute_import import itertools -import os -import platform from collections import OrderedDict, defaultdict from pex.common import pluralize @@ -15,6 +13,7 @@ from pex.pep_503 import ProjectName from pex.pex import PEX from pex.platforms import PlatformSpec +from pex.sysconfig import SysPlatform from pex.targets import Targets from pex.third_party.packaging import tags # noqa from pex.typing import TYPE_CHECKING, cast @@ -230,89 +229,6 @@ class BusyBoxEntryPoints(object): ad_hoc_entry_points = attr.ib() # type: Tuple[NamedEntryPoint, ...] -class _CurrentPlatform(object): - def __get__(self, obj, objtype=None): - # type: (...) -> SciePlatform.Value - if not hasattr(self, "_current"): - system = platform.system().lower() - machine = platform.machine().lower() - if "linux" == system: - if machine in ("aarch64", "arm64"): - self._current = SciePlatform.LINUX_AARCH64 - elif machine in ("armv7l", "armv8l"): - self._current = SciePlatform.LINUX_ARMV7L - elif machine == "ppc64le": - self._current = SciePlatform.LINUX_PPC64LE - elif machine == "s390x": - self._current = SciePlatform.LINUX_S390X - elif machine in ("amd64", "x86_64"): - self._current = SciePlatform.LINUX_X86_64 - elif "darwin" == system: - if machine in ("aarch64", "arm64"): - self._current = SciePlatform.MACOS_AARCH64 - elif machine in ("amd64", "x86_64"): - self._current = SciePlatform.MACOS_X86_64 - elif "windows" == system: - if machine in ("aarch64", "arm64"): - self._current = SciePlatform.WINDOWS_AARCH64 - elif machine in ("amd64", "x86_64"): - self._current = SciePlatform.WINDOWS_X86_64 - if not hasattr(self, "_current"): - raise ValueError( - "The current operating system / machine pair is not supported!: " - "{system} / {machine}".format(system=system, machine=machine) - ) - return self._current - - -class SciePlatform(Enum["SciePlatform.Value"]): - class Value(Enum.Value): - @property - def extension(self): - # type: () -> str - return ( - ".exe" - if self in (SciePlatform.WINDOWS_AARCH64, SciePlatform.WINDOWS_X86_64) - else "" - ) - - def binary_name(self, binary_name): - # type: (str) -> str - return "{binary_name}{extension}".format( - binary_name=binary_name, extension=self.extension - ) - - def qualified_binary_name(self, binary_name): - # type: (str) -> str - return "{binary_name}-{platform}{extension}".format( - binary_name=binary_name, platform=self, extension=self.extension - ) - - def qualified_file_name(self, file_name): - # type: (str) -> str - stem, ext = os.path.splitext(file_name) - return "{stem}-{platform}{ext}".format(stem=stem, platform=self, ext=ext) - - LINUX_AARCH64 = Value("linux-aarch64") - LINUX_ARMV7L = Value("linux-armv7l") - LINUX_PPC64LE = Value("linux-powerpc64") - LINUX_S390X = Value("linux-s390x") - LINUX_X86_64 = Value("linux-x86_64") - MACOS_AARCH64 = Value("macos-aarch64") - MACOS_X86_64 = Value("macos-x86_64") - WINDOWS_AARCH64 = Value("windows-aarch64") - WINDOWS_X86_64 = Value("windows-x86_64") - CURRENT = _CurrentPlatform() - - @classmethod - def parse(cls, value): - # type: (str) -> SciePlatform.Value - return cls.CURRENT if "current" == value else cls.for_value(value) - - -SciePlatform.seal() - - class Provider(Enum["Provider.Value"]): class Value(Enum.Value): pass @@ -327,7 +243,7 @@ class Value(Enum.Value): @attr.s(frozen=True) class InterpreterDistribution(object): provider = attr.ib() # type: Provider.Value - platform = attr.ib() # type: SciePlatform.Value + platform = attr.ib() # type: SysPlatform.Value version = attr.ib() # type: Union[Tuple[int, int], Tuple[int, int, int]] release = attr.ib(default=None) # type: Optional[str] @@ -357,7 +273,7 @@ class ScieInfo(object): @property def platform(self): - # type: () -> SciePlatform.Value + # type: () -> SysPlatform.Value return self.interpreter.platform @property @@ -381,7 +297,7 @@ class ScieOptions(object): scie_only = attr.ib(default=False) # type: bool busybox_entrypoints = attr.ib(default=None) # type: Optional[BusyBoxEntryPoints] busybox_pex_entrypoint_env_passthrough = attr.ib(default=False) # type: bool - platforms = attr.ib(default=()) # type: Tuple[SciePlatform.Value, ...] + platforms = attr.ib(default=()) # type: Tuple[SysPlatform.Value, ...] pbs_release = attr.ib(default=None) # type: Optional[str] pypy_release = attr.ib(default=None) # type: Optional[str] python_version = attr.ib( @@ -433,7 +349,7 @@ def _from_platform_specs( python_version = options.python_version python_versions_by_platform = defaultdict( set - ) # type: DefaultDict[SciePlatform.Value, Set[Union[Tuple[int, int], Tuple[int, int, int]]]] + ) # type: DefaultDict[SysPlatform.Value, Set[Union[Tuple[int, int], Tuple[int, int, int]]]] for platform_spec in platform_specs: if python_version: plat_python_version = python_version @@ -459,22 +375,22 @@ def _from_platform_specs( if "linux" in platform_str: if is_aarch64: - scie_platform = SciePlatform.LINUX_AARCH64 + scie_platform = SysPlatform.LINUX_AARCH64 elif is_armv7l: - scie_platform = SciePlatform.LINUX_ARMV7L + scie_platform = SysPlatform.LINUX_ARMV7L elif is_ppc64le: - scie_platform = SciePlatform.LINUX_PPC64LE + scie_platform = SysPlatform.LINUX_PPC64LE elif is_s390x: - scie_platform = SciePlatform.LINUX_S390X + scie_platform = SysPlatform.LINUX_S390X else: - scie_platform = SciePlatform.LINUX_X86_64 + scie_platform = SysPlatform.LINUX_X86_64 elif "mac" in platform_str: scie_platform = ( - SciePlatform.MACOS_AARCH64 if is_aarch64 else SciePlatform.MACOS_X86_64 + SysPlatform.MACOS_AARCH64 if is_aarch64 else SysPlatform.MACOS_X86_64 ) elif "win" in platform_str: scie_platform = ( - SciePlatform.WINDOWS_AARCH64 if is_aarch64 else SciePlatform.WINDOWS_X86_64 + SysPlatform.WINDOWS_AARCH64 if is_aarch64 else SysPlatform.WINDOWS_X86_64 ) else: continue @@ -488,17 +404,17 @@ def _from_platform_specs( # PyPy distributions for Linux aarch64 start with 3.7 (and PyPy always releases for # 2.7). if ( - SciePlatform.LINUX_AARCH64 is scie_platform + SysPlatform.LINUX_AARCH64 is scie_platform and plat_python_version[0] == 3 and plat_python_version < (3, 7) ): continue # PyPy distributions are not available for Linux armv7l - if SciePlatform.LINUX_ARMV7L is scie_platform: + if SysPlatform.LINUX_ARMV7L is scie_platform: continue # PyPy distributions for Linux ppc64le are only available for 2.7 and 3.{5,6}. if ( - SciePlatform.LINUX_PPC64LE is scie_platform + SysPlatform.LINUX_PPC64LE is scie_platform and plat_python_version[0] == 3 and plat_python_version >= (3, 7) ): @@ -506,7 +422,7 @@ def _from_platform_specs( # PyPy distributions for Mac arm64 start with 3.8 (and PyPy always releases for # 2.7). if ( - SciePlatform.MACOS_AARCH64 is scie_platform + SysPlatform.MACOS_AARCH64 is scie_platform and plat_python_version[0] == 3 and plat_python_version < (3, 8) ): diff --git a/pex/scie/science.py b/pex/scie/science.py index 5541950cf..14f73916b 100644 --- a/pex/scie/science.py +++ b/pex/scie/science.py @@ -32,10 +32,10 @@ Provider, ScieConfiguration, ScieInfo, - SciePlatform, ScieStyle, Url, ) +from pex.sysconfig import SysPlatform from pex.third_party.packaging.specifiers import SpecifierSet from pex.third_party.packaging.version import InvalidVersion from pex.tracer import TRACER @@ -75,7 +75,7 @@ def _science_binary_url(suffix=""): return "{science_releases_url}/download/v{version}/{binary}{suffix}".format( science_releases_url=SCIENCE_RELEASES_URL, version=MIN_SCIENCE_VERSION.raw, - binary=SciePlatform.CURRENT.qualified_binary_name("science-fat"), + binary=SysPlatform.CURRENT.qualified_binary_name("science-fat"), suffix=suffix, ) @@ -290,10 +290,10 @@ def _science_dir( def _science_binary_names(): # type: () -> Iterator[str] - yield SciePlatform.CURRENT.binary_name("science-fat") - yield SciePlatform.CURRENT.qualified_binary_name("science-fat") - yield SciePlatform.CURRENT.binary_name("science") - yield SciePlatform.CURRENT.qualified_binary_name("science") + yield SysPlatform.CURRENT.binary_name("science-fat") + yield SysPlatform.CURRENT.qualified_binary_name("science-fat") + yield SysPlatform.CURRENT.binary_name("science") + yield SysPlatform.CURRENT.qualified_binary_name("science") def _is_compatible_science_binary( diff --git a/pex/sysconfig.py b/pex/sysconfig.py index 0cb72dfdd..152ffce01 100644 --- a/pex/sysconfig.py +++ b/pex/sysconfig.py @@ -3,10 +3,17 @@ from __future__ import absolute_import +import os import os.path +import platform from sysconfig import get_config_var -from pex.os import WINDOWS +from pex.enum import Enum +from pex.os import WINDOWS, Os +from pex.typing import TYPE_CHECKING + +if TYPE_CHECKING: + from typing import Text, TypeVar EXE_EXTENSION = get_config_var("EXE") or "" EXE_EXTENSIONS = ( @@ -16,8 +23,12 @@ ) +if TYPE_CHECKING: + _Text = TypeVar("_Text", str, Text) + + def script_name(name): - # type: (str) -> str + # type: (_Text) -> _Text if not EXE_EXTENSION: return name stem, ext = os.path.splitext(name) @@ -28,3 +39,92 @@ def script_name(name): # with either sysconfig.get_config_vars() or Formatter().parse() to pick apart the script dir # suffix from any base dir template. SCRIPT_DIR = "Scripts" if WINDOWS else "bin" + + +class _CurrentPlatform(object): + def __get__(self, obj, objtype=None): + # type: (...) -> SysPlatform.Value + if not hasattr(self, "_current"): + machine = platform.machine().lower() + if Os.CURRENT is Os.LINUX: + if machine in ("aarch64", "arm64"): + self._current = SysPlatform.LINUX_AARCH64 + elif machine in ("armv7l", "armv8l"): + self._current = SysPlatform.LINUX_ARMV7L + elif machine == "ppc64le": + self._current = SysPlatform.LINUX_PPC64LE + elif machine == "s390x": + self._current = SysPlatform.LINUX_S390X + elif machine in ("amd64", "x86_64"): + self._current = SysPlatform.LINUX_X86_64 + if Os.CURRENT is Os.MACOS: + if machine in ("aarch64", "arm64"): + self._current = SysPlatform.MACOS_AARCH64 + elif machine in ("amd64", "x86_64"): + self._current = SysPlatform.MACOS_X86_64 + if Os.CURRENT is Os.WINDOWS: + if machine in ("aarch64", "arm64"): + self._current = SysPlatform.WINDOWS_AARCH64 + elif machine in ("amd64", "x86_64"): + self._current = SysPlatform.WINDOWS_X86_64 + if not hasattr(self, "_current"): + raise ValueError( + "The current operating system / machine pair is not supported!: " + "{system} / {machine}".format(system=Os.CURRENT, machine=machine) + ) + return self._current + + +class _PlatformValue(Enum.Value): + def __init__( + self, + os_type, # type: Os.Value + arch, + ): + super(_PlatformValue, self).__init__("{os}-{arch}".format(os=os_type, arch=arch)) + self.os = os_type + self.arch = arch + + @property + def extension(self): + # type: () -> str + return ".exe" if self.os is Os.WINDOWS else "" + + def binary_name(self, binary_name): + # type: (_Text) -> _Text + return "{binary_name}{extension}".format(binary_name=binary_name, extension=self.extension) + + def qualified_binary_name(self, binary_name): + # type: (_Text) -> _Text + return "{binary_name}-{platform}{extension}".format( + binary_name=binary_name, platform=self, extension=self.extension + ) + + def qualified_file_name(self, file_name): + # type: (_Text) -> _Text + stem, ext = os.path.splitext(file_name) + return "{stem}-{platform}{ext}".format(stem=stem, platform=self, ext=ext) + + +class SysPlatform(Enum["SysPlatform.Value"]): + class Value(_PlatformValue): + pass + + LINUX_AARCH64 = Value(Os.LINUX, "aarch64") + LINUX_ARMV7L = Value(Os.LINUX, "armv7l") + LINUX_PPC64LE = Value(Os.LINUX, "powerpc64") + LINUX_S390X = Value(Os.LINUX, "s390x") + LINUX_X86_64 = Value(Os.LINUX, "x86_64") + MACOS_AARCH64 = Value(Os.MACOS, "aarch64") + MACOS_X86_64 = Value(Os.MACOS, "x86_64") + WINDOWS_AARCH64 = Value(Os.WINDOWS, "aarch64") + WINDOWS_X86_64 = Value(Os.WINDOWS, "x86_64") + CURRENT = _CurrentPlatform() + + @classmethod + def parse(cls, value): + # type: (str) -> SysPlatform.Value + return cls.CURRENT if "current" == value else cls.for_value(value) + + +SysPlatform.seal() diff --git a/pex/windows/__init__.py b/pex/windows/__init__.py new file mode 100644 index 000000000..c679168fa --- /dev/null +++ b/pex/windows/__init__.py @@ -0,0 +1,111 @@ +# Copyright 2025 Pex project contributors. +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import absolute_import + +import contextlib +import os.path +import struct +import uuid +import zipfile +from typing import Iterator, Optional + +from pex.common import safe_open +from pex.fetcher import URLFetcher +from pex.fs import safe_rename +from pex.os import Os +from pex.sysconfig import SysPlatform +from pex.typing import TYPE_CHECKING + +if TYPE_CHECKING: + from typing import Text + + import attr # vendor:skip +else: + from pex.third_party import attr + + +def _stub_name( + platform=SysPlatform.CURRENT, # type: SysPlatform.Value + gui=False, # type: bool +): + # type: (...) -> str + + if platform.os is not Os.WINDOWS: + raise ValueError( + "Script stubs are only available for Windows platforms; given: {platform}".format( + platform=platform + ) + ) + + return platform.binary_name( + "uv-trampoline-{arch}-{type}".format(arch=platform.arch, type="gui" if gui else "console") + ) + + +_TRAMPOLINE_VERSION = "0.5.29" + + +def _fetch_stub(stub_name): + # type: (str) -> bytes + with URLFetcher().get_body_stream( + "https://raw.githubusercontent.com/astral-sh/uv/refs/tags/{version}/crates/uv-trampoline/" + "trampolines/{stub_name}".format(version=_TRAMPOLINE_VERSION, stub_name=stub_name) + ) as in_fp: + return in_fp.read() + + +@attr.s(frozen=True) +class Stub(object): + path = attr.ib() # type: str + data = attr.ib() # type: bytes + + +def _load_stub( + platform=SysPlatform.CURRENT, # type: SysPlatform.Value + gui=False, # type: bool +): + # type: (...) -> Stub + + stub_name = _stub_name(platform=platform, gui=gui) + stub_dst = os.path.join(os.path.dirname(__file__), "stubs", stub_name) + if os.path.exists(stub_dst): + with open(stub_dst, "rb") as fp: + return Stub(path=stub_dst, data=fp.read()) + + stub = _fetch_stub(stub_name) + with safe_open( + "{stub_dst}.{unique}".format(stub_dst=stub_dst, unique=uuid.uuid4().hex), "wb" + ) as out_fp: + out_fp.write(stub) + safe_rename(out_fp.name, stub_dst) + return Stub(path=stub_dst, data=stub) + + +def fetch_all_stubs(): + # type: () -> Iterator[Stub] + for platform in (SysPlatform.WINDOWS_AARCH64, SysPlatform.WINDOWS_X86_64): + for gui in (True, False): + yield _load_stub(platform=platform, gui=gui) + + +def create_script( + path, # type: Text + contents, # type: Text + platform=SysPlatform.CURRENT, # type: SysPlatform.Value + gui=False, # type: bool + python_path=None, # type: Optional[Text] +): + # type: (...) -> None + + with open("{path}.{unique}".format(path=path, unique=uuid.uuid4().hex), "wb") as fp: + fp.write(_load_stub(platform=platform, gui=gui).data) + with contextlib.closing(zipfile.ZipFile(fp, "a")) as zip_fp: + zip_fp.writestr("__main__.py", contents.encode("utf-8"), zipfile.ZIP_STORED) + python_path_bytes = platform.binary_name( + python_path or ("pythonw" if gui else "python") + ).encode("utf-8") + fp.write(python_path_bytes) + fp.write(struct.pack("= (3, 7) - elif SciePlatform.MACOS_AARCH64 is SciePlatform.CURRENT: + elif SysPlatform.MACOS_AARCH64 is SysPlatform.CURRENT: return PY_VER >= (3, 8) else: return PY_VER >= (3, 6) diff --git a/tests/integration/scie/test_discussion_2516.py b/tests/integration/scie/test_discussion_2516.py index 691153154..23b783d81 100644 --- a/tests/integration/scie/test_discussion_2516.py +++ b/tests/integration/scie/test_discussion_2516.py @@ -9,7 +9,7 @@ from textwrap import dedent from pex.common import safe_open -from pex.scie import SciePlatform +from pex.sysconfig import SysPlatform from pex.typing import TYPE_CHECKING from testing import make_env, run_pex_command @@ -97,7 +97,7 @@ def main() -> None: os.path.join(str(tmpdir), "ardia*") ), "We expected no PEX or scie leaked in the CWD." - native_scie = os.path.join(out_dir, SciePlatform.CURRENT.value, "ardia") + native_scie = os.path.join(out_dir, SysPlatform.CURRENT.value, "ardia") output = subprocess.check_output( args=[native_scie, "Tux", "says", "Moo?"], env=make_env(PATH=None) ).decode("utf-8") diff --git a/tests/integration/scie/test_pex_scie.py b/tests/integration/scie/test_pex_scie.py index 826e9c59e..c608111e6 100644 --- a/tests/integration/scie/test_pex_scie.py +++ b/tests/integration/scie/test_pex_scie.py @@ -22,7 +22,8 @@ from pex.layout import Layout from pex.orderedset import OrderedSet from pex.os import is_exe -from pex.scie import SciePlatform, ScieStyle +from pex.scie import ScieStyle +from pex.sysconfig import SysPlatform from pex.targets import LocalInterpreter from pex.typing import TYPE_CHECKING from pex.version import __version__ @@ -179,19 +180,19 @@ def create_scies( ).assert_success() python_version_by_platform = { - SciePlatform.LINUX_AARCH64: "3.9", - SciePlatform.LINUX_ARMV7L: "3.11", - SciePlatform.LINUX_PPC64LE: "3.12", - SciePlatform.LINUX_S390X: "3.13", - SciePlatform.LINUX_X86_64: "3.10", - SciePlatform.MACOS_AARCH64: "3.11", - SciePlatform.MACOS_X86_64: "3.12", + SysPlatform.LINUX_AARCH64: "3.9", + SysPlatform.LINUX_ARMV7L: "3.11", + SysPlatform.LINUX_PPC64LE: "3.12", + SysPlatform.LINUX_S390X: "3.13", + SysPlatform.LINUX_X86_64: "3.10", + SysPlatform.MACOS_AARCH64: "3.11", + SysPlatform.MACOS_X86_64: "3.12", } - assert SciePlatform.CURRENT in python_version_by_platform + assert SysPlatform.CURRENT in python_version_by_platform def assert_platforms( output_dir, # type: str - expected_platforms, # type: Iterable[SciePlatform.Value] + expected_platforms, # type: Iterable[SysPlatform.Value] ): # type: (...) -> None @@ -209,7 +210,7 @@ def assert_platforms( assert is_exe(scie), "Expected --scie build to produce a {binary} binary.".format( binary=binary ) - if platform is SciePlatform.CURRENT: + if platform is SysPlatform.CURRENT: assert b"| PEX-scie wabbit! |" in subprocess.check_output( args=[scie, "PEX-scie wabbit!"], env=make_env(PATH=None) ) @@ -238,13 +239,13 @@ def assert_platforms( assert_platforms( output_dir=all_platforms_output_dir, expected_platforms=( - SciePlatform.LINUX_AARCH64, - SciePlatform.LINUX_ARMV7L, - SciePlatform.LINUX_PPC64LE, - SciePlatform.LINUX_S390X, - SciePlatform.LINUX_X86_64, - SciePlatform.MACOS_AARCH64, - SciePlatform.MACOS_X86_64, + SysPlatform.LINUX_AARCH64, + SysPlatform.LINUX_ARMV7L, + SysPlatform.LINUX_PPC64LE, + SysPlatform.LINUX_S390X, + SysPlatform.LINUX_X86_64, + SysPlatform.MACOS_AARCH64, + SysPlatform.MACOS_X86_64, ), ) @@ -257,17 +258,17 @@ def assert_platforms( "--scie-platform", "current", "--scie-platform", - str(SciePlatform.LINUX_AARCH64), + str(SysPlatform.LINUX_AARCH64), "--scie-platform", - str(SciePlatform.LINUX_X86_64), + str(SysPlatform.LINUX_X86_64), ], ) assert_platforms( output_dir=restricted_platforms_output_dir, expected_platforms=( - SciePlatform.CURRENT, - SciePlatform.LINUX_AARCH64, - SciePlatform.LINUX_X86_64, + SysPlatform.CURRENT, + SysPlatform.LINUX_AARCH64, + SysPlatform.LINUX_X86_64, ), ) @@ -313,7 +314,7 @@ def test_specified_science_binary(tmpdir): local_science_binary = os.path.join(str(tmpdir), "science") with open(local_science_binary, "wb") as write_fp, URLFetcher().get_body_stream( "https://github.com/a-scie/lift/releases/download/v0.10.1/{binary}".format( - binary=SciePlatform.CURRENT.qualified_binary_name("science") + binary=SysPlatform.CURRENT.qualified_binary_name("science") ) ) as read_fp: shutil.copyfileobj(read_fp, write_fp) @@ -427,19 +428,19 @@ def make_20240415_3_10_14_url(platform): ) expected_platform = None # type: Optional[str] - if SciePlatform.CURRENT is SciePlatform.LINUX_AARCH64: + if SysPlatform.CURRENT is SysPlatform.LINUX_AARCH64: expected_platform = "aarch64-unknown-linux-gnu" - elif SciePlatform.CURRENT is SciePlatform.LINUX_ARMV7L: + elif SysPlatform.CURRENT is SysPlatform.LINUX_ARMV7L: expected_platform = "armv7-unknown-linux-gnueabihf" - elif SciePlatform.CURRENT is SciePlatform.LINUX_PPC64LE: + elif SysPlatform.CURRENT is SysPlatform.LINUX_PPC64LE: expected_platform = "ppc64le-unknown-linux-gnu" - elif SciePlatform.CURRENT is SciePlatform.LINUX_S390X: + elif SysPlatform.CURRENT is SysPlatform.LINUX_S390X: expected_platform = "s390x-unknown-linux-gnu" - elif SciePlatform.CURRENT is SciePlatform.LINUX_X86_64: + elif SysPlatform.CURRENT is SysPlatform.LINUX_X86_64: expected_platform = "x86_64-unknown-linux-gnu" - elif SciePlatform.CURRENT is SciePlatform.MACOS_AARCH64: + elif SysPlatform.CURRENT is SysPlatform.MACOS_AARCH64: expected_platform = "aarch64-apple-darwin" - elif SciePlatform.CURRENT is SciePlatform.MACOS_X86_64: + elif SysPlatform.CURRENT is SysPlatform.MACOS_X86_64: expected_platform = "x86_64-apple-darwin" assert expected_platform is not None @@ -1118,7 +1119,7 @@ def test_scie_name_style_platform_file_suffix(tmpdir): run_pex_command( args=["--scie", "lazy", "--scie-name-style", "platform-file-suffix", "-o", output_file] ).assert_success() - assert sorted(["app", SciePlatform.CURRENT.qualified_binary_name("app")]) == sorted( + assert sorted(["app", SysPlatform.CURRENT.qualified_binary_name("app")]) == sorted( os.listdir(dist_dir) ) @@ -1128,7 +1129,7 @@ def test_scie_name_style_platform_parent_dir(tmpdir): # type: (Any) -> None foreign_platform = next( - plat for plat in SciePlatform.values() if SciePlatform.CURRENT is not plat + plat for plat in SysPlatform.values() if SysPlatform.CURRENT is not plat ) dist_dir = os.path.join(str(tmpdir), "dist") output_file = os.path.join(dist_dir, "app")