relenv 0.22.1__tar.gz → 0.22.3__tar.gz

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 (59) hide show
  1. {relenv-0.22.1/relenv.egg-info → relenv-0.22.3}/PKG-INFO +1 -1
  2. {relenv-0.22.1 → relenv-0.22.3}/relenv/__init__.py +1 -1
  3. {relenv-0.22.1 → relenv-0.22.3}/relenv/__main__.py +1 -1
  4. relenv-0.22.3/relenv/_resources/xz/crc32_table.c +22 -0
  5. relenv-0.22.3/relenv/_resources/xz/crc64_table.c +33 -0
  6. relenv-0.22.3/relenv/_resources/xz/readme.md +13 -0
  7. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/__init__.py +21 -25
  8. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/common/__init__.py +1 -1
  9. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/common/_sysconfigdata_template.py +1 -1
  10. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/common/builder.py +1 -1
  11. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/common/builders.py +1 -1
  12. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/common/download.py +1 -1
  13. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/common/install.py +6 -2
  14. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/common/ui.py +1 -1
  15. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/darwin.py +1 -1
  16. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/linux.py +1 -1
  17. {relenv-0.22.1 → relenv-0.22.3}/relenv/build/windows.py +9 -1
  18. {relenv-0.22.1 → relenv-0.22.3}/relenv/buildenv.py +1 -1
  19. {relenv-0.22.1 → relenv-0.22.3}/relenv/check.py +1 -1
  20. {relenv-0.22.1 → relenv-0.22.3}/relenv/common.py +2 -4
  21. {relenv-0.22.1 → relenv-0.22.3}/relenv/create.py +19 -27
  22. {relenv-0.22.1 → relenv-0.22.3}/relenv/fetch.py +7 -5
  23. {relenv-0.22.1 → relenv-0.22.3}/relenv/manifest.py +1 -1
  24. {relenv-0.22.1 → relenv-0.22.3}/relenv/python-versions.json +43 -0
  25. {relenv-0.22.1 → relenv-0.22.3}/relenv/pyversions.py +49 -1
  26. {relenv-0.22.1 → relenv-0.22.3}/relenv/relocate.py +118 -4
  27. {relenv-0.22.1 → relenv-0.22.3}/relenv/runtime.py +29 -20
  28. {relenv-0.22.1 → relenv-0.22.3}/relenv/toolchain.py +1 -1
  29. {relenv-0.22.1 → relenv-0.22.3/relenv.egg-info}/PKG-INFO +1 -1
  30. {relenv-0.22.1 → relenv-0.22.3}/relenv.egg-info/SOURCES.txt +3 -0
  31. {relenv-0.22.1 → relenv-0.22.3}/tests/__init__.py +1 -1
  32. {relenv-0.22.1 → relenv-0.22.3}/tests/_pytest_typing.py +1 -1
  33. {relenv-0.22.1 → relenv-0.22.3}/tests/conftest.py +1 -1
  34. {relenv-0.22.1 → relenv-0.22.3}/tests/test_build.py +3 -7
  35. {relenv-0.22.1 → relenv-0.22.3}/tests/test_common.py +2 -2
  36. {relenv-0.22.1 → relenv-0.22.3}/tests/test_create.py +1 -1
  37. {relenv-0.22.1 → relenv-0.22.3}/tests/test_downloads.py +1 -1
  38. {relenv-0.22.1 → relenv-0.22.3}/tests/test_fips_photon.py +1 -1
  39. {relenv-0.22.1 → relenv-0.22.3}/tests/test_module_imports.py +1 -1
  40. {relenv-0.22.1 → relenv-0.22.3}/tests/test_pyversions_runtime.py +78 -1
  41. {relenv-0.22.1 → relenv-0.22.3}/tests/test_relocate.py +86 -1
  42. {relenv-0.22.1 → relenv-0.22.3}/tests/test_relocate_module.py +1 -1
  43. relenv-0.22.3/tests/test_relocate_tools.py +152 -0
  44. {relenv-0.22.1 → relenv-0.22.3}/tests/test_runtime.py +73 -1
  45. {relenv-0.22.1 → relenv-0.22.3}/tests/test_verify_build.py +10 -5
  46. relenv-0.22.1/relenv/_resources/xz/readme.md +0 -4
  47. {relenv-0.22.1 → relenv-0.22.3}/LICENSE.md +0 -0
  48. {relenv-0.22.1 → relenv-0.22.3}/MANIFEST.in +0 -0
  49. {relenv-0.22.1 → relenv-0.22.3}/NOTICE +0 -0
  50. {relenv-0.22.1 → relenv-0.22.3}/README.md +0 -0
  51. {relenv-0.22.1 → relenv-0.22.3}/pyproject.toml +0 -0
  52. {relenv-0.22.1 → relenv-0.22.3}/relenv/_resources/xz/config.h +0 -0
  53. {relenv-0.22.1 → relenv-0.22.3}/relenv/_scripts/install_vc_build.ps1 +0 -0
  54. {relenv-0.22.1 → relenv-0.22.3}/relenv.egg-info/dependency_links.txt +0 -0
  55. {relenv-0.22.1 → relenv-0.22.3}/relenv.egg-info/entry_points.txt +0 -0
  56. {relenv-0.22.1 → relenv-0.22.3}/relenv.egg-info/requires.txt +0 -0
  57. {relenv-0.22.1 → relenv-0.22.3}/relenv.egg-info/top_level.txt +0 -0
  58. {relenv-0.22.1 → relenv-0.22.3}/setup.cfg +0 -0
  59. {relenv-0.22.1 → relenv-0.22.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: relenv
3
- Version: 0.22.1
3
+ Version: 0.22.3
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
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  from __future__ import annotations
4
4
 
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  The entrypoint into relenv.
@@ -0,0 +1,22 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ /// \file crc32_table.c
4
+ /// \brief Precalculated CRC32 table with correct endianness
5
+ //
6
+ // Author: Lasse Collin
7
+ //
8
+ // This file has been put into the public domain.
9
+ // You can do whatever you want with this file.
10
+ //
11
+ ///////////////////////////////////////////////////////////////////////////////
12
+
13
+ #include "common.h"
14
+
15
+ // Having the declaration here silences clang -Wmissing-variable-declarations.
16
+ extern const uint32_t lzma_crc32_table[8][256];
17
+
18
+ #ifdef WORDS_BIGENDIAN
19
+ # include "crc32_table_be.h"
20
+ #else
21
+ # include "crc32_table_le.h"
22
+ #endif
@@ -0,0 +1,33 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ //
3
+ /// \file crc64_table.c
4
+ /// \brief Precalculated CRC64 table with correct endianness
5
+ //
6
+ // Author: Lasse Collin
7
+ //
8
+ // This file has been put into the public domain.
9
+ // You can do whatever you want with this file.
10
+ //
11
+ ///////////////////////////////////////////////////////////////////////////////
12
+
13
+ #include "common.h"
14
+
15
+
16
+ // FIXME: Compared to crc64_fast.c this has to check for __x86_64__ too
17
+ // so that in 32-bit builds crc64_x86.S won't break due to a missing table.
18
+ #if (defined(__x86_64__) && defined(__SSSE3__) \
19
+ && defined(__SSE4_1__) && defined(__PCLMUL__)) \
20
+ || (defined(__e2k__) && __iset__ >= 6)
21
+ // No table needed. Use a typedef to avoid an empty translation unit.
22
+ typedef void lzma_crc64_dummy;
23
+
24
+ #else
25
+ // Having the declaration here silences clang -Wmissing-variable-declarations.
26
+ extern const uint64_t lzma_crc64_table[4][256];
27
+
28
+ # if defined(WORDS_BIGENDIAN)
29
+ # include "crc64_table_be.h"
30
+ # else
31
+ # include "crc64_table_le.h"
32
+ # endif
33
+ #endif
@@ -0,0 +1,13 @@
1
+ The config.h file was removed from XZ-Utils starting with version 5.5.0.
2
+ XZ-Utils switched to CMake and removed Visual Studio project files and
3
+ pre-generated headers/sources.
4
+
5
+ We include the following files from XZ 5.4.7 to maintain compatibility with
6
+ Python's MSBuild-based build system on Windows (PCbuild/liblzma.vcxproj):
7
+
8
+ - config.h (src/common/config.h)
9
+ - crc32_table.c (src/liblzma/check/crc32_table.c)
10
+ - crc64_table.c (src/liblzma/check/crc64_table.c)
11
+
12
+ These files are copied into the extracted XZ source directory during the
13
+ Windows build process if they are missing.
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  # mypy: ignore-errors
4
4
  """
@@ -15,8 +15,13 @@ from types import FrameType, ModuleType
15
15
 
16
16
  from . import darwin, linux, windows
17
17
  from .common import builds
18
- from ..common import DEFAULT_PYTHON, build_arch
19
- from ..pyversions import Version, python_versions
18
+ from ..common import build_arch
19
+ from ..pyversions import (
20
+ Version,
21
+ get_default_python_version,
22
+ python_versions,
23
+ resolve_python_version,
24
+ )
20
25
 
21
26
 
22
27
  def platform_module() -> ModuleType:
@@ -62,11 +67,12 @@ def setup_parser(
62
67
  "logs, src, build, and previous tarball."
63
68
  ),
64
69
  )
70
+ default_version = get_default_python_version()
65
71
  build_subparser.add_argument(
66
72
  "--python",
67
- default=DEFAULT_PYTHON,
73
+ default=default_version,
68
74
  type=str,
69
- help="The python version [default: %(default)s]",
75
+ help="The python version (e.g., 3.10, 3.13.7) [default: %(default)s]",
70
76
  )
71
77
  build_subparser.add_argument(
72
78
  "--no-cleanup",
@@ -146,27 +152,17 @@ def main(args: argparse.Namespace) -> None:
146
152
  print(f"Unsupported platform: {sys.platform}")
147
153
  sys.exit(1)
148
154
 
149
- requested = Version(args.python)
150
-
151
- if requested.micro:
155
+ try:
156
+ build_version_str = resolve_python_version(args.python)
157
+ except RuntimeError as e:
158
+ print(f"Error: {e}")
152
159
  pyversions = python_versions()
153
- if requested not in pyversions:
154
- print(f"Unknown version {requested}")
155
- strversions = "\n".join([str(_) for _ in pyversions])
156
- print(f"Known versions are:\n{strversions}")
157
- sys.exit(1)
158
- build_version = requested
159
- else:
160
- pyversions = python_versions(args.python)
161
- build_version = sorted(list(pyversions.keys()))[-1]
162
-
163
- # print(pyversions)
164
- # print(pyversions[0].major)
165
- # print(pyversions[0].minor)
166
- # print(pyversions[0].micro)
167
- # print(pyversions[0].pre)
168
- # print(pyversions[0].post)
169
- # print(pyversions)
160
+ strversions = "\n".join([str(_) for _ in pyversions])
161
+ print(f"Known versions are:\n{strversions}")
162
+ sys.exit(1)
163
+
164
+ build_version = Version(build_version_str)
165
+ pyversions = python_versions()
170
166
  print(f"Build Python {build_version}")
171
167
 
172
168
  # XXX
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Build process common methods.
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  # mypy: ignore-errors
4
4
  # flake8: noqa
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Builder and Builds classes for managing the build process.
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Build functions for specific dependencies.
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Download utility class for fetching build dependencies.
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Installation and finalization functions for the build process.
@@ -427,7 +427,11 @@ def finalize(
427
427
  :type logfp: file
428
428
  """
429
429
  # Run relok8 to make sure the rpaths are relocatable.
430
- relenv.relocate.main(dirs.prefix, log_file_name=str(dirs.logs / "relocate.py.log"))
430
+ # Modules that don't link to relenv libs will have their RPATH removed
431
+ relenv.relocate.main(
432
+ dirs.prefix,
433
+ log_file_name=str(dirs.logs / "relocate.py.log"),
434
+ )
431
435
  # Install relenv-sysconfigdata module
432
436
  libdir = pathlib.Path(dirs.prefix) / "lib"
433
437
 
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  UI and build statistics utilities.
@@ -1,4 +1,4 @@
1
- # Copyright 2025 Broadcom.
1
+ # Copyright 2025-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2
3
3
  # mypy: ignore-errors
4
4
  """
@@ -1,4 +1,4 @@
1
- # Copyright 2025 Broadcom.
1
+ # Copyright 2025-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2
3
3
  # mypy: ignore-errors
4
4
  """
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2
3
3
  # mypy: ignore-errors
4
4
  """
@@ -197,6 +197,14 @@ def update_xz(dirs: Dirs, env: EnvMapping) -> None:
197
197
  config_file_source = dirs.root / "_resources" / "xz" / "config.h"
198
198
  if not config_file.exists():
199
199
  shutil.copy(str(config_file_source), str(config_file))
200
+
201
+ # Also copy crc32_table.c and crc64_table.c which are missing in newer XZ tarballs
202
+ check_dir = target_dir / "src" / "liblzma" / "check"
203
+ for filename in ["crc32_table.c", "crc64_table.c"]:
204
+ target_file = check_dir / filename
205
+ source_file = dirs.root / "_resources" / "xz" / filename
206
+ if not target_file.exists():
207
+ shutil.copy(str(source_file), str(target_file))
200
208
  # Update externals.spdx.json with the correct version, url, and hash
201
209
  # This became a thing in 3.12
202
210
  if env["RELENV_PY_MAJOR_VERSION"] in ["3.12", "3.13", "3.14"]:
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Helper for building libraries to install into a relenv environment.
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Check the integrety of a relenv environment.
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Common classes and values used around relenv.
@@ -34,14 +34,12 @@ from typing import (
34
34
  )
35
35
 
36
36
  # relenv package version
37
- __version__ = "0.22.1"
37
+ __version__ = "0.22.3"
38
38
 
39
39
  log = logging.getLogger(__name__)
40
40
 
41
41
  MODULE_DIR = pathlib.Path(__file__).resolve().parent
42
42
 
43
- DEFAULT_PYTHON = "3.10.18"
44
-
45
43
  LINUX = "linux"
46
44
  WIN32 = "win32"
47
45
  DARWIN = "darwin"
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  The ``relenv create`` command.
@@ -23,7 +23,11 @@ from .common import (
23
23
  format_shebang,
24
24
  relative_interpreter,
25
25
  )
26
- from .pyversions import Version, python_versions
26
+ from .pyversions import (
27
+ get_default_python_version,
28
+ python_versions,
29
+ resolve_python_version,
30
+ )
27
31
 
28
32
 
29
33
  @contextlib.contextmanager
@@ -73,11 +77,12 @@ def setup_parser(
73
77
  type=str,
74
78
  help="The host architecture [default: %(default)s]",
75
79
  )
80
+ default_version = get_default_python_version()
76
81
  subparser.add_argument(
77
82
  "--python",
78
- default="3.10.17",
83
+ default=default_version,
79
84
  type=str,
80
- help="The python version [default: %(default)s]",
85
+ help="The python version (e.g., 3.10, 3.13.7) [default: %(default)s]",
81
86
  )
82
87
 
83
88
 
@@ -106,8 +111,9 @@ def create(
106
111
  else:
107
112
  writeto = pathlib.Path(name).resolve()
108
113
 
114
+ # Version should be provided by main(), but handle None just in case
109
115
  if version is None:
110
- version = "3.10.17"
116
+ version = get_default_python_version()
111
117
 
112
118
  if pathlib.Path(writeto).exists():
113
119
  raise CreateException("The requested path already exists.")
@@ -253,31 +259,17 @@ def main(args: argparse.Namespace) -> None:
253
259
  "Warning: Cross compilation support is experimental and is not fully tested or working!"
254
260
  )
255
261
 
256
- # Resolve version (support minor version like "3.12" or full version like "3.12.7")
257
- requested = Version(args.python)
258
-
259
- if requested.micro:
260
- # Full version specified (e.g., "3.12.7")
262
+ try:
263
+ create_version = resolve_python_version(args.python)
264
+ except RuntimeError as e:
265
+ print(f"Error: {e}")
261
266
  pyversions = python_versions()
262
- if requested not in pyversions:
263
- print(f"Unknown version {requested}")
264
- strversions = "\n".join([str(_) for _ in pyversions])
265
- print(f"Known versions are:\n{strversions}")
266
- sys.exit(1)
267
- create_version = requested
268
- else:
269
- # Minor version specified (e.g., "3.12"), resolve to latest
270
- pyversions = python_versions(args.python)
271
- if not pyversions:
272
- print(f"Unknown minor version {requested}")
273
- all_versions = python_versions()
274
- strversions = "\n".join([str(_) for _ in all_versions])
275
- print(f"Known versions are:\n{strversions}")
276
- sys.exit(1)
277
- create_version = sorted(list(pyversions.keys()))[-1]
267
+ strversions = "\n".join([str(_) for _ in pyversions])
268
+ print(f"Known versions are:\n{strversions}")
269
+ sys.exit(1)
278
270
 
279
271
  try:
280
- create(name, arch=args.arch, version=str(create_version))
272
+ create(name, arch=args.arch, version=create_version)
281
273
  except CreateException as exc:
282
274
  print(exc)
283
275
  sys.exit(1)
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  # mypy: ignore-errors
4
4
  """
@@ -16,7 +16,6 @@ from .build import platform_module
16
16
  from .common import (
17
17
  CHECK_HOSTS,
18
18
  DATA_DIR,
19
- DEFAULT_PYTHON,
20
19
  __version__,
21
20
  build_arch,
22
21
  check_url,
@@ -24,6 +23,7 @@ from .common import (
24
23
  get_triplet,
25
24
  work_dir,
26
25
  )
26
+ from .pyversions import get_default_python_version, resolve_python_version
27
27
 
28
28
 
29
29
  def setup_parser(
@@ -45,11 +45,12 @@ def setup_parser(
45
45
  type=str,
46
46
  help="Architecture to download. [default: %(default)s]",
47
47
  )
48
+ default_version = get_default_python_version()
48
49
  subparser.add_argument(
49
50
  "--python",
50
- default=DEFAULT_PYTHON,
51
+ default=default_version,
51
52
  type=str,
52
- help="The python version [default: %(default)s]",
53
+ help="The python version (e.g., 3.10, 3.13.7) [default: %(default)s]",
53
54
  )
54
55
 
55
56
 
@@ -87,7 +88,8 @@ def main(args: argparse.Namespace) -> None:
87
88
  """
88
89
  version = os.environ.get("RELENV_FETCH_VERSION", __version__)
89
90
  triplet = get_triplet(machine=args.arch)
90
- python = args.python
91
+ # args.python will be the default version or user-specified version
92
+ python = resolve_python_version(args.python)
91
93
  check_hosts = CHECK_HOSTS
92
94
  if os.environ.get("RELENV_FETCH_HOST", ""):
93
95
  check_hosts = [os.environ["RELENV_FETCH_HOST"]]
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  #
4
4
  """
@@ -203,6 +203,14 @@
203
203
  "linux",
204
204
  "darwin"
205
205
  ]
206
+ },
207
+ "3.6.1": {
208
+ "url": "https://github.com/openssl/openssl/releases/download/openssl-{version}/openssl-{version}.tar.gz",
209
+ "sha256": "b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e",
210
+ "platforms": [
211
+ "linux",
212
+ "darwin"
213
+ ]
206
214
  }
207
215
  },
208
216
  "sqlite": {
@@ -225,6 +233,16 @@
225
233
  "darwin",
226
234
  "win32"
227
235
  ]
236
+ },
237
+ "3.51.2.0": {
238
+ "url": "https://sqlite.org/2026/sqlite-autoconf-{version}.tar.gz",
239
+ "sha256": "fbd89f866b1403bb66a143065440089dd76100f2238314d92274a082d4f2b7bb",
240
+ "sqliteversion": "3510200",
241
+ "platforms": [
242
+ "linux",
243
+ "darwin",
244
+ "win32"
245
+ ]
228
246
  }
229
247
  },
230
248
  "xz": {
@@ -235,6 +253,15 @@
235
253
  "linux",
236
254
  "darwin"
237
255
  ]
256
+ },
257
+ "5.8.2": {
258
+ "url": "http://tukaani.org/xz/xz-{version}.tar.gz",
259
+ "sha256": "ce09c50a5962786b83e5da389c90dd2c15ecd0980a258dd01f70f9e7ce58a8f1",
260
+ "platforms": [
261
+ "linux",
262
+ "darwin",
263
+ "win32"
264
+ ]
238
265
  }
239
266
  },
240
267
  "libffi": {
@@ -262,6 +289,13 @@
262
289
  "platforms": [
263
290
  "linux"
264
291
  ]
292
+ },
293
+ "6.6": {
294
+ "url": "https://mirrors.ocf.berkeley.edu/gnu/ncurses/ncurses-{version}.tar.gz",
295
+ "sha256": "355b4cbbed880b0381a04c46617b7656e362585d52e9cf84a67e2009b749ff11",
296
+ "platforms": [
297
+ "linux"
298
+ ]
265
299
  }
266
300
  },
267
301
  "readline": {
@@ -344,6 +378,15 @@
344
378
  "darwin",
345
379
  "win32"
346
380
  ]
381
+ },
382
+ "2.7.4": {
383
+ "url": "https://github.com/libexpat/libexpat/releases/download/R_2_7_4/expat-{version}.tar.xz",
384
+ "sha256": "9e9cabb457c1e09de91db2706d8365645792638eb3be1f94dbb2149301086ac0",
385
+ "platforms": [
386
+ "linux",
387
+ "darwin",
388
+ "win32"
389
+ ]
347
390
  }
348
391
  }
349
392
  }
@@ -1,4 +1,4 @@
1
- # Copyright 2022-2025 Broadcom.
1
+ # Copyright 2022-2026 Broadcom.
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  """
4
4
  Versions utility.
@@ -947,6 +947,54 @@ def python_versions(
947
947
  return {version: pyversions[str(version)] for version in versions}
948
948
 
949
949
 
950
+ def get_default_python_version() -> str:
951
+ """
952
+ Get the default Python version to use when none is specified.
953
+
954
+ :return: The default Python version string (e.g., "3.10.19")
955
+ """
956
+ # Default to latest 3.10 version
957
+ pyversions = python_versions("3.10")
958
+ if not pyversions:
959
+ raise RuntimeError("No 3.10 versions found")
960
+ latest = sorted(list(pyversions.keys()))[-1]
961
+ return str(latest)
962
+
963
+
964
+ def resolve_python_version(version_spec: str | None = None) -> str:
965
+ """
966
+ Resolve a Python version specification to a full version string.
967
+
968
+ If version_spec is None, returns the latest Python 3.10 version.
969
+ If version_spec is partial (e.g., "3.10"), returns the latest micro version.
970
+ If version_spec is full (e.g., "3.10.19"), returns it as-is after validation.
971
+
972
+ :param version_spec: Version specification (None, "3.10", or "3.10.19")
973
+ :return: Full version string (e.g., "3.10.19")
974
+ :raises RuntimeError: If the version is not found
975
+ """
976
+ if version_spec is None:
977
+ # Default to latest 3.10 version
978
+ return get_default_python_version()
979
+
980
+ requested = Version(version_spec)
981
+
982
+ if requested.micro is not None:
983
+ # Full version specified - validate it exists
984
+ pyversions = python_versions()
985
+ if requested not in pyversions:
986
+ raise RuntimeError(f"Unknown version {requested}")
987
+ return str(requested)
988
+ else:
989
+ # Partial version (major.minor) - get latest micro
990
+ pyversions = python_versions(version_spec)
991
+ if not pyversions:
992
+ raise RuntimeError(f"Unknown minor version {requested}")
993
+ # Return the latest version for this major.minor
994
+ latest = sorted(list(pyversions.keys()))[-1]
995
+ return str(latest)
996
+
997
+
950
998
  def setup_parser(
951
999
  subparsers: argparse._SubParsersAction[argparse.ArgumentParser],
952
1000
  ) -> None: