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
|
@@ -7,8 +7,10 @@ import json
|
|
|
7
7
|
|
|
8
8
|
from pex import compatibility
|
|
9
9
|
from pex.artifact_url import Fingerprint
|
|
10
|
+
from pex.dependency_configuration import Override
|
|
10
11
|
from pex.dist_metadata import Requirement, RequirementParseError
|
|
11
12
|
from pex.enum import Enum
|
|
13
|
+
from pex.interpreter_constraints import InterpreterConstraint
|
|
12
14
|
from pex.pep_440 import Version
|
|
13
15
|
from pex.pep_503 import ProjectName
|
|
14
16
|
from pex.pip.version import PipVersion
|
|
@@ -16,18 +18,20 @@ from pex.resolve.locked_resolve import (
|
|
|
16
18
|
Artifact,
|
|
17
19
|
FileArtifact,
|
|
18
20
|
LocalProjectArtifact,
|
|
21
|
+
LockConfiguration,
|
|
19
22
|
LockedRequirement,
|
|
20
23
|
LockedResolve,
|
|
21
24
|
LockStyle,
|
|
22
|
-
TargetSystem,
|
|
23
25
|
VCSArtifact,
|
|
24
26
|
)
|
|
25
27
|
from pex.resolve.lockfile.model import Lockfile
|
|
26
28
|
from pex.resolve.path_mappings import PathMappings
|
|
27
29
|
from pex.resolve.resolved_requirement import Pin
|
|
28
30
|
from pex.resolve.resolver_configuration import BuildConfiguration, PipConfiguration, ResolverVersion
|
|
31
|
+
from pex.resolve.target_system import TargetSystem
|
|
29
32
|
from pex.sorted_tuple import SortedTuple
|
|
30
33
|
from pex.third_party.packaging import tags
|
|
34
|
+
from pex.third_party.packaging.markers import InvalidMarker, Marker
|
|
31
35
|
from pex.third_party.packaging.specifiers import InvalidSpecifier, SpecifierSet
|
|
32
36
|
from pex.typing import TYPE_CHECKING, cast
|
|
33
37
|
|
|
@@ -184,6 +188,18 @@ def loads(
|
|
|
184
188
|
"The requirement string at '{path}' is invalid: {err}".format(path=path, err=e)
|
|
185
189
|
)
|
|
186
190
|
|
|
191
|
+
def parse_override(
|
|
192
|
+
raw_override, # type: str
|
|
193
|
+
path, # type: str
|
|
194
|
+
):
|
|
195
|
+
# type: (...) -> Override
|
|
196
|
+
try:
|
|
197
|
+
return Override.parse(raw_override)
|
|
198
|
+
except Override.InvalidError as e:
|
|
199
|
+
raise ParseError(
|
|
200
|
+
"The override string at '{path}' is invalid: {err}".format(path=path, err=e)
|
|
201
|
+
)
|
|
202
|
+
|
|
187
203
|
def parse_version_specifier(
|
|
188
204
|
raw_version_specifier, # type: str
|
|
189
205
|
path, # type: str
|
|
@@ -196,6 +212,28 @@ def loads(
|
|
|
196
212
|
"The version specifier at '{path}' is invalid: {err}".format(path=path, err=e)
|
|
197
213
|
)
|
|
198
214
|
|
|
215
|
+
def parse_interpreter_constraint(
|
|
216
|
+
value, # type: str
|
|
217
|
+
path, # type: str
|
|
218
|
+
):
|
|
219
|
+
# type: (...) -> InterpreterConstraint
|
|
220
|
+
try:
|
|
221
|
+
return InterpreterConstraint.parse(value)
|
|
222
|
+
except ValueError as e:
|
|
223
|
+
raise ParseError(
|
|
224
|
+
"The interpreter constraint at '{path}' is invalid: {err}".format(path=path, err=e)
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
def parse_marker(
|
|
228
|
+
raw_marker, # type: str
|
|
229
|
+
path, # type: str
|
|
230
|
+
):
|
|
231
|
+
# type: (...) -> Marker
|
|
232
|
+
try:
|
|
233
|
+
return Marker(raw_marker)
|
|
234
|
+
except InvalidMarker as e:
|
|
235
|
+
raise ParseError("The marker at '{path}' is invalid: {err}".format(path=path, err=e))
|
|
236
|
+
|
|
199
237
|
required_path_mappings = get("path_mappings", dict, optional=True) or {}
|
|
200
238
|
given_mappings = set(mapping.name for mapping in path_mappings.mappings)
|
|
201
239
|
unspecified_paths = set(required_path_mappings) - given_mappings
|
|
@@ -204,16 +242,33 @@ def loads(
|
|
|
204
242
|
required_path_mappings=required_path_mappings, unspecified_paths=unspecified_paths
|
|
205
243
|
)
|
|
206
244
|
|
|
207
|
-
|
|
208
|
-
parse_enum_value(
|
|
209
|
-
enum_type=TargetSystem,
|
|
210
|
-
value=target_system,
|
|
211
|
-
path=".target_systems[{index}]".format(index=index),
|
|
212
|
-
)
|
|
213
|
-
for index, target_system in enumerate(get("target_systems", list, optional=True) or ())
|
|
214
|
-
]
|
|
215
|
-
|
|
245
|
+
style = get_enum_value(LockStyle, "style")
|
|
216
246
|
elide_unused_requires_dist = get("elide_unused_requires_dist", bool, optional=True) or False
|
|
247
|
+
if style is LockStyle.UNIVERSAL:
|
|
248
|
+
lock_configuration = LockConfiguration.universal(
|
|
249
|
+
interpreter_constraints=[
|
|
250
|
+
parse_interpreter_constraint(
|
|
251
|
+
value=interpreter_constraint,
|
|
252
|
+
path=".requires_python[{index}]".format(index=index),
|
|
253
|
+
)
|
|
254
|
+
for index, interpreter_constraint in enumerate(get("requires_python", list))
|
|
255
|
+
],
|
|
256
|
+
systems=[
|
|
257
|
+
parse_enum_value(
|
|
258
|
+
enum_type=TargetSystem,
|
|
259
|
+
value=target_system,
|
|
260
|
+
path=".target_systems[{index}]".format(index=index),
|
|
261
|
+
)
|
|
262
|
+
for index, target_system in enumerate(
|
|
263
|
+
get("target_systems", list, optional=True) or ()
|
|
264
|
+
)
|
|
265
|
+
],
|
|
266
|
+
elide_unused_requires_dist=elide_unused_requires_dist,
|
|
267
|
+
)
|
|
268
|
+
else:
|
|
269
|
+
lock_configuration = LockConfiguration(
|
|
270
|
+
style=style, elide_unused_requires_dist=elide_unused_requires_dist
|
|
271
|
+
)
|
|
217
272
|
|
|
218
273
|
only_wheels = [
|
|
219
274
|
parse_project_name(project_name, path=".only_wheels[{index}]".format(index=index))
|
|
@@ -245,8 +300,8 @@ def loads(
|
|
|
245
300
|
]
|
|
246
301
|
|
|
247
302
|
overridden = [
|
|
248
|
-
|
|
249
|
-
for index,
|
|
303
|
+
parse_override(override, path=".overridden[{index}]".format(index=index))
|
|
304
|
+
for index, override in enumerate(get("overridden", list, optional=True) or ())
|
|
250
305
|
]
|
|
251
306
|
|
|
252
307
|
def assemble_tag(
|
|
@@ -280,6 +335,12 @@ def loads(
|
|
|
280
335
|
if platform_tag_components
|
|
281
336
|
else None
|
|
282
337
|
)
|
|
338
|
+
marker_str = get("marker", str, data=locked_resolve, path=lock_path, optional=True)
|
|
339
|
+
marker = (
|
|
340
|
+
parse_marker(marker_str, path='{lock_path}["marker"]'.format(lock_path=lock_path))
|
|
341
|
+
if marker_str
|
|
342
|
+
else None
|
|
343
|
+
)
|
|
283
344
|
locked_reqs = []
|
|
284
345
|
for req_index, req in enumerate(
|
|
285
346
|
get("locked_requirements", list, data=locked_resolve, path=lock_path)
|
|
@@ -337,15 +398,16 @@ def loads(
|
|
|
337
398
|
)
|
|
338
399
|
|
|
339
400
|
locked_resolves.append(
|
|
340
|
-
LockedResolve(
|
|
401
|
+
LockedResolve(
|
|
402
|
+
locked_requirements=SortedTuple(locked_reqs),
|
|
403
|
+
platform_tag=platform_tag,
|
|
404
|
+
marker=marker,
|
|
405
|
+
)
|
|
341
406
|
)
|
|
342
407
|
|
|
343
408
|
return Lockfile.create(
|
|
344
409
|
pex_version=get("pex_version"),
|
|
345
|
-
|
|
346
|
-
requires_python=get("requires_python", list),
|
|
347
|
-
target_systems=target_systems,
|
|
348
|
-
elide_unused_requires_dist=elide_unused_requires_dist,
|
|
410
|
+
lock_configuration=lock_configuration,
|
|
349
411
|
pip_version=get_enum_value(
|
|
350
412
|
PipVersion,
|
|
351
413
|
"pip_version",
|
|
@@ -406,12 +468,22 @@ def as_json_data(
|
|
|
406
468
|
data["editable"] = artifact.editable
|
|
407
469
|
return data
|
|
408
470
|
|
|
471
|
+
requires_python = [] # type: List[str]
|
|
472
|
+
target_systems = [] # type: List[str]
|
|
473
|
+
if lockfile.configuration.universal_target:
|
|
474
|
+
universal_target = lockfile.configuration.universal_target
|
|
475
|
+
requires_python.extend(
|
|
476
|
+
str(interpreter_constraint)
|
|
477
|
+
for interpreter_constraint in universal_target.iter_interpreter_constraints()
|
|
478
|
+
)
|
|
479
|
+
target_systems.extend(str(target_system) for target_system in universal_target.systems)
|
|
480
|
+
|
|
409
481
|
return {
|
|
410
482
|
"pex_version": lockfile.pex_version,
|
|
411
|
-
"style": str(lockfile.style),
|
|
412
|
-
"requires_python":
|
|
413
|
-
"target_systems":
|
|
414
|
-
"elide_unused_requires_dist": lockfile.elide_unused_requires_dist,
|
|
483
|
+
"style": str(lockfile.configuration.style),
|
|
484
|
+
"requires_python": requires_python,
|
|
485
|
+
"target_systems": target_systems,
|
|
486
|
+
"elide_unused_requires_dist": lockfile.configuration.elide_unused_requires_dist,
|
|
415
487
|
"pip_version": str(lockfile.pip_version),
|
|
416
488
|
"resolver_version": str(lockfile.resolver_version),
|
|
417
489
|
"requirements": [
|
|
@@ -432,13 +504,16 @@ def as_json_data(
|
|
|
432
504
|
"overridden": [str(override) for override in lockfile.overridden],
|
|
433
505
|
"locked_resolves": [
|
|
434
506
|
{
|
|
435
|
-
"platform_tag":
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
507
|
+
"platform_tag": (
|
|
508
|
+
[
|
|
509
|
+
locked_resolve.platform_tag.interpreter,
|
|
510
|
+
locked_resolve.platform_tag.abi,
|
|
511
|
+
locked_resolve.platform_tag.platform,
|
|
512
|
+
]
|
|
513
|
+
if locked_resolve.platform_tag
|
|
514
|
+
else None
|
|
515
|
+
),
|
|
516
|
+
"marker": str(locked_resolve.marker) if locked_resolve.marker else None,
|
|
442
517
|
"locked_requirements": [
|
|
443
518
|
{
|
|
444
519
|
"project_name": str(req.pin.project_name),
|
pex/resolve/lockfile/model.py
CHANGED
|
@@ -5,19 +5,13 @@ from __future__ import absolute_import, print_function
|
|
|
5
5
|
|
|
6
6
|
import os
|
|
7
7
|
|
|
8
|
-
from pex.dependency_configuration import DependencyConfiguration
|
|
8
|
+
from pex.dependency_configuration import DependencyConfiguration, Override
|
|
9
9
|
from pex.dist_metadata import Constraint, Requirement
|
|
10
10
|
from pex.orderedset import OrderedSet
|
|
11
11
|
from pex.pep_503 import ProjectName
|
|
12
12
|
from pex.pip.version import PipVersion, PipVersionValue
|
|
13
13
|
from pex.requirements import LocalProjectRequirement
|
|
14
|
-
from pex.resolve.locked_resolve import
|
|
15
|
-
LocalProjectArtifact,
|
|
16
|
-
LockConfiguration,
|
|
17
|
-
LockedResolve,
|
|
18
|
-
LockStyle,
|
|
19
|
-
TargetSystem,
|
|
20
|
-
)
|
|
14
|
+
from pex.resolve.locked_resolve import LocalProjectArtifact, LockConfiguration, LockedResolve
|
|
21
15
|
from pex.resolve.lockfile import requires_dist
|
|
22
16
|
from pex.resolve.resolved_requirement import Pin
|
|
23
17
|
from pex.resolve.resolver_configuration import BuildConfiguration, ResolverVersion
|
|
@@ -40,21 +34,18 @@ class Lockfile(object):
|
|
|
40
34
|
def create(
|
|
41
35
|
cls,
|
|
42
36
|
pex_version, # type: str
|
|
43
|
-
|
|
44
|
-
requires_python, # type: Iterable[str]
|
|
45
|
-
target_systems, # type: Iterable[TargetSystem.Value]
|
|
37
|
+
lock_configuration, # type: LockConfiguration
|
|
46
38
|
requirements, # type: Iterable[Union[Requirement, ParsedRequirement]]
|
|
47
39
|
constraints, # type: Iterable[Constraint]
|
|
48
40
|
allow_prereleases, # type: bool
|
|
49
41
|
build_configuration, # type: BuildConfiguration
|
|
50
42
|
transitive, # type: bool
|
|
51
43
|
excluded, # type: Iterable[Requirement]
|
|
52
|
-
overridden, # type: Iterable[
|
|
44
|
+
overridden, # type: Iterable[Override]
|
|
53
45
|
locked_resolves, # type: Iterable[LockedResolve]
|
|
54
46
|
source=None, # type: Optional[str]
|
|
55
47
|
pip_version=None, # type: Optional[PipVersionValue]
|
|
56
48
|
resolver_version=None, # type: Optional[ResolverVersion.Value]
|
|
57
|
-
elide_unused_requires_dist=False, # type: bool
|
|
58
49
|
):
|
|
59
50
|
# type: (...) -> Lockfile
|
|
60
51
|
|
|
@@ -96,14 +87,11 @@ class Lockfile(object):
|
|
|
96
87
|
return req.requirement
|
|
97
88
|
|
|
98
89
|
resolve_requirements = OrderedSet(extract_requirement(req) for req in requirements)
|
|
99
|
-
|
|
100
90
|
pip_ver = pip_version or PipVersion.DEFAULT
|
|
91
|
+
|
|
101
92
|
return cls(
|
|
102
93
|
pex_version=pex_version,
|
|
103
|
-
|
|
104
|
-
requires_python=SortedTuple(requires_python),
|
|
105
|
-
target_systems=SortedTuple(target_systems),
|
|
106
|
-
elide_unused_requires_dist=elide_unused_requires_dist,
|
|
94
|
+
configuration=lock_configuration,
|
|
107
95
|
pip_version=pip_ver,
|
|
108
96
|
resolver_version=resolver_version or ResolverVersion.default(pip_ver),
|
|
109
97
|
requirements=SortedTuple(resolve_requirements, key=str),
|
|
@@ -125,10 +113,12 @@ class Lockfile(object):
|
|
|
125
113
|
requires_dist.remove_unused_requires_dist(
|
|
126
114
|
resolve_requirements,
|
|
127
115
|
locked_resolve,
|
|
128
|
-
|
|
129
|
-
|
|
116
|
+
universal_target=lock_configuration.universal_target,
|
|
117
|
+
dependency_configuration=DependencyConfiguration.create(
|
|
118
|
+
excluded=excluded, overridden=overridden
|
|
119
|
+
),
|
|
130
120
|
)
|
|
131
|
-
if elide_unused_requires_dist
|
|
121
|
+
if lock_configuration.elide_unused_requires_dist
|
|
132
122
|
else locked_resolve
|
|
133
123
|
)
|
|
134
124
|
for locked_resolve in locked_resolves
|
|
@@ -138,10 +128,7 @@ class Lockfile(object):
|
|
|
138
128
|
)
|
|
139
129
|
|
|
140
130
|
pex_version = attr.ib() # type: str
|
|
141
|
-
|
|
142
|
-
requires_python = attr.ib() # type: SortedTuple[str]
|
|
143
|
-
target_systems = attr.ib() # type: SortedTuple[TargetSystem.Value]
|
|
144
|
-
elide_unused_requires_dist = attr.ib() # type: bool
|
|
131
|
+
configuration = attr.ib() # type: LockConfiguration
|
|
145
132
|
pip_version = attr.ib() # type: PipVersionValue
|
|
146
133
|
resolver_version = attr.ib() # type: ResolverVersion.Value
|
|
147
134
|
requirements = attr.ib() # type: SortedTuple[Requirement]
|
|
@@ -157,20 +144,11 @@ class Lockfile(object):
|
|
|
157
144
|
use_system_time = attr.ib() # type: bool
|
|
158
145
|
transitive = attr.ib() # type: bool
|
|
159
146
|
excluded = attr.ib() # type: SortedTuple[Requirement]
|
|
160
|
-
overridden = attr.ib() # type: SortedTuple[
|
|
147
|
+
overridden = attr.ib() # type: SortedTuple[Override]
|
|
161
148
|
locked_resolves = attr.ib() # type: SortedTuple[LockedResolve]
|
|
162
149
|
local_project_requirement_mapping = attr.ib(eq=False) # type: Mapping[str, Requirement]
|
|
163
150
|
source = attr.ib(default=None, eq=False) # type: Optional[str]
|
|
164
151
|
|
|
165
|
-
def lock_configuration(self):
|
|
166
|
-
# type: () -> LockConfiguration
|
|
167
|
-
return LockConfiguration(
|
|
168
|
-
style=self.style,
|
|
169
|
-
requires_python=self.requires_python,
|
|
170
|
-
target_systems=self.target_systems,
|
|
171
|
-
elide_unused_requires_dist=self.elide_unused_requires_dist,
|
|
172
|
-
)
|
|
173
|
-
|
|
174
152
|
def build_configuration(self):
|
|
175
153
|
# type: () -> BuildConfiguration
|
|
176
154
|
return BuildConfiguration.create(
|
pex/resolve/lockfile/pep_751.py
CHANGED
|
@@ -14,6 +14,7 @@ from pex.compatibility import text, urlparse
|
|
|
14
14
|
from pex.dependency_configuration import DependencyConfiguration
|
|
15
15
|
from pex.dist_metadata import Constraint, Requirement
|
|
16
16
|
from pex.exceptions import production_assert
|
|
17
|
+
from pex.interpreter_implementation import InterpreterImplementation
|
|
17
18
|
from pex.network_configuration import NetworkConfiguration
|
|
18
19
|
from pex.orderedset import OrderedSet
|
|
19
20
|
from pex.pep_425 import CompatibilityTags, RankedTag
|
|
@@ -27,7 +28,6 @@ from pex.resolve.locked_resolve import (
|
|
|
27
28
|
LockedRequirement,
|
|
28
29
|
LockedResolve,
|
|
29
30
|
Resolved,
|
|
30
|
-
TargetSystem,
|
|
31
31
|
UnFingerprintedLocalProjectArtifact,
|
|
32
32
|
UnFingerprintedVCSArtifact,
|
|
33
33
|
VCSArtifact,
|
|
@@ -38,6 +38,7 @@ from pex.resolve.lockfile.subset import Subset, SubsetResult
|
|
|
38
38
|
from pex.resolve.requirement_configuration import RequirementConfiguration
|
|
39
39
|
from pex.resolve.resolved_requirement import Pin
|
|
40
40
|
from pex.resolve.resolver_configuration import BuildConfiguration
|
|
41
|
+
from pex.resolve.target_system import TargetSystem, UniversalTarget
|
|
41
42
|
from pex.result import Error, ResultError, try_
|
|
42
43
|
from pex.sorted_tuple import SortedTuple
|
|
43
44
|
from pex.targets import Target, Targets
|
|
@@ -175,53 +176,105 @@ def _elide_extras(marker):
|
|
|
175
176
|
return marker
|
|
176
177
|
|
|
177
178
|
|
|
178
|
-
def
|
|
179
|
-
# type:
|
|
179
|
+
def _implementation_marker(
|
|
180
|
+
implementation, # type: InterpreterImplementation.Value
|
|
181
|
+
extra_marker=None, # type: Optional[Marker]
|
|
182
|
+
):
|
|
183
|
+
# type: (...) -> str
|
|
184
|
+
platform_python_implementation = "platform_python_implementation == '{implementation}'".format(
|
|
185
|
+
implementation=implementation
|
|
186
|
+
)
|
|
187
|
+
if not extra_marker:
|
|
188
|
+
return platform_python_implementation
|
|
189
|
+
return "{platform_python_implementation} and {extra_marker}".format(
|
|
190
|
+
platform_python_implementation=platform_python_implementation, extra_marker=extra_marker
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def _to_environment(
|
|
195
|
+
system, # type: TargetSystem.Value
|
|
196
|
+
implementation=None, # type: Optional[InterpreterImplementation.Value]
|
|
197
|
+
extra_marker=None, # type: Optional[Marker]
|
|
198
|
+
):
|
|
199
|
+
# type: (...) -> str
|
|
200
|
+
|
|
180
201
|
if system is TargetSystem.LINUX:
|
|
181
|
-
|
|
202
|
+
platform_system = "platform_system == 'Linux'"
|
|
182
203
|
elif system is TargetSystem.MAC:
|
|
183
|
-
|
|
204
|
+
platform_system = "platform_system == 'Darwin'"
|
|
184
205
|
else:
|
|
185
206
|
production_assert(system is TargetSystem.WINDOWS)
|
|
186
|
-
|
|
207
|
+
platform_system = "platform_system == 'Windows'"
|
|
208
|
+
|
|
209
|
+
if not implementation:
|
|
210
|
+
if not extra_marker:
|
|
211
|
+
return platform_system
|
|
212
|
+
return "{platform_system} and {extra_marker}".format(
|
|
213
|
+
platform_system=platform_system, extra_marker=extra_marker
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
return "{platform_system} and {platform_python_implementation}".format(
|
|
217
|
+
platform_system=platform_system,
|
|
218
|
+
platform_python_implementation=_implementation_marker(
|
|
219
|
+
implementation, extra_marker=extra_marker
|
|
220
|
+
),
|
|
221
|
+
)
|
|
187
222
|
|
|
188
223
|
|
|
189
224
|
def convert(
|
|
190
225
|
root_requirements, # type: Iterable[Requirement]
|
|
191
226
|
locked_resolve, # type: LockedResolve
|
|
192
227
|
output, # type: IO[bytes]
|
|
193
|
-
|
|
194
|
-
target_systems=(), # type: Iterable[TargetSystem.Value]
|
|
228
|
+
universal_target=None, # type: Optional[UniversalTarget]
|
|
195
229
|
subset=(), # type: Iterable[DownloadableArtifact]
|
|
196
230
|
include_dependency_info=True, # type bool
|
|
197
231
|
):
|
|
198
232
|
# type: (...) -> None
|
|
199
233
|
|
|
200
|
-
locked_resolve = remove_unused_requires_dist(
|
|
201
|
-
resolve_requirements=root_requirements,
|
|
202
|
-
locked_resolve=locked_resolve,
|
|
203
|
-
requires_python=[requires_python] if requires_python else [],
|
|
204
|
-
target_systems=target_systems,
|
|
205
|
-
)
|
|
206
|
-
|
|
207
234
|
pylock = OrderedDict() # type: OrderedDict[str, Any]
|
|
208
235
|
pylock["lock-version"] = "1.0" # https://peps.python.org/pep-0751/#lock-version
|
|
209
236
|
|
|
210
|
-
if
|
|
237
|
+
if universal_target:
|
|
211
238
|
# https://peps.python.org/pep-0751/#environments
|
|
212
239
|
#
|
|
213
|
-
# TODO: We just stick to mapping `--target-system`
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
240
|
+
# TODO: We just stick to mapping `--target-system` and any `--interpreter-constraint` that
|
|
241
|
+
# have an implementation specified into markers currently but this should probably include
|
|
242
|
+
# the full marker needed to rule out invalid installs, like Python 2.7 attempting to
|
|
243
|
+
# install a lock with only Python 3 wheels.
|
|
244
|
+
if universal_target.systems:
|
|
245
|
+
pylock["environments"] = sorted(
|
|
246
|
+
_to_environment(
|
|
247
|
+
system,
|
|
248
|
+
implementation=universal_target.implementation,
|
|
249
|
+
extra_marker=locked_resolve.marker,
|
|
250
|
+
)
|
|
251
|
+
for system in universal_target.systems
|
|
252
|
+
)
|
|
253
|
+
elif universal_target.implementation:
|
|
254
|
+
pylock["environments"] = [
|
|
255
|
+
_implementation_marker(
|
|
256
|
+
universal_target.implementation, extra_marker=locked_resolve.marker
|
|
257
|
+
)
|
|
258
|
+
]
|
|
259
|
+
elif locked_resolve.marker:
|
|
260
|
+
pylock["environments"] = [str(locked_resolve.marker)]
|
|
261
|
+
|
|
262
|
+
if universal_target.requires_python:
|
|
263
|
+
if len(universal_target.requires_python) > 1:
|
|
264
|
+
# TODO(John Sirois): Provide a better error message. We could guide on OR
|
|
265
|
+
# to and AND paired with != to remove disjoint portions of the range.
|
|
266
|
+
raise ValueError(
|
|
267
|
+
"Can only convert a lock file with a single interpreter constraint."
|
|
268
|
+
)
|
|
269
|
+
requires_python = universal_target.requires_python[0]
|
|
270
|
+
|
|
271
|
+
# https://peps.python.org/pep-0751/#requires-python
|
|
272
|
+
#
|
|
273
|
+
# TODO: This is currently just any `--interpreter-constraint` specifiers for
|
|
274
|
+
# `--style universal` locks but it should probably be further refined (or purely
|
|
275
|
+
# calculated for non universal locks) from locked project requires-python values and
|
|
276
|
+
# even more narrowly by locked projects with only wheel artifacts by the wheel tags.
|
|
277
|
+
pylock["requires-python"] = str(requires_python)
|
|
225
278
|
|
|
226
279
|
# TODO: These 3 assume a `pyproject.toml` is the input source for the lock. It almost never is
|
|
227
280
|
# for current Pex lock use cases. Figure out if there is anything better that can be done.
|
|
@@ -251,6 +304,11 @@ def convert(
|
|
|
251
304
|
if req.url and isinstance(parse_requirement_string(str(req)), URLRequirement)
|
|
252
305
|
} # type: Dict[ProjectName, Requirement]
|
|
253
306
|
|
|
307
|
+
locked_resolve = remove_unused_requires_dist(
|
|
308
|
+
resolve_requirements=root_requirements,
|
|
309
|
+
locked_resolve=locked_resolve,
|
|
310
|
+
universal_target=universal_target,
|
|
311
|
+
)
|
|
254
312
|
dependants_by_project_name = defaultdict(
|
|
255
313
|
OrderedSet
|
|
256
314
|
) # type: DefaultDict[ProjectName, OrderedSet[Tuple[ProjectName, Optional[Marker]]]]
|
|
@@ -508,11 +566,12 @@ class ParseContext(object):
|
|
|
508
566
|
self,
|
|
509
567
|
key, # type: str
|
|
510
568
|
default=None, # type: Optional[str]
|
|
569
|
+
footer_message=None, # type: Optional[str]
|
|
511
570
|
):
|
|
512
571
|
# type: (...) -> str
|
|
513
572
|
# The cast is of Python 2. The return type will actually be `unicode` in that case, but it
|
|
514
573
|
# doesn't matter since there will be no further runtime type checks above this call.
|
|
515
|
-
return cast(str, self.get(key, text, default=default))
|
|
574
|
+
return cast(str, self.get(key, text, default=default, footer_message=footer_message))
|
|
516
575
|
|
|
517
576
|
def get_array_of_strings(
|
|
518
577
|
self,
|
|
@@ -593,14 +652,16 @@ class ParseContext(object):
|
|
|
593
652
|
key, # type: str
|
|
594
653
|
item_type, # type: Type[_T]
|
|
595
654
|
default=None, # type: Optional[_T]
|
|
655
|
+
footer_message=None, # type: Optional[str]
|
|
596
656
|
):
|
|
597
657
|
# type: (...) -> _T
|
|
598
658
|
value = self.table.get(key, None)
|
|
599
659
|
if value is None:
|
|
600
660
|
if default is None:
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
661
|
+
msg_lines = ["A value for {key} is required.".format(key=self.subpath(key))]
|
|
662
|
+
if footer_message:
|
|
663
|
+
msg_lines.append(footer_message)
|
|
664
|
+
raise ResultError(self.error(os.linesep.join(msg_lines)))
|
|
604
665
|
return default
|
|
605
666
|
if not isinstance(value, item_type):
|
|
606
667
|
raise ResultError(
|
|
@@ -797,43 +858,11 @@ class PackageIndex(object):
|
|
|
797
858
|
return self._indexed_packages_by_name.get(project_name)
|
|
798
859
|
|
|
799
860
|
|
|
800
|
-
def spec_matches(
|
|
801
|
-
spec, # type: Any
|
|
802
|
-
package_data, # type: Any
|
|
803
|
-
):
|
|
804
|
-
# type: (...) -> bool
|
|
805
|
-
|
|
806
|
-
if isinstance(spec, dict) and isinstance(package_data, dict):
|
|
807
|
-
for key, value in spec.items():
|
|
808
|
-
if not spec_matches(value, package_data.get(key)):
|
|
809
|
-
return False
|
|
810
|
-
return True
|
|
811
|
-
|
|
812
|
-
if isinstance(spec, list) and isinstance(package_data, list):
|
|
813
|
-
# All instances of lists in packages are currently array of tables:
|
|
814
|
-
# + dependencies
|
|
815
|
-
# + wheels
|
|
816
|
-
# + attestation-identities
|
|
817
|
-
#
|
|
818
|
-
# As such, we consider the list matches if any of its contained tables matches each of the
|
|
819
|
-
# spec tables. This allows a dependency spec like so to match the torch cpu wheel in a lock
|
|
820
|
-
# that also includes torch-2.7.0-cp311-none-macosx_11_0_arm64.whl (cuda 12.8):
|
|
821
|
-
# {name = "torch", wheels = [{ name = "torch-2.7.0+xpu-cp39-cp39-win_amd64.whl" }]}
|
|
822
|
-
for spec_item in spec:
|
|
823
|
-
if not any(
|
|
824
|
-
spec_matches(spec_item, package_data_item) for package_data_item in package_data
|
|
825
|
-
):
|
|
826
|
-
return False
|
|
827
|
-
return True
|
|
828
|
-
|
|
829
|
-
# I have no clue why MyPy can't track this as bool.
|
|
830
|
-
return cast(bool, spec == package_data)
|
|
831
|
-
|
|
832
|
-
|
|
833
861
|
@attr.s
|
|
834
862
|
class PackageParser(object):
|
|
835
863
|
package_index = attr.ib() # type: PackageIndex
|
|
836
864
|
source = attr.ib() # type: str
|
|
865
|
+
created_by = attr.ib() # type: str
|
|
837
866
|
|
|
838
867
|
parsed_packages_by_index = attr.ib(factory=dict) # type: Dict[int, Package]
|
|
839
868
|
|
|
@@ -905,7 +934,22 @@ class PackageParser(object):
|
|
|
905
934
|
"dependencies", default=[], diagnostic_key="name"
|
|
906
935
|
)
|
|
907
936
|
for dep_idx, dep_parse_context in enumerate(dep_parse_contexts):
|
|
908
|
-
dep_name = ProjectName(
|
|
937
|
+
dep_name = ProjectName(
|
|
938
|
+
dep_parse_context.get_string(
|
|
939
|
+
"name",
|
|
940
|
+
footer_message=os.linesep.join(
|
|
941
|
+
(
|
|
942
|
+
"Pex requires dependency tables specify at least a `name`.",
|
|
943
|
+
"The pylock.toml spec does not require this however.",
|
|
944
|
+
"To subset locks created by {creator}, either they will need to add "
|
|
945
|
+
"names for their dependencies or Pex will need to support more "
|
|
946
|
+
"sophisticated dependency parsing.".format(creator=self.created_by),
|
|
947
|
+
"For more information, see the comments starting here: "
|
|
948
|
+
"https://github.com/pex-tool/pex/issues/2885#issuecomment-3263138568",
|
|
949
|
+
)
|
|
950
|
+
),
|
|
951
|
+
)
|
|
952
|
+
)
|
|
909
953
|
|
|
910
954
|
package_deps = self.package_index.packages(dep_name)
|
|
911
955
|
if not package_deps:
|
|
@@ -915,31 +959,9 @@ class PackageParser(object):
|
|
|
915
959
|
project_name=project_name.raw, dep_name=dep_name.raw
|
|
916
960
|
)
|
|
917
961
|
)
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
for indexed_package in package_deps
|
|
922
|
-
if spec_matches(dep_parse_context.table, indexed_package.package_data)
|
|
923
|
-
] # type: List[IndexedPackage]
|
|
924
|
-
if not deps:
|
|
925
|
-
return dep_parse_context.error(
|
|
926
|
-
"No matching {dep_name} package could be found for {project_name} "
|
|
927
|
-
"dependencies[{dep_idx}].".format(
|
|
928
|
-
dep_name=dep_name.raw, project_name=project_name.raw, dep_idx=dep_idx
|
|
929
|
-
)
|
|
930
|
-
)
|
|
931
|
-
elif len(deps) > 1:
|
|
932
|
-
return dep_parse_context.error(
|
|
933
|
-
"More than one package matches {project_name} dependencies[{dep_idx}]:\n"
|
|
934
|
-
"{matches}".format(
|
|
935
|
-
project_name=project_name.raw,
|
|
936
|
-
dep_idx=dep_idx,
|
|
937
|
-
matches="\n".join(
|
|
938
|
-
"+ packages[{index}]".format(index=dep.index) for dep in deps
|
|
939
|
-
),
|
|
940
|
-
)
|
|
941
|
-
)
|
|
942
|
-
dependencies.append(Dependency(index=deps[0].index, project_name=dep_name))
|
|
962
|
+
dependencies.extend(
|
|
963
|
+
Dependency(index=dep.index, project_name=dep_name) for dep in package_deps
|
|
964
|
+
)
|
|
943
965
|
|
|
944
966
|
vcs_parse_context = parse_context.get_table("vcs", default={})
|
|
945
967
|
directory_parse_context = parse_context.get_table("directory", default={})
|
|
@@ -1342,12 +1364,7 @@ class Pylock(object):
|
|
|
1342
1364
|
except TomlDecodeError as e:
|
|
1343
1365
|
return parse_context.error("Failed to parse TOML", e)
|
|
1344
1366
|
|
|
1345
|
-
lock_version = Version(
|
|
1346
|
-
parse_context.get_string(
|
|
1347
|
-
"lock-version",
|
|
1348
|
-
"Pex only supports lock version 1.0 and refuses to guess compatibility.",
|
|
1349
|
-
)
|
|
1350
|
-
)
|
|
1367
|
+
lock_version = Version(parse_context.get_string("lock-version"))
|
|
1351
1368
|
if lock_version != Version("1.0"):
|
|
1352
1369
|
return parse_context.error(
|
|
1353
1370
|
"Found `lock-version` {version}, but Pex only supports version 1.0.".format(
|
|
@@ -1370,7 +1387,9 @@ class Pylock(object):
|
|
|
1370
1387
|
"packages", default=[], diagnostic_key="name"
|
|
1371
1388
|
)
|
|
1372
1389
|
package_index = PackageIndex.create(packages_data)
|
|
1373
|
-
package_parser = PackageParser(
|
|
1390
|
+
package_parser = PackageParser(
|
|
1391
|
+
package_index=package_index, source=pylock_toml_path, created_by=created_by
|
|
1392
|
+
)
|
|
1374
1393
|
|
|
1375
1394
|
local_project_requirement_mapping = {} # type: Dict[str, Requirement]
|
|
1376
1395
|
packages = [] # type: List[Package]
|