pex 2.54.2__py2.py3-none-any.whl → 2.69.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/auth.py +1 -1
- pex/bin/pex.py +15 -2
- pex/build_backend/configuration.py +5 -5
- pex/build_backend/wrap.py +27 -23
- pex/build_system/pep_517.py +4 -1
- pex/cache/dirs.py +17 -12
- pex/cli/commands/lock.py +302 -165
- pex/cli/commands/pip/core.py +4 -12
- pex/cli/commands/pip/wheel.py +1 -1
- pex/cli/commands/run.py +13 -20
- pex/cli/commands/venv.py +85 -16
- pex/cli/pex.py +11 -4
- pex/common.py +57 -7
- pex/compatibility.py +1 -1
- pex/dependency_configuration.py +87 -15
- pex/dist_metadata.py +143 -25
- pex/docs/html/_pagefind/fragment/en_4250138.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_7125dad.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_785d562.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_8e94bb8.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_a0396bb.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_a8a3588.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_c07d988.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_d718411.pf_fragment +0 -0
- pex/docs/html/_pagefind/index/en_a2e3c5e.pf_index +0 -0
- pex/docs/html/_pagefind/pagefind-entry.json +1 -1
- pex/docs/html/_pagefind/pagefind.en_4ce1afa9e3.pf_meta +0 -0
- pex/docs/html/_static/documentation_options.js +1 -1
- pex/docs/html/_static/pygments.css +164 -146
- pex/docs/html/_static/styles/furo.css +1 -1
- pex/docs/html/_static/styles/furo.css.map +1 -1
- pex/docs/html/api/vars.html +25 -34
- pex/docs/html/buildingpex.html +25 -34
- pex/docs/html/genindex.html +24 -33
- pex/docs/html/index.html +25 -34
- pex/docs/html/recipes.html +25 -34
- pex/docs/html/scie.html +25 -34
- pex/docs/html/search.html +24 -33
- pex/docs/html/whatispex.html +25 -34
- pex/entry_points_txt.py +98 -0
- pex/environment.py +54 -33
- pex/finders.py +1 -1
- pex/hashing.py +71 -9
- pex/installed_wheel.py +141 -0
- pex/interpreter.py +41 -38
- pex/interpreter_constraints.py +25 -25
- pex/interpreter_implementation.py +40 -0
- pex/jobs.py +13 -6
- pex/pep_376.py +68 -384
- pex/pep_425.py +11 -2
- pex/pep_427.py +937 -205
- pex/pep_508.py +4 -5
- pex/pex_builder.py +5 -8
- pex/pex_info.py +14 -9
- pex/pip/dependencies/__init__.py +85 -13
- pex/pip/dependencies/requires.py +38 -3
- pex/pip/foreign_platform/__init__.py +4 -3
- pex/pip/installation.py +2 -2
- pex/pip/local_project.py +6 -14
- pex/pip/package_repositories/__init__.py +78 -0
- pex/pip/package_repositories/link_collector.py +96 -0
- pex/pip/tool.py +139 -33
- pex/pip/vcs.py +109 -43
- pex/pip/version.py +8 -1
- pex/requirements.py +121 -16
- pex/resolve/config.py +5 -1
- pex/resolve/configured_resolve.py +32 -10
- pex/resolve/configured_resolver.py +10 -39
- pex/resolve/downloads.py +4 -3
- pex/resolve/lock_downloader.py +16 -23
- pex/resolve/lock_resolver.py +41 -51
- pex/resolve/locked_resolve.py +89 -32
- pex/resolve/locker.py +145 -101
- pex/resolve/locker_patches.py +123 -197
- pex/resolve/lockfile/create.py +232 -87
- pex/resolve/lockfile/download_manager.py +5 -1
- pex/resolve/lockfile/json_codec.py +103 -28
- pex/resolve/lockfile/model.py +13 -35
- pex/resolve/lockfile/pep_751.py +117 -98
- pex/resolve/lockfile/requires_dist.py +17 -262
- pex/resolve/lockfile/subset.py +11 -0
- pex/resolve/lockfile/targets.py +445 -0
- pex/resolve/lockfile/updater.py +22 -10
- pex/resolve/package_repository.py +406 -0
- pex/resolve/pex_repository_resolver.py +1 -1
- pex/resolve/pre_resolved_resolver.py +19 -16
- pex/resolve/project.py +233 -47
- pex/resolve/requirement_configuration.py +28 -10
- pex/resolve/resolver_configuration.py +18 -32
- pex/resolve/resolver_options.py +234 -28
- pex/resolve/resolvers.py +3 -12
- pex/resolve/target_options.py +18 -2
- pex/resolve/target_system.py +908 -0
- pex/resolve/venv_resolver.py +670 -0
- pex/resolver.py +673 -209
- pex/scie/__init__.py +40 -1
- pex/scie/model.py +2 -0
- pex/scie/science.py +25 -3
- pex/sdist.py +219 -0
- pex/sh_boot.py +24 -21
- pex/sysconfig.py +5 -3
- pex/targets.py +31 -10
- pex/third_party/__init__.py +1 -1
- pex/tools/commands/repository.py +48 -25
- pex/vendor/__init__.py +4 -9
- pex/vendor/__main__.py +65 -41
- pex/vendor/_vendored/ansicolors/.layout.json +1 -1
- pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.dist-info/RECORD +11 -0
- pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/appdirs/.layout.json +1 -1
- pex/vendor/_vendored/appdirs/appdirs-1.4.4.dist-info/RECORD +7 -0
- pex/vendor/_vendored/appdirs/appdirs-1.4.4.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/attrs/.layout.json +1 -1
- pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.dist-info/RECORD +37 -0
- pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/packaging_20_9/.layout.json +1 -1
- pex/vendor/_vendored/packaging_20_9/packaging-20.9.dist-info/RECORD +20 -0
- pex/vendor/_vendored/packaging_20_9/packaging-20.9.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.dist-info/RECORD +7 -0
- pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/packaging_21_3/.layout.json +1 -1
- pex/vendor/_vendored/packaging_21_3/packaging-21.3.dist-info/RECORD +20 -0
- pex/vendor/_vendored/packaging_21_3/packaging-21.3.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.dist-info/RECORD +18 -0
- pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/packaging_24_0/.layout.json +1 -1
- pex/vendor/_vendored/packaging_24_0/packaging-24.0.dist-info/RECORD +22 -0
- pex/vendor/_vendored/packaging_24_0/packaging-24.0.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/packaging_25_0/.layout.json +1 -1
- pex/vendor/_vendored/packaging_25_0/packaging-25.0.dist-info/RECORD +24 -0
- pex/vendor/_vendored/packaging_25_0/packaging-25.0.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/pip/.layout.json +1 -1
- pex/vendor/_vendored/pip/pip/_vendor/certifi/cacert.pem +63 -1
- pex/vendor/_vendored/pip/pip-20.3.4.dist-info/RECORD +388 -0
- pex/vendor/_vendored/pip/pip-20.3.4.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/setuptools/.layout.json +1 -1
- pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/RECORD +107 -0
- pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/toml/.layout.json +1 -1
- pex/vendor/_vendored/toml/toml-0.10.2.dist-info/RECORD +11 -0
- pex/vendor/_vendored/toml/toml-0.10.2.pex-info/original-whl-info.json +1 -0
- pex/vendor/_vendored/tomli/.layout.json +1 -1
- pex/vendor/_vendored/tomli/tomli-2.0.1.dist-info/RECORD +10 -0
- pex/vendor/_vendored/tomli/tomli-2.0.1.pex-info/original-whl-info.json +1 -0
- pex/venv/installer.py +46 -19
- pex/venv/venv_pex.py +6 -3
- pex/version.py +1 -1
- pex/wheel.py +188 -40
- pex/whl.py +67 -0
- pex/windows/__init__.py +14 -11
- {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/METADATA +6 -5
- {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/RECORD +157 -133
- {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/entry_points.txt +1 -0
- {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/pylock/pylock.toml +1 -1
- pex/docs/html/_pagefind/fragment/en_42c9d8c.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_45dd5a2.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_4ca74d2.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_77273d5.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_87a59c5.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_8dc89b5.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_9d1319b.pf_fragment +0 -0
- pex/docs/html/_pagefind/fragment/en_e55df9d.pf_fragment +0 -0
- pex/docs/html/_pagefind/index/en_1e98c6f.pf_index +0 -0
- pex/docs/html/_pagefind/pagefind.en_d1c488ecae.pf_meta +0 -0
- pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/appdirs/appdirs-1.4.4.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/packaging_20_9/packaging-20.9.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/packaging_21_3/packaging-21.3.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/packaging_24_0/packaging-24.0.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/packaging_25_0/packaging-25.0.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/pip/pip-20.3.4.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/toml/toml-0.10.2.dist-info/INSTALLER +0 -1
- pex/vendor/_vendored/tomli/tomli-2.0.1.dist-info/INSTALLER +0 -1
- {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/WHEEL +0 -0
- {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/licenses/LICENSE +0 -0
- {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/top_level.txt +0 -0
pex/cli/commands/lock.py
CHANGED
|
@@ -32,11 +32,12 @@ from pex.dist_metadata import (
|
|
|
32
32
|
)
|
|
33
33
|
from pex.enum import Enum
|
|
34
34
|
from pex.exceptions import production_assert
|
|
35
|
+
from pex.installed_wheel import InstalledWheel
|
|
35
36
|
from pex.interpreter import PythonInterpreter
|
|
36
37
|
from pex.orderedset import OrderedSet
|
|
37
38
|
from pex.os import is_exe, safe_execv
|
|
38
|
-
from pex.pep_376 import
|
|
39
|
-
from pex.pep_427 import InstallableType
|
|
39
|
+
from pex.pep_376 import InstalledFile, Record
|
|
40
|
+
from pex.pep_427 import InstallableType, reinstall_venv
|
|
40
41
|
from pex.pep_440 import Version
|
|
41
42
|
from pex.pep_503 import ProjectName
|
|
42
43
|
from pex.pip.version import PipVersionValue
|
|
@@ -52,7 +53,6 @@ from pex.resolve.locked_resolve import (
|
|
|
52
53
|
LockedResolve,
|
|
53
54
|
LockStyle,
|
|
54
55
|
Resolved,
|
|
55
|
-
TargetSystem,
|
|
56
56
|
VCSArtifact,
|
|
57
57
|
)
|
|
58
58
|
from pex.resolve.lockfile import json_codec, pep_751, requires_dist
|
|
@@ -77,6 +77,7 @@ from pex.resolve.resolver_options import parse_lockfile
|
|
|
77
77
|
from pex.resolve.resolvers import Resolver
|
|
78
78
|
from pex.resolve.script_metadata import ScriptMetadataApplication, apply_script_metadata
|
|
79
79
|
from pex.resolve.target_configuration import InterpreterConstraintsNotSatisfied, TargetConfiguration
|
|
80
|
+
from pex.resolve.target_system import TargetSystem, UniversalTarget
|
|
80
81
|
from pex.result import Error, Ok, Result, try_
|
|
81
82
|
from pex.sorted_tuple import SortedTuple
|
|
82
83
|
from pex.targets import LocalInterpreter, Target, Targets
|
|
@@ -88,8 +89,10 @@ from pex.version import __version__
|
|
|
88
89
|
if TYPE_CHECKING:
|
|
89
90
|
from typing import (
|
|
90
91
|
IO,
|
|
92
|
+
Deque,
|
|
91
93
|
Dict,
|
|
92
94
|
Iterable,
|
|
95
|
+
Iterator,
|
|
93
96
|
List,
|
|
94
97
|
Mapping,
|
|
95
98
|
Optional,
|
|
@@ -300,7 +303,10 @@ class SyncTarget(object):
|
|
|
300
303
|
if distribution.metadata.type is MetadataType.DIST_INFO:
|
|
301
304
|
to_unlink.extend(
|
|
302
305
|
os.path.realpath(os.path.join(distribution.location, installed_file.path))
|
|
303
|
-
for installed_file in Record.read(
|
|
306
|
+
for installed_file in Record.read(
|
|
307
|
+
lines=distribution.iter_metadata_lines("RECORD")
|
|
308
|
+
)
|
|
309
|
+
if isinstance(installed_file, InstalledFile)
|
|
304
310
|
)
|
|
305
311
|
elif distribution.metadata.type is MetadataType.EGG_INFO:
|
|
306
312
|
installed_files = distribution.metadata.files.metadata_file_rel_path(
|
|
@@ -354,8 +360,8 @@ class SyncTarget(object):
|
|
|
354
360
|
|
|
355
361
|
if to_install:
|
|
356
362
|
for distribution in to_install:
|
|
357
|
-
for src, dst in
|
|
358
|
-
self.venv
|
|
363
|
+
for src, dst in reinstall_venv(
|
|
364
|
+
installed_wheel=InstalledWheel.load(distribution.location), venv=self.venv
|
|
359
365
|
):
|
|
360
366
|
TRACER.log("Installed {src} -> {dst}".format(src=src, dst=dst))
|
|
361
367
|
for script in self.venv.rewrite_scripts():
|
|
@@ -418,7 +424,7 @@ class LockUpdateRequest(object):
|
|
|
418
424
|
lock_file=self._lock_file_path,
|
|
419
425
|
missing_platforms="\n".join(
|
|
420
426
|
sorted(
|
|
421
|
-
"+ {platform}".format(platform=locked_resolve.
|
|
427
|
+
"+ {platform}".format(platform=locked_resolve.target_platform)
|
|
422
428
|
for locked_resolve in self._lock_updater.lock_file.locked_resolves
|
|
423
429
|
)
|
|
424
430
|
),
|
|
@@ -481,6 +487,162 @@ class LockfileSubset(object):
|
|
|
481
487
|
locked_resolves = attr.ib() # type: Sequence[LockedResolve]
|
|
482
488
|
|
|
483
489
|
|
|
490
|
+
@attr.s(frozen=True)
|
|
491
|
+
class RootRequirement(object):
|
|
492
|
+
project_name = attr.ib() # type: ProjectName
|
|
493
|
+
requirements = attr.ib() # type: Tuple[Requirement, ...]
|
|
494
|
+
|
|
495
|
+
def select(self, project_name_and_version):
|
|
496
|
+
# type: (ProjectNameAndVersion) -> Tuple[Requirement, ...]
|
|
497
|
+
return tuple(
|
|
498
|
+
requirement
|
|
499
|
+
for requirement in self.requirements
|
|
500
|
+
if project_name_and_version in requirement
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
def __str__(self):
|
|
504
|
+
# type: () -> str
|
|
505
|
+
return " or ".join("'{req}'".format(req=requirement) for requirement in self.requirements)
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
@attr.s(frozen=True)
|
|
509
|
+
class RootRequirements(object):
|
|
510
|
+
@classmethod
|
|
511
|
+
def create(cls, requirements):
|
|
512
|
+
# type: (Iterable[Requirement]) -> RootRequirements
|
|
513
|
+
|
|
514
|
+
requirements_by_project_name = (
|
|
515
|
+
OrderedDict()
|
|
516
|
+
) # type: OrderedDict[ProjectName, OrderedSet[Requirement]]
|
|
517
|
+
for requirement in requirements:
|
|
518
|
+
requirements_by_project_name.setdefault(requirement.project_name, OrderedSet()).add(
|
|
519
|
+
requirement
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
return cls(
|
|
523
|
+
root_requirements=tuple(
|
|
524
|
+
RootRequirement(project_name=project_name, requirements=tuple(reqs))
|
|
525
|
+
for project_name, reqs in requirements_by_project_name.items()
|
|
526
|
+
)
|
|
527
|
+
)
|
|
528
|
+
|
|
529
|
+
_root_requirements = attr.ib() # type: Tuple[RootRequirement, ...]
|
|
530
|
+
|
|
531
|
+
def iter_requirements(self):
|
|
532
|
+
# type: () -> Iterator[Requirement]
|
|
533
|
+
for root_requirement in self._root_requirements:
|
|
534
|
+
for requirement in root_requirement.requirements:
|
|
535
|
+
yield requirement
|
|
536
|
+
|
|
537
|
+
def __iter__(self):
|
|
538
|
+
# type: () -> Iterator[RootRequirement]
|
|
539
|
+
return iter(self._root_requirements)
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def subset_locked_resolve(
|
|
543
|
+
locked_resolve, # type: LockedResolve
|
|
544
|
+
root_requirements, # type: RootRequirements
|
|
545
|
+
constraint_by_project_name, # type: Mapping[ProjectName, Constraint]
|
|
546
|
+
lock_file_description, # type: str
|
|
547
|
+
universal_target=None, # type: Optional[UniversalTarget]
|
|
548
|
+
):
|
|
549
|
+
# type: (...) -> Union[LockedResolve, Error]
|
|
550
|
+
|
|
551
|
+
available = {
|
|
552
|
+
locked_req.pin.project_name: (
|
|
553
|
+
ProjectNameAndVersion(locked_req.pin.project_name.raw, locked_req.pin.version.raw),
|
|
554
|
+
locked_req,
|
|
555
|
+
)
|
|
556
|
+
for locked_req in locked_resolve.locked_requirements
|
|
557
|
+
}
|
|
558
|
+
retain = set()
|
|
559
|
+
to_resolve = deque(root_requirements) # type: Deque[Union[RootRequirement, Requirement]]
|
|
560
|
+
while to_resolve:
|
|
561
|
+
req = to_resolve.popleft()
|
|
562
|
+
if req.project_name in retain:
|
|
563
|
+
continue
|
|
564
|
+
retain.add(req.project_name)
|
|
565
|
+
|
|
566
|
+
dep = available.get(req.project_name)
|
|
567
|
+
if not dep:
|
|
568
|
+
return Error(
|
|
569
|
+
"There is no lock entry for {project} in {lock_file} to satisfy the "
|
|
570
|
+
"{transitive}{req} requirement.".format(
|
|
571
|
+
project=req.project_name,
|
|
572
|
+
lock_file=lock_file_description,
|
|
573
|
+
transitive="" if isinstance(req, RootRequirement) else "transitive ",
|
|
574
|
+
req=(req if isinstance(req, RootRequirement) else "'{req}'".format(req=req)),
|
|
575
|
+
)
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
pnav, locked_req = dep
|
|
579
|
+
if isinstance(req, RootRequirement):
|
|
580
|
+
reqs = req.select(pnav)
|
|
581
|
+
if not reqs:
|
|
582
|
+
return Error(
|
|
583
|
+
"The locked version of {project} in {lock_file} is {version} which "
|
|
584
|
+
"does not satisfy the {req} requirement.".format(
|
|
585
|
+
project=pnav.project_name,
|
|
586
|
+
lock_file=lock_file_description,
|
|
587
|
+
version=pnav.version,
|
|
588
|
+
req=req,
|
|
589
|
+
)
|
|
590
|
+
)
|
|
591
|
+
elif pnav not in req:
|
|
592
|
+
production_assert(
|
|
593
|
+
isinstance(req, RootRequirement),
|
|
594
|
+
"Transitive requirements in a lock should always match existing lock "
|
|
595
|
+
"entries. Found {project} {version} in {lock_file}, which does not satisfy "
|
|
596
|
+
"transitive requirement '{req}' found in the same lock.",
|
|
597
|
+
project=pnav.project_name,
|
|
598
|
+
version=pnav.version,
|
|
599
|
+
lock_file=lock_file_description,
|
|
600
|
+
req=req,
|
|
601
|
+
)
|
|
602
|
+
return Error(
|
|
603
|
+
"The locked version of {project} in {lock_file} is {version} which does "
|
|
604
|
+
"not satisfy the '{req}' requirement.".format(
|
|
605
|
+
project=pnav.project_name,
|
|
606
|
+
lock_file=lock_file_description,
|
|
607
|
+
version=pnav.version,
|
|
608
|
+
req=req,
|
|
609
|
+
)
|
|
610
|
+
)
|
|
611
|
+
elif (
|
|
612
|
+
req.project_name in constraint_by_project_name
|
|
613
|
+
and pnav not in constraint_by_project_name[req.project_name]
|
|
614
|
+
):
|
|
615
|
+
return Error(
|
|
616
|
+
"The locked version of {project} in {lock_file} is {version} which does "
|
|
617
|
+
"not satisfy the '{constraint}' constraint.".format(
|
|
618
|
+
project=pnav.project_name,
|
|
619
|
+
lock_file=lock_file_description,
|
|
620
|
+
version=pnav.version,
|
|
621
|
+
constraint=constraint_by_project_name[req.project_name],
|
|
622
|
+
)
|
|
623
|
+
)
|
|
624
|
+
else:
|
|
625
|
+
reqs = (req,)
|
|
626
|
+
|
|
627
|
+
for req in reqs:
|
|
628
|
+
to_resolve.extend(
|
|
629
|
+
requires_dist.filter_dependencies(
|
|
630
|
+
req,
|
|
631
|
+
locked_req,
|
|
632
|
+
universal_target=universal_target,
|
|
633
|
+
)
|
|
634
|
+
)
|
|
635
|
+
|
|
636
|
+
return attr.evolve(
|
|
637
|
+
locked_resolve,
|
|
638
|
+
locked_requirements=SortedTuple(
|
|
639
|
+
locked_requirement
|
|
640
|
+
for locked_requirement in locked_resolve.locked_requirements
|
|
641
|
+
if locked_requirement.pin.project_name in retain
|
|
642
|
+
),
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
|
|
484
646
|
class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
485
647
|
"""Operate on PEX lock files."""
|
|
486
648
|
|
|
@@ -527,7 +689,8 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
527
689
|
options_group,
|
|
528
690
|
project_help=(
|
|
529
691
|
"Add the transitive dependencies of the local project at the specified path to "
|
|
530
|
-
"the lock but do not lock project itself."
|
|
692
|
+
"the lock but do not lock project itself. The path can be that of a project "
|
|
693
|
+
"directory, a project sdist or a pre-built project wheel."
|
|
531
694
|
),
|
|
532
695
|
)
|
|
533
696
|
dependency_configuration.register(options_group)
|
|
@@ -565,6 +728,18 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
565
728
|
def _add_lock_options(cls, parser):
|
|
566
729
|
# type: (_ActionsContainer) -> None
|
|
567
730
|
resolver_options.register_pex_lock_options(parser)
|
|
731
|
+
parser.add_argument(
|
|
732
|
+
"--avoid-downloads",
|
|
733
|
+
"--no-avoid-downloads",
|
|
734
|
+
dest="avoid_downloads",
|
|
735
|
+
default=True,
|
|
736
|
+
action=HandleBoolAction,
|
|
737
|
+
help=(
|
|
738
|
+
"When locking, prefer not downloading distributions unless necessary. This can "
|
|
739
|
+
"save time locking, although the downloads will need to happen later when using "
|
|
740
|
+
"the lock."
|
|
741
|
+
),
|
|
742
|
+
)
|
|
568
743
|
|
|
569
744
|
@classmethod
|
|
570
745
|
def _add_create_arguments(cls, create_parser):
|
|
@@ -783,22 +958,6 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
783
958
|
),
|
|
784
959
|
)
|
|
785
960
|
|
|
786
|
-
update_parser.add_argument(
|
|
787
|
-
"--fingerprint-mismatch",
|
|
788
|
-
default=FingerprintMismatch.ERROR,
|
|
789
|
-
choices=FingerprintMismatch.values(),
|
|
790
|
-
type=FingerprintMismatch.for_value,
|
|
791
|
-
help=(
|
|
792
|
-
"What to do when a lock update would result in at least one artifact fingerprint "
|
|
793
|
-
"changing: {ignore!r} the mismatch and use the new fingerprint, {warn!r} about the "
|
|
794
|
-
"mismatch but use the new fingerprint anyway or {error!r} and refuse to use the "
|
|
795
|
-
"new mismatching fingerprint".format(
|
|
796
|
-
ignore=FingerprintMismatch.IGNORE,
|
|
797
|
-
warn=FingerprintMismatch.WARN,
|
|
798
|
-
error=FingerprintMismatch.ERROR,
|
|
799
|
-
)
|
|
800
|
-
),
|
|
801
|
-
)
|
|
802
961
|
cls._add_lockfile_option(update_parser, verb="update")
|
|
803
962
|
cls._add_lock_options(update_parser)
|
|
804
963
|
cls.add_json_options(update_parser, entity="lock", include_switch=False)
|
|
@@ -845,6 +1004,22 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
845
1004
|
)
|
|
846
1005
|
),
|
|
847
1006
|
)
|
|
1007
|
+
update_parser.add_argument(
|
|
1008
|
+
"--fingerprint-mismatch",
|
|
1009
|
+
default=FingerprintMismatch.ERROR,
|
|
1010
|
+
choices=FingerprintMismatch.values(),
|
|
1011
|
+
type=FingerprintMismatch.for_value,
|
|
1012
|
+
help=(
|
|
1013
|
+
"What to do when a lock update would result in at least one artifact fingerprint "
|
|
1014
|
+
"changing: {ignore!r} the mismatch and use the new fingerprint, {warn!r} about the "
|
|
1015
|
+
"mismatch but use the new fingerprint anyway or {error!r} and refuse to use the "
|
|
1016
|
+
"new mismatching fingerprint".format(
|
|
1017
|
+
ignore=FingerprintMismatch.IGNORE,
|
|
1018
|
+
warn=FingerprintMismatch.WARN,
|
|
1019
|
+
error=FingerprintMismatch.ERROR,
|
|
1020
|
+
)
|
|
1021
|
+
),
|
|
1022
|
+
)
|
|
848
1023
|
|
|
849
1024
|
@classmethod
|
|
850
1025
|
def _add_sync_arguments(cls, sync_parser):
|
|
@@ -1036,13 +1211,9 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1036
1211
|
requirement_configuration = script_metadata_application.requirement_configuration
|
|
1037
1212
|
target_configuration = script_metadata_application.target_configuration
|
|
1038
1213
|
if self.options.style == LockStyle.UNIVERSAL:
|
|
1039
|
-
lock_configuration = LockConfiguration(
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
str(interpreter_constraint.requires_python)
|
|
1043
|
-
for interpreter_constraint in target_configuration.interpreter_constraints
|
|
1044
|
-
),
|
|
1045
|
-
target_systems=tuple(self.options.target_systems),
|
|
1214
|
+
lock_configuration = LockConfiguration.universal(
|
|
1215
|
+
interpreter_constraints=target_configuration.interpreter_constraints,
|
|
1216
|
+
systems=self.options.target_systems,
|
|
1046
1217
|
elide_unused_requires_dist=self.options.elide_unused_requires_dist,
|
|
1047
1218
|
)
|
|
1048
1219
|
elif self.options.target_systems:
|
|
@@ -1097,6 +1268,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1097
1268
|
targets=targets,
|
|
1098
1269
|
pip_configuration=pip_configuration,
|
|
1099
1270
|
dependency_configuration=dependency_config,
|
|
1271
|
+
avoid_downloads=self.options.avoid_downloads,
|
|
1100
1272
|
)
|
|
1101
1273
|
)
|
|
1102
1274
|
)
|
|
@@ -1158,56 +1330,74 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1158
1330
|
# type: (RequirementConfiguration) -> Result
|
|
1159
1331
|
|
|
1160
1332
|
lockfile_path, lock_file = self._load_lockfile()
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1333
|
+
|
|
1334
|
+
pip_configuration = resolver_options.create_pip_configuration(
|
|
1335
|
+
self.options, use_system_time=False
|
|
1336
|
+
)
|
|
1337
|
+
targets = target_options.configure(
|
|
1338
|
+
self.options, pip_configuration=pip_configuration
|
|
1339
|
+
).resolve_targets()
|
|
1340
|
+
target = try_(
|
|
1341
|
+
targets.require_unique_target(
|
|
1342
|
+
purpose="exporting a lock in the {format!r} format".format(
|
|
1343
|
+
format=self.options.format
|
|
1344
|
+
)
|
|
1167
1345
|
)
|
|
1346
|
+
)
|
|
1347
|
+
|
|
1348
|
+
if self.options.format is ExportFormat.PEP_751 and lock_file.configuration.universal_target:
|
|
1349
|
+
self._check_pylock_toml_output_name()
|
|
1168
1350
|
|
|
1169
|
-
if requirement_configuration.has_requirements:
|
|
1351
|
+
if len(lock_file.locked_resolves) > 1 or requirement_configuration.has_requirements:
|
|
1170
1352
|
lock_subset = try_(
|
|
1171
1353
|
self._create_subset(
|
|
1172
1354
|
lockfile_path,
|
|
1173
1355
|
lock_file,
|
|
1174
|
-
requirement_configuration=
|
|
1356
|
+
requirement_configuration=(
|
|
1357
|
+
requirement_configuration
|
|
1358
|
+
if requirement_configuration.has_requirements
|
|
1359
|
+
else RequirementConfiguration(
|
|
1360
|
+
requirements=map(str, lock_file.requirements)
|
|
1361
|
+
)
|
|
1362
|
+
),
|
|
1175
1363
|
)
|
|
1176
1364
|
)
|
|
1365
|
+
marker_environment = target.marker_environment.as_dict()
|
|
1366
|
+
locked_resolves = [
|
|
1367
|
+
locked_resolve
|
|
1368
|
+
for locked_resolve in lock_subset.locked_resolves
|
|
1369
|
+
if not locked_resolve.marker
|
|
1370
|
+
or locked_resolve.marker.evaluate(marker_environment)
|
|
1371
|
+
]
|
|
1372
|
+
count = len(locked_resolves)
|
|
1373
|
+
production_assert(
|
|
1374
|
+
count == 1,
|
|
1375
|
+
msg=(
|
|
1376
|
+
"Expected {target} to select one subset from {lock}, but found {count} "
|
|
1377
|
+
"locked resolve that applies."
|
|
1378
|
+
),
|
|
1379
|
+
target=target.render_description(),
|
|
1380
|
+
lock=lockfile_path,
|
|
1381
|
+
count=count,
|
|
1382
|
+
)
|
|
1383
|
+
lock_subset = attr.evolve(lock_subset, locked_resolves=[locked_resolves[0]])
|
|
1177
1384
|
else:
|
|
1178
1385
|
lock_subset = LockfileSubset(
|
|
1179
1386
|
root_requirements=lock_file.requirements,
|
|
1180
1387
|
constraints=lock_file.constraints,
|
|
1181
|
-
locked_resolves=lock_file.locked_resolves,
|
|
1388
|
+
locked_resolves=[lock_file.locked_resolves[0]],
|
|
1182
1389
|
)
|
|
1183
1390
|
|
|
1184
|
-
if len(lock_file.requires_python) > 1:
|
|
1185
|
-
# TODO(John Sirois): Provide a better error message. We could guide on OR
|
|
1186
|
-
# to and AND paired with != to remove disjoint portions of the range.
|
|
1187
|
-
raise ValueError(
|
|
1188
|
-
"Can only export a lock file with a single interpreter constraint."
|
|
1189
|
-
)
|
|
1190
1391
|
with self.output(self.options, binary=True) as toml_output:
|
|
1191
1392
|
pep_751.convert(
|
|
1192
1393
|
root_requirements=lock_subset.root_requirements,
|
|
1193
1394
|
locked_resolve=lock_subset.locked_resolves[0],
|
|
1194
|
-
|
|
1195
|
-
target_systems=lock_file.target_systems,
|
|
1395
|
+
universal_target=lock_file.configuration.universal_target,
|
|
1196
1396
|
output=toml_output,
|
|
1197
1397
|
include_dependency_info=self.options.include_dependency_info,
|
|
1198
1398
|
)
|
|
1199
1399
|
return Ok()
|
|
1200
1400
|
|
|
1201
|
-
pip_configuration = resolver_options.create_pip_configuration(
|
|
1202
|
-
self.options, use_system_time=False
|
|
1203
|
-
)
|
|
1204
|
-
targets = target_options.configure(
|
|
1205
|
-
self.options, pip_configuration=pip_configuration
|
|
1206
|
-
).resolve_targets()
|
|
1207
|
-
target = targets.require_unique_target(
|
|
1208
|
-
purpose="exporting a lock in the {format!r} format".format(format=self.options.format)
|
|
1209
|
-
)
|
|
1210
|
-
|
|
1211
1401
|
with TRACER.timed("Selecting locks for {target}".format(target=target)):
|
|
1212
1402
|
subset_result = try_(
|
|
1213
1403
|
subset(
|
|
@@ -1234,7 +1424,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1234
1424
|
lockfile=lock_file.source,
|
|
1235
1425
|
pip=ExportFormat.PIP,
|
|
1236
1426
|
target=target,
|
|
1237
|
-
platform=resolved.source.
|
|
1427
|
+
platform=resolved.source.target_platform,
|
|
1238
1428
|
)
|
|
1239
1429
|
)
|
|
1240
1430
|
else:
|
|
@@ -1461,13 +1651,13 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1461
1651
|
locking_configuration = LockingConfiguration(
|
|
1462
1652
|
requirement_configuration,
|
|
1463
1653
|
target_configuration=target_configuration,
|
|
1464
|
-
lock_configuration=lock_file.
|
|
1654
|
+
lock_configuration=lock_file.configuration,
|
|
1465
1655
|
script_metadata_application=script_metadata_application,
|
|
1466
1656
|
)
|
|
1467
1657
|
targets = try_(
|
|
1468
1658
|
self._resolve_targets(
|
|
1469
1659
|
action="creating",
|
|
1470
|
-
style=lock_file.style,
|
|
1660
|
+
style=lock_file.configuration.style,
|
|
1471
1661
|
target_configuration=locking_configuration.target_configuration,
|
|
1472
1662
|
)
|
|
1473
1663
|
)
|
|
@@ -1502,14 +1692,14 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1502
1692
|
],
|
|
1503
1693
|
)
|
|
1504
1694
|
)
|
|
1505
|
-
root_requirements =
|
|
1695
|
+
root_requirements = RootRequirements.create(
|
|
1506
1696
|
(
|
|
1507
1697
|
local_project_requirements[req]
|
|
1508
1698
|
if isinstance(req, LocalProjectRequirement)
|
|
1509
1699
|
else req.requirement
|
|
1510
1700
|
)
|
|
1511
1701
|
for req in parsed_requirements
|
|
1512
|
-
|
|
1702
|
+
)
|
|
1513
1703
|
|
|
1514
1704
|
constraint_by_project_name = OrderedDict(
|
|
1515
1705
|
(constraint.requirement.project_name, constraint.requirement.as_constraint())
|
|
@@ -1519,91 +1709,41 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1519
1709
|
)
|
|
1520
1710
|
|
|
1521
1711
|
resolve_subsets = [] # type: List[LockedResolve]
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1712
|
+
errors = [] # type: List[Error]
|
|
1713
|
+
for index, locked_resolve in enumerate(lock_file.locked_resolves, start=0):
|
|
1714
|
+
if len(lock_file.locked_resolves) == 1:
|
|
1715
|
+
lock_file_description = lockfile_path
|
|
1716
|
+
else:
|
|
1717
|
+
lock_file_description = "locked resolve {index} (0-based) of {lock_file}".format(
|
|
1718
|
+
index=index, lock_file=lockfile_path
|
|
1529
1719
|
)
|
|
1530
|
-
for locked_req in locked_resolve.locked_requirements
|
|
1531
|
-
}
|
|
1532
|
-
retain = set()
|
|
1533
|
-
to_resolve = deque(root_requirements)
|
|
1534
|
-
while to_resolve:
|
|
1535
|
-
req = to_resolve.popleft()
|
|
1536
|
-
if req.project_name in retain:
|
|
1537
|
-
continue
|
|
1538
|
-
retain.add(req.project_name)
|
|
1539
|
-
dep = available.get(req.project_name)
|
|
1540
|
-
if not dep:
|
|
1541
|
-
return Error(
|
|
1542
|
-
"There is no lock entry for {project} in {lock_file} to satisfy the "
|
|
1543
|
-
"{transitive}'{req}' requirement.".format(
|
|
1544
|
-
project=req.project_name,
|
|
1545
|
-
lock_file=lockfile_path,
|
|
1546
|
-
transitive="" if req in root_requirements else "transitive ",
|
|
1547
|
-
req=req,
|
|
1548
|
-
)
|
|
1549
|
-
)
|
|
1550
|
-
elif dep:
|
|
1551
|
-
pnav, locked_req = dep
|
|
1552
|
-
if pnav not in req:
|
|
1553
|
-
production_assert(
|
|
1554
|
-
req in root_requirements,
|
|
1555
|
-
"Transitive requirements in a lock should always match existing lock "
|
|
1556
|
-
"entries. Found {project} {version} in {lock_file}, which does not "
|
|
1557
|
-
"satisfy transitive requirement '{req}' found in the same lock.",
|
|
1558
|
-
project=pnav.project_name,
|
|
1559
|
-
version=pnav.version,
|
|
1560
|
-
lock_file=lockfile_path,
|
|
1561
|
-
req=req,
|
|
1562
|
-
)
|
|
1563
|
-
return Error(
|
|
1564
|
-
"The locked version of {project} in {lock_file} is {version} which "
|
|
1565
|
-
"does not satisfy the '{req}' requirement.".format(
|
|
1566
|
-
project=pnav.project_name,
|
|
1567
|
-
lock_file=lockfile_path,
|
|
1568
|
-
version=pnav.version,
|
|
1569
|
-
req=req,
|
|
1570
|
-
)
|
|
1571
|
-
)
|
|
1572
|
-
elif (
|
|
1573
|
-
req.project_name in constraint_by_project_name
|
|
1574
|
-
and pnav not in constraint_by_project_name[req.project_name]
|
|
1575
|
-
):
|
|
1576
|
-
return Error(
|
|
1577
|
-
"The locked version of {project} in {lock_file} is {version} which "
|
|
1578
|
-
"does not satisfy the '{constraint}' constraint.".format(
|
|
1579
|
-
project=pnav.project_name,
|
|
1580
|
-
lock_file=lockfile_path,
|
|
1581
|
-
version=pnav.version,
|
|
1582
|
-
constraint=constraint_by_project_name[req.project_name],
|
|
1583
|
-
)
|
|
1584
|
-
)
|
|
1585
|
-
to_resolve.extend(
|
|
1586
|
-
requires_dist.filter_dependencies(
|
|
1587
|
-
req,
|
|
1588
|
-
locked_req,
|
|
1589
|
-
requires_python=lock_file.requires_python,
|
|
1590
|
-
target_systems=lock_file.target_systems,
|
|
1591
|
-
)
|
|
1592
|
-
)
|
|
1593
1720
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1721
|
+
result = subset_locked_resolve(
|
|
1722
|
+
locked_resolve,
|
|
1723
|
+
root_requirements,
|
|
1724
|
+
constraint_by_project_name,
|
|
1725
|
+
lock_file_description=lock_file_description,
|
|
1726
|
+
universal_target=lock_file.configuration.universal_target,
|
|
1727
|
+
)
|
|
1728
|
+
if isinstance(result, LockedResolve):
|
|
1729
|
+
resolve_subsets.append(result)
|
|
1730
|
+
else:
|
|
1731
|
+
errors.append(result)
|
|
1732
|
+
|
|
1733
|
+
if not resolve_subsets:
|
|
1734
|
+
if len(errors) == 1:
|
|
1735
|
+
return errors[0]
|
|
1736
|
+
return Error(
|
|
1737
|
+
"Failed to subset any of the {count} locked resolves contained in {lock_file}:\n"
|
|
1738
|
+
"{errors}".format(
|
|
1739
|
+
count=len(lock_file.locked_resolves),
|
|
1740
|
+
lock_file=lockfile_path,
|
|
1741
|
+
errors="\n".join(str(error) for error in errors),
|
|
1602
1742
|
)
|
|
1603
1743
|
)
|
|
1604
1744
|
|
|
1605
1745
|
return LockfileSubset(
|
|
1606
|
-
root_requirements=root_requirements,
|
|
1746
|
+
root_requirements=tuple(root_requirements.iter_requirements()),
|
|
1607
1747
|
constraints=constraint_by_project_name.values(),
|
|
1608
1748
|
locked_resolves=resolve_subsets,
|
|
1609
1749
|
)
|
|
@@ -1651,6 +1791,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1651
1791
|
use_pip_config=pip_configuration.use_pip_config,
|
|
1652
1792
|
dependency_configuration=dependency_config,
|
|
1653
1793
|
pip_log=resolver_options.get_pip_log(self.options),
|
|
1794
|
+
avoid_downloads=self.options.avoid_downloads,
|
|
1654
1795
|
)
|
|
1655
1796
|
|
|
1656
1797
|
target_configuration = target_options.configure(
|
|
@@ -1658,7 +1799,9 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1658
1799
|
)
|
|
1659
1800
|
targets = try_(
|
|
1660
1801
|
self._resolve_targets(
|
|
1661
|
-
action="updating",
|
|
1802
|
+
action="updating",
|
|
1803
|
+
style=lock_file.configuration.style,
|
|
1804
|
+
target_configuration=target_configuration,
|
|
1662
1805
|
)
|
|
1663
1806
|
)
|
|
1664
1807
|
|
|
@@ -1675,23 +1818,17 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1675
1818
|
)
|
|
1676
1819
|
|
|
1677
1820
|
with TRACER.timed("Selecting locks to update"):
|
|
1821
|
+
update_targets = (
|
|
1822
|
+
Targets.from_target(LocalInterpreter.create(targets.interpreter))
|
|
1823
|
+
if lock_file.configuration.style is LockStyle.UNIVERSAL
|
|
1824
|
+
else targets
|
|
1825
|
+
)
|
|
1678
1826
|
locked_resolve_count = len(lock_file.locked_resolves)
|
|
1679
|
-
if lock_file.style is LockStyle.UNIVERSAL and locked_resolve_count != 1:
|
|
1680
|
-
return Error(
|
|
1681
|
-
"The lock at {path} contains {count} locked resolves; so it "
|
|
1682
|
-
"cannot be updated as a universal lock which requires exactly one locked "
|
|
1683
|
-
"resolve.".format(path=lock_file_path, count=locked_resolve_count)
|
|
1684
|
-
)
|
|
1685
1827
|
if locked_resolve_count == 1:
|
|
1686
1828
|
locked_resolve = lock_file.locked_resolves[0]
|
|
1687
|
-
update_targets = (
|
|
1688
|
-
[LocalInterpreter.create(targets.interpreter)]
|
|
1689
|
-
if lock_file.style is LockStyle.UNIVERSAL
|
|
1690
|
-
else targets.unique_targets()
|
|
1691
|
-
)
|
|
1692
1829
|
update_requests = [
|
|
1693
1830
|
ResolveUpdateRequest(target=target, locked_resolve=locked_resolve)
|
|
1694
|
-
for target in update_targets
|
|
1831
|
+
for target in update_targets.unique_targets()
|
|
1695
1832
|
]
|
|
1696
1833
|
else:
|
|
1697
1834
|
# N.B.: With 1 locked resolve in the lock file we're updating, there is no ambiguity
|
|
@@ -1709,7 +1846,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1709
1846
|
|
|
1710
1847
|
subset_result = try_(
|
|
1711
1848
|
subset(
|
|
1712
|
-
targets=
|
|
1849
|
+
targets=update_targets,
|
|
1713
1850
|
lock=lock_file,
|
|
1714
1851
|
network_configuration=pip_configuration.network_configuration,
|
|
1715
1852
|
build_configuration=lock_file.build_configuration(),
|
|
@@ -1723,7 +1860,10 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1723
1860
|
)
|
|
1724
1861
|
for resolved_subset in subset_result.subsets
|
|
1725
1862
|
]
|
|
1726
|
-
if
|
|
1863
|
+
if (
|
|
1864
|
+
getattr(self.options, "strict", False)
|
|
1865
|
+
and lock_file.configuration.style is not LockStyle.UNIVERSAL
|
|
1866
|
+
):
|
|
1727
1867
|
missing_updates = set(lock_file.locked_resolves) - {
|
|
1728
1868
|
update_request.locked_resolve for update_request in update_requests
|
|
1729
1869
|
}
|
|
@@ -1737,7 +1877,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
1737
1877
|
lock_file=lock_file_path,
|
|
1738
1878
|
missing_platforms="\n".join(
|
|
1739
1879
|
sorted(
|
|
1740
|
-
"+ {platform}".format(platform=locked_resolve.
|
|
1880
|
+
"+ {platform}".format(platform=locked_resolve.target_platform)
|
|
1741
1881
|
for locked_resolve in missing_updates
|
|
1742
1882
|
)
|
|
1743
1883
|
),
|
|
@@ -2087,10 +2227,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
2087
2227
|
original_lock_file = try_(parse_lockfile(self.options, lock_file_path=lock_file_path))
|
|
2088
2228
|
lock_file = attr.evolve(
|
|
2089
2229
|
original_lock_file,
|
|
2090
|
-
|
|
2091
|
-
requires_python=SortedTuple(lock_configuration.requires_python),
|
|
2092
|
-
target_systems=SortedTuple(lock_configuration.target_systems),
|
|
2093
|
-
elide_unused_requires_dist=lock_configuration.elide_unused_requires_dist,
|
|
2230
|
+
configuration=lock_configuration,
|
|
2094
2231
|
pip_version=pip_configuration.version,
|
|
2095
2232
|
resolver_version=pip_configuration.resolver_version,
|
|
2096
2233
|
allow_prereleases=pip_configuration.allow_prereleases,
|
|
@@ -2158,6 +2295,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
2158
2295
|
targets=targets,
|
|
2159
2296
|
pip_configuration=pip_configuration,
|
|
2160
2297
|
dependency_configuration=dependency_config,
|
|
2298
|
+
avoid_downloads=self.options.avoid_downloads,
|
|
2161
2299
|
)
|
|
2162
2300
|
)
|
|
2163
2301
|
if self.options.dry_run:
|
|
@@ -2248,11 +2386,9 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
2248
2386
|
requirements=requirement_configuration.requirements,
|
|
2249
2387
|
requirement_files=requirement_configuration.requirement_files,
|
|
2250
2388
|
constraint_files=requirement_configuration.constraint_files,
|
|
2251
|
-
|
|
2252
|
-
find_links=pip_configuration.repos_configuration.find_links,
|
|
2389
|
+
repos_configuration=pip_configuration.repos_configuration,
|
|
2253
2390
|
resolver_version=pip_configuration.resolver_version,
|
|
2254
2391
|
network_configuration=pip_configuration.network_configuration,
|
|
2255
|
-
password_entries=pip_configuration.repos_configuration.password_entries,
|
|
2256
2392
|
build_configuration=pip_configuration.build_configuration,
|
|
2257
2393
|
transitive=pip_configuration.transitive,
|
|
2258
2394
|
max_parallel_jobs=pip_configuration.max_jobs,
|
|
@@ -2261,6 +2397,7 @@ class Lock(OutputMixin, JsonMixin, BuildTimeCommand):
|
|
|
2261
2397
|
extra_pip_requirements=pip_configuration.extra_requirements,
|
|
2262
2398
|
keyring_provider=pip_configuration.keyring_provider,
|
|
2263
2399
|
result_type=InstallableType.INSTALLED_WHEEL_CHROOT,
|
|
2400
|
+
dependency_configuration=dependency_config,
|
|
2264
2401
|
)
|
|
2265
2402
|
)
|
|
2266
2403
|
return sync_target.sync(
|