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
@@ -9,7 +9,7 @@ from collections import OrderedDict, defaultdict
9
9
  from multiprocessing.pool import ThreadPool
10
10
 
11
11
  from pex import hashing
12
- from pex.auth import PasswordDatabase, PasswordEntry
12
+ from pex.auth import PasswordDatabase
13
13
  from pex.build_system import pep_517
14
14
  from pex.common import pluralize, safe_mkdtemp
15
15
  from pex.dependency_configuration import DependencyConfiguration
@@ -23,7 +23,7 @@ from pex.pep_440 import Version
23
23
  from pex.pep_503 import ProjectName
24
24
  from pex.pip.download_observer import DownloadObserver
25
25
  from pex.pip.tool import PackageIndexConfiguration
26
- from pex.pip.version import PipVersionValue
26
+ from pex.pip.version import PipVersion, PipVersionValue
27
27
  from pex.resolve import lock_resolver, locker, resolvers
28
28
  from pex.resolve.configured_resolver import ConfiguredResolver
29
29
  from pex.resolve.downloads import ArtifactDownloader
@@ -41,13 +41,23 @@ from pex.resolve.locked_resolve import (
41
41
  from pex.resolve.locker import Locker
42
42
  from pex.resolve.lockfile.download_manager import DownloadManager
43
43
  from pex.resolve.lockfile.model import Lockfile
44
+ from pex.resolve.lockfile.targets import DownloadInput, calculate_download_input
45
+ from pex.resolve.package_repository import ReposConfiguration
44
46
  from pex.resolve.pep_691.fingerprint_service import FingerprintService
45
47
  from pex.resolve.requirement_configuration import RequirementConfiguration
46
48
  from pex.resolve.resolved_requirement import Pin, ResolvedRequirement
47
49
  from pex.resolve.resolver_configuration import BuildConfiguration, PipConfiguration, ResolverVersion
48
50
  from pex.resolve.resolvers import Resolver
49
- from pex.resolver import BuildRequest, Downloaded, ResolveObserver, WheelBuilder
50
- from pex.resolver import download as pip_download
51
+ from pex.resolver import (
52
+ BuildRequest,
53
+ Downloaded,
54
+ DownloadTarget,
55
+ Reports,
56
+ ResolveObserver,
57
+ WheelBuilder,
58
+ )
59
+ from pex.resolver import download_requests as pip_download_requests
60
+ from pex.resolver import reports as pip_reports
51
61
  from pex.result import Error, try_
52
62
  from pex.targets import Target, Targets
53
63
  from pex.tracer import TRACER
@@ -147,7 +157,7 @@ class CreateLockDownloadManager(DownloadManager[Artifact]):
147
157
 
148
158
  def __init__(
149
159
  self,
150
- path_and_version_by_artifact_and_project_name, # type: Mapping[Tuple[AnyArtifact, ProjectName], Tuple[Optional[str], Version]]
160
+ path_and_version_by_artifact_and_project_name, # type: Mapping[Tuple[AnyArtifact, ProjectName], Tuple[Optional[str], Optional[Version]]]
151
161
  pex_root=ENV, # type: Union[str, Variables]
152
162
  ):
153
163
  # type: (...) -> None
@@ -161,13 +171,11 @@ class CreateLockDownloadManager(DownloadManager[Artifact]):
161
171
  targets, # type: Iterable[Target]
162
172
  lock_configuration, # type: LockConfiguration
163
173
  resolver, # type: Resolver
164
- indexes=None, # type: Optional[Sequence[str]]
165
- find_links=None, # type: Optional[Sequence[str]]
174
+ repos_configuration=ReposConfiguration(), # type: ReposConfiguration
166
175
  max_parallel_jobs=None, # type: Optional[int]
167
176
  pip_version=None, # type: Optional[PipVersionValue]
168
177
  resolver_version=None, # type: Optional[ResolverVersion.Value]
169
178
  network_configuration=None, # type: Optional[NetworkConfiguration]
170
- password_entries=(), # type: Iterable[PasswordEntry]
171
179
  build_configuration=BuildConfiguration(), # type: BuildConfiguration
172
180
  use_pip_config=False, # type: bool
173
181
  extra_pip_requirements=(), # type: Tuple[Requirement, ...]
@@ -187,13 +195,11 @@ class CreateLockDownloadManager(DownloadManager[Artifact]):
187
195
  targets=targets,
188
196
  lock_configuration=lock_configuration,
189
197
  resolver=resolver,
190
- indexes=indexes,
191
- find_links=find_links,
198
+ repos_configuration=repos_configuration,
192
199
  max_parallel_jobs=max_parallel_jobs,
193
200
  pip_version=pip_version,
194
201
  resolver_version=resolver_version,
195
202
  network_configuration=network_configuration,
196
- password_entries=password_entries,
197
203
  build_configuration=build_configuration,
198
204
  use_pip_config=use_pip_config,
199
205
  extra_pip_requirements=extra_pip_requirements,
@@ -257,7 +263,7 @@ class CreateLockDownloadManager(DownloadManager[Artifact]):
257
263
 
258
264
  @attr.s(frozen=True)
259
265
  class _LockAnalysis(object):
260
- target = attr.ib() # type: Target
266
+ download_target = attr.ib() # type: DownloadTarget
261
267
  analyzer = attr.ib() # type: Locker
262
268
  download_dir = attr.ib() # type: str
263
269
 
@@ -274,25 +280,26 @@ def _prepare_project_directory(build_request):
274
280
  @attr.s(frozen=True)
275
281
  class LockObserver(ResolveObserver):
276
282
  root_requirements = attr.ib() # type: Tuple[ParsedRequirement, ...]
277
- lock_configuration = attr.ib() # type: LockConfiguration
283
+ lock_style = attr.ib() # type: LockStyle.Value
278
284
  resolver = attr.ib() # type: Resolver
279
285
  wheel_builder = attr.ib() # type: WheelBuilder
280
286
  package_index_configuration = attr.ib() # type: PackageIndexConfiguration
281
287
  max_parallel_jobs = attr.ib(default=None) # type: Optional[int]
288
+ lock_is_via_pip_download = attr.ib(default=False) # type: bool
282
289
  _analysis = attr.ib(factory=OrderedSet, eq=False) # type: OrderedSet[_LockAnalysis]
283
290
 
284
291
  def observe_download(
285
292
  self,
286
- target, # type: Target
293
+ download_target, # type: DownloadTarget
287
294
  download_dir, # type: str
288
295
  ):
289
296
  # type: (...) -> DownloadObserver
290
297
  analyzer = Locker(
291
- target=target,
298
+ target=download_target.target,
292
299
  root_requirements=self.root_requirements,
293
300
  pip_version=self.package_index_configuration.pip_version,
294
301
  resolver=self.resolver,
295
- lock_configuration=self.lock_configuration,
302
+ lock_style=self.lock_style,
296
303
  download_dir=download_dir,
297
304
  fingerprint_service=FingerprintService.create(
298
305
  url_fetcher=URLFetcher(
@@ -301,11 +308,14 @@ class LockObserver(ResolveObserver):
301
308
  ),
302
309
  max_parallel_jobs=self.max_parallel_jobs,
303
310
  ),
311
+ lock_is_via_pip_download=self.lock_is_via_pip_download,
304
312
  )
305
- patch_set = locker.patch(lock_configuration=self.lock_configuration)
313
+ patch_set = locker.patch(universal_target=download_target.universal_target)
306
314
  observer = DownloadObserver(analyzer=analyzer, patch_set=patch_set)
307
315
  self._analysis.add(
308
- _LockAnalysis(target=target, analyzer=analyzer, download_dir=download_dir)
316
+ _LockAnalysis(
317
+ download_target=download_target, analyzer=analyzer, download_dir=download_dir
318
+ )
309
319
  )
310
320
  return observer
311
321
 
@@ -323,35 +333,47 @@ class LockObserver(ResolveObserver):
323
333
  def lock(self, downloaded):
324
334
  # type: (Downloaded) -> Tuple[LockedResolve, ...]
325
335
 
326
- dist_metadatas_by_target = defaultdict(
336
+ dist_metadatas_by_download_target = defaultdict(
327
337
  OrderedSet
328
- ) # type: DefaultDict[Target, OrderedSet[DistMetadata]]
338
+ ) # type: DefaultDict[DownloadTarget, OrderedSet[DistMetadata]]
329
339
  build_requests = OrderedSet() # type: OrderedSet[BuildRequest]
330
340
 
331
341
  for local_distribution in downloaded.local_distributions:
332
342
  if local_distribution.is_wheel:
333
- dist_metadatas_by_target[local_distribution.target].add(
343
+ dist_metadatas_by_download_target[local_distribution.download_target].add(
334
344
  DistMetadata.load(local_distribution.path)
335
345
  )
346
+ elif os.path.isfile(local_distribution.path):
347
+ build_requests.add(
348
+ BuildRequest.for_file(
349
+ target=local_distribution.download_target,
350
+ source_path=local_distribution.path,
351
+ subdirectory=local_distribution.subdirectory,
352
+ )
353
+ )
336
354
  else:
337
355
  build_requests.add(
338
- BuildRequest.create(
339
- target=local_distribution.target,
356
+ BuildRequest.for_directory(
357
+ target=local_distribution.download_target,
340
358
  source_path=local_distribution.path,
341
359
  subdirectory=local_distribution.subdirectory,
342
360
  )
343
361
  )
344
362
 
345
- resolved_requirements_by_target = (
363
+ resolved_requirements_by_download_target = (
346
364
  OrderedDict()
347
- ) # type: OrderedDict[Target, Tuple[ResolvedRequirement, ...]]
365
+ ) # type: OrderedDict[DownloadTarget, Tuple[ResolvedRequirement, ...]]
348
366
  for analysis in self._analysis:
349
367
  lock_result = analysis.analyzer.lock_result
350
368
  build_requests.update(
351
- BuildRequest.create(target=analysis.target, source_path=local_project)
369
+ BuildRequest.for_directory(
370
+ target=analysis.download_target, source_path=local_project
371
+ )
352
372
  for local_project in lock_result.local_projects
353
373
  )
354
- resolved_requirements_by_target[analysis.target] = lock_result.resolved_requirements
374
+ resolved_requirements_by_download_target[
375
+ analysis.download_target
376
+ ] = lock_result.resolved_requirements
355
377
 
356
378
  with TRACER.timed(
357
379
  "Building {count} source {distributions} to gather metadata for lock.".format(
@@ -376,12 +398,14 @@ class LockObserver(ResolveObserver):
376
398
  targets_and_project_directories,
377
399
  # MyPy just can't figure out the next two args types; they're OK.
378
400
  self._spawn_prepare_metadata, # type: ignore[arg-type]
379
- error_handler=Retain[str](), # type: ignore[arg-type]
401
+ error_handler=Retain["Tuple[Target, str]"](), # type: ignore[arg-type]
380
402
  max_jobs=self.max_parallel_jobs,
381
403
  ),
382
404
  ):
383
405
  if isinstance(dist_metadata_result, DistMetadata):
384
- dist_metadatas_by_target[build_request.target].add(dist_metadata_result)
406
+ dist_metadatas_by_download_target[build_request.download_target].add(
407
+ dist_metadata_result
408
+ )
385
409
  else:
386
410
  _item, error = dist_metadata_result
387
411
  if isinstance(error, Job.Error) and pep_517.is_hook_unavailable_error(error):
@@ -423,30 +447,160 @@ class LockObserver(ResolveObserver):
423
447
  )
424
448
  for install_requests in build_wheel_results.values():
425
449
  for install_request in install_requests:
426
- dist_metadatas_by_target[install_request.target].add(
450
+ dist_metadatas_by_download_target[install_request.download_target].add(
427
451
  DistMetadata.load(install_request.wheel_path)
428
452
  )
429
453
 
454
+ universal_targets = tuple(
455
+ download_target.universal_target
456
+ for download_target in resolved_requirements_by_download_target
457
+ if download_target.universal_target
458
+ )
430
459
  return tuple(
431
460
  LockedResolve.create(
432
461
  resolved_requirements=resolved_requirements,
433
- dist_metadatas=dist_metadatas_by_target[target],
462
+ project_metadatas=dist_metadatas_by_download_target[download_target],
434
463
  fingerprinter=ArtifactDownloader(
435
464
  resolver=self.resolver,
436
- lock_configuration=self.lock_configuration,
437
- target=target,
465
+ universal_target=download_target.universal_target,
466
+ target=download_target.target,
438
467
  package_index_configuration=self.package_index_configuration,
439
468
  max_parallel_jobs=self.max_parallel_jobs,
440
469
  ),
441
470
  platform_tag=(
442
471
  None
443
- if self.lock_configuration.style == LockStyle.UNIVERSAL
444
- else target.platform.tag
472
+ if self.lock_style == LockStyle.UNIVERSAL
473
+ else download_target.target.platform.tag
474
+ ),
475
+ marker=(
476
+ download_target.universal_target.marker()
477
+ if download_target.universal_target and len(universal_targets) > 1
478
+ else None
445
479
  ),
446
480
  )
447
- for target, resolved_requirements in resolved_requirements_by_target.items()
481
+ for download_target, resolved_requirements in resolved_requirements_by_download_target.items()
448
482
  )
449
483
 
484
+ def lock_reports(self, reports):
485
+ # type: (Reports) -> Tuple[LockedResolve, ...]
486
+
487
+ project_metadatas_by_download_target = {
488
+ report.download_target: tuple(report.metadata.values()) for report in reports
489
+ }
490
+ resolved_requirements_by_download_target = (
491
+ OrderedDict()
492
+ ) # type: OrderedDict[DownloadTarget, Tuple[ResolvedRequirement, ...]]
493
+ for analysis in self._analysis:
494
+ lock_result = analysis.analyzer.lock_result
495
+ resolved_requirements_by_download_target[
496
+ analysis.download_target
497
+ ] = lock_result.resolved_requirements
498
+
499
+ universal_targets = tuple(
500
+ download_target.universal_target
501
+ for download_target in resolved_requirements_by_download_target
502
+ if download_target.universal_target
503
+ )
504
+ return tuple(
505
+ LockedResolve.create(
506
+ resolved_requirements=resolved_requirements,
507
+ project_metadatas=project_metadatas_by_download_target[download_target],
508
+ fingerprinter=ArtifactDownloader(
509
+ resolver=self.resolver,
510
+ universal_target=download_target.universal_target,
511
+ target=download_target.target,
512
+ package_index_configuration=self.package_index_configuration,
513
+ max_parallel_jobs=self.max_parallel_jobs,
514
+ ),
515
+ platform_tag=(
516
+ None
517
+ if self.lock_style == LockStyle.UNIVERSAL
518
+ else download_target.target.platform.tag
519
+ ),
520
+ marker=(
521
+ download_target.universal_target.marker()
522
+ if download_target.universal_target and len(universal_targets) > 1
523
+ else None
524
+ ),
525
+ )
526
+ for download_target, resolved_requirements in resolved_requirements_by_download_target.items()
527
+ )
528
+
529
+
530
+ def _create_lock_pip_download(
531
+ download_input, # type: DownloadInput
532
+ pip_configuration, # type: PipConfiguration
533
+ network_configuration, # type: NetworkConfiguration
534
+ download_dir, # type: str
535
+ lock_observer, # type: LockObserver
536
+ configured_resolver, # type: ConfiguredResolver
537
+ dependency_configuration, # type: DependencyConfiguration
538
+ ):
539
+ # type: (...) -> Union[Tuple[LockedResolve, ...], Error]
540
+ try:
541
+ downloaded = pip_download_requests(
542
+ requests=download_input.download_requests,
543
+ direct_requirements=download_input.direct_requirements,
544
+ allow_prereleases=pip_configuration.allow_prereleases,
545
+ transitive=pip_configuration.transitive,
546
+ repos_configuration=pip_configuration.repos_configuration,
547
+ resolver_version=pip_configuration.resolver_version,
548
+ network_configuration=network_configuration,
549
+ build_configuration=pip_configuration.build_configuration,
550
+ max_parallel_jobs=pip_configuration.max_jobs,
551
+ observer=lock_observer,
552
+ dest=download_dir,
553
+ pip_log=pip_configuration.log,
554
+ pip_version=pip_configuration.version,
555
+ resolver=configured_resolver,
556
+ use_pip_config=pip_configuration.use_pip_config,
557
+ extra_pip_requirements=pip_configuration.extra_requirements,
558
+ keyring_provider=pip_configuration.keyring_provider,
559
+ dependency_configuration=dependency_configuration,
560
+ )
561
+ except resolvers.ResolveError as e:
562
+ return Error(str(e))
563
+
564
+ with TRACER.timed("Creating lock from resolve"):
565
+ return lock_observer.lock(downloaded)
566
+
567
+
568
+ def _create_lock_pip_reports(
569
+ download_input, # type: DownloadInput
570
+ pip_configuration, # type: PipConfiguration
571
+ network_configuration, # type: NetworkConfiguration
572
+ lock_observer, # type: LockObserver
573
+ configured_resolver, # type: ConfiguredResolver
574
+ dependency_configuration, # type: DependencyConfiguration
575
+ ):
576
+ # type: (...) -> Union[Tuple[LockedResolve, ...], Error]
577
+
578
+ try:
579
+ reports = pip_reports(
580
+ requests=download_input.download_requests,
581
+ direct_requirements=download_input.direct_requirements,
582
+ allow_prereleases=pip_configuration.allow_prereleases,
583
+ transitive=pip_configuration.transitive,
584
+ repos_configuration=pip_configuration.repos_configuration,
585
+ resolver_version=pip_configuration.resolver_version,
586
+ network_configuration=network_configuration,
587
+ build_configuration=pip_configuration.build_configuration,
588
+ max_parallel_jobs=pip_configuration.max_jobs,
589
+ observer=lock_observer,
590
+ pip_log=pip_configuration.log,
591
+ pip_version=pip_configuration.version,
592
+ resolver=configured_resolver,
593
+ use_pip_config=pip_configuration.use_pip_config,
594
+ extra_pip_requirements=pip_configuration.extra_requirements,
595
+ keyring_provider=pip_configuration.keyring_provider,
596
+ dependency_configuration=dependency_configuration,
597
+ )
598
+ except resolvers.ResolveError as e:
599
+ return Error(str(e))
600
+
601
+ with TRACER.timed("Creating lock from resolve"):
602
+ return lock_observer.lock_reports(reports)
603
+
450
604
 
451
605
  def create(
452
606
  lock_configuration, # type: LockConfiguration
@@ -454,6 +608,7 @@ def create(
454
608
  targets, # type: Targets
455
609
  pip_configuration, # type: PipConfiguration
456
610
  dependency_configuration=DependencyConfiguration(), # type: DependencyConfiguration
611
+ avoid_downloads=False, # type: bool
457
612
  ):
458
613
  # type: (...) -> Union[Lockfile, Error]
459
614
  """Create a lock file for the given resolve configurations."""
@@ -465,16 +620,15 @@ def create(
465
620
  for parsed_constraint in requirement_configuration.parse_constraints(network_configuration)
466
621
  )
467
622
 
623
+ password_database = PasswordDatabase.from_netrc().append(
624
+ pip_configuration.repos_configuration.password_entries
625
+ )
468
626
  package_index_configuration = PackageIndexConfiguration.create(
469
627
  pip_version=pip_configuration.version,
470
628
  resolver_version=pip_configuration.resolver_version,
471
629
  network_configuration=network_configuration,
472
- find_links=pip_configuration.repos_configuration.find_links,
473
- indexes=pip_configuration.repos_configuration.indexes,
474
- password_entries=(
475
- PasswordDatabase.from_netrc()
476
- .append(pip_configuration.repos_configuration.password_entries)
477
- .entries
630
+ repos_configuration=attr.evolve(
631
+ pip_configuration.repos_configuration, password_entries=password_database.entries
478
632
  ),
479
633
  use_pip_config=pip_configuration.use_pip_config,
480
634
  extra_pip_requirements=pip_configuration.extra_requirements,
@@ -482,9 +636,12 @@ def create(
482
636
  )
483
637
 
484
638
  configured_resolver = ConfiguredResolver(pip_configuration=pip_configuration)
639
+ lock_is_via_pip_download = (
640
+ pip_configuration.version is PipVersion.VENDORED or not avoid_downloads
641
+ )
485
642
  lock_observer = LockObserver(
486
643
  root_requirements=parsed_requirements,
487
- lock_configuration=lock_configuration,
644
+ lock_style=lock_configuration.style,
488
645
  resolver=configured_resolver,
489
646
  wheel_builder=WheelBuilder(
490
647
  package_index_configuration=package_index_configuration,
@@ -494,63 +651,55 @@ def create(
494
651
  ),
495
652
  package_index_configuration=package_index_configuration,
496
653
  max_parallel_jobs=pip_configuration.max_jobs,
654
+ lock_is_via_pip_download=lock_is_via_pip_download,
497
655
  )
498
656
 
499
657
  download_dir = safe_mkdtemp()
500
-
501
- if lock_configuration.style is LockStyle.UNIVERSAL:
502
- download_targets = (
503
- Targets(interpreters=(targets.interpreter,)) if targets.interpreter else Targets()
658
+ with TRACER.timed("Calculating lock targets"):
659
+ download_input = calculate_download_input(
660
+ targets=targets,
661
+ requirement_configuration=requirement_configuration,
662
+ network_configuration=network_configuration,
663
+ repos_configuration=pip_configuration.repos_configuration,
664
+ universal_target=lock_configuration.universal_target,
504
665
  )
505
- else:
506
- download_targets = targets
507
666
 
508
- try:
509
- downloaded = pip_download(
510
- targets=download_targets,
511
- requirements=requirement_configuration.requirements,
512
- requirement_files=requirement_configuration.requirement_files,
513
- constraint_files=requirement_configuration.constraint_files,
514
- allow_prereleases=pip_configuration.allow_prereleases,
515
- transitive=pip_configuration.transitive,
516
- indexes=pip_configuration.repos_configuration.indexes,
517
- find_links=pip_configuration.repos_configuration.find_links,
518
- resolver_version=pip_configuration.resolver_version,
667
+ locked_resolves = try_(
668
+ _create_lock_pip_download(
669
+ download_input=download_input,
670
+ pip_configuration=pip_configuration,
519
671
  network_configuration=network_configuration,
520
- password_entries=pip_configuration.repos_configuration.password_entries,
521
- build_configuration=pip_configuration.build_configuration,
522
- max_parallel_jobs=pip_configuration.max_jobs,
523
- observer=lock_observer,
524
- dest=download_dir,
525
- pip_log=pip_configuration.log,
526
- pip_version=pip_configuration.version,
527
- resolver=configured_resolver,
528
- use_pip_config=pip_configuration.use_pip_config,
529
- extra_pip_requirements=pip_configuration.extra_requirements,
530
- keyring_provider=pip_configuration.keyring_provider,
672
+ download_dir=download_dir,
673
+ lock_observer=lock_observer,
674
+ configured_resolver=configured_resolver,
531
675
  dependency_configuration=dependency_configuration,
532
676
  )
533
- except resolvers.ResolveError as e:
534
- return Error(str(e))
535
-
536
- with TRACER.timed("Creating lock from resolve"):
537
- locked_resolves = lock_observer.lock(downloaded)
677
+ if lock_is_via_pip_download
678
+ else _create_lock_pip_reports(
679
+ download_input=download_input,
680
+ pip_configuration=pip_configuration,
681
+ network_configuration=network_configuration,
682
+ lock_observer=lock_observer,
683
+ configured_resolver=configured_resolver,
684
+ dependency_configuration=dependency_configuration,
685
+ )
686
+ )
538
687
 
539
688
  with TRACER.timed("Indexing downloads"):
540
689
  create_lock_download_manager = CreateLockDownloadManager.create(
541
690
  download_dir=download_dir, locked_resolves=locked_resolves
542
691
  )
543
692
  create_lock_download_manager.store_all(
544
- targets=download_targets.unique_targets(),
693
+ targets=OrderedSet(
694
+ download_request.target for download_request in download_input.download_requests
695
+ ),
545
696
  lock_configuration=lock_configuration,
546
697
  resolver=configured_resolver,
547
- indexes=pip_configuration.repos_configuration.indexes,
548
- find_links=pip_configuration.repos_configuration.find_links,
698
+ repos_configuration=pip_configuration.repos_configuration,
549
699
  max_parallel_jobs=pip_configuration.max_jobs,
550
700
  pip_version=pip_configuration.version,
551
701
  resolver_version=pip_configuration.resolver_version,
552
702
  network_configuration=network_configuration,
553
- password_entries=pip_configuration.repos_configuration.password_entries,
554
703
  build_configuration=pip_configuration.build_configuration,
555
704
  use_pip_config=pip_configuration.use_pip_config,
556
705
  extra_pip_requirements=pip_configuration.extra_requirements,
@@ -559,9 +708,7 @@ def create(
559
708
 
560
709
  lock = Lockfile.create(
561
710
  pex_version=__version__,
562
- style=lock_configuration.style,
563
- requires_python=lock_configuration.requires_python,
564
- target_systems=lock_configuration.target_systems,
711
+ lock_configuration=lock_configuration,
565
712
  pip_version=pip_configuration.version,
566
713
  resolver_version=pip_configuration.resolver_version,
567
714
  requirements=parsed_requirements,
@@ -572,7 +719,6 @@ def create(
572
719
  excluded=dependency_configuration.excluded,
573
720
  overridden=dependency_configuration.all_overrides(),
574
721
  locked_resolves=locked_resolves,
575
- elide_unused_requires_dist=lock_configuration.elide_unused_requires_dist,
576
722
  )
577
723
 
578
724
  if lock_configuration.style is LockStyle.UNIVERSAL and (
@@ -589,17 +735,16 @@ def create(
589
735
  targets=check_targets,
590
736
  lock=lock,
591
737
  resolver=configured_resolver,
592
- indexes=pip_configuration.repos_configuration.indexes,
593
- find_links=pip_configuration.repos_configuration.find_links,
738
+ repos_configuration=pip_configuration.repos_configuration,
594
739
  resolver_version=pip_configuration.resolver_version,
595
740
  network_configuration=network_configuration,
596
- password_entries=pip_configuration.repos_configuration.password_entries,
597
741
  build_configuration=pip_configuration.build_configuration,
598
742
  transitive=pip_configuration.transitive,
599
743
  max_parallel_jobs=pip_configuration.max_jobs,
600
744
  pip_version=pip_configuration.version,
601
745
  use_pip_config=pip_configuration.use_pip_config,
602
746
  extra_pip_requirements=pip_configuration.extra_requirements,
747
+ dependency_configuration=dependency_configuration,
603
748
  )
604
749
  )
605
750
 
@@ -142,7 +142,11 @@ class DownloadManager(Generic["_A"]):
142
142
  ) # type: str
143
143
  with atomic_directory(download_dir, lock_style=self._file_lock_style) as atomic_dir:
144
144
  if atomic_dir.is_finalized():
145
- TRACER.log("Using cached artifact at {} for {}".format(download_dir, artifact))
145
+ TRACER.log(
146
+ "Using cached artifact at {} for {}".format(
147
+ download_dir, artifact.url.raw_url
148
+ )
149
+ )
146
150
  else:
147
151
  self._download(artifact, project_name, atomic_dir.work_dir)
148
152
  else: