pbs-installer 2024.3.27__tar.gz → 2024.4.1__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.
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/PKG-INFO +3 -1
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/pyproject.toml +5 -1
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/src/pbs_installer/_install.py +9 -5
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/src/pbs_installer/_utils.py +12 -23
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/src/pbs_installer/_versions.py +1507 -455
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/LICENSE +0 -0
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/README.md +0 -0
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/src/pbs_installer/__init__.py +0 -0
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/src/pbs_installer/__main__.py +0 -0
- {pbs_installer-2024.3.27 → pbs_installer-2024.4.1}/tests/__init__.py +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pbs-installer
|
|
3
|
-
Version: 2024.
|
|
3
|
+
Version: 2024.4.1
|
|
4
4
|
Summary: Installer for Python Build Standalone
|
|
5
5
|
Author-Email: Frost Ming <me@frostming.com>
|
|
6
6
|
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/frostming/pbs-installer
|
|
8
|
+
Project-URL: Documentation, http://pbs-installer.readthedocs.io
|
|
7
9
|
Requires-Python: >=3.8
|
|
8
10
|
Provides-Extra: download
|
|
9
11
|
Provides-Extra: install
|
|
@@ -7,11 +7,15 @@ authors = [
|
|
|
7
7
|
requires-python = ">=3.8"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
dynamic = []
|
|
10
|
-
version = "2024.
|
|
10
|
+
version = "2024.4.1"
|
|
11
11
|
|
|
12
12
|
[project.license]
|
|
13
13
|
text = "MIT"
|
|
14
14
|
|
|
15
|
+
[project.urls]
|
|
16
|
+
Repository = "https://github.com/frostming/pbs-installer"
|
|
17
|
+
Documentation = "http://pbs-installer.readthedocs.io"
|
|
18
|
+
|
|
15
19
|
[project.optional-dependencies]
|
|
16
20
|
download = [
|
|
17
21
|
"httpx<1,>=0.27.0",
|
|
@@ -33,6 +33,7 @@ def get_download_link(
|
|
|
33
33
|
arch: str = THIS_ARCH,
|
|
34
34
|
platform: str = THIS_PLATFORM,
|
|
35
35
|
implementation: str = "cpython",
|
|
36
|
+
build_dir: bool = False,
|
|
36
37
|
) -> tuple[PythonVersion, PythonFile]:
|
|
37
38
|
"""Get the download URL matching the given requested version.
|
|
38
39
|
|
|
@@ -41,6 +42,7 @@ def get_download_link(
|
|
|
41
42
|
arch: The architecture to install, e.g. x86_64, arm64
|
|
42
43
|
platform: The platform to install, e.g. linux, macos
|
|
43
44
|
implementation: The implementation of Python to install, allowed values are 'cpython' and 'pypy'
|
|
45
|
+
build_dir: Whether to include the `build/` directory from indygreg builds
|
|
44
46
|
|
|
45
47
|
Returns:
|
|
46
48
|
A tuple of the PythonVersion and the download URL
|
|
@@ -56,9 +58,11 @@ def get_download_link(
|
|
|
56
58
|
if not py_ver.matches(request, implementation):
|
|
57
59
|
continue
|
|
58
60
|
|
|
59
|
-
matched = urls.get((platform, arch))
|
|
61
|
+
matched = urls.get((platform, arch, not build_dir))
|
|
60
62
|
if matched is not None:
|
|
61
63
|
return py_ver, matched
|
|
64
|
+
if build_dir and (matched := urls.get((platform, arch, False))) is not None:
|
|
65
|
+
return py_ver, matched
|
|
62
66
|
raise ValueError(
|
|
63
67
|
f"Could not find a version matching version={request!r}, implementation={implementation}"
|
|
64
68
|
)
|
|
@@ -137,11 +141,11 @@ def install_file(
|
|
|
137
141
|
original_filename,
|
|
138
142
|
)
|
|
139
143
|
if original_filename.endswith(".zst"):
|
|
140
|
-
unpack_zst(filename, destination
|
|
144
|
+
unpack_zst(filename, destination)
|
|
141
145
|
elif original_filename.endswith(".zip"):
|
|
142
|
-
unpack_zip(filename, destination
|
|
146
|
+
unpack_zip(filename, destination)
|
|
143
147
|
else:
|
|
144
|
-
unpack_tar(filename, destination
|
|
148
|
+
unpack_tar(filename, destination)
|
|
145
149
|
|
|
146
150
|
|
|
147
151
|
def install(
|
|
@@ -181,7 +185,7 @@ def install(
|
|
|
181
185
|
arch = THIS_ARCH
|
|
182
186
|
|
|
183
187
|
ver, python_file = get_download_link(
|
|
184
|
-
request, arch=arch, platform=platform, implementation=implementation
|
|
188
|
+
request, arch=arch, platform=platform, implementation=implementation, build_dir=build_dir
|
|
185
189
|
)
|
|
186
190
|
if version_dir:
|
|
187
191
|
destination = os.path.join(destination, str(ver))
|
|
@@ -53,36 +53,31 @@ def get_arch_platform() -> tuple[str, str]:
|
|
|
53
53
|
return ARCH_MAPPING.get(arch, arch), PLATFORM_MAPPING.get(plat, plat)
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
def _unpack_tar(tf: tarfile.TarFile, destination: StrPath
|
|
56
|
+
def _unpack_tar(tf: tarfile.TarFile, destination: StrPath) -> None:
|
|
57
57
|
"""Unpack the tarfile to the destination, with the first skip_parts parts of the path removed"""
|
|
58
58
|
members: list[tarfile.TarInfo] = []
|
|
59
|
-
has_build = any(
|
|
60
|
-
(p := fn.lstrip("/").split("/")) and len(p) > 1 and p[1] == "build" for fn in tf.getnames()
|
|
61
|
-
)
|
|
62
59
|
for member in tf.getmembers():
|
|
63
60
|
parts = member.name.lstrip("/").split("/")
|
|
64
|
-
|
|
65
|
-
member.name = "/".join(parts[1:])
|
|
66
|
-
elif len(parts) > 1 and parts[1] == "install":
|
|
67
|
-
member.name = "/".join(parts[2:])
|
|
68
|
-
else:
|
|
69
|
-
continue
|
|
61
|
+
member.name = "/".join(parts[1:])
|
|
70
62
|
if member.name:
|
|
71
63
|
members.append(member)
|
|
72
64
|
tf.extractall(destination, members=members)
|
|
73
65
|
|
|
74
66
|
|
|
75
|
-
def unpack_tar(filename: str, destination: StrPath
|
|
67
|
+
def unpack_tar(filename: str, destination: StrPath) -> None:
|
|
76
68
|
"""Unpack the tarfile to the destination"""
|
|
77
69
|
with tarfile.open(filename) as z:
|
|
78
|
-
_unpack_tar(z, destination
|
|
70
|
+
_unpack_tar(z, destination)
|
|
79
71
|
|
|
80
72
|
|
|
81
|
-
def unpack_zst(filename: str, destination: StrPath
|
|
73
|
+
def unpack_zst(filename: str, destination: StrPath) -> None:
|
|
82
74
|
"""Unpack the zstd compressed tarfile to the destination"""
|
|
83
75
|
import tempfile
|
|
84
76
|
|
|
85
|
-
|
|
77
|
+
try:
|
|
78
|
+
import zstandard as zstd
|
|
79
|
+
except ModuleNotFoundError:
|
|
80
|
+
raise ModuleNotFoundError("zstandard is required to unpack .zst files") from None
|
|
86
81
|
|
|
87
82
|
dctx = zstd.ZstdDecompressor()
|
|
88
83
|
with tempfile.TemporaryFile(suffix=".tar") as ofh:
|
|
@@ -90,24 +85,18 @@ def unpack_zst(filename: str, destination: StrPath, build_dir: bool = False) ->
|
|
|
90
85
|
dctx.copy_stream(ifh, ofh)
|
|
91
86
|
ofh.seek(0)
|
|
92
87
|
with tarfile.open(fileobj=ofh) as z:
|
|
93
|
-
_unpack_tar(z, destination
|
|
88
|
+
_unpack_tar(z, destination)
|
|
94
89
|
|
|
95
90
|
|
|
96
|
-
def unpack_zip(filename: str, destination: StrPath
|
|
91
|
+
def unpack_zip(filename: str, destination: StrPath) -> None:
|
|
97
92
|
"""Unpack the zip file to the destination"""
|
|
98
93
|
import zipfile
|
|
99
94
|
|
|
100
95
|
with zipfile.ZipFile(filename) as z:
|
|
101
96
|
members: list[zipfile.ZipInfo] = []
|
|
102
|
-
has_build = any(fn.lstrip("/").split("/")[1] == "build" for fn in z.namelist())
|
|
103
97
|
for member in z.infolist():
|
|
104
98
|
parts = member.filename.lstrip("/").split("/")
|
|
105
|
-
|
|
106
|
-
member.filename = "/".join(parts[1:])
|
|
107
|
-
elif len(parts) > 1 and parts[1] == "install":
|
|
108
|
-
member.filename = "/".join(parts[2:])
|
|
109
|
-
else:
|
|
110
|
-
continue
|
|
99
|
+
member.filename = "/".join(parts[1:])
|
|
111
100
|
if member.filename:
|
|
112
101
|
members.append(member)
|
|
113
102
|
|