relenv 0.21.1__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.
- relenv/__init__.py +14 -2
- relenv/__main__.py +12 -6
- relenv/_resources/xz/config.h +148 -0
- relenv/_resources/xz/readme.md +4 -0
- relenv/build/__init__.py +28 -30
- relenv/build/common/__init__.py +50 -0
- relenv/build/common/_sysconfigdata_template.py +72 -0
- relenv/build/common/builder.py +907 -0
- relenv/build/common/builders.py +163 -0
- relenv/build/common/download.py +324 -0
- relenv/build/common/install.py +609 -0
- relenv/build/common/ui.py +432 -0
- relenv/build/darwin.py +128 -14
- relenv/build/linux.py +296 -78
- relenv/build/windows.py +259 -44
- relenv/buildenv.py +48 -17
- relenv/check.py +10 -5
- relenv/common.py +499 -163
- relenv/create.py +147 -7
- relenv/fetch.py +16 -4
- relenv/manifest.py +15 -7
- relenv/python-versions.json +329 -0
- relenv/pyversions.py +817 -30
- relenv/relocate.py +101 -55
- relenv/runtime.py +452 -253
- relenv/toolchain.py +9 -3
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/METADATA +1 -1
- relenv-0.22.0.dist-info/RECORD +48 -0
- tests/__init__.py +2 -0
- tests/_pytest_typing.py +45 -0
- tests/conftest.py +42 -36
- tests/test_build.py +426 -9
- tests/test_common.py +311 -48
- tests/test_create.py +149 -6
- tests/test_downloads.py +19 -15
- tests/test_fips_photon.py +6 -3
- tests/test_module_imports.py +44 -0
- tests/test_pyversions_runtime.py +177 -0
- tests/test_relocate.py +45 -39
- tests/test_relocate_module.py +257 -0
- tests/test_runtime.py +1802 -6
- tests/test_verify_build.py +500 -34
- relenv/build/common.py +0 -1609
- relenv-0.21.1.dist-info/RECORD +0 -35
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/WHEEL +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/entry_points.txt +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/licenses/LICENSE.md +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/licenses/NOTICE +0 -0
- {relenv-0.21.1.dist-info → relenv-0.22.0.dist-info}/top_level.txt +0 -0
relenv/runtime.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Copyright 2022-2025 Broadcom.
|
|
2
|
-
# SPDX-License-Identifier: Apache-2
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
"""
|
|
4
4
|
This code is run when initializing the python interperter in a Relenv environment.
|
|
5
5
|
|
|
@@ -10,19 +10,61 @@ This code is run when initializing the python interperter in a Relenv environmen
|
|
|
10
10
|
gcc. This ensures when using pip any c dependencies are compiled against the
|
|
11
11
|
proper glibc version.
|
|
12
12
|
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
13
15
|
import contextlib
|
|
14
|
-
import ctypes
|
|
16
|
+
import ctypes as _ctypes
|
|
15
17
|
import functools
|
|
16
|
-
import importlib
|
|
17
|
-
import json
|
|
18
|
+
import importlib as _importlib
|
|
19
|
+
import json as _json
|
|
18
20
|
import os
|
|
19
21
|
import pathlib
|
|
20
|
-
import shutil
|
|
21
|
-
import site
|
|
22
|
-
import subprocess
|
|
23
|
-
import sys
|
|
22
|
+
import shutil as _shutil
|
|
23
|
+
import site as _site
|
|
24
|
+
import subprocess as _subprocess
|
|
25
|
+
import sys as _sys
|
|
24
26
|
import textwrap
|
|
25
|
-
import warnings
|
|
27
|
+
import warnings as _warnings
|
|
28
|
+
from importlib.machinery import ModuleSpec
|
|
29
|
+
from types import ModuleType
|
|
30
|
+
from typing import (
|
|
31
|
+
Any,
|
|
32
|
+
Callable,
|
|
33
|
+
Dict,
|
|
34
|
+
Iterable,
|
|
35
|
+
Iterator,
|
|
36
|
+
Optional,
|
|
37
|
+
Sequence,
|
|
38
|
+
Union,
|
|
39
|
+
cast,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# The tests monkeypatch these module-level imports (e.g., json.loads) inside
|
|
43
|
+
# relenv.runtime itself; keeping them as Any both preserves test isolation—no
|
|
44
|
+
# need to patch the global stdlib modules—and avoids mypy attr-defined noise
|
|
45
|
+
# while still exercising the real runtime wiring.
|
|
46
|
+
json = cast(Any, _json)
|
|
47
|
+
importlib = cast(Any, _importlib)
|
|
48
|
+
site = cast(Any, _site)
|
|
49
|
+
subprocess = cast(Any, _subprocess)
|
|
50
|
+
sys = cast(Any, _sys)
|
|
51
|
+
ctypes = cast(Any, _ctypes)
|
|
52
|
+
shutil = cast(Any, _shutil)
|
|
53
|
+
warnings = cast(Any, _warnings)
|
|
54
|
+
|
|
55
|
+
__all__ = [
|
|
56
|
+
"sys",
|
|
57
|
+
"shutil",
|
|
58
|
+
"subprocess",
|
|
59
|
+
"json",
|
|
60
|
+
"importlib",
|
|
61
|
+
"site",
|
|
62
|
+
"ctypes",
|
|
63
|
+
"warnings",
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
PathType = Union[str, os.PathLike[str]]
|
|
67
|
+
ConfigVars = Dict[str, str]
|
|
26
68
|
|
|
27
69
|
# relenv.pth has a __file__ which is set to the path to site.py of the python
|
|
28
70
|
# interpreter being used. We're using that to determine the proper
|
|
@@ -32,7 +74,7 @@ import warnings
|
|
|
32
74
|
# imports happen before our path munghing in site in wrapsitecustomize.
|
|
33
75
|
|
|
34
76
|
|
|
35
|
-
def path_import(name, path):
|
|
77
|
+
def path_import(name: str, path: PathType) -> ModuleType:
|
|
36
78
|
"""
|
|
37
79
|
Import module from a path.
|
|
38
80
|
|
|
@@ -42,46 +84,50 @@ def path_import(name, path):
|
|
|
42
84
|
import importlib.util
|
|
43
85
|
|
|
44
86
|
spec = importlib.util.spec_from_file_location(name, path)
|
|
87
|
+
if spec is None or spec.loader is None:
|
|
88
|
+
raise ImportError(f"Unable to load module {name} from {path}")
|
|
45
89
|
module = importlib.util.module_from_spec(spec)
|
|
46
90
|
spec.loader.exec_module(module)
|
|
47
91
|
sys.modules[name] = module
|
|
48
92
|
return module
|
|
49
93
|
|
|
50
94
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
95
|
+
_COMMON: Optional[ModuleType] = None
|
|
96
|
+
_RELOCATE: Optional[ModuleType] = None
|
|
97
|
+
_BUILDENV: Optional[ModuleType] = None
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def common() -> ModuleType:
|
|
101
|
+
"""Return the cached ``relenv.common`` module."""
|
|
102
|
+
global _COMMON
|
|
103
|
+
if _COMMON is None:
|
|
104
|
+
_COMMON = path_import(
|
|
57
105
|
"relenv.common", str(pathlib.Path(__file__).parent / "common.py")
|
|
58
106
|
)
|
|
59
|
-
return
|
|
107
|
+
return _COMMON
|
|
60
108
|
|
|
61
109
|
|
|
62
|
-
def relocate():
|
|
63
|
-
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
relocate.relocate = path_import(
|
|
110
|
+
def relocate() -> ModuleType:
|
|
111
|
+
"""Return the cached ``relenv.relocate`` module."""
|
|
112
|
+
global _RELOCATE
|
|
113
|
+
if _RELOCATE is None:
|
|
114
|
+
_RELOCATE = path_import(
|
|
68
115
|
"relenv.relocate", str(pathlib.Path(__file__).parent / "relocate.py")
|
|
69
116
|
)
|
|
70
|
-
return
|
|
117
|
+
return _RELOCATE
|
|
71
118
|
|
|
72
119
|
|
|
73
|
-
def buildenv():
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
buildenv.buildenv = path_import(
|
|
120
|
+
def buildenv() -> ModuleType:
|
|
121
|
+
"""Return the cached ``relenv.buildenv`` module."""
|
|
122
|
+
global _BUILDENV
|
|
123
|
+
if _BUILDENV is None:
|
|
124
|
+
_BUILDENV = path_import(
|
|
79
125
|
"relenv.buildenv", str(pathlib.Path(__file__).parent / "buildenv.py")
|
|
80
126
|
)
|
|
81
|
-
return
|
|
127
|
+
return _BUILDENV
|
|
82
128
|
|
|
83
129
|
|
|
84
|
-
def get_major_version():
|
|
130
|
+
def get_major_version() -> str:
|
|
85
131
|
"""
|
|
86
132
|
Current python major version.
|
|
87
133
|
"""
|
|
@@ -89,7 +135,7 @@ def get_major_version():
|
|
|
89
135
|
|
|
90
136
|
|
|
91
137
|
@contextlib.contextmanager
|
|
92
|
-
def pushd(new_dir):
|
|
138
|
+
def pushd(new_dir: PathType) -> Iterator[None]:
|
|
93
139
|
"""
|
|
94
140
|
Changedir context.
|
|
95
141
|
"""
|
|
@@ -101,7 +147,7 @@ def pushd(new_dir):
|
|
|
101
147
|
os.chdir(old_dir)
|
|
102
148
|
|
|
103
149
|
|
|
104
|
-
def debug(string):
|
|
150
|
+
def debug(string: str) -> None:
|
|
105
151
|
"""
|
|
106
152
|
Prints the provided message if RELENV_DEBUG is truthy in the environment.
|
|
107
153
|
|
|
@@ -113,7 +159,7 @@ def debug(string):
|
|
|
113
159
|
sys.stdout.flush()
|
|
114
160
|
|
|
115
161
|
|
|
116
|
-
def relenv_root():
|
|
162
|
+
def relenv_root() -> pathlib.Path:
|
|
117
163
|
"""
|
|
118
164
|
Return the relenv module root.
|
|
119
165
|
"""
|
|
@@ -126,7 +172,9 @@ def relenv_root():
|
|
|
126
172
|
return MODULE_DIR.parent.parent.parent.parent
|
|
127
173
|
|
|
128
174
|
|
|
129
|
-
def _build_shebang(
|
|
175
|
+
def _build_shebang(
|
|
176
|
+
func: Callable[..., bytes], *args: Any, **kwargs: Any
|
|
177
|
+
) -> Callable[..., bytes]:
|
|
130
178
|
"""
|
|
131
179
|
Build a shebang to point to the proper location.
|
|
132
180
|
|
|
@@ -135,34 +183,37 @@ def _build_shebang(func, *args, **kwargs):
|
|
|
135
183
|
"""
|
|
136
184
|
|
|
137
185
|
@functools.wraps(func)
|
|
138
|
-
def wrapped(self, *args, **kwargs):
|
|
186
|
+
def wrapped(self: Any, *args: Any, **kwargs: Any) -> bytes:
|
|
139
187
|
scripts = pathlib.Path(self.target_dir)
|
|
140
188
|
if TARGET.TARGET:
|
|
141
|
-
scripts = pathlib.Path(
|
|
189
|
+
scripts = pathlib.Path(_ensure_target_path()).absolute() / "bin"
|
|
142
190
|
try:
|
|
143
191
|
interpreter = common().relative_interpreter(
|
|
144
192
|
sys.RELENV, scripts, pathlib.Path(sys.executable).resolve()
|
|
145
193
|
)
|
|
146
194
|
except ValueError:
|
|
147
195
|
debug(f"Relenv Value Error - _build_shebang {self.target_dir}")
|
|
148
|
-
|
|
196
|
+
original_result: bytes = func(self, *args, **kwargs)
|
|
197
|
+
return original_result
|
|
149
198
|
debug(f"Relenv - _build_shebang {scripts} {interpreter}")
|
|
150
199
|
if sys.platform == "win32":
|
|
151
200
|
return (
|
|
152
201
|
str(pathlib.Path("#!<launcher_dir>") / interpreter).encode() + b"\r\n"
|
|
153
202
|
)
|
|
154
|
-
|
|
203
|
+
rel_path = str(pathlib.PurePosixPath("/") / interpreter)
|
|
204
|
+
formatted = cast(str, common().format_shebang(rel_path))
|
|
205
|
+
return formatted.encode()
|
|
155
206
|
|
|
156
207
|
return wrapped
|
|
157
208
|
|
|
158
209
|
|
|
159
|
-
def get_config_var_wrapper(func):
|
|
210
|
+
def get_config_var_wrapper(func: Callable[[str], Any]) -> Callable[[str], Any]:
|
|
160
211
|
"""
|
|
161
212
|
Return a wrapper to resolve paths relative to the relenv root.
|
|
162
213
|
"""
|
|
163
214
|
|
|
164
215
|
@functools.wraps(func)
|
|
165
|
-
def wrapped(name):
|
|
216
|
+
def wrapped(name: str) -> Any:
|
|
166
217
|
if name == "BINDIR":
|
|
167
218
|
orig = func(name)
|
|
168
219
|
if os.environ.get("RELENV_PIP_DIR"):
|
|
@@ -179,13 +230,13 @@ def get_config_var_wrapper(func):
|
|
|
179
230
|
return wrapped
|
|
180
231
|
|
|
181
232
|
|
|
182
|
-
|
|
233
|
+
CONFIG_VARS_DEFAULTS: ConfigVars = {
|
|
183
234
|
"AR": "ar",
|
|
184
235
|
"CC": "gcc",
|
|
185
236
|
"CFLAGS": "-Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall",
|
|
186
237
|
"CPPFLAGS": "-I. -I./Include",
|
|
187
238
|
"CXX": "g++",
|
|
188
|
-
"LIBDEST": "/usr/local/lib/python3.
|
|
239
|
+
"LIBDEST": "/usr/local/lib/python3.10",
|
|
189
240
|
"SCRIPTDIR": "/usr/local/lib",
|
|
190
241
|
"BLDSHARED": "gcc -shared",
|
|
191
242
|
"LDFLAGS": "",
|
|
@@ -193,10 +244,10 @@ _CONFIG_VARS_DEFAULTS = {
|
|
|
193
244
|
"LDSHARED": "gcc -shared",
|
|
194
245
|
}
|
|
195
246
|
|
|
196
|
-
_SYSTEM_CONFIG_VARS = None
|
|
247
|
+
_SYSTEM_CONFIG_VARS: Optional[ConfigVars] = None
|
|
197
248
|
|
|
198
249
|
|
|
199
|
-
def system_sysconfig():
|
|
250
|
+
def system_sysconfig() -> ConfigVars:
|
|
200
251
|
"""
|
|
201
252
|
Read the system python's sysconfig values.
|
|
202
253
|
|
|
@@ -204,7 +255,7 @@ def system_sysconfig():
|
|
|
204
255
|
to avoid the overhead of shelling out.
|
|
205
256
|
"""
|
|
206
257
|
global _SYSTEM_CONFIG_VARS
|
|
207
|
-
if _SYSTEM_CONFIG_VARS:
|
|
258
|
+
if _SYSTEM_CONFIG_VARS is not None:
|
|
208
259
|
return _SYSTEM_CONFIG_VARS
|
|
209
260
|
pyexec = pathlib.Path("/usr/bin/python3")
|
|
210
261
|
if pyexec.exists():
|
|
@@ -220,25 +271,27 @@ def system_sysconfig():
|
|
|
220
271
|
_SYSTEM_CONFIG_VARS = json.loads(p.stdout.strip())
|
|
221
272
|
except json.JSONDecodeError:
|
|
222
273
|
debug(f"Failed to load JSON from: {p.stdout.strip()}")
|
|
223
|
-
_SYSTEM_CONFIG_VARS =
|
|
274
|
+
_SYSTEM_CONFIG_VARS = CONFIG_VARS_DEFAULTS
|
|
224
275
|
else:
|
|
225
276
|
debug("System python not found")
|
|
226
|
-
_SYSTEM_CONFIG_VARS =
|
|
277
|
+
_SYSTEM_CONFIG_VARS = CONFIG_VARS_DEFAULTS
|
|
227
278
|
return _SYSTEM_CONFIG_VARS
|
|
228
279
|
|
|
229
280
|
|
|
230
|
-
def get_config_vars_wrapper(
|
|
281
|
+
def get_config_vars_wrapper(
|
|
282
|
+
func: Callable[..., ConfigVars], mod: ModuleType
|
|
283
|
+
) -> Callable[..., ConfigVars]:
|
|
231
284
|
"""
|
|
232
285
|
Return a wrapper to resolve paths relative to the relenv root.
|
|
233
286
|
"""
|
|
234
287
|
|
|
235
288
|
@functools.wraps(func)
|
|
236
|
-
def wrapped(*args):
|
|
289
|
+
def wrapped(*args: Any) -> ConfigVars:
|
|
237
290
|
if sys.platform == "win32" or "RELENV_BUILDENV" in os.environ:
|
|
238
291
|
return func(*args)
|
|
239
292
|
|
|
240
|
-
|
|
241
|
-
|
|
293
|
+
config_vars = func()
|
|
294
|
+
system_config_vars = system_sysconfig()
|
|
242
295
|
for name in [
|
|
243
296
|
"AR",
|
|
244
297
|
"CC",
|
|
@@ -252,20 +305,26 @@ def get_config_vars_wrapper(func, mod):
|
|
|
252
305
|
"LDCXXSHARED",
|
|
253
306
|
"LDSHARED",
|
|
254
307
|
]:
|
|
255
|
-
|
|
256
|
-
mod
|
|
308
|
+
config_vars[name] = system_config_vars[name]
|
|
309
|
+
setattr(mod, "_CONFIG_VARS", config_vars)
|
|
257
310
|
return func(*args)
|
|
258
311
|
|
|
259
312
|
return wrapped
|
|
260
313
|
|
|
261
314
|
|
|
262
|
-
def get_paths_wrapper(
|
|
315
|
+
def get_paths_wrapper(
|
|
316
|
+
func: Callable[..., Dict[str, str]], default_scheme: str
|
|
317
|
+
) -> Callable[..., Dict[str, str]]:
|
|
263
318
|
"""
|
|
264
319
|
Return a wrapper to resolve paths relative to the relenv root.
|
|
265
320
|
"""
|
|
266
321
|
|
|
267
322
|
@functools.wraps(func)
|
|
268
|
-
def wrapped(
|
|
323
|
+
def wrapped(
|
|
324
|
+
scheme: Optional[str] = default_scheme,
|
|
325
|
+
vars: Optional[Dict[str, str]] = None,
|
|
326
|
+
expand: bool = True,
|
|
327
|
+
) -> Dict[str, str]:
|
|
269
328
|
paths = func(scheme=scheme, vars=vars, expand=expand)
|
|
270
329
|
if "RELENV_PIP_DIR" in os.environ:
|
|
271
330
|
paths["scripts"] = str(relenv_root())
|
|
@@ -275,7 +334,7 @@ def get_paths_wrapper(func, default_scheme):
|
|
|
275
334
|
return wrapped
|
|
276
335
|
|
|
277
336
|
|
|
278
|
-
def finalize_options_wrapper(func):
|
|
337
|
+
def finalize_options_wrapper(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
279
338
|
"""
|
|
280
339
|
Wrapper around build_ext.finalize_options.
|
|
281
340
|
|
|
@@ -283,15 +342,15 @@ def finalize_options_wrapper(func):
|
|
|
283
342
|
"""
|
|
284
343
|
|
|
285
344
|
@functools.wraps(func)
|
|
286
|
-
def wrapper(self, *args, **kwargs):
|
|
345
|
+
def wrapper(self: Any, *args: Any, **kwargs: Any) -> None:
|
|
287
346
|
func(self, *args, **kwargs)
|
|
288
347
|
if "RELENV_BUILDENV" in os.environ:
|
|
289
|
-
self.include_dirs.append(
|
|
348
|
+
self.include_dirs.append(str(relenv_root() / "include"))
|
|
290
349
|
|
|
291
350
|
return wrapper
|
|
292
351
|
|
|
293
352
|
|
|
294
|
-
def install_wheel_wrapper(func):
|
|
353
|
+
def install_wheel_wrapper(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
295
354
|
"""
|
|
296
355
|
Wrap pip's wheel install function.
|
|
297
356
|
|
|
@@ -300,15 +359,15 @@ def install_wheel_wrapper(func):
|
|
|
300
359
|
|
|
301
360
|
@functools.wraps(func)
|
|
302
361
|
def wrapper(
|
|
303
|
-
name,
|
|
304
|
-
wheel_path,
|
|
305
|
-
scheme,
|
|
306
|
-
req_description,
|
|
307
|
-
pycompile,
|
|
308
|
-
warn_script_location,
|
|
309
|
-
direct_url,
|
|
310
|
-
requested,
|
|
311
|
-
):
|
|
362
|
+
name: str,
|
|
363
|
+
wheel_path: PathType,
|
|
364
|
+
scheme: Any,
|
|
365
|
+
req_description: str,
|
|
366
|
+
pycompile: Any,
|
|
367
|
+
warn_script_location: Any,
|
|
368
|
+
direct_url: Any,
|
|
369
|
+
requested: Any,
|
|
370
|
+
) -> Any:
|
|
312
371
|
from zipfile import ZipFile
|
|
313
372
|
|
|
314
373
|
from pip._internal.utils.wheel import parse_wheel
|
|
@@ -348,7 +407,7 @@ def install_wheel_wrapper(func):
|
|
|
348
407
|
return wrapper
|
|
349
408
|
|
|
350
409
|
|
|
351
|
-
def install_legacy_wrapper(func):
|
|
410
|
+
def install_legacy_wrapper(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
352
411
|
"""
|
|
353
412
|
Wrap pip's legacy install function.
|
|
354
413
|
|
|
@@ -359,21 +418,21 @@ def install_legacy_wrapper(func):
|
|
|
359
418
|
|
|
360
419
|
@functools.wraps(func)
|
|
361
420
|
def wrapper(
|
|
362
|
-
install_options,
|
|
363
|
-
global_options,
|
|
364
|
-
root,
|
|
365
|
-
home,
|
|
366
|
-
prefix,
|
|
367
|
-
use_user_site,
|
|
368
|
-
pycompile,
|
|
369
|
-
scheme,
|
|
370
|
-
setup_py_path,
|
|
371
|
-
isolated,
|
|
372
|
-
req_name,
|
|
373
|
-
build_env,
|
|
374
|
-
unpacked_source_directory,
|
|
375
|
-
req_description,
|
|
376
|
-
):
|
|
421
|
+
install_options: Any,
|
|
422
|
+
global_options: Any,
|
|
423
|
+
root: Any,
|
|
424
|
+
home: Any,
|
|
425
|
+
prefix: Any,
|
|
426
|
+
use_user_site: Any,
|
|
427
|
+
pycompile: Any,
|
|
428
|
+
scheme: Any,
|
|
429
|
+
setup_py_path: Any,
|
|
430
|
+
isolated: Any,
|
|
431
|
+
req_name: Any,
|
|
432
|
+
build_env: Any,
|
|
433
|
+
unpacked_source_directory: Any,
|
|
434
|
+
req_description: Any,
|
|
435
|
+
) -> Any:
|
|
377
436
|
|
|
378
437
|
pkginfo = pathlib.Path(setup_py_path).parent / "PKG-INFO"
|
|
379
438
|
with open(pkginfo) as fp:
|
|
@@ -447,13 +506,19 @@ class Wrapper:
|
|
|
447
506
|
Wrap methods of an imported module.
|
|
448
507
|
"""
|
|
449
508
|
|
|
450
|
-
def __init__(
|
|
509
|
+
def __init__(
|
|
510
|
+
self,
|
|
511
|
+
module: str,
|
|
512
|
+
wrapper: Callable[[str], ModuleType],
|
|
513
|
+
matcher: str = "equals",
|
|
514
|
+
_loading: bool = False,
|
|
515
|
+
) -> None:
|
|
451
516
|
self.module = module
|
|
452
517
|
self.wrapper = wrapper
|
|
453
518
|
self.matcher = matcher
|
|
454
519
|
self.loading = _loading
|
|
455
520
|
|
|
456
|
-
def matches(self, module):
|
|
521
|
+
def matches(self: "Wrapper", module: str) -> bool:
|
|
457
522
|
"""
|
|
458
523
|
Check if wrapper metches module being imported.
|
|
459
524
|
"""
|
|
@@ -461,7 +526,7 @@ class Wrapper:
|
|
|
461
526
|
return module.startswith(self.module)
|
|
462
527
|
return self.module == module
|
|
463
528
|
|
|
464
|
-
def __call__(self, module_name):
|
|
529
|
+
def __call__(self: "Wrapper", module_name: str) -> ModuleType:
|
|
465
530
|
"""
|
|
466
531
|
Preform the wrapper operation.
|
|
467
532
|
"""
|
|
@@ -473,15 +538,24 @@ class RelenvImporter:
|
|
|
473
538
|
Handle runtime wrapping of module methods.
|
|
474
539
|
"""
|
|
475
540
|
|
|
476
|
-
def __init__(
|
|
541
|
+
def __init__(
|
|
542
|
+
self,
|
|
543
|
+
wrappers: Optional[Iterable[Wrapper]] = None,
|
|
544
|
+
_loads: Optional[Dict[str, ModuleType]] = None,
|
|
545
|
+
) -> None:
|
|
477
546
|
if wrappers is None:
|
|
478
547
|
wrappers = []
|
|
479
|
-
self.wrappers = set(wrappers)
|
|
548
|
+
self.wrappers: set[Wrapper] = set(wrappers)
|
|
480
549
|
if _loads is None:
|
|
481
550
|
_loads = {}
|
|
482
|
-
self._loads = _loads
|
|
483
|
-
|
|
484
|
-
def find_spec(
|
|
551
|
+
self._loads: Dict[str, ModuleType] = _loads
|
|
552
|
+
|
|
553
|
+
def find_spec(
|
|
554
|
+
self: "RelenvImporter",
|
|
555
|
+
module_name: str,
|
|
556
|
+
package_path: Optional[Sequence[str]] = None,
|
|
557
|
+
target: Any = None,
|
|
558
|
+
) -> Optional[ModuleSpec]:
|
|
485
559
|
"""
|
|
486
560
|
Find modules being imported.
|
|
487
561
|
"""
|
|
@@ -489,9 +563,15 @@ class RelenvImporter:
|
|
|
489
563
|
if wrapper.matches(module_name) and not wrapper.loading:
|
|
490
564
|
debug(f"RelenvImporter - match {module_name} {package_path} {target}")
|
|
491
565
|
wrapper.loading = True
|
|
492
|
-
|
|
566
|
+
spec = importlib.util.spec_from_loader(module_name, self)
|
|
567
|
+
return cast(Optional[ModuleSpec], spec)
|
|
568
|
+
return None
|
|
493
569
|
|
|
494
|
-
def find_module(
|
|
570
|
+
def find_module(
|
|
571
|
+
self: "RelenvImporter",
|
|
572
|
+
module_name: str,
|
|
573
|
+
package_path: Optional[Sequence[str]] = None,
|
|
574
|
+
) -> Optional["RelenvImporter"]:
|
|
495
575
|
"""
|
|
496
576
|
Find modules being imported.
|
|
497
577
|
"""
|
|
@@ -500,38 +580,43 @@ class RelenvImporter:
|
|
|
500
580
|
debug(f"RelenvImporter - match {module_name}")
|
|
501
581
|
wrapper.loading = True
|
|
502
582
|
return self
|
|
583
|
+
return None
|
|
503
584
|
|
|
504
|
-
def load_module(self, name):
|
|
585
|
+
def load_module(self: "RelenvImporter", name: str) -> ModuleType:
|
|
505
586
|
"""
|
|
506
587
|
Load an imported module.
|
|
507
588
|
"""
|
|
589
|
+
mod: Optional[ModuleType] = None
|
|
508
590
|
for wrapper in self.wrappers:
|
|
509
591
|
if wrapper.matches(name):
|
|
510
592
|
debug(f"RelenvImporter - load_module {name}")
|
|
511
593
|
mod = wrapper(name)
|
|
512
594
|
wrapper.loading = False
|
|
513
595
|
break
|
|
596
|
+
if mod is None:
|
|
597
|
+
mod = importlib.import_module(name)
|
|
514
598
|
sys.modules[name] = mod
|
|
515
599
|
return mod
|
|
516
600
|
|
|
517
|
-
def create_module(self, spec):
|
|
601
|
+
def create_module(self: "RelenvImporter", spec: ModuleSpec) -> Optional[ModuleType]:
|
|
518
602
|
"""
|
|
519
603
|
Create the module via a spec.
|
|
520
604
|
"""
|
|
521
605
|
return self.load_module(spec.name)
|
|
522
606
|
|
|
523
|
-
def exec_module(self, module):
|
|
607
|
+
def exec_module(self: "RelenvImporter", module: ModuleType) -> None:
|
|
524
608
|
"""
|
|
525
609
|
Exec module noop.
|
|
526
610
|
"""
|
|
527
611
|
return None
|
|
528
612
|
|
|
529
613
|
|
|
530
|
-
def wrap_sysconfig(name):
|
|
614
|
+
def wrap_sysconfig(name: str) -> ModuleType:
|
|
531
615
|
"""
|
|
532
616
|
Sysconfig wrapper.
|
|
533
617
|
"""
|
|
534
|
-
|
|
618
|
+
module: ModuleType = importlib.import_module("sysconfig")
|
|
619
|
+
mod = cast(Any, module)
|
|
535
620
|
mod.get_config_var = get_config_var_wrapper(mod.get_config_var)
|
|
536
621
|
mod.get_config_vars = get_config_vars_wrapper(mod.get_config_vars, mod)
|
|
537
622
|
mod._PIP_USE_SYSCONFIG = True
|
|
@@ -542,48 +627,52 @@ def wrap_sysconfig(name):
|
|
|
542
627
|
# Python < 3.10
|
|
543
628
|
scheme = mod._get_default_scheme()
|
|
544
629
|
mod.get_paths = get_paths_wrapper(mod.get_paths, scheme)
|
|
545
|
-
return
|
|
630
|
+
return module
|
|
546
631
|
|
|
547
632
|
|
|
548
|
-
def wrap_pip_distlib_scripts(name):
|
|
633
|
+
def wrap_pip_distlib_scripts(name: str) -> ModuleType:
|
|
549
634
|
"""
|
|
550
635
|
pip.distlib.scripts wrapper.
|
|
551
636
|
"""
|
|
552
|
-
|
|
637
|
+
module: ModuleType = importlib.import_module(name)
|
|
638
|
+
mod = cast(Any, module)
|
|
553
639
|
mod.ScriptMaker._build_shebang = _build_shebang(mod.ScriptMaker._build_shebang)
|
|
554
|
-
return
|
|
640
|
+
return module
|
|
555
641
|
|
|
556
642
|
|
|
557
|
-
def wrap_distutils_command(name):
|
|
643
|
+
def wrap_distutils_command(name: str) -> ModuleType:
|
|
558
644
|
"""
|
|
559
645
|
distutils.command wrapper.
|
|
560
646
|
"""
|
|
561
|
-
|
|
647
|
+
module: ModuleType = importlib.import_module(name)
|
|
648
|
+
mod = cast(Any, module)
|
|
562
649
|
mod.build_ext.finalize_options = finalize_options_wrapper(
|
|
563
650
|
mod.build_ext.finalize_options
|
|
564
651
|
)
|
|
565
|
-
return
|
|
652
|
+
return module
|
|
566
653
|
|
|
567
654
|
|
|
568
|
-
def wrap_pip_install_wheel(name):
|
|
655
|
+
def wrap_pip_install_wheel(name: str) -> ModuleType:
|
|
569
656
|
"""
|
|
570
657
|
pip._internal.operations.install.wheel wrapper.
|
|
571
658
|
"""
|
|
572
|
-
|
|
659
|
+
module: ModuleType = importlib.import_module(name)
|
|
660
|
+
mod = cast(Any, module)
|
|
573
661
|
mod.install_wheel = install_wheel_wrapper(mod.install_wheel)
|
|
574
|
-
return
|
|
662
|
+
return module
|
|
575
663
|
|
|
576
664
|
|
|
577
|
-
def wrap_pip_install_legacy(name):
|
|
665
|
+
def wrap_pip_install_legacy(name: str) -> ModuleType:
|
|
578
666
|
"""
|
|
579
667
|
pip._internal.operations.install.legacy wrapper.
|
|
580
668
|
"""
|
|
581
|
-
|
|
669
|
+
module: ModuleType = importlib.import_module(name)
|
|
670
|
+
mod = cast(Any, module)
|
|
582
671
|
mod.install = install_legacy_wrapper(mod.install)
|
|
583
|
-
return
|
|
672
|
+
return module
|
|
584
673
|
|
|
585
674
|
|
|
586
|
-
def set_env_if_not_set(name, value):
|
|
675
|
+
def set_env_if_not_set(name: str, value: str) -> None:
|
|
587
676
|
"""
|
|
588
677
|
Set an environment variable if not already set.
|
|
589
678
|
|
|
@@ -600,21 +689,21 @@ def set_env_if_not_set(name, value):
|
|
|
600
689
|
os.environ[name] = value
|
|
601
690
|
|
|
602
691
|
|
|
603
|
-
def wrap_pip_build_wheel(name):
|
|
692
|
+
def wrap_pip_build_wheel(name: str) -> ModuleType:
|
|
604
693
|
"""
|
|
605
694
|
pip._internal.operations.build wrapper.
|
|
606
695
|
"""
|
|
607
|
-
|
|
696
|
+
module: ModuleType = importlib.import_module(name)
|
|
697
|
+
mod = cast(Any, module)
|
|
608
698
|
|
|
609
|
-
def wrap(func):
|
|
699
|
+
def wrap(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
610
700
|
@functools.wraps(func)
|
|
611
|
-
def wrapper(*args, **kwargs):
|
|
701
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
612
702
|
if sys.platform != "linux":
|
|
613
703
|
return func(*args, **kwargs)
|
|
614
|
-
|
|
615
|
-
toolchain = base_dir / common().get_triplet()
|
|
704
|
+
toolchain = common().get_toolchain()
|
|
616
705
|
cargo_home = str(common().DATA_DIR / "cargo")
|
|
617
|
-
if not toolchain.exists():
|
|
706
|
+
if toolchain is None or not toolchain.exists():
|
|
618
707
|
debug("Unable to set CARGO_HOME no toolchain exists")
|
|
619
708
|
else:
|
|
620
709
|
relenvroot = str(sys.RELENV)
|
|
@@ -631,7 +720,7 @@ def wrap_pip_build_wheel(name):
|
|
|
631
720
|
return wrapper
|
|
632
721
|
|
|
633
722
|
mod.build_wheel_pep517 = wrap(mod.build_wheel_pep517)
|
|
634
|
-
return
|
|
723
|
+
return module
|
|
635
724
|
|
|
636
725
|
|
|
637
726
|
class TARGET:
|
|
@@ -639,21 +728,31 @@ class TARGET:
|
|
|
639
728
|
Container for global pip target state.
|
|
640
729
|
"""
|
|
641
730
|
|
|
642
|
-
TARGET = False
|
|
643
|
-
|
|
644
|
-
IGNORE = False
|
|
645
|
-
INSTALL = False
|
|
731
|
+
TARGET: bool = False
|
|
732
|
+
PATH: Optional[str] = None
|
|
733
|
+
IGNORE: bool = False
|
|
734
|
+
INSTALL: bool = False
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
def _ensure_target_path() -> str:
|
|
738
|
+
"""
|
|
739
|
+
Return the stored target path, raising if it is unavailable.
|
|
740
|
+
"""
|
|
741
|
+
if TARGET.PATH is None:
|
|
742
|
+
raise RuntimeError("TARGET path requested but not initialized")
|
|
743
|
+
return TARGET.PATH
|
|
646
744
|
|
|
647
745
|
|
|
648
|
-
def wrap_cmd_install(name):
|
|
746
|
+
def wrap_cmd_install(name: str) -> ModuleType:
|
|
649
747
|
"""
|
|
650
748
|
Wrap pip install command to store target argument state.
|
|
651
749
|
"""
|
|
652
|
-
|
|
750
|
+
module: ModuleType = importlib.import_module(name)
|
|
751
|
+
mod = cast(Any, module)
|
|
653
752
|
|
|
654
|
-
def
|
|
753
|
+
def wrap_run(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
655
754
|
@functools.wraps(func)
|
|
656
|
-
def wrapper(self, options, args):
|
|
755
|
+
def wrapper(self: Any, options: Any, args: Sequence[str]) -> Any:
|
|
657
756
|
if not options.use_user_site:
|
|
658
757
|
if options.target_dir:
|
|
659
758
|
TARGET.TARGET = True
|
|
@@ -663,11 +762,13 @@ def wrap_cmd_install(name):
|
|
|
663
762
|
|
|
664
763
|
return wrapper
|
|
665
764
|
|
|
666
|
-
mod.InstallCommand.run =
|
|
765
|
+
mod.InstallCommand.run = wrap_run(mod.InstallCommand.run)
|
|
667
766
|
|
|
668
|
-
def
|
|
767
|
+
def wrap_handle_target(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
669
768
|
@functools.wraps(func)
|
|
670
|
-
def wrapper(
|
|
769
|
+
def wrapper(
|
|
770
|
+
self: Any, target_dir: str, target_temp_dir: str, upgrade: bool
|
|
771
|
+
) -> int:
|
|
671
772
|
from pip._internal.cli.status_codes import SUCCESS
|
|
672
773
|
|
|
673
774
|
return SUCCESS
|
|
@@ -675,30 +776,37 @@ def wrap_cmd_install(name):
|
|
|
675
776
|
return wrapper
|
|
676
777
|
|
|
677
778
|
if hasattr(mod.InstallCommand, "_handle_target_dir"):
|
|
678
|
-
mod.InstallCommand._handle_target_dir =
|
|
779
|
+
mod.InstallCommand._handle_target_dir = wrap_handle_target(
|
|
679
780
|
mod.InstallCommand._handle_target_dir
|
|
680
781
|
)
|
|
681
|
-
return
|
|
782
|
+
return module
|
|
682
783
|
|
|
683
784
|
|
|
684
|
-
def wrap_locations(name):
|
|
785
|
+
def wrap_locations(name: str) -> ModuleType:
|
|
685
786
|
"""
|
|
686
787
|
Wrap pip locations to fix locations when installing with target.
|
|
687
788
|
"""
|
|
688
|
-
|
|
789
|
+
module: ModuleType = importlib.import_module(name)
|
|
790
|
+
mod = cast(Any, module)
|
|
689
791
|
|
|
690
|
-
def
|
|
792
|
+
def make_scheme_wrapper(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
691
793
|
@functools.wraps(func)
|
|
692
794
|
def wrapper(
|
|
693
|
-
dist_name
|
|
694
|
-
|
|
795
|
+
dist_name: str,
|
|
796
|
+
user: bool = False,
|
|
797
|
+
home: Optional[PathType] = None,
|
|
798
|
+
root: Optional[PathType] = None,
|
|
799
|
+
isolated: bool = False,
|
|
800
|
+
prefix: Optional[PathType] = None,
|
|
801
|
+
) -> Any:
|
|
695
802
|
scheme = func(dist_name, user, home, root, isolated, prefix)
|
|
696
803
|
if TARGET.TARGET and TARGET.INSTALL:
|
|
697
804
|
from pip._internal.models.scheme import Scheme
|
|
698
805
|
|
|
806
|
+
target_path = _ensure_target_path()
|
|
699
807
|
scheme = Scheme(
|
|
700
|
-
platlib=
|
|
701
|
-
purelib=
|
|
808
|
+
platlib=target_path,
|
|
809
|
+
purelib=target_path,
|
|
702
810
|
headers=scheme.headers,
|
|
703
811
|
scripts=scheme.scripts,
|
|
704
812
|
data=scheme.data,
|
|
@@ -709,113 +817,179 @@ def wrap_locations(name):
|
|
|
709
817
|
|
|
710
818
|
# get_scheme is not available on pip-19.2.3
|
|
711
819
|
# try:
|
|
712
|
-
mod.get_scheme =
|
|
820
|
+
mod.get_scheme = make_scheme_wrapper(mod.get_scheme)
|
|
713
821
|
# except AttributeError:
|
|
714
822
|
# debug(f"Module {mod} does not have attribute get_scheme")
|
|
715
823
|
|
|
716
|
-
return
|
|
824
|
+
return module
|
|
717
825
|
|
|
718
826
|
|
|
719
|
-
def wrap_req_command(name):
|
|
827
|
+
def wrap_req_command(name: str) -> ModuleType:
|
|
720
828
|
"""
|
|
721
829
|
Honor ignore installed option from pip cli.
|
|
722
830
|
"""
|
|
723
|
-
|
|
831
|
+
module: ModuleType = importlib.import_module(name)
|
|
832
|
+
mod = cast(Any, module)
|
|
724
833
|
|
|
725
|
-
def
|
|
834
|
+
def make_package_finder_wrapper(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
726
835
|
@functools.wraps(func)
|
|
727
836
|
def wrapper(
|
|
728
|
-
self,
|
|
729
|
-
options,
|
|
730
|
-
session,
|
|
731
|
-
target_python=None,
|
|
732
|
-
ignore_requires_python=None,
|
|
733
|
-
):
|
|
837
|
+
self: Any,
|
|
838
|
+
options: Any,
|
|
839
|
+
session: Any,
|
|
840
|
+
target_python: Any = None,
|
|
841
|
+
ignore_requires_python: Any = None,
|
|
842
|
+
) -> Any:
|
|
734
843
|
if TARGET.TARGET:
|
|
735
844
|
options.ignore_installed = TARGET.IGNORE
|
|
736
845
|
return func(self, options, session, target_python, ignore_requires_python)
|
|
737
846
|
|
|
738
847
|
return wrapper
|
|
739
848
|
|
|
740
|
-
mod.RequirementCommand._build_package_finder =
|
|
849
|
+
mod.RequirementCommand._build_package_finder = make_package_finder_wrapper(
|
|
741
850
|
mod.RequirementCommand._build_package_finder
|
|
742
851
|
)
|
|
743
|
-
return
|
|
852
|
+
return module
|
|
744
853
|
|
|
745
854
|
|
|
746
|
-
def wrap_req_install(name):
|
|
855
|
+
def wrap_req_install(name: str) -> ModuleType:
|
|
747
856
|
"""
|
|
748
857
|
Honor ignore installed option from pip cli.
|
|
749
858
|
"""
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
def wrap(func):
|
|
753
|
-
if mod.InstallRequirement.install.__code__.co_argcount == 9:
|
|
754
|
-
|
|
755
|
-
@functools.wraps(func)
|
|
756
|
-
def wrapper(
|
|
757
|
-
self,
|
|
758
|
-
install_options,
|
|
759
|
-
global_options=None,
|
|
760
|
-
root=None,
|
|
761
|
-
home=None,
|
|
762
|
-
prefix=None,
|
|
763
|
-
warn_script_location=True,
|
|
764
|
-
use_user_site=False,
|
|
765
|
-
pycompile=True,
|
|
766
|
-
):
|
|
767
|
-
try:
|
|
768
|
-
if TARGET.TARGET:
|
|
769
|
-
TARGET.INSTALL = True
|
|
770
|
-
home = TARGET.PATH
|
|
771
|
-
return func(
|
|
772
|
-
self,
|
|
773
|
-
install_options,
|
|
774
|
-
global_options,
|
|
775
|
-
root,
|
|
776
|
-
home,
|
|
777
|
-
prefix,
|
|
778
|
-
warn_script_location,
|
|
779
|
-
use_user_site,
|
|
780
|
-
pycompile,
|
|
781
|
-
)
|
|
782
|
-
finally:
|
|
783
|
-
TARGET.INSTALL = False
|
|
859
|
+
module: ModuleType = importlib.import_module(name)
|
|
860
|
+
mod = cast(Any, module)
|
|
784
861
|
|
|
785
|
-
|
|
862
|
+
original = mod.InstallRequirement.install
|
|
863
|
+
argcount = original.__code__.co_argcount
|
|
786
864
|
|
|
787
|
-
|
|
788
|
-
def wrapper(
|
|
789
|
-
self,
|
|
790
|
-
global_options=None,
|
|
791
|
-
root=None,
|
|
792
|
-
home=None,
|
|
793
|
-
prefix=None,
|
|
794
|
-
warn_script_location=True,
|
|
795
|
-
use_user_site=False,
|
|
796
|
-
pycompile=True,
|
|
797
|
-
):
|
|
798
|
-
try:
|
|
799
|
-
if TARGET.TARGET:
|
|
800
|
-
TARGET.INSTALL = True
|
|
801
|
-
home = TARGET.PATH
|
|
802
|
-
return func(
|
|
803
|
-
self,
|
|
804
|
-
global_options,
|
|
805
|
-
root,
|
|
806
|
-
home,
|
|
807
|
-
prefix,
|
|
808
|
-
warn_script_location,
|
|
809
|
-
use_user_site,
|
|
810
|
-
pycompile,
|
|
811
|
-
)
|
|
812
|
-
finally:
|
|
813
|
-
TARGET.INSTALL = False
|
|
865
|
+
if argcount == 7:
|
|
814
866
|
|
|
815
|
-
|
|
867
|
+
@functools.wraps(original)
|
|
868
|
+
def install_wrapper_pep517(
|
|
869
|
+
self: Any,
|
|
870
|
+
root: Optional[PathType] = None,
|
|
871
|
+
home: Optional[PathType] = None,
|
|
872
|
+
prefix: Optional[PathType] = None,
|
|
873
|
+
warn_script_location: bool = True,
|
|
874
|
+
use_user_site: bool = False,
|
|
875
|
+
pycompile: bool = True,
|
|
876
|
+
) -> Any:
|
|
877
|
+
try:
|
|
878
|
+
if TARGET.TARGET:
|
|
879
|
+
TARGET.INSTALL = True
|
|
880
|
+
home = _ensure_target_path()
|
|
881
|
+
return original(
|
|
882
|
+
self,
|
|
883
|
+
root,
|
|
884
|
+
home,
|
|
885
|
+
prefix,
|
|
886
|
+
warn_script_location,
|
|
887
|
+
use_user_site,
|
|
888
|
+
pycompile,
|
|
889
|
+
)
|
|
890
|
+
finally:
|
|
891
|
+
TARGET.INSTALL = False
|
|
892
|
+
|
|
893
|
+
mod.InstallRequirement.install = install_wrapper_pep517
|
|
894
|
+
|
|
895
|
+
elif argcount == 8:
|
|
896
|
+
|
|
897
|
+
@functools.wraps(original)
|
|
898
|
+
def install_wrapper_pep517_opts(
|
|
899
|
+
self: Any,
|
|
900
|
+
global_options: Any = None,
|
|
901
|
+
root: Optional[PathType] = None,
|
|
902
|
+
home: Optional[PathType] = None,
|
|
903
|
+
prefix: Optional[PathType] = None,
|
|
904
|
+
warn_script_location: bool = True,
|
|
905
|
+
use_user_site: bool = False,
|
|
906
|
+
pycompile: bool = True,
|
|
907
|
+
) -> Any:
|
|
908
|
+
try:
|
|
909
|
+
if TARGET.TARGET:
|
|
910
|
+
TARGET.INSTALL = True
|
|
911
|
+
home = _ensure_target_path()
|
|
912
|
+
return original(
|
|
913
|
+
self,
|
|
914
|
+
global_options,
|
|
915
|
+
root,
|
|
916
|
+
home,
|
|
917
|
+
prefix,
|
|
918
|
+
warn_script_location,
|
|
919
|
+
use_user_site,
|
|
920
|
+
pycompile,
|
|
921
|
+
)
|
|
922
|
+
finally:
|
|
923
|
+
TARGET.INSTALL = False
|
|
924
|
+
|
|
925
|
+
mod.InstallRequirement.install = install_wrapper_pep517_opts
|
|
926
|
+
|
|
927
|
+
elif argcount == 9:
|
|
928
|
+
|
|
929
|
+
@functools.wraps(original)
|
|
930
|
+
def install_wrapper_legacy(
|
|
931
|
+
self: Any,
|
|
932
|
+
install_options: Any,
|
|
933
|
+
global_options: Any = None,
|
|
934
|
+
root: Optional[PathType] = None,
|
|
935
|
+
home: Optional[PathType] = None,
|
|
936
|
+
prefix: Optional[PathType] = None,
|
|
937
|
+
warn_script_location: bool = True,
|
|
938
|
+
use_user_site: bool = False,
|
|
939
|
+
pycompile: bool = True,
|
|
940
|
+
) -> Any:
|
|
941
|
+
try:
|
|
942
|
+
if TARGET.TARGET:
|
|
943
|
+
TARGET.INSTALL = True
|
|
944
|
+
home = _ensure_target_path()
|
|
945
|
+
return original(
|
|
946
|
+
self,
|
|
947
|
+
install_options,
|
|
948
|
+
global_options,
|
|
949
|
+
root,
|
|
950
|
+
home,
|
|
951
|
+
prefix,
|
|
952
|
+
warn_script_location,
|
|
953
|
+
use_user_site,
|
|
954
|
+
pycompile,
|
|
955
|
+
)
|
|
956
|
+
finally:
|
|
957
|
+
TARGET.INSTALL = False
|
|
958
|
+
|
|
959
|
+
mod.InstallRequirement.install = install_wrapper_legacy
|
|
960
|
+
|
|
961
|
+
else:
|
|
962
|
+
|
|
963
|
+
@functools.wraps(original)
|
|
964
|
+
def install_wrapper_generic(
|
|
965
|
+
self: Any,
|
|
966
|
+
global_options: Any = None,
|
|
967
|
+
root: Optional[PathType] = None,
|
|
968
|
+
home: Optional[PathType] = None,
|
|
969
|
+
prefix: Optional[PathType] = None,
|
|
970
|
+
warn_script_location: bool = True,
|
|
971
|
+
use_user_site: bool = False,
|
|
972
|
+
pycompile: bool = True,
|
|
973
|
+
) -> Any:
|
|
974
|
+
try:
|
|
975
|
+
if TARGET.TARGET:
|
|
976
|
+
TARGET.INSTALL = True
|
|
977
|
+
home = _ensure_target_path()
|
|
978
|
+
return original(
|
|
979
|
+
self,
|
|
980
|
+
global_options,
|
|
981
|
+
root,
|
|
982
|
+
home,
|
|
983
|
+
prefix,
|
|
984
|
+
warn_script_location,
|
|
985
|
+
use_user_site,
|
|
986
|
+
pycompile,
|
|
987
|
+
)
|
|
988
|
+
finally:
|
|
989
|
+
TARGET.INSTALL = False
|
|
816
990
|
|
|
817
|
-
|
|
818
|
-
return
|
|
991
|
+
mod.InstallRequirement.install = install_wrapper_generic
|
|
992
|
+
return module
|
|
819
993
|
|
|
820
994
|
|
|
821
995
|
importer = RelenvImporter(
|
|
@@ -834,7 +1008,7 @@ importer = RelenvImporter(
|
|
|
834
1008
|
)
|
|
835
1009
|
|
|
836
1010
|
|
|
837
|
-
def install_cargo_config():
|
|
1011
|
+
def install_cargo_config() -> None:
|
|
838
1012
|
"""
|
|
839
1013
|
Setup cargo config.
|
|
840
1014
|
"""
|
|
@@ -845,8 +1019,8 @@ def install_cargo_config():
|
|
|
845
1019
|
# load the ssl module. Causing out setup_openssl method to fail to load
|
|
846
1020
|
# fips module.
|
|
847
1021
|
dirs = common().work_dirs()
|
|
848
|
-
triplet = common().get_triplet()
|
|
849
1022
|
cargo_home = dirs.data / "cargo"
|
|
1023
|
+
triplet = common().get_triplet()
|
|
850
1024
|
|
|
851
1025
|
toolchain = common().get_toolchain()
|
|
852
1026
|
if not toolchain:
|
|
@@ -858,27 +1032,46 @@ def install_cargo_config():
|
|
|
858
1032
|
return
|
|
859
1033
|
|
|
860
1034
|
# cargo_home = dirs.data / "cargo"
|
|
861
|
-
|
|
862
|
-
cargo_home.mkdir()
|
|
1035
|
+
cargo_home.mkdir(parents=True, exist_ok=True)
|
|
863
1036
|
cargo_config = cargo_home / "config.toml"
|
|
864
|
-
if
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1037
|
+
if triplet == "x86_64-linux-gnu":
|
|
1038
|
+
cargo_triplet = "x86_64-unknown-linux-gnu"
|
|
1039
|
+
else:
|
|
1040
|
+
cargo_triplet = "aarch64-unknown-linux-gnu"
|
|
1041
|
+
gcc = toolchain / "bin" / f"{triplet}-gcc"
|
|
1042
|
+
|
|
1043
|
+
def existing_linker() -> str | None:
|
|
1044
|
+
if not cargo_config.exists():
|
|
1045
|
+
return None
|
|
1046
|
+
try:
|
|
1047
|
+
contents = cargo_config.read_text()
|
|
1048
|
+
except OSError:
|
|
1049
|
+
return None
|
|
1050
|
+
marker = f"[target.{cargo_triplet}]"
|
|
1051
|
+
if marker not in contents:
|
|
1052
|
+
return None
|
|
1053
|
+
for line in contents.splitlines():
|
|
1054
|
+
stripped = line.strip()
|
|
1055
|
+
if stripped.startswith("linker"):
|
|
1056
|
+
value_part: str
|
|
1057
|
+
_, _, value_part = stripped.partition("=")
|
|
1058
|
+
value_str: str = value_part.strip().strip('"')
|
|
1059
|
+
if value_str:
|
|
1060
|
+
return value_str
|
|
1061
|
+
return None
|
|
1062
|
+
|
|
1063
|
+
if existing_linker() != str(gcc):
|
|
1064
|
+
cargo_config.write_text(
|
|
1065
|
+
textwrap.dedent(
|
|
1066
|
+
"""\
|
|
1067
|
+
[target.{triplet}]
|
|
1068
|
+
linker = "{linker}"
|
|
876
1069
|
"""
|
|
877
|
-
|
|
878
|
-
|
|
1070
|
+
).format(triplet=cargo_triplet, linker=gcc)
|
|
1071
|
+
)
|
|
879
1072
|
|
|
880
1073
|
|
|
881
|
-
def setup_openssl():
|
|
1074
|
+
def setup_openssl() -> None:
|
|
882
1075
|
"""
|
|
883
1076
|
Configure openssl certificate locations.
|
|
884
1077
|
"""
|
|
@@ -918,7 +1111,7 @@ def setup_openssl():
|
|
|
918
1111
|
debug(msg)
|
|
919
1112
|
else:
|
|
920
1113
|
try:
|
|
921
|
-
_, directory = proc.stdout.split(":")
|
|
1114
|
+
_, directory = proc.stdout.split(":", 1)
|
|
922
1115
|
except ValueError:
|
|
923
1116
|
debug("Unable to parse modules dir")
|
|
924
1117
|
return
|
|
@@ -952,7 +1145,7 @@ def setup_openssl():
|
|
|
952
1145
|
debug(msg)
|
|
953
1146
|
else:
|
|
954
1147
|
try:
|
|
955
|
-
_, directory = proc.stdout.split(":")
|
|
1148
|
+
_, directory = proc.stdout.split(":", 1)
|
|
956
1149
|
except ValueError:
|
|
957
1150
|
debug("Unable to parse openssldir")
|
|
958
1151
|
return
|
|
@@ -964,7 +1157,7 @@ def setup_openssl():
|
|
|
964
1157
|
os.environ["SSL_CERT_FILE"] = str(cert_file)
|
|
965
1158
|
|
|
966
1159
|
|
|
967
|
-
def set_openssl_modules_dir(path):
|
|
1160
|
+
def set_openssl_modules_dir(path: str) -> None:
|
|
968
1161
|
"""
|
|
969
1162
|
Set the default search location for openssl modules.
|
|
970
1163
|
"""
|
|
@@ -982,7 +1175,7 @@ def set_openssl_modules_dir(path):
|
|
|
982
1175
|
OSSL_PROVIDER_set_default_search_path(None, path.encode())
|
|
983
1176
|
|
|
984
1177
|
|
|
985
|
-
def load_openssl_provider(name):
|
|
1178
|
+
def load_openssl_provider(name: str) -> int:
|
|
986
1179
|
"""
|
|
987
1180
|
Load an openssl module.
|
|
988
1181
|
"""
|
|
@@ -995,10 +1188,11 @@ def load_openssl_provider(name):
|
|
|
995
1188
|
OSSL_PROVIDER_load = libcrypto.OSSL_PROVIDER_load
|
|
996
1189
|
OSSL_PROVIDER_load.argtypes = (POSSL_LIB_CTX, ctypes.c_char_p)
|
|
997
1190
|
OSSL_PROVIDER_load.restype = ctypes.c_int
|
|
998
|
-
|
|
1191
|
+
result = OSSL_PROVIDER_load(None, name.encode())
|
|
1192
|
+
return int(result)
|
|
999
1193
|
|
|
1000
1194
|
|
|
1001
|
-
def setup_crossroot():
|
|
1195
|
+
def setup_crossroot() -> None:
|
|
1002
1196
|
"""
|
|
1003
1197
|
Setup cross root if needed.
|
|
1004
1198
|
"""
|
|
@@ -1016,7 +1210,7 @@ def setup_crossroot():
|
|
|
1016
1210
|
] + [_ for _ in sys.path if "site-packages" not in _]
|
|
1017
1211
|
|
|
1018
1212
|
|
|
1019
|
-
def wrapsitecustomize(func):
|
|
1213
|
+
def wrapsitecustomize(func: Callable[[], Any]) -> Callable[[], None]:
|
|
1020
1214
|
"""
|
|
1021
1215
|
Wrap site.execsitecustomize.
|
|
1022
1216
|
|
|
@@ -1025,12 +1219,14 @@ def wrapsitecustomize(func):
|
|
|
1025
1219
|
"""
|
|
1026
1220
|
|
|
1027
1221
|
@functools.wraps(func)
|
|
1028
|
-
def wrapper():
|
|
1222
|
+
def wrapper() -> None:
|
|
1029
1223
|
func()
|
|
1030
1224
|
|
|
1031
|
-
|
|
1225
|
+
sitecustomize_module = None
|
|
1032
1226
|
try:
|
|
1033
|
-
import sitecustomize
|
|
1227
|
+
import sitecustomize as _sitecustomize
|
|
1228
|
+
|
|
1229
|
+
sitecustomize_module = _sitecustomize
|
|
1034
1230
|
except ImportError as exc:
|
|
1035
1231
|
if exc.name != "sitecustomize":
|
|
1036
1232
|
raise
|
|
@@ -1039,7 +1235,10 @@ def wrapsitecustomize(func):
|
|
|
1039
1235
|
# relenv environment. This can't be done when pip is using build_env to
|
|
1040
1236
|
# install packages. This code seems potentially brittle and there may
|
|
1041
1237
|
# be reasonable arguments against doing it at all.
|
|
1042
|
-
if
|
|
1238
|
+
if (
|
|
1239
|
+
sitecustomize_module is None
|
|
1240
|
+
or "pip-build-env" not in sitecustomize_module.__file__
|
|
1241
|
+
):
|
|
1043
1242
|
_orig = sys.path[:]
|
|
1044
1243
|
# Replace sys.path
|
|
1045
1244
|
sys.path[:] = common().sanitize_sys_path(sys.path)
|
|
@@ -1054,7 +1253,7 @@ def wrapsitecustomize(func):
|
|
|
1054
1253
|
return wrapper
|
|
1055
1254
|
|
|
1056
1255
|
|
|
1057
|
-
def bootstrap():
|
|
1256
|
+
def bootstrap() -> None:
|
|
1058
1257
|
"""
|
|
1059
1258
|
Bootstrap the relenv environment.
|
|
1060
1259
|
"""
|