relenv 0.21.2__py3-none-any.whl → 0.22.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. relenv/__init__.py +14 -2
  2. relenv/__main__.py +12 -6
  3. relenv/_resources/xz/config.h +148 -0
  4. relenv/_resources/xz/readme.md +4 -0
  5. relenv/build/__init__.py +28 -30
  6. relenv/build/common/__init__.py +50 -0
  7. relenv/build/common/_sysconfigdata_template.py +72 -0
  8. relenv/build/common/builder.py +907 -0
  9. relenv/build/common/builders.py +163 -0
  10. relenv/build/common/download.py +324 -0
  11. relenv/build/common/install.py +609 -0
  12. relenv/build/common/ui.py +432 -0
  13. relenv/build/darwin.py +128 -14
  14. relenv/build/linux.py +292 -74
  15. relenv/build/windows.py +123 -169
  16. relenv/buildenv.py +48 -17
  17. relenv/check.py +10 -5
  18. relenv/common.py +489 -165
  19. relenv/create.py +147 -7
  20. relenv/fetch.py +16 -4
  21. relenv/manifest.py +15 -7
  22. relenv/python-versions.json +329 -0
  23. relenv/pyversions.py +817 -30
  24. relenv/relocate.py +101 -55
  25. relenv/runtime.py +452 -282
  26. relenv/toolchain.py +9 -3
  27. {relenv-0.21.2.dist-info → relenv-0.22.0.dist-info}/METADATA +1 -1
  28. relenv-0.22.0.dist-info/RECORD +48 -0
  29. tests/__init__.py +2 -0
  30. tests/_pytest_typing.py +45 -0
  31. tests/conftest.py +42 -36
  32. tests/test_build.py +426 -9
  33. tests/test_common.py +311 -48
  34. tests/test_create.py +149 -6
  35. tests/test_downloads.py +19 -15
  36. tests/test_fips_photon.py +6 -3
  37. tests/test_module_imports.py +44 -0
  38. tests/test_pyversions_runtime.py +177 -0
  39. tests/test_relocate.py +45 -39
  40. tests/test_relocate_module.py +257 -0
  41. tests/test_runtime.py +1802 -6
  42. tests/test_verify_build.py +477 -34
  43. relenv/build/common.py +0 -1707
  44. relenv-0.21.2.dist-info/RECORD +0 -35
  45. {relenv-0.21.2.dist-info → relenv-0.22.0.dist-info}/WHEEL +0 -0
  46. {relenv-0.21.2.dist-info → relenv-0.22.0.dist-info}/entry_points.txt +0 -0
  47. {relenv-0.21.2.dist-info → relenv-0.22.0.dist-info}/licenses/LICENSE.md +0 -0
  48. {relenv-0.21.2.dist-info → relenv-0.22.0.dist-info}/licenses/NOTICE +0 -0
  49. {relenv-0.21.2.dist-info → relenv-0.22.0.dist-info}/top_level.txt +0 -0
relenv/toolchain.py CHANGED
@@ -1,12 +1,18 @@
1
1
  # Copyright 2022-2025 Broadcom.
2
- # SPDX-License-Identifier: Apache-2
2
+ # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  The ``relenv toolchain`` command.
5
5
  """
6
+
7
+ from __future__ import annotations
8
+
9
+ import argparse
6
10
  import sys
7
11
 
8
12
 
9
- def setup_parser(subparsers):
13
+ def setup_parser(
14
+ subparsers: argparse._SubParsersAction[argparse.ArgumentParser],
15
+ ) -> None:
10
16
  """
11
17
  Setup the subparser for the ``toolchain`` command.
12
18
 
@@ -17,7 +23,7 @@ def setup_parser(subparsers):
17
23
  subparser.set_defaults(func=main)
18
24
 
19
25
 
20
- def main(*args, **kwargs):
26
+ def main(*args: object, **kwargs: object) -> None:
21
27
  """
22
28
  Notify users of toolchain command deprecation.
23
29
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: relenv
3
- Version: 0.21.2
3
+ Version: 0.22.0
4
4
  Project-URL: Source Code, https://github.com/saltstack/relative-environment-for-python
5
5
  Project-URL: Documentation, https://relenv.readthedocs.io/en/latest/
6
6
  Project-URL: Changelog, https://relenv.readthedocs.io/en/latest/changelog.html
@@ -0,0 +1,48 @@
1
+ relenv/__init__.py,sha256=JGbn7yb2-o9LBupMRzj1RYcvMWC6eB8yJv76NHCM0-w,325
2
+ relenv/__main__.py,sha256=6N3x5KYX02c2xLWvvtmmLjpcG5Oi2yt9DvP0UW4srM8,1538
3
+ relenv/buildenv.py,sha256=MioqMak_bjA5lhKUU8NDyJOFvjv7MoGY2S7PJld-vyA,4120
4
+ relenv/check.py,sha256=KnYu60lKud9bwAyUKEzSn5MNBHpA6e3D_pGe_Toml70,1133
5
+ relenv/common.py,sha256=vmQjI3g99hqdZ-9zpzWl_xn7L7V5W1FkgA3aQysbVgk,35731
6
+ relenv/create.py,sha256=8Pxqc5rrOER8iWiOMFwA6b0oG7il6fICyjhGh4h2uw0,8383
7
+ relenv/fetch.py,sha256=6kIla7zOV43r-1NAXzOg4TFGH6z0vPOcF99SkneGSPA,2567
8
+ relenv/manifest.py,sha256=W2QTjPsDHlm4OLUpL1bwIGvlNpJijhh1LDYidqCm538,1057
9
+ relenv/python-versions.json,sha256=ZuNUnq1uEYH7c-KYivsQAIeK1l1Z7dZTcVoBD-N9BV0,14694
10
+ relenv/pyversions.py,sha256=8SnFqHdtb0Lrp4JH7Ri6h-YHJngroh8SOL1chHn3GjY,41276
11
+ relenv/relocate.py,sha256=Xfmr1lTMu7DwB8SdMIYQFFfC5La5je8Z33G4md557ew,13182
12
+ relenv/runtime.py,sha256=9lrQ2MZqSe2UE0oSsLfyPpMwtubcKbdVwdzOhmVOZsc,39844
13
+ relenv/toolchain.py,sha256=wRRtgDfkOsvY6N1wQQWf7cc7SRXaFBsO_gxIK8mfjOM,929
14
+ relenv/_resources/xz/config.h,sha256=2IofvMqyAa8xBaQb6QGStiUugMmjyUCq_Of5drh7fro,4117
15
+ relenv/_resources/xz/readme.md,sha256=aOs7hz9RhTnTwHUt6gbO-2Sl0xLKIJp8-w6Du4VIFgY,258
16
+ relenv/_scripts/install_vc_build.ps1,sha256=ir1bcz7rNOuFw4E5_AqBidiKS0SpPViXW7zaanRPCoM,7629
17
+ relenv/build/__init__.py,sha256=Wfs38kXJTKJodtWLAvAUeEOrVnu0ss-krzv2ICM7XnI,6341
18
+ relenv/build/darwin.py,sha256=OvsTmpKq87WILxkmjP0aDdUv8lh3DadJ5MwRqPyXXK0,7131
19
+ relenv/build/linux.py,sha256=S5v4jp4_nCYN3H5h_fel-VbjQcuY_XfZqBeFWdS6qjo,26156
20
+ relenv/build/windows.py,sha256=b1hxd8NmmbvblB8W7-qu_b1_TdMQBNl3Vee-C-edUHc,16102
21
+ relenv/build/common/__init__.py,sha256=YzSyjBpW6StrbiQ4Q0CCT4Iaj-wok2ZtuaHW4cCheDE,1004
22
+ relenv/build/common/_sysconfigdata_template.py,sha256=six70jAkN_4eBP4aKrJhABu9hXMxudUE6ccNQbQT-J8,1955
23
+ relenv/build/common/builder.py,sha256=RaRlWMeShYRcTvT47ry135cpeqhEJ_lMwHZeMtZCuGM,31000
24
+ relenv/build/common/builders.py,sha256=sEwJu9HApcPwp2nSrDHvX42Jc8W3dqRqo4Kt9D2mNdo,4772
25
+ relenv/build/common/download.py,sha256=jHuIrc5jhDGoa4lWGMYdrO6FsYxJvmiuTVhjDzs7ogc,10479
26
+ relenv/build/common/install.py,sha256=1s8cl2GV8yauGAIyAqsOvAWZEorWPPI_hrHkk3Oy9_4,19201
27
+ relenv/build/common/ui.py,sha256=j14BE0uFqa5u8XoSBfphSW38XSwboi4StMJ81gLgkkQ,14192
28
+ relenv-0.22.0.dist-info/licenses/LICENSE.md,sha256=T0SRk3vJM1YcAJjDz9vsX9gsCRatAVSBS7LeU0tklRM,9919
29
+ relenv-0.22.0.dist-info/licenses/NOTICE,sha256=Ns0AybPHBsgJKJJfjE6YnGgWEQQ9F7lQ6QNlYLlQT3E,548
30
+ tests/__init__.py,sha256=PFmZ0Etkh3YyYMcTEuVClZE9LTIC_7LYZQ-U6TpFO-g,70
31
+ tests/_pytest_typing.py,sha256=aTeDhNtOJCKhwkZ-BP560Zi4Jkac_Ylv1RimBpNGtMA,1204
32
+ tests/conftest.py,sha256=inPHwb4duz33BzIxfPoH3z3PK_dbMCbtytUZU785NPk,2628
33
+ tests/test_build.py,sha256=48-4ZWdDk8oCHiWcGhhWoPwyqOhZNrSfXrEsXZuhfmw,14992
34
+ tests/test_common.py,sha256=n2JDIvJWvu_EjFt-S7kN-zv7hVfpPAc2jnP97TyUm4E,15824
35
+ tests/test_create.py,sha256=rjJ7mvInJXqn0r3a5D_q6zzftR4pkzI7M-ipkR5qD9U,6849
36
+ tests/test_downloads.py,sha256=OJViW_atWbQiAUhHImIp4dU7U4hNoJQVDEFD-0hSHx8,3528
37
+ tests/test_fips_photon.py,sha256=LD6a3jUmMmNrERoDPYgW63ts1Dy48aMr4eZpzkGcixE,1397
38
+ tests/test_module_imports.py,sha256=RhwPeUvdKLvuFcZSxCt2WCu81SKTjykaunrrN1sORpw,1354
39
+ tests/test_pyversions_runtime.py,sha256=utmG3CLP061AIbAqRE0n6mVqsQ2DCZDc54LUz3SOQts,5980
40
+ tests/test_relocate.py,sha256=TAYARIL5VRCEPwz1HL1BJpvUSS6RQkk4D0DqGag7rv4,9694
41
+ tests/test_relocate_module.py,sha256=G_KQqR5d7y7WCru_c2fPZKplhtzKgAJX9QONEQmzUAI,7802
42
+ tests/test_runtime.py,sha256=Ih7KquGZjWjBHot21kbYqQaaeRYHId-qwdNKVp_9bgo,65809
43
+ tests/test_verify_build.py,sha256=G4HsBbtHCYgBGX1KFKbm3_cskJZcQT6m4hBfZOeltig,67750
44
+ relenv-0.22.0.dist-info/METADATA,sha256=E8RjqcMC4CJDuvwPiLVWoY1-xi9Vq_xQ_4CGSjxrXfk,1360
45
+ relenv-0.22.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
46
+ relenv-0.22.0.dist-info/entry_points.txt,sha256=dO66nWPPWl8ALWWnZFlHKAo6mfPFuQid7purYWL2ddc,48
47
+ relenv-0.22.0.dist-info/top_level.txt,sha256=P4Ro6JLZE53ZdsQ76o2OzBcpb0MaVJmbfr0HAn9WF8M,13
48
+ relenv-0.22.0.dist-info/RECORD,,
tests/__init__.py CHANGED
@@ -0,0 +1,2 @@
1
+ # Copyright 2022-2025 Broadcom.
2
+ # SPDX-License-Identifier: Apache-2.0
@@ -0,0 +1,45 @@
1
+ # Copyright 2022-2025 Broadcom.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """
4
+ Typed helper wrappers for common pytest decorators so mypy understands them.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ from typing import Any, Callable, Iterable, Sequence, TypeVar, cast
9
+
10
+ import pytest
11
+
12
+ F = TypeVar("F", bound=Callable[..., object])
13
+
14
+
15
+ def fixture(*args: Any, **kwargs: Any) -> Callable[[F], F] | F:
16
+ if args and callable(args[0]) and not kwargs:
17
+ func = cast(F, args[0])
18
+ return cast(F, pytest.fixture()(func))
19
+
20
+ def decorator(func: F) -> F:
21
+ wrapped = pytest.fixture(*args, **kwargs)(func)
22
+ return cast(F, wrapped)
23
+
24
+ return decorator
25
+
26
+
27
+ def mark_skipif(*args: Any, **kwargs: Any) -> Callable[[F], F]:
28
+ def decorator(func: F) -> F:
29
+ wrapped = pytest.mark.skipif(*args, **kwargs)(func)
30
+ return cast(F, wrapped)
31
+
32
+ return decorator
33
+
34
+
35
+ def parametrize(
36
+ argnames: str | Sequence[str],
37
+ argvalues: Iterable[Sequence[Any] | Any],
38
+ *args: Any,
39
+ **kwargs: Any,
40
+ ) -> Callable[[F], F]:
41
+ def decorator(func: F) -> F:
42
+ wrapped = pytest.mark.parametrize(argnames, argvalues, *args, **kwargs)(func)
43
+ return cast(F, wrapped)
44
+
45
+ return decorator
tests/conftest.py CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2025 Broadcom.
1
+ # Copyright 2022-2025 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  #
4
4
  import logging
@@ -6,20 +6,27 @@ import os
6
6
  import platform
7
7
  import shutil
8
8
  import sys
9
+ from pathlib import Path
10
+ from typing import Iterator, Optional
9
11
 
10
12
  import pytest
13
+ from _pytest.config import Config
11
14
 
12
15
  from relenv.common import list_archived_builds, plat_from_triplet
13
16
  from relenv.create import create
17
+ from tests._pytest_typing import fixture
18
+
19
+ # mypy: ignore-errors
20
+
14
21
 
15
22
  log = logging.getLogger(__name__)
16
23
 
17
24
 
18
- def get_build_version():
25
+ def get_build_version() -> Optional[str]:
19
26
  if "RELENV_PY_VERSION" in os.environ:
20
27
  return os.environ["RELENV_PY_VERSION"]
21
28
  builds = list(list_archived_builds())
22
- versions = []
29
+ versions: list[str] = []
23
30
  for version, arch, plat in builds:
24
31
  sysplat = plat_from_triplet(plat)
25
32
  if sysplat == sys.platform and arch == platform.machine().lower():
@@ -30,60 +37,59 @@ def get_build_version():
30
37
  "Environment RELENV_PY_VERSION not set, detected version %s", version
31
38
  )
32
39
  return version
40
+ return None
33
41
 
34
42
 
35
- def pytest_report_header(config):
43
+ def pytest_report_header(config: Config) -> str:
36
44
  return f"relenv python version: {get_build_version()}"
37
45
 
38
46
 
39
- @pytest.fixture(scope="module")
40
- def build_version():
41
- return get_build_version()
47
+ @fixture(scope="module")
48
+ def build_version() -> Iterator[str]:
49
+ version = get_build_version()
50
+ if version is None:
51
+ pytest.skip("No relenv build version available for current platform")
52
+ assert version is not None
53
+ yield version
42
54
 
43
55
 
44
- @pytest.fixture(scope="module")
45
- def minor_version():
46
- yield get_build_version().rsplit(".", 1)[0]
56
+ @fixture(scope="module")
57
+ def minor_version(build_version: str) -> Iterator[str]:
58
+ yield build_version.rsplit(".", 1)[0]
47
59
 
48
60
 
49
- @pytest.fixture
50
- def build(tmp_path, build_version):
61
+ @fixture
62
+ def build(tmp_path: Path, build_version: str) -> Iterator[Path]:
51
63
  create("test", tmp_path, version=build_version)
52
- os.chdir(tmp_path / "test")
64
+ build_path = tmp_path / "test"
65
+ original_cwd = Path.cwd()
66
+ os.chdir(build_path)
53
67
  try:
54
- yield tmp_path / "test"
68
+ yield build_path
55
69
  finally:
56
- try:
57
- shutil.rmtree(tmp_path)
58
- except Exception as exc:
59
- log.error("Failed to remove build directory %s", exc)
70
+ os.chdir(original_cwd)
71
+ shutil.rmtree(tmp_path, ignore_errors=True)
60
72
 
61
73
 
62
- @pytest.fixture
63
- def pipexec(build):
64
- if sys.platform == "win32":
65
- path = build / "Scripts"
66
- else:
67
- path = build / "bin"
68
-
69
- exe = shutil.which("pip3", path=path)
74
+ @fixture
75
+ def pipexec(build: Path) -> Iterator[str]:
76
+ path = build / ("Scripts" if sys.platform == "win32" else "bin")
77
+ exe = shutil.which("pip3", path=str(path))
70
78
  if exe is None:
71
- exe = shutil.which("pip", path=path)
79
+ exe = shutil.which("pip", path=str(path))
72
80
  if exe is None:
73
81
  pytest.fail(f"Failed to find 'pip3' and 'pip' in '{path}'")
82
+ assert exe is not None
74
83
  yield exe
75
84
 
76
85
 
77
- @pytest.fixture
78
- def pyexec(build):
79
- if sys.platform == "win32":
80
- path = build / "Scripts"
81
- else:
82
- path = build / "bin"
83
-
84
- exe = shutil.which("python3", path=path)
86
+ @fixture
87
+ def pyexec(build: Path) -> Iterator[str]:
88
+ path = build / ("Scripts" if sys.platform == "win32" else "bin")
89
+ exe = shutil.which("python3", path=str(path))
85
90
  if exe is None:
86
- exe = shutil.which("python", path=path)
91
+ exe = shutil.which("python", path=str(path))
87
92
  if exe is None:
88
93
  pytest.fail(f"Failed to find 'python3' and 'python' in '{path}'")
94
+ assert exe is not None
89
95
  yield exe