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.

Files changed (180) hide show
  1. pex/auth.py +1 -1
  2. pex/bin/pex.py +15 -2
  3. pex/build_backend/configuration.py +5 -5
  4. pex/build_backend/wrap.py +27 -23
  5. pex/build_system/pep_517.py +4 -1
  6. pex/cache/dirs.py +17 -12
  7. pex/cli/commands/lock.py +302 -165
  8. pex/cli/commands/pip/core.py +4 -12
  9. pex/cli/commands/pip/wheel.py +1 -1
  10. pex/cli/commands/run.py +13 -20
  11. pex/cli/commands/venv.py +85 -16
  12. pex/cli/pex.py +11 -4
  13. pex/common.py +57 -7
  14. pex/compatibility.py +1 -1
  15. pex/dependency_configuration.py +87 -15
  16. pex/dist_metadata.py +143 -25
  17. pex/docs/html/_pagefind/fragment/en_4250138.pf_fragment +0 -0
  18. pex/docs/html/_pagefind/fragment/en_7125dad.pf_fragment +0 -0
  19. pex/docs/html/_pagefind/fragment/en_785d562.pf_fragment +0 -0
  20. pex/docs/html/_pagefind/fragment/en_8e94bb8.pf_fragment +0 -0
  21. pex/docs/html/_pagefind/fragment/en_a0396bb.pf_fragment +0 -0
  22. pex/docs/html/_pagefind/fragment/en_a8a3588.pf_fragment +0 -0
  23. pex/docs/html/_pagefind/fragment/en_c07d988.pf_fragment +0 -0
  24. pex/docs/html/_pagefind/fragment/en_d718411.pf_fragment +0 -0
  25. pex/docs/html/_pagefind/index/en_a2e3c5e.pf_index +0 -0
  26. pex/docs/html/_pagefind/pagefind-entry.json +1 -1
  27. pex/docs/html/_pagefind/pagefind.en_4ce1afa9e3.pf_meta +0 -0
  28. pex/docs/html/_static/documentation_options.js +1 -1
  29. pex/docs/html/_static/pygments.css +164 -146
  30. pex/docs/html/_static/styles/furo.css +1 -1
  31. pex/docs/html/_static/styles/furo.css.map +1 -1
  32. pex/docs/html/api/vars.html +25 -34
  33. pex/docs/html/buildingpex.html +25 -34
  34. pex/docs/html/genindex.html +24 -33
  35. pex/docs/html/index.html +25 -34
  36. pex/docs/html/recipes.html +25 -34
  37. pex/docs/html/scie.html +25 -34
  38. pex/docs/html/search.html +24 -33
  39. pex/docs/html/whatispex.html +25 -34
  40. pex/entry_points_txt.py +98 -0
  41. pex/environment.py +54 -33
  42. pex/finders.py +1 -1
  43. pex/hashing.py +71 -9
  44. pex/installed_wheel.py +141 -0
  45. pex/interpreter.py +41 -38
  46. pex/interpreter_constraints.py +25 -25
  47. pex/interpreter_implementation.py +40 -0
  48. pex/jobs.py +13 -6
  49. pex/pep_376.py +68 -384
  50. pex/pep_425.py +11 -2
  51. pex/pep_427.py +937 -205
  52. pex/pep_508.py +4 -5
  53. pex/pex_builder.py +5 -8
  54. pex/pex_info.py +14 -9
  55. pex/pip/dependencies/__init__.py +85 -13
  56. pex/pip/dependencies/requires.py +38 -3
  57. pex/pip/foreign_platform/__init__.py +4 -3
  58. pex/pip/installation.py +2 -2
  59. pex/pip/local_project.py +6 -14
  60. pex/pip/package_repositories/__init__.py +78 -0
  61. pex/pip/package_repositories/link_collector.py +96 -0
  62. pex/pip/tool.py +139 -33
  63. pex/pip/vcs.py +109 -43
  64. pex/pip/version.py +8 -1
  65. pex/requirements.py +121 -16
  66. pex/resolve/config.py +5 -1
  67. pex/resolve/configured_resolve.py +32 -10
  68. pex/resolve/configured_resolver.py +10 -39
  69. pex/resolve/downloads.py +4 -3
  70. pex/resolve/lock_downloader.py +16 -23
  71. pex/resolve/lock_resolver.py +41 -51
  72. pex/resolve/locked_resolve.py +89 -32
  73. pex/resolve/locker.py +145 -101
  74. pex/resolve/locker_patches.py +123 -197
  75. pex/resolve/lockfile/create.py +232 -87
  76. pex/resolve/lockfile/download_manager.py +5 -1
  77. pex/resolve/lockfile/json_codec.py +103 -28
  78. pex/resolve/lockfile/model.py +13 -35
  79. pex/resolve/lockfile/pep_751.py +117 -98
  80. pex/resolve/lockfile/requires_dist.py +17 -262
  81. pex/resolve/lockfile/subset.py +11 -0
  82. pex/resolve/lockfile/targets.py +445 -0
  83. pex/resolve/lockfile/updater.py +22 -10
  84. pex/resolve/package_repository.py +406 -0
  85. pex/resolve/pex_repository_resolver.py +1 -1
  86. pex/resolve/pre_resolved_resolver.py +19 -16
  87. pex/resolve/project.py +233 -47
  88. pex/resolve/requirement_configuration.py +28 -10
  89. pex/resolve/resolver_configuration.py +18 -32
  90. pex/resolve/resolver_options.py +234 -28
  91. pex/resolve/resolvers.py +3 -12
  92. pex/resolve/target_options.py +18 -2
  93. pex/resolve/target_system.py +908 -0
  94. pex/resolve/venv_resolver.py +670 -0
  95. pex/resolver.py +673 -209
  96. pex/scie/__init__.py +40 -1
  97. pex/scie/model.py +2 -0
  98. pex/scie/science.py +25 -3
  99. pex/sdist.py +219 -0
  100. pex/sh_boot.py +24 -21
  101. pex/sysconfig.py +5 -3
  102. pex/targets.py +31 -10
  103. pex/third_party/__init__.py +1 -1
  104. pex/tools/commands/repository.py +48 -25
  105. pex/vendor/__init__.py +4 -9
  106. pex/vendor/__main__.py +65 -41
  107. pex/vendor/_vendored/ansicolors/.layout.json +1 -1
  108. pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.dist-info/RECORD +11 -0
  109. pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.pex-info/original-whl-info.json +1 -0
  110. pex/vendor/_vendored/appdirs/.layout.json +1 -1
  111. pex/vendor/_vendored/appdirs/appdirs-1.4.4.dist-info/RECORD +7 -0
  112. pex/vendor/_vendored/appdirs/appdirs-1.4.4.pex-info/original-whl-info.json +1 -0
  113. pex/vendor/_vendored/attrs/.layout.json +1 -1
  114. pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.dist-info/RECORD +37 -0
  115. pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.pex-info/original-whl-info.json +1 -0
  116. pex/vendor/_vendored/packaging_20_9/.layout.json +1 -1
  117. pex/vendor/_vendored/packaging_20_9/packaging-20.9.dist-info/RECORD +20 -0
  118. pex/vendor/_vendored/packaging_20_9/packaging-20.9.pex-info/original-whl-info.json +1 -0
  119. pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.dist-info/RECORD +7 -0
  120. pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.pex-info/original-whl-info.json +1 -0
  121. pex/vendor/_vendored/packaging_21_3/.layout.json +1 -1
  122. pex/vendor/_vendored/packaging_21_3/packaging-21.3.dist-info/RECORD +20 -0
  123. pex/vendor/_vendored/packaging_21_3/packaging-21.3.pex-info/original-whl-info.json +1 -0
  124. pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.dist-info/RECORD +18 -0
  125. pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.pex-info/original-whl-info.json +1 -0
  126. pex/vendor/_vendored/packaging_24_0/.layout.json +1 -1
  127. pex/vendor/_vendored/packaging_24_0/packaging-24.0.dist-info/RECORD +22 -0
  128. pex/vendor/_vendored/packaging_24_0/packaging-24.0.pex-info/original-whl-info.json +1 -0
  129. pex/vendor/_vendored/packaging_25_0/.layout.json +1 -1
  130. pex/vendor/_vendored/packaging_25_0/packaging-25.0.dist-info/RECORD +24 -0
  131. pex/vendor/_vendored/packaging_25_0/packaging-25.0.pex-info/original-whl-info.json +1 -0
  132. pex/vendor/_vendored/pip/.layout.json +1 -1
  133. pex/vendor/_vendored/pip/pip/_vendor/certifi/cacert.pem +63 -1
  134. pex/vendor/_vendored/pip/pip-20.3.4.dist-info/RECORD +388 -0
  135. pex/vendor/_vendored/pip/pip-20.3.4.pex-info/original-whl-info.json +1 -0
  136. pex/vendor/_vendored/setuptools/.layout.json +1 -1
  137. pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/RECORD +107 -0
  138. pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.pex-info/original-whl-info.json +1 -0
  139. pex/vendor/_vendored/toml/.layout.json +1 -1
  140. pex/vendor/_vendored/toml/toml-0.10.2.dist-info/RECORD +11 -0
  141. pex/vendor/_vendored/toml/toml-0.10.2.pex-info/original-whl-info.json +1 -0
  142. pex/vendor/_vendored/tomli/.layout.json +1 -1
  143. pex/vendor/_vendored/tomli/tomli-2.0.1.dist-info/RECORD +10 -0
  144. pex/vendor/_vendored/tomli/tomli-2.0.1.pex-info/original-whl-info.json +1 -0
  145. pex/venv/installer.py +46 -19
  146. pex/venv/venv_pex.py +6 -3
  147. pex/version.py +1 -1
  148. pex/wheel.py +188 -40
  149. pex/whl.py +67 -0
  150. pex/windows/__init__.py +14 -11
  151. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/METADATA +6 -5
  152. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/RECORD +157 -133
  153. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/entry_points.txt +1 -0
  154. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/pylock/pylock.toml +1 -1
  155. pex/docs/html/_pagefind/fragment/en_42c9d8c.pf_fragment +0 -0
  156. pex/docs/html/_pagefind/fragment/en_45dd5a2.pf_fragment +0 -0
  157. pex/docs/html/_pagefind/fragment/en_4ca74d2.pf_fragment +0 -0
  158. pex/docs/html/_pagefind/fragment/en_77273d5.pf_fragment +0 -0
  159. pex/docs/html/_pagefind/fragment/en_87a59c5.pf_fragment +0 -0
  160. pex/docs/html/_pagefind/fragment/en_8dc89b5.pf_fragment +0 -0
  161. pex/docs/html/_pagefind/fragment/en_9d1319b.pf_fragment +0 -0
  162. pex/docs/html/_pagefind/fragment/en_e55df9d.pf_fragment +0 -0
  163. pex/docs/html/_pagefind/index/en_1e98c6f.pf_index +0 -0
  164. pex/docs/html/_pagefind/pagefind.en_d1c488ecae.pf_meta +0 -0
  165. pex/vendor/_vendored/ansicolors/ansicolors-1.1.8.dist-info/INSTALLER +0 -1
  166. pex/vendor/_vendored/appdirs/appdirs-1.4.4.dist-info/INSTALLER +0 -1
  167. pex/vendor/_vendored/attrs/attrs-21.5.0.dev0.dist-info/INSTALLER +0 -1
  168. pex/vendor/_vendored/packaging_20_9/packaging-20.9.dist-info/INSTALLER +0 -1
  169. pex/vendor/_vendored/packaging_20_9/pyparsing-2.4.7.dist-info/INSTALLER +0 -1
  170. pex/vendor/_vendored/packaging_21_3/packaging-21.3.dist-info/INSTALLER +0 -1
  171. pex/vendor/_vendored/packaging_21_3/pyparsing-3.0.7.dist-info/INSTALLER +0 -1
  172. pex/vendor/_vendored/packaging_24_0/packaging-24.0.dist-info/INSTALLER +0 -1
  173. pex/vendor/_vendored/packaging_25_0/packaging-25.0.dist-info/INSTALLER +0 -1
  174. pex/vendor/_vendored/pip/pip-20.3.4.dist-info/INSTALLER +0 -1
  175. pex/vendor/_vendored/setuptools/setuptools-44.0.0+3acb925dd708430aeaf197ea53ac8a752f7c1863.dist-info/INSTALLER +0 -1
  176. pex/vendor/_vendored/toml/toml-0.10.2.dist-info/INSTALLER +0 -1
  177. pex/vendor/_vendored/tomli/tomli-2.0.1.dist-info/INSTALLER +0 -1
  178. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/WHEEL +0 -0
  179. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/licenses/LICENSE +0 -0
  180. {pex-2.54.2.dist-info → pex-2.69.0.dist-info}/top_level.txt +0 -0
pex/resolve/locker.py CHANGED
@@ -3,7 +3,6 @@
3
3
 
4
4
  from __future__ import absolute_import
5
5
 
6
- import itertools
7
6
  import json
8
7
  import os
9
8
  import re
@@ -17,18 +16,21 @@ from pex.dist_metadata import ProjectNameAndVersion, Requirement
17
16
  from pex.hashing import Sha256
18
17
  from pex.orderedset import OrderedSet
19
18
  from pex.pep_440 import Version
19
+ from pex.pep_503 import ProjectName
20
20
  from pex.pip import foreign_platform
21
21
  from pex.pip.download_observer import Patch, PatchSet
22
22
  from pex.pip.local_project import digest_local_project
23
23
  from pex.pip.log_analyzer import LogAnalyzer
24
- from pex.pip.vcs import fingerprint_downloaded_vcs_archive
24
+ from pex.pip.vcs import digest_vcs_repo, fingerprint_downloaded_vcs_archive
25
25
  from pex.pip.version import PipVersionValue
26
26
  from pex.requirements import LocalProjectRequirement, VCSRequirement
27
- from pex.resolve.locked_resolve import LockConfiguration, LockStyle, TargetSystem
27
+ from pex.resolve.locked_resolve import LockStyle
28
28
  from pex.resolve.pep_691.fingerprint_service import FingerprintService
29
29
  from pex.resolve.pep_691.model import Endpoint
30
30
  from pex.resolve.resolved_requirement import PartialArtifact, Pin, ResolvedRequirement
31
31
  from pex.resolve.resolvers import Resolver
32
+ from pex.resolve.target_system import UniversalTarget
33
+ from pex.result import try_
32
34
  from pex.targets import Target
33
35
  from pex.typing import TYPE_CHECKING
34
36
 
@@ -194,6 +196,7 @@ class AnalyzeError(Exception):
194
196
 
195
197
  @attr.s(frozen=True)
196
198
  class ArtifactBuildResult(object):
199
+ path = attr.ib() # type: str
197
200
  url = attr.ib() # type: ArtifactURL
198
201
  pin = attr.ib() # type: Pin
199
202
 
@@ -211,17 +214,18 @@ class ArtifactBuildObserver(object):
211
214
  # type: (str) -> Optional[ArtifactBuildResult]
212
215
 
213
216
  match = re.search(
214
- r"Source in .+ has version (?P<version>\S+), which satisfies requirement "
217
+ r"Source in (?P<path>.+) has version (?P<version>\S+), which satisfies requirement "
215
218
  r"(?P<requirement>.+) .*from {url}".format(url=re.escape(self._artifact_url.raw_url)),
216
219
  line,
217
220
  )
218
221
  if not match:
219
222
  return None
220
223
 
224
+ path = match.group("path")
221
225
  version = Version(match.group("version"))
222
226
  requirement = Requirement.parse(match.group("requirement"))
223
227
  pin = Pin(project_name=requirement.project_name, version=version)
224
- return ArtifactBuildResult(url=self._artifact_url, pin=pin)
228
+ return ArtifactBuildResult(path=path, url=self._artifact_url, pin=pin)
225
229
 
226
230
 
227
231
  class Locker(LogAnalyzer):
@@ -230,18 +234,20 @@ class Locker(LogAnalyzer):
230
234
  target, # type: Target
231
235
  root_requirements, # type: Iterable[ParsedRequirement]
232
236
  resolver, # type: Resolver
233
- lock_configuration, # type: LockConfiguration
237
+ lock_style, # type: LockStyle.Value
234
238
  download_dir, # type: str
235
239
  fingerprint_service=None, # type: Optional[FingerprintService]
236
240
  pip_version=None, # type: Optional[PipVersionValue]
241
+ lock_is_via_pip_download=False, # type: bool
237
242
  ):
238
243
  # type: (...) -> None
239
244
 
240
245
  self._target = target
241
246
  self._vcs_url_manager = VCSURLManager.create(root_requirements)
242
247
  self._pip_version = pip_version
248
+ self._lock_is_via_pip_download = lock_is_via_pip_download
243
249
  self._resolver = resolver
244
- self._lock_configuration = lock_configuration
250
+ self._lock_style = lock_style
245
251
  self._download_dir = download_dir
246
252
  self._fingerprint_service = fingerprint_service or FingerprintService()
247
253
 
@@ -264,16 +270,6 @@ class Locker(LogAnalyzer):
264
270
  self._local_projects = OrderedSet() # type: OrderedSet[str]
265
271
  self._lock_result = None # type: Optional[LockResult]
266
272
 
267
- @property
268
- def style(self):
269
- # type: () -> LockStyle.Value
270
- return self._lock_configuration.style
271
-
272
- @property
273
- def requires_python(self):
274
- # type: () -> Tuple[str, ...]
275
- return self._lock_configuration.requires_python
276
-
277
273
  def should_collect(self, returncode):
278
274
  # type: (int) -> bool
279
275
  return returncode == 0
@@ -296,6 +292,16 @@ class Locker(LogAnalyzer):
296
292
  def _maybe_record_wheel(self, url):
297
293
  # type: (str) -> ArtifactURL
298
294
  artifact_url = self.parse_url_and_maybe_record_fingerprint(url)
295
+
296
+ # N.B.: Lock resolves driven by `pip install --dry-run --report` will only consult PEP-658
297
+ # `.whl.metadata` side-car files in the happy path; so we must use these as a proxy for the
298
+ # `.whl` file they are paired with.
299
+ # See: https://peps.python.org/pep-0658/
300
+ if not self._lock_is_via_pip_download and artifact_url.url_info.path.endswith(".metadata"):
301
+ artifact_url = ArtifactURL.from_url_info(
302
+ artifact_url.url_info._replace(path=artifact_url.url_info.path[:-9])
303
+ )
304
+
299
305
  if artifact_url.is_wheel:
300
306
  pin, partial_artifact = self._extract_resolve_data(artifact_url)
301
307
 
@@ -367,29 +373,29 @@ class Locker(LogAnalyzer):
367
373
  return self.Continue()
368
374
 
369
375
  build_result = self._artifact_build_observer.build_result(line)
370
- if build_result:
376
+ source_fingerprint = None # type: Optional[Fingerprint]
377
+ verified = False
378
+ commit_id = None # type: Optional[str]
379
+ editable = False
380
+ if build_result and self._lock_is_via_pip_download:
371
381
  artifact_url = build_result.url
372
- source_fingerprint = None # type: Optional[Fingerprint]
373
- verified = False
374
- commit_id = None # type: Optional[str]
375
- editable = False
376
382
  if isinstance(artifact_url.scheme, VCSScheme):
377
383
  source_fingerprint, archive_path = fingerprint_downloaded_vcs_archive(
378
384
  download_dir=self._download_dir,
379
- project_name=str(build_result.pin.project_name),
380
- version=str(build_result.pin.version),
385
+ project_name=build_result.pin.project_name,
386
+ version=build_result.pin.version,
381
387
  vcs=artifact_url.scheme.vcs,
382
- subdirectory=artifact_url.subdirectory,
383
388
  )
384
389
  verified = True
385
390
  selected_path = os.path.basename(archive_path)
386
- artifact_url = self.parse_url_and_maybe_record_fingerprint(
391
+ artifact_url = ArtifactURL.parse(
387
392
  self._vcs_url_manager.normalize_url(artifact_url.raw_url)
388
393
  )
389
394
  self._selected_path_to_pin[selected_path] = build_result.pin
390
395
 
391
- vcs, _, vcs_url = artifact_url.normalized_url.partition("+")
392
- vcs_url, _, _ = vcs_url.partition("@")
396
+ vcs, _, vcs_url = build_result.url.raw_url.partition("+")
397
+ if "@" in build_result.url.path:
398
+ vcs_url, _, _ = vcs_url.rpartition("@")
393
399
  commit_id = self._commit_ids.pop(vcs_url, None)
394
400
  elif isinstance(artifact_url.scheme, ArchiveScheme.Value):
395
401
  selected_path = os.path.basename(artifact_url.path)
@@ -412,12 +418,89 @@ class Locker(LogAnalyzer):
412
418
  os.path.basename(artifact_url.path)
413
419
  ] = build_result.pin
414
420
  else:
415
- digest_local_project(
416
- directory=artifact_url.path,
417
- digest=digest,
418
- pip_version=self._pip_version,
419
- target=self._target,
420
- resolver=self._resolver,
421
+ try_(
422
+ digest_local_project(
423
+ directory=artifact_url.path,
424
+ digest=digest,
425
+ pip_version=self._pip_version,
426
+ target=self._target,
427
+ resolver=self._resolver,
428
+ )
429
+ )
430
+ self._local_projects.add(artifact_url.path)
431
+ self._saved.add(build_result.pin)
432
+ editable = artifact_url.path in self._editable_projects
433
+ source_fingerprint = Fingerprint.from_digest(digest)
434
+ verified = True
435
+ else:
436
+ raise AnalyzeError(
437
+ "Unexpected scheme {scheme!r} for artifact at {url}".format(
438
+ scheme=artifact_url.scheme, url=artifact_url
439
+ )
440
+ )
441
+
442
+ additional_artifacts = self._links[build_result.pin]
443
+ additional_artifacts.pop(artifact_url, None)
444
+
445
+ self._resolved_requirements[build_result.pin] = ResolvedRequirement(
446
+ pin=build_result.pin,
447
+ artifact=PartialArtifact(
448
+ url=artifact_url,
449
+ fingerprint=source_fingerprint,
450
+ verified=verified,
451
+ commit_id=commit_id,
452
+ editable=editable,
453
+ ),
454
+ additional_artifacts=tuple(additional_artifacts.values()),
455
+ )
456
+ elif build_result:
457
+ artifact_url = build_result.url
458
+ if isinstance(artifact_url.scheme, VCSScheme):
459
+ digest = Sha256()
460
+ digest_vcs_repo(
461
+ project_name=build_result.pin.project_name,
462
+ repo_path=build_result.path,
463
+ vcs=artifact_url.scheme.vcs,
464
+ digest=digest,
465
+ subdirectory=artifact_url.subdirectory,
466
+ )
467
+ source_fingerprint = Fingerprint.from_digest(digest)
468
+ verified = True # noqa
469
+ artifact_url = ArtifactURL.parse(
470
+ self._vcs_url_manager.normalize_url(artifact_url.raw_url)
471
+ )
472
+
473
+ vcs, _, vcs_url = build_result.url.raw_url.partition("+")
474
+ if "@" in build_result.url.path:
475
+ vcs_url, _, _ = vcs_url.rpartition("@")
476
+ commit_id = self._commit_ids.pop(vcs_url, None)
477
+ elif isinstance(artifact_url.scheme, ArchiveScheme.Value):
478
+ source_archive_path = build_result.path
479
+ # If Pip resolves the artifact from its own cache, we will not find it in the
480
+ # download dir for this run; so guard against that. In this case the existing
481
+ # machinery that finalizes a locks missing fingerprints will download the
482
+ # artifact and hash it.
483
+ if os.path.isfile(source_archive_path):
484
+ digest = Sha256()
485
+ hashing.file_hash(source_archive_path, digest)
486
+ source_fingerprint = Fingerprint.from_digest(digest)
487
+ verified = True
488
+ elif "file" == artifact_url.scheme:
489
+ digest = Sha256()
490
+ if os.path.isfile(artifact_url.path):
491
+ hashing.file_hash(artifact_url.path, digest)
492
+ self._selected_path_to_pin[
493
+ os.path.basename(artifact_url.path)
494
+ ] = build_result.pin
495
+ else:
496
+ try_(
497
+ digest_local_project(
498
+ directory=artifact_url.path,
499
+ digest=digest,
500
+ pip_version=self._pip_version,
501
+ target=self._target,
502
+ resolver=self._resolver,
503
+ )
421
504
  )
422
505
  self._local_projects.add(artifact_url.path)
423
506
  self._saved.add(build_result.pin)
@@ -515,15 +598,23 @@ class Locker(LogAnalyzer):
515
598
  )
516
599
  return self.Continue()
517
600
 
518
- match = re.search(r"Saved (?P<file_path>.+)$", line)
519
- if match:
520
- saved_path = match.group("file_path")
521
- build_result_pin = self._selected_path_to_pin.get(os.path.basename(saved_path))
522
- if build_result_pin:
523
- self._saved.add(build_result_pin)
524
- return self.Continue()
601
+ if self._lock_is_via_pip_download:
602
+ match = re.search(r"Saved (?P<file_path>.+)$", line)
603
+ if match:
604
+ saved_path = match.group("file_path")
605
+ build_result_pin = self._selected_path_to_pin.get(os.path.basename(saved_path))
606
+ if build_result_pin:
607
+ self._saved.add(build_result_pin)
608
+ return self.Continue()
609
+ else:
610
+ match = re.search(r"Would install (?P<pnavs>.+)$", line)
611
+ if match:
612
+ for pnav in match.group("pnavs").split():
613
+ project_name, _, version = pnav.rpartition("-")
614
+ self._saved.add(Pin(ProjectName(project_name), Version(version)))
615
+ return self.Continue()
525
616
 
526
- if self.style in (LockStyle.SOURCES, LockStyle.UNIVERSAL):
617
+ if self._lock_style in (LockStyle.SOURCES, LockStyle.UNIVERSAL):
527
618
  match = re.search(r"Found link (?P<url>\S+)(?: \(from .*\))?, version: ", line)
528
619
  if match:
529
620
  url = self.parse_url_and_maybe_record_fingerprint(match.group("url"))
@@ -586,73 +677,26 @@ class Locker(LogAnalyzer):
586
677
  return self._lock_result
587
678
 
588
679
 
589
- # See https://peps.python.org/pep-0508/#environment-markers for more about these values.
590
- _OS_NAME = {
591
- TargetSystem.LINUX: "posix",
592
- TargetSystem.MAC: "posix",
593
- TargetSystem.WINDOWS: "nt",
594
- }
595
- _PLATFORM_SYSTEM = {
596
- TargetSystem.LINUX: "Linux",
597
- TargetSystem.MAC: "Darwin",
598
- TargetSystem.WINDOWS: "Windows",
599
- }
600
- _SYS_PLATFORMS = {
601
- TargetSystem.LINUX: ("linux", "linux2"),
602
- TargetSystem.MAC: ("darwin",),
603
- TargetSystem.WINDOWS: ("win32",),
604
- }
605
-
606
- # See: https://peps.python.org/pep-0425/#platform-tag for more about the wheel platform tag.
607
- _PLATFORM_TAG_REGEXP = {
608
- TargetSystem.LINUX: r"linux",
609
- TargetSystem.MAC: r"macosx",
610
- TargetSystem.WINDOWS: r"win",
611
- }
612
-
613
-
614
- def patch(lock_configuration):
615
- # type: (LockConfiguration) -> PatchSet
616
-
617
- if lock_configuration.style != LockStyle.UNIVERSAL:
680
+ def patch(universal_target):
681
+ # type: (Optional[UniversalTarget]) -> PatchSet
682
+
683
+ if not universal_target:
618
684
  return PatchSet()
619
685
 
620
686
  patches_dir = safe_mkdtemp()
621
687
  patches = []
622
- if lock_configuration.requires_python:
688
+ if universal_target.requires_python:
623
689
  patches.append(
624
690
  foreign_platform.patch_requires_python(
625
- requires_python=lock_configuration.requires_python, patches_dir=patches_dir
691
+ requires_python=universal_target.requires_python,
692
+ patches_dir=patches_dir,
626
693
  )
627
694
  )
628
695
 
629
- env = {} # type: Dict[str, str]
630
- if lock_configuration.target_systems and set(lock_configuration.target_systems) != set(
631
- TargetSystem.values()
632
- ):
633
- target_systems = {
634
- "os_names": [
635
- _OS_NAME[target_system] for target_system in lock_configuration.target_systems
636
- ],
637
- "platform_systems": [
638
- _PLATFORM_SYSTEM[target_system]
639
- for target_system in lock_configuration.target_systems
640
- ],
641
- "sys_platforms": list(
642
- itertools.chain.from_iterable(
643
- _SYS_PLATFORMS[target_system]
644
- for target_system in lock_configuration.target_systems
645
- )
646
- ),
647
- "platform_tag_regexps": [
648
- _PLATFORM_TAG_REGEXP[target_system]
649
- for target_system in lock_configuration.target_systems
650
- ],
651
- }
652
- with open(os.path.join(patches_dir, "target_systems.json"), "w") as fp:
653
- json.dump(target_systems, fp)
654
- env.update(_PEX_TARGET_SYSTEMS_FILE=fp.name)
655
-
656
- patches.append(Patch.from_code_resource(__name__, "locker_patches.py", **env))
696
+ with open(os.path.join(patches_dir, "universal_target.json"), "w") as fp:
697
+ json.dump(universal_target.to_dict(), fp)
698
+ patches.append(
699
+ Patch.from_code_resource(__name__, "locker_patches.py", _PEX_UNIVERSAL_TARGET_FILE=fp.name)
700
+ )
657
701
 
658
702
  return PatchSet(patches=tuple(patches))