pex 2.66.0__py2.py3-none-any.whl → 2.67.0__py2.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.
Potentially problematic release.
This version of pex might be problematic. Click here for more details.
- pex/docs/html/_pagefind/fragment/en_4dc5d41.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_5ff234a.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_7faba29.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_8531963.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_8d197bb.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_e195b46.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/{en_af1fb65.pf_fragment → en_f384da1.pf_fragment} +0 -0
- pex/docs/html/_pagefind/fragment/en_fbb9204.pf_fragment +0 -0
- pex/docs/html/_pagefind/index/{en_f48c2e4.pf_index → en_c236b81.pf_index} +0 -0
- pex/docs/html/_pagefind/pagefind-entry.json +1 -1
- pex/docs/html/_pagefind/pagefind.en_849a96a3e6.pf_meta +0 -0
- pex/docs/html/_static/documentation_options.js +1 -1
- pex/docs/html/api/vars.html +5 -5
- pex/docs/html/buildingpex.html +5 -5
- pex/docs/html/genindex.html +5 -5
- pex/docs/html/index.html +5 -5
- pex/docs/html/recipes.html +5 -5
- pex/docs/html/scie.html +5 -5
- pex/docs/html/search.html +5 -5
- pex/docs/html/whatispex.html +5 -5
- pex/jobs.py +13 -6
- pex/resolve/configured_resolve.py +13 -5
- pex/resolve/locker.py +17 -12
- pex/resolve/lockfile/create.py +1 -6
- pex/resolve/pre_resolved_resolver.py +1 -7
- pex/resolve/resolver_configuration.py +1 -1
- pex/resolve/resolver_options.py +14 -9
- pex/resolve/venv_resolver.py +189 -55
- pex/resolver.py +40 -35
- pex/version.py +1 -1
- {pex-2.66.0.dist-info → pex-2.67.0.dist-info}/METADATA +4 -4
- {pex-2.66.0.dist-info → pex-2.67.0.dist-info}/RECORD +37 -37
- pex/docs/html/_pagefind/fragment/en_1caf19d.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_2268ed8.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_469c87d.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_4a75d8d.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_9fe4bcc.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_a951443.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_e0b014e.pf_fragment +0 -0
- pex/docs/html/_pagefind/pagefind.en_4eb6e6f279.pf_meta +0 -0
- {pex-2.66.0.dist-info → pex-2.67.0.dist-info}/WHEEL +0 -0
- {pex-2.66.0.dist-info → pex-2.67.0.dist-info}/entry_points.txt +0 -0
- {pex-2.66.0.dist-info → pex-2.67.0.dist-info}/licenses/LICENSE +0 -0
- {pex-2.66.0.dist-info → pex-2.67.0.dist-info}/pylock/pylock.toml +0 -0
- {pex-2.66.0.dist-info → pex-2.67.0.dist-info}/top_level.txt +0 -0
pex/resolve/resolver_options.py
CHANGED
|
@@ -56,9 +56,10 @@ class _HandleTransitiveAction(Action):
|
|
|
56
56
|
class _ResolveVenvAction(Action):
|
|
57
57
|
def __init__(self, *args, **kwargs):
|
|
58
58
|
kwargs["nargs"] = "?"
|
|
59
|
-
super(_ResolveVenvAction, self).__init__(*args, **kwargs)
|
|
59
|
+
super(_ResolveVenvAction, self).__init__(*args, default=[], **kwargs)
|
|
60
60
|
|
|
61
61
|
def __call__(self, parser, namespace, value, option_str=None):
|
|
62
|
+
venvs = getattr(namespace, self.dest)
|
|
62
63
|
if value:
|
|
63
64
|
if not os.path.exists(value):
|
|
64
65
|
raise ArgumentError(
|
|
@@ -86,7 +87,7 @@ class _ResolveVenvAction(Action):
|
|
|
86
87
|
"path.".format(option=option_str, value=value)
|
|
87
88
|
),
|
|
88
89
|
)
|
|
89
|
-
|
|
90
|
+
venvs.append(venv)
|
|
90
91
|
else:
|
|
91
92
|
current_venv = Virtualenv.enclosing(python=sys.executable)
|
|
92
93
|
if not current_venv:
|
|
@@ -105,7 +106,7 @@ class _ResolveVenvAction(Action):
|
|
|
105
106
|
)
|
|
106
107
|
),
|
|
107
108
|
)
|
|
108
|
-
|
|
109
|
+
venvs.append(current_venv)
|
|
109
110
|
|
|
110
111
|
|
|
111
112
|
def register(
|
|
@@ -320,14 +321,18 @@ def register(
|
|
|
320
321
|
if include_venv_repository:
|
|
321
322
|
repository_choice.add_argument(
|
|
322
323
|
"--venv-repository",
|
|
323
|
-
dest="
|
|
324
|
+
dest="venv_repositories",
|
|
324
325
|
action=_ResolveVenvAction,
|
|
325
|
-
type=str,
|
|
326
326
|
help=(
|
|
327
327
|
"Resolve requirements from the given virtual environment instead of from "
|
|
328
328
|
"--index servers, --find-links repos or a --lock file. The virtual environment to "
|
|
329
329
|
"resolve from can be specified as the path to the venv or the path of its"
|
|
330
|
-
"interpreter. If no value is specified, the current active venv is used."
|
|
330
|
+
"interpreter. If no value is specified, the current active venv is used. Multiple "
|
|
331
|
+
"virtual environments may be specified via multiple --venv-repository options and "
|
|
332
|
+
"the resolve will be the combined results. Each virtual environment will be "
|
|
333
|
+
"resolved from individually and must contain the full transitive closure of "
|
|
334
|
+
"requirements. This allows for creating a multi-platform PEX by specifying "
|
|
335
|
+
"multiple virtual environments; say one for Python 3.12 and one for Python 3.13."
|
|
331
336
|
),
|
|
332
337
|
)
|
|
333
338
|
|
|
@@ -803,9 +808,9 @@ def configure(
|
|
|
803
808
|
sdists=tuple(sdists), wheels=tuple(wheels), pip_configuration=pip_configuration
|
|
804
809
|
)
|
|
805
810
|
|
|
806
|
-
|
|
807
|
-
if
|
|
808
|
-
return VenvRepositoryConfiguration(
|
|
811
|
+
venvs = getattr(options, "venv_repositories", None)
|
|
812
|
+
if venvs:
|
|
813
|
+
return VenvRepositoryConfiguration(venvs=tuple(venvs), pip_configuration=pip_configuration)
|
|
809
814
|
|
|
810
815
|
if pylock:
|
|
811
816
|
return PylockRepositoryConfiguration(
|
pex/resolve/venv_resolver.py
CHANGED
|
@@ -5,14 +5,13 @@ from __future__ import absolute_import
|
|
|
5
5
|
|
|
6
6
|
import functools
|
|
7
7
|
import hashlib
|
|
8
|
-
import itertools
|
|
9
8
|
import os
|
|
10
9
|
from collections import defaultdict, deque
|
|
11
10
|
|
|
12
11
|
from pex import pex_warnings
|
|
13
12
|
from pex.atomic_directory import atomic_directory
|
|
14
13
|
from pex.cache.dirs import CacheDir, InstalledWheelDir
|
|
15
|
-
from pex.common import safe_relative_symlink
|
|
14
|
+
from pex.common import pluralize, safe_relative_symlink
|
|
16
15
|
from pex.compatibility import commonpath
|
|
17
16
|
from pex.dependency_configuration import DependencyConfiguration
|
|
18
17
|
from pex.dist_metadata import (
|
|
@@ -26,7 +25,6 @@ from pex.dist_metadata import (
|
|
|
26
25
|
from pex.exceptions import production_assert, reportable_unexpected_error_msg
|
|
27
26
|
from pex.fingerprinted_distribution import FingerprintedDistribution
|
|
28
27
|
from pex.installed_wheel import InstalledWheel
|
|
29
|
-
from pex.interpreter import PythonInterpreter
|
|
30
28
|
from pex.jobs import DEFAULT_MAX_JOBS, iter_map_parallel
|
|
31
29
|
from pex.orderedset import OrderedSet
|
|
32
30
|
from pex.pep_376 import Record
|
|
@@ -47,7 +45,18 @@ from pex.wheel import WHEEL, Wheel
|
|
|
47
45
|
from pex.whl import repacked_whl
|
|
48
46
|
|
|
49
47
|
if TYPE_CHECKING:
|
|
50
|
-
from typing import
|
|
48
|
+
from typing import (
|
|
49
|
+
DefaultDict,
|
|
50
|
+
Deque,
|
|
51
|
+
FrozenSet,
|
|
52
|
+
Iterable,
|
|
53
|
+
Iterator,
|
|
54
|
+
List,
|
|
55
|
+
Mapping,
|
|
56
|
+
Set,
|
|
57
|
+
Tuple,
|
|
58
|
+
Union,
|
|
59
|
+
)
|
|
51
60
|
|
|
52
61
|
import attr # vendor:skip
|
|
53
62
|
else:
|
|
@@ -96,12 +105,14 @@ def _normalize_record(
|
|
|
96
105
|
|
|
97
106
|
|
|
98
107
|
def _install_distribution(
|
|
99
|
-
|
|
108
|
+
venv_distribution, # type: VenvDistribution
|
|
100
109
|
result_type, # type: InstallableType.Value
|
|
101
110
|
use_system_time, # type: bool
|
|
102
|
-
distribution, # type: Distribution
|
|
103
111
|
):
|
|
104
|
-
# type: (...) ->
|
|
112
|
+
# type: (...) -> ResolvedDistribution
|
|
113
|
+
|
|
114
|
+
interpreter = venv_distribution.target.interpreter
|
|
115
|
+
distribution = venv_distribution.distribution
|
|
105
116
|
|
|
106
117
|
production_assert(distribution.type is DistributionType.INSTALLED)
|
|
107
118
|
production_assert(distribution.metadata.files.metadata.type is MetadataType.DIST_INFO)
|
|
@@ -160,31 +171,86 @@ def _install_distribution(
|
|
|
160
171
|
raise AssertionError(reportable_unexpected_error_msg())
|
|
161
172
|
|
|
162
173
|
if result_type is InstallableType.INSTALLED_WHEEL_CHROOT:
|
|
163
|
-
return
|
|
164
|
-
|
|
165
|
-
|
|
174
|
+
return ResolvedDistribution(
|
|
175
|
+
target=venv_distribution.target,
|
|
176
|
+
fingerprinted_distribution=FingerprintedDistribution(
|
|
177
|
+
distribution=Distribution.load(installed_wheel.prefix_dir),
|
|
178
|
+
fingerprint=installed_wheel.fingerprint,
|
|
179
|
+
),
|
|
180
|
+
direct_requirements=venv_distribution.direct_requirements,
|
|
166
181
|
)
|
|
167
|
-
|
|
168
|
-
|
|
182
|
+
|
|
183
|
+
return ResolvedDistribution(
|
|
184
|
+
target=venv_distribution.target,
|
|
185
|
+
fingerprinted_distribution=repacked_whl(
|
|
186
|
+
installed_wheel,
|
|
187
|
+
fingerprint=installed_wheel.fingerprint,
|
|
188
|
+
use_system_time=use_system_time,
|
|
189
|
+
),
|
|
190
|
+
direct_requirements=venv_distribution.direct_requirements,
|
|
169
191
|
)
|
|
170
192
|
|
|
171
193
|
|
|
194
|
+
@attr.s(frozen=True)
|
|
195
|
+
class VenvDistribution(object):
|
|
196
|
+
target = attr.ib() # type: LocalInterpreter
|
|
197
|
+
distribution = attr.ib() # type: Distribution
|
|
198
|
+
direct_requirements = attr.ib() # type: Iterable[Requirement]
|
|
199
|
+
|
|
200
|
+
|
|
172
201
|
def _install_venv_distributions(
|
|
173
|
-
|
|
174
|
-
distributions, # type: Iterable[Distribution]
|
|
202
|
+
venv_resolve_results, # type: Iterable[VenvResolveResult]
|
|
175
203
|
max_install_jobs=DEFAULT_MAX_JOBS, # type: int
|
|
176
204
|
result_type=InstallableType.INSTALLED_WHEEL_CHROOT, # type: InstallableType.Value
|
|
177
205
|
use_system_time=False, # type: bool
|
|
178
206
|
):
|
|
179
|
-
# type: (...) -> Iterator[
|
|
207
|
+
# type: (...) -> Iterator[ResolvedDistribution]
|
|
208
|
+
|
|
209
|
+
seen = set() # type: Set[str]
|
|
210
|
+
|
|
211
|
+
venv_distributions = [] # type: List[VenvDistribution]
|
|
212
|
+
for venv_resolve_result in venv_resolve_results:
|
|
213
|
+
target = venv_resolve_result.target
|
|
214
|
+
direct_requirements = venv_resolve_result.direct_requirements_by_project_name
|
|
215
|
+
for re_resolved_distribution in venv_resolve_result.re_resolved_distributions:
|
|
216
|
+
wheel_file_name = Wheel.from_distribution(
|
|
217
|
+
re_resolved_distribution.distribution
|
|
218
|
+
).wheel_file_name
|
|
219
|
+
if wheel_file_name in seen:
|
|
220
|
+
continue
|
|
221
|
+
|
|
222
|
+
seen.add(wheel_file_name)
|
|
223
|
+
yield ResolvedDistribution(
|
|
224
|
+
target=target,
|
|
225
|
+
fingerprinted_distribution=re_resolved_distribution,
|
|
226
|
+
direct_requirements=direct_requirements.get(
|
|
227
|
+
re_resolved_distribution.project_name, ()
|
|
228
|
+
),
|
|
229
|
+
)
|
|
230
|
+
for venv_distribution in venv_resolve_result.venv_distributions:
|
|
231
|
+
wheel_file_name = Wheel.from_distribution(venv_distribution).wheel_file_name
|
|
232
|
+
if wheel_file_name in seen:
|
|
233
|
+
continue
|
|
234
|
+
|
|
235
|
+
seen.add(wheel_file_name)
|
|
236
|
+
venv_distributions.append(
|
|
237
|
+
VenvDistribution(
|
|
238
|
+
target=target,
|
|
239
|
+
distribution=venv_distribution,
|
|
240
|
+
direct_requirements=direct_requirements.get(
|
|
241
|
+
venv_distribution.metadata.project_name, ()
|
|
242
|
+
),
|
|
243
|
+
)
|
|
244
|
+
)
|
|
180
245
|
|
|
181
|
-
|
|
182
|
-
inputs=
|
|
246
|
+
for resolved_distribution in iter_map_parallel(
|
|
247
|
+
inputs=venv_distributions,
|
|
183
248
|
function=functools.partial(
|
|
184
|
-
_install_distribution,
|
|
249
|
+
_install_distribution, result_type=result_type, use_system_time=use_system_time
|
|
185
250
|
),
|
|
186
251
|
max_jobs=max_install_jobs,
|
|
187
|
-
)
|
|
252
|
+
):
|
|
253
|
+
yield resolved_distribution
|
|
188
254
|
|
|
189
255
|
|
|
190
256
|
@attr.s(frozen=True)
|
|
@@ -359,27 +425,32 @@ def _resolve_distributions(
|
|
|
359
425
|
)
|
|
360
426
|
|
|
361
427
|
|
|
362
|
-
|
|
363
|
-
|
|
428
|
+
@attr.s(frozen=True)
|
|
429
|
+
class VenvResolveResult(object):
|
|
430
|
+
venv = attr.ib() # type: Virtualenv
|
|
431
|
+
venv_distributions = attr.ib() # type: Tuple[Distribution, ...]
|
|
432
|
+
re_resolved_distributions = attr.ib() # type: Tuple[FingerprintedDistribution, ...]
|
|
433
|
+
direct_requirements_by_project_name = attr.ib(
|
|
434
|
+
eq=False
|
|
435
|
+
) # type: Mapping[ProjectName, Iterable[Requirement]]
|
|
436
|
+
|
|
437
|
+
@property
|
|
438
|
+
def target(self):
|
|
439
|
+
# type: () -> LocalInterpreter
|
|
440
|
+
return LocalInterpreter.create(self.venv.interpreter)
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def _resolve_from_venv(
|
|
364
444
|
venv, # type: Virtualenv
|
|
365
|
-
requirement_configuration
|
|
366
|
-
pip_configuration
|
|
367
|
-
compile
|
|
368
|
-
ignore_errors
|
|
369
|
-
result_type
|
|
370
|
-
dependency_configuration
|
|
445
|
+
requirement_configuration, # type: RequirementConfiguration
|
|
446
|
+
pip_configuration, # type: PipConfiguration
|
|
447
|
+
compile, # type: bool
|
|
448
|
+
ignore_errors, # type: bool
|
|
449
|
+
result_type, # type: InstallableType.Value
|
|
450
|
+
dependency_configuration, # type: DependencyConfiguration
|
|
371
451
|
):
|
|
372
|
-
# type: (...) -> Union[
|
|
373
|
-
|
|
452
|
+
# type: (...) -> Union[VenvResolveResult, Error]
|
|
374
453
|
target = LocalInterpreter.create(venv.interpreter)
|
|
375
|
-
if not targets.is_empty:
|
|
376
|
-
return Error(
|
|
377
|
-
"You configured custom targets via --python, --interpreter-constraint, --platform or "
|
|
378
|
-
"--complete-platform but custom targets are not allowed when resolving from a virtual "
|
|
379
|
-
"environment.\n"
|
|
380
|
-
"For such resolves, the supported target is implicitly the one matching the venv "
|
|
381
|
-
"interpreter; in this case: {target}.".format(target=target.render_description())
|
|
382
|
-
)
|
|
383
454
|
|
|
384
455
|
if pip_configuration.version:
|
|
385
456
|
compatible_pip_version = (
|
|
@@ -487,27 +558,90 @@ def resolve_from_venv(
|
|
|
487
558
|
dist.fingerprinted_distribution for dist in result.distributions
|
|
488
559
|
)
|
|
489
560
|
|
|
561
|
+
return VenvResolveResult(
|
|
562
|
+
venv=venv,
|
|
563
|
+
venv_distributions=tuple(venv_distributions),
|
|
564
|
+
re_resolved_distributions=tuple(fingerprinted_distributions),
|
|
565
|
+
direct_requirements_by_project_name=direct_requirements_by_project_name,
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
def resolve_from_venvs(
|
|
570
|
+
targets, # type: Targets
|
|
571
|
+
venvs, # type: Tuple[Virtualenv, ...]
|
|
572
|
+
requirement_configuration=RequirementConfiguration(), # type: RequirementConfiguration
|
|
573
|
+
pip_configuration=PipConfiguration(), # type: PipConfiguration
|
|
574
|
+
compile=False, # type: bool
|
|
575
|
+
ignore_errors=False, # type: bool
|
|
576
|
+
result_type=InstallableType.INSTALLED_WHEEL_CHROOT, # type: InstallableType.Value
|
|
577
|
+
dependency_configuration=DependencyConfiguration(), # type: DependencyConfiguration
|
|
578
|
+
):
|
|
579
|
+
# type: (...) -> Union[ResolveResult, Error]
|
|
580
|
+
|
|
581
|
+
if not targets.is_empty:
|
|
582
|
+
return Error(
|
|
583
|
+
"You configured custom targets via --python, --interpreter-constraint, --platform or "
|
|
584
|
+
"--complete-platform but custom targets are not allowed when resolving from {venvs}.\n"
|
|
585
|
+
"For such resolves, the supported target is implicitly the one matching the venv "
|
|
586
|
+
"{interpreters}; in this case:{targets}.".format(
|
|
587
|
+
venvs="a virtual environment" if len(venvs) == 1 else "virtual environments",
|
|
588
|
+
interpreters=pluralize(venvs, "interpreter"),
|
|
589
|
+
targets=(
|
|
590
|
+
" {target}".format(
|
|
591
|
+
target=LocalInterpreter.create(venvs[0].interpreter).render_description()
|
|
592
|
+
)
|
|
593
|
+
if len(venvs) == 1
|
|
594
|
+
else "\n {targets}".format(
|
|
595
|
+
targets="\n ".join(
|
|
596
|
+
LocalInterpreter.create(venv.interpreter).render_description()
|
|
597
|
+
for venv in venvs
|
|
598
|
+
)
|
|
599
|
+
)
|
|
600
|
+
),
|
|
601
|
+
)
|
|
602
|
+
)
|
|
603
|
+
|
|
604
|
+
errors = [] # type: List[Error]
|
|
605
|
+
venv_resolve_results = [] # type: List[VenvResolveResult]
|
|
606
|
+
for result in iter_map_parallel(
|
|
607
|
+
venvs,
|
|
608
|
+
functools.partial(
|
|
609
|
+
_resolve_from_venv,
|
|
610
|
+
requirement_configuration=requirement_configuration,
|
|
611
|
+
pip_configuration=pip_configuration,
|
|
612
|
+
compile=compile,
|
|
613
|
+
ignore_errors=ignore_errors,
|
|
614
|
+
result_type=result_type,
|
|
615
|
+
dependency_configuration=dependency_configuration,
|
|
616
|
+
),
|
|
617
|
+
):
|
|
618
|
+
if isinstance(result, Error):
|
|
619
|
+
errors.append(result)
|
|
620
|
+
else:
|
|
621
|
+
venv_resolve_results.append(result)
|
|
622
|
+
|
|
623
|
+
if len(errors) == 1:
|
|
624
|
+
return errors[0]
|
|
625
|
+
elif errors:
|
|
626
|
+
return Error(
|
|
627
|
+
"Failed to resolve from {count} of {total} virtual environments:\n{failures}".format(
|
|
628
|
+
count=len(errors),
|
|
629
|
+
total=len(venvs),
|
|
630
|
+
failures="\n".join(
|
|
631
|
+
"{index}. {error}".format(index=index, error=error)
|
|
632
|
+
for index, error in enumerate(errors, start=1)
|
|
633
|
+
),
|
|
634
|
+
)
|
|
635
|
+
)
|
|
636
|
+
|
|
490
637
|
return ResolveResult(
|
|
491
638
|
dependency_configuration=dependency_configuration,
|
|
492
639
|
distributions=tuple(
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
],
|
|
499
|
-
)
|
|
500
|
-
for fingerprinted_distribution in itertools.chain(
|
|
501
|
-
list(
|
|
502
|
-
_install_venv_distributions(
|
|
503
|
-
venv=venv,
|
|
504
|
-
distributions=venv_distributions,
|
|
505
|
-
max_install_jobs=pip_configuration.max_jobs,
|
|
506
|
-
result_type=result_type,
|
|
507
|
-
use_system_time=True,
|
|
508
|
-
)
|
|
509
|
-
),
|
|
510
|
-
fingerprinted_distributions,
|
|
640
|
+
_install_venv_distributions(
|
|
641
|
+
venv_resolve_results,
|
|
642
|
+
max_install_jobs=pip_configuration.max_jobs,
|
|
643
|
+
result_type=result_type,
|
|
644
|
+
use_system_time=True,
|
|
511
645
|
)
|
|
512
646
|
),
|
|
513
647
|
type=result_type,
|
pex/resolver.py
CHANGED
|
@@ -65,6 +65,7 @@ from pex.resolve.resolvers import (
|
|
|
65
65
|
check_resolve,
|
|
66
66
|
)
|
|
67
67
|
from pex.resolve.target_system import TargetSystem, UniversalTarget
|
|
68
|
+
from pex.result import Error
|
|
68
69
|
from pex.targets import AbbreviatedPlatform, CompletePlatform, LocalInterpreter, Target, Targets
|
|
69
70
|
from pex.third_party.packaging.specifiers import SpecifierSet
|
|
70
71
|
from pex.third_party.packaging.tags import Tag
|
|
@@ -309,10 +310,7 @@ class _PipSession(object):
|
|
|
309
310
|
if isinstance(requirement, LocalProjectRequirement):
|
|
310
311
|
for request in self.requests:
|
|
311
312
|
yield BuildRequest.for_directory(
|
|
312
|
-
target=request.target,
|
|
313
|
-
source_path=requirement.path,
|
|
314
|
-
resolver=self.resolver,
|
|
315
|
-
pip_version=self.pip_version,
|
|
313
|
+
target=request.target, source_path=requirement.path
|
|
316
314
|
)
|
|
317
315
|
|
|
318
316
|
def generate_reports(self, max_parallel_jobs=None):
|
|
@@ -594,12 +592,17 @@ def _fingerprint_directory(path):
|
|
|
594
592
|
return CacheHelper.dir_hash(path, digest=_hasher())
|
|
595
593
|
|
|
596
594
|
|
|
595
|
+
class BuildError(Exception):
|
|
596
|
+
pass
|
|
597
|
+
|
|
598
|
+
|
|
597
599
|
def _fingerprint_local_project(
|
|
598
600
|
path, # type: str
|
|
599
601
|
target, # type: Target
|
|
600
602
|
resolver=None, # type: Optional[Resolver]
|
|
601
603
|
pip_version=None, # type: Optional[PipVersionValue]
|
|
602
604
|
):
|
|
605
|
+
# type: (...) -> str
|
|
603
606
|
if resolver:
|
|
604
607
|
build_system_resolver = resolver
|
|
605
608
|
else:
|
|
@@ -607,17 +610,20 @@ def _fingerprint_local_project(
|
|
|
607
610
|
|
|
608
611
|
build_system_resolver = ConfiguredResolver.default()
|
|
609
612
|
|
|
610
|
-
|
|
613
|
+
hasher = _hasher()
|
|
614
|
+
result = digest_local_project(
|
|
611
615
|
directory=path,
|
|
612
|
-
digest=
|
|
616
|
+
digest=hasher,
|
|
613
617
|
target=target,
|
|
614
618
|
resolver=build_system_resolver,
|
|
615
619
|
pip_version=pip_version,
|
|
616
620
|
)
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
+
if isinstance(result, Error):
|
|
622
|
+
raise BuildError(
|
|
623
|
+
"Failed to create an sdist for hashing from the local project at {path}: "
|
|
624
|
+
"{err}".format(path=path, err=result)
|
|
625
|
+
)
|
|
626
|
+
return hasher.hexdigest()
|
|
621
627
|
|
|
622
628
|
|
|
623
629
|
def _as_download_target(target):
|
|
@@ -649,27 +655,19 @@ class BuildRequest(object):
|
|
|
649
655
|
target, # type: Union[DownloadTarget, Target]
|
|
650
656
|
source_path, # type: str
|
|
651
657
|
subdirectory=None, # type: Optional[str]
|
|
652
|
-
resolver=None, # type: Optional[Resolver]
|
|
653
|
-
pip_version=None, # type: Optional[PipVersionValue]
|
|
654
658
|
):
|
|
655
659
|
# type: (...) -> BuildRequest
|
|
656
660
|
download_target = _as_download_target(target)
|
|
657
|
-
fingerprint = _fingerprint_local_project(
|
|
658
|
-
path=source_path,
|
|
659
|
-
target=download_target.target,
|
|
660
|
-
resolver=resolver,
|
|
661
|
-
pip_version=pip_version,
|
|
662
|
-
)
|
|
663
661
|
return cls(
|
|
664
662
|
download_target=download_target,
|
|
665
663
|
source_path=source_path,
|
|
666
|
-
fingerprint=
|
|
664
|
+
fingerprint=None,
|
|
667
665
|
subdirectory=subdirectory,
|
|
668
666
|
)
|
|
669
667
|
|
|
670
668
|
download_target = attr.ib(converter=_as_download_target) # type: DownloadTarget
|
|
671
669
|
source_path = attr.ib() # type: str
|
|
672
|
-
fingerprint = attr.ib() # type: str
|
|
670
|
+
fingerprint = attr.ib() # type: Optional[str]
|
|
673
671
|
subdirectory = attr.ib() # type: Optional[str]
|
|
674
672
|
|
|
675
673
|
@property
|
|
@@ -724,12 +722,16 @@ class BuildResult(object):
|
|
|
724
722
|
source_path=None, # type: Optional[str]
|
|
725
723
|
):
|
|
726
724
|
# type: (...) -> BuildResult
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
725
|
+
if build_request.fingerprint:
|
|
726
|
+
built_wheel = BuiltWheelDir.create(
|
|
727
|
+
sdist=source_path or build_request.source_path,
|
|
728
|
+
fingerprint=build_request.fingerprint,
|
|
729
|
+
target=build_request.target,
|
|
730
|
+
)
|
|
731
|
+
target_dir = built_wheel.dist_dir
|
|
732
|
+
else:
|
|
733
|
+
target_dir = os.path.join(safe_mkdtemp(), "build")
|
|
734
|
+
return cls(request=build_request, atomic_dir=AtomicDirectory(target_dir))
|
|
733
735
|
|
|
734
736
|
request = attr.ib() # type: BuildRequest
|
|
735
737
|
_atomic_dir = attr.ib() # type: AtomicDirectory
|
|
@@ -1290,14 +1292,7 @@ class BuildAndInstallRequest(object):
|
|
|
1290
1292
|
if is_wheel(dist_path):
|
|
1291
1293
|
to_install.add(InstallRequest.create(install_request.target, dist_path))
|
|
1292
1294
|
elif os.path.isdir(dist_path):
|
|
1293
|
-
to_build.add(
|
|
1294
|
-
BuildRequest.for_directory(
|
|
1295
|
-
install_request.target,
|
|
1296
|
-
dist_path,
|
|
1297
|
-
resolver=self._resolver,
|
|
1298
|
-
pip_version=self._pip_version,
|
|
1299
|
-
)
|
|
1300
|
-
)
|
|
1295
|
+
to_build.add(BuildRequest.for_directory(install_request.target, dist_path))
|
|
1301
1296
|
else:
|
|
1302
1297
|
to_build.add(BuildRequest.for_file(install_request.target, dist_path))
|
|
1303
1298
|
already_analyzed.add(metadata.project_name)
|
|
@@ -1907,11 +1902,21 @@ def download_requests(
|
|
|
1907
1902
|
def add_build_requests(requests):
|
|
1908
1903
|
# type: (Iterable[BuildRequest]) -> None
|
|
1909
1904
|
for request in requests:
|
|
1905
|
+
if request.fingerprint:
|
|
1906
|
+
fingerprint = request.fingerprint
|
|
1907
|
+
else:
|
|
1908
|
+
production_assert(os.path.isdir(request.source_path))
|
|
1909
|
+
fingerprint = _fingerprint_local_project(
|
|
1910
|
+
path=request.source_path,
|
|
1911
|
+
target=request.target,
|
|
1912
|
+
resolver=resolver,
|
|
1913
|
+
pip_version=pip_version,
|
|
1914
|
+
)
|
|
1910
1915
|
local_distributions.append(
|
|
1911
1916
|
LocalDistribution(
|
|
1912
1917
|
download_target=request.download_target,
|
|
1913
1918
|
path=request.source_path,
|
|
1914
|
-
fingerprint=
|
|
1919
|
+
fingerprint=fingerprint,
|
|
1915
1920
|
subdirectory=request.subdirectory,
|
|
1916
1921
|
)
|
|
1917
1922
|
)
|
pex/version.py
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pex
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.67.0
|
|
4
4
|
Summary: The PEX packaging toolchain.
|
|
5
5
|
Home-page: https://github.com/pex-tool/pex
|
|
6
|
-
Download-URL: https://github.com/pex-tool/pex/releases/download/v2.
|
|
6
|
+
Download-URL: https://github.com/pex-tool/pex/releases/download/v2.67.0/pex
|
|
7
7
|
Author: The PEX developers
|
|
8
8
|
Author-email: developers@pex-tool.org
|
|
9
9
|
License-Expression: Apache-2.0
|
|
10
|
-
Project-URL: Changelog, https://github.com/pex-tool/pex/blob/v2.
|
|
10
|
+
Project-URL: Changelog, https://github.com/pex-tool/pex/blob/v2.67.0/CHANGES.md
|
|
11
11
|
Project-URL: Documentation, https://docs.pex-tool.org/
|
|
12
|
-
Project-URL: Source, https://github.com/pex-tool/pex/tree/v2.
|
|
12
|
+
Project-URL: Source, https://github.com/pex-tool/pex/tree/v2.67.0
|
|
13
13
|
Keywords: package,executable,virtualenv,lock,freeze
|
|
14
14
|
Classifier: Development Status :: 5 - Production/Stable
|
|
15
15
|
Classifier: Intended Audience :: Developers
|