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/requirements.py CHANGED
@@ -5,6 +5,9 @@ from __future__ import absolute_import
5
5
 
6
6
  import os
7
7
  import re
8
+ import shlex
9
+ import sys
10
+ from argparse import ArgumentParser
8
11
  from contextlib import contextmanager
9
12
 
10
13
  from pex import attrs, dist_metadata, pex_warnings
@@ -17,6 +20,7 @@ from pex.dist_metadata import (
17
20
  RequirementParseError,
18
21
  )
19
22
  from pex.fetcher import URLFetcher
23
+ from pex.orderedset import OrderedSet
20
24
  from pex.pep_503 import ProjectName
21
25
  from pex.third_party.packaging.markers import Marker
22
26
  from pex.third_party.packaging.specifiers import SpecifierSet
@@ -139,7 +143,7 @@ class Source(object):
139
143
 
140
144
 
141
145
  @attr.s(frozen=True)
142
- class _ParsedRequirement(object):
146
+ class _ParsedItem(object):
143
147
  line = attr.ib() # type: LogicalLine
144
148
 
145
149
  def __str__(self):
@@ -148,38 +152,67 @@ class _ParsedRequirement(object):
148
152
 
149
153
 
150
154
  @attr.s(frozen=True)
151
- class PyPIRequirement(_ParsedRequirement):
155
+ class _Repo(_ParsedItem):
156
+ location = attr.ib() # Text
157
+
158
+
159
+ @attr.s(frozen=True)
160
+ class FindLinks(_Repo):
161
+ pass
162
+
163
+
164
+ @attr.s(frozen=True)
165
+ class Index(_Repo):
166
+ pass
167
+
168
+
169
+ @attr.s(frozen=True)
170
+ class PyPIRequirement(_ParsedItem):
152
171
  """A requirement realized through a package index or find links repository."""
153
172
 
154
173
  requirement = attr.ib() # type: Requirement
155
174
 
175
+ @property
176
+ def project_name(self):
177
+ return self.requirement.project_name
178
+
156
179
  @property
157
180
  def extras(self):
158
181
  # type: () -> FrozenSet[str]
159
182
  return self.requirement.extras
160
183
 
184
+ @property
185
+ def marker(self):
186
+ # type: () -> Optional[Marker]
187
+ return self.requirement.marker
188
+
161
189
 
162
190
  @attr.s(frozen=True)
163
- class URLRequirement(_ParsedRequirement):
191
+ class URLRequirement(_ParsedItem):
164
192
  """A requirement realized through a distribution archive at a fixed URL."""
165
193
 
166
194
  url = attr.ib() # type: ArtifactURL
167
195
  requirement = attr.ib() # type: Requirement
168
196
 
197
+ @property
198
+ def project_name(self):
199
+ return self.requirement.project_name
200
+
169
201
  @property
170
202
  def extras(self):
171
203
  # type: () -> FrozenSet[str]
172
204
  return self.requirement.extras
173
205
 
206
+ @property
207
+ def marker(self):
208
+ # type: () -> Optional[Marker]
209
+ return self.requirement.marker
210
+
174
211
  @property
175
212
  def filename(self):
176
213
  # type: () -> str
177
214
  return os.path.basename(self.url.path)
178
215
 
179
- @property
180
- def project_name(self):
181
- return self.requirement.project_name
182
-
183
216
  @property
184
217
  def subdirectory(self):
185
218
  # type: () -> Optional[str]
@@ -188,18 +221,27 @@ class URLRequirement(_ParsedRequirement):
188
221
 
189
222
 
190
223
  @attr.s(frozen=True)
191
- class VCSRequirement(_ParsedRequirement):
224
+ class VCSRequirement(_ParsedItem):
192
225
  """A requirement realized by building a distribution from sources retrieved from a VCS."""
193
226
 
194
227
  vcs = attr.ib() # type: VCS.Value
195
228
  url = attr.ib() # type: Text
196
229
  requirement = attr.ib() # type: Requirement
197
230
 
231
+ @property
232
+ def project_name(self):
233
+ return self.requirement.project_name
234
+
198
235
  @property
199
236
  def extras(self):
200
237
  # type: () -> FrozenSet[str]
201
238
  return self.requirement.extras
202
239
 
240
+ @property
241
+ def marker(self):
242
+ # type: () -> Optional[Marker]
243
+ return self.requirement.marker
244
+
203
245
 
204
246
  def parse_requirement_from_project_name_and_specifier(
205
247
  project_name, # type: Text
@@ -246,7 +288,7 @@ def parse_requirement_from_dist(
246
288
 
247
289
 
248
290
  @attr.s(frozen=True)
249
- class LocalProjectRequirement(_ParsedRequirement):
291
+ class LocalProjectRequirement(_ParsedItem):
250
292
  """A requirement realized by building a distribution from local sources."""
251
293
 
252
294
  path = attr.ib() # type: str
@@ -283,9 +325,18 @@ if TYPE_CHECKING:
283
325
 
284
326
 
285
327
  @attr.s(frozen=True)
286
- class Constraint(_ParsedRequirement):
328
+ class Constraint(_ParsedItem):
287
329
  requirement = attr.ib() # type: Requirement
288
330
 
331
+ @property
332
+ def project_name(self):
333
+ return self.requirement.project_name
334
+
335
+ @property
336
+ def marker(self):
337
+ # type: () -> Optional[Marker]
338
+ return self.requirement.marker
339
+
289
340
 
290
341
  class ParseError(Exception):
291
342
  def __init__(
@@ -598,11 +649,59 @@ def _get_parameter(line):
598
649
  return split_line[1]
599
650
 
600
651
 
652
+ _REPOS_PARSER = None # type: Optional[ArgumentParser]
653
+
654
+
655
+ def _parse_repos(line):
656
+ # type: (LogicalLine) -> Iterator[Union[FindLinks, Index]]
657
+
658
+ try:
659
+ # The arg-type type ignore is due to Python 2.7 shlex.split not being able to parse unicode
660
+ # strings; but we handle that with a useful error message.
661
+ args = shlex.split(line.processed_text) # type: ignore[arg-type]
662
+ except UnicodeEncodeError as e:
663
+ raise ParseError(
664
+ line,
665
+ "Options line has unicode characters which are not supported under Python {version}: "
666
+ "{err}".format(version=".".join(map(str, sys.version[:2])), err=e),
667
+ )
668
+
669
+ global _REPOS_PARSER
670
+ if _REPOS_PARSER is not None:
671
+ parser = _REPOS_PARSER
672
+ else:
673
+ parser = ArgumentParser()
674
+ # See:
675
+ # + https://pip.pypa.io/en/stable/reference/requirements-file-format/#global-options
676
+ # + https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-f
677
+ # + https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-i
678
+ # + https://pip.pypa.io/en/stable/cli/pip_install/#cmdoption-extra-index-url
679
+ parser.add_argument("-f", "--find-links", dest="find_links", action="append", default=[])
680
+ parser.add_argument("-i", "--index-url", dest="index_url")
681
+ parser.add_argument(
682
+ "--extra-index-url", dest="extra_index_urls", action="append", default=[]
683
+ )
684
+ _REPOS_PARSER = parser
685
+
686
+ options, _ = parser.parse_known_args(args)
687
+
688
+ for find_links in OrderedSet(options.find_links): # type: OrderedSet[str]
689
+ yield FindLinks(line, location=find_links)
690
+
691
+ index_locations = OrderedSet() # type: OrderedSet[str]
692
+ if options.index_url:
693
+ index_locations.add(options.index_url)
694
+ index_locations.update(options.extra_index_urls)
695
+
696
+ for index in index_locations:
697
+ yield Index(line, location=index)
698
+
699
+
601
700
  def parse_requirements(
602
701
  source, # type: Source
603
702
  fetcher=None, # type: Optional[URLFetcher]
604
703
  ):
605
- # type: (...) -> Iterator[Union[ParsedRequirement, Constraint]]
704
+ # type: (...) -> Iterator[Union[ParsedRequirement, Constraint, FindLinks, Index]]
606
705
 
607
706
  # For the format specification, see:
608
707
  # https://pip.pypa.io/en/stable/reference/pip_install/#requirements-file-format
@@ -654,11 +753,17 @@ def parse_requirements(
654
753
  yield requirement
655
754
  continue
656
755
 
657
- # Skip empty lines, comment lines and all Pip global options.
658
- if not processed_text or (
659
- processed_text.startswith("-")
660
- and not re.match(r"^(?:-e|--editable)\s.*", processed_text)
756
+ # Skip empty lines and comment lines.
757
+ if not processed_text:
758
+ continue
759
+
760
+ if processed_text.startswith("-") and not re.match(
761
+ # N.B.: We deal with editable when parsing requirement lines below.
762
+ r"^(?:-e|--editable)\s.*",
763
+ processed_text,
661
764
  ):
765
+ for repo in _parse_repos(logical_line):
766
+ yield repo
662
767
  continue
663
768
 
664
769
  # Only requirement lines remain.
@@ -689,7 +794,7 @@ def parse_requirement_file(
689
794
  is_constraints=False, # type: bool
690
795
  fetcher=None, # type: Optional[URLFetcher]
691
796
  ):
692
- # type: (...) -> Iterator[Union[ParsedRequirement, Constraint]]
797
+ # type: (...) -> Iterator[Union[ParsedRequirement, Constraint, FindLinks, Index]]
693
798
  def open_source():
694
799
  url = urlparse.urlparse(location)
695
800
  if url.scheme and url.netloc:
pex/resolve/config.py CHANGED
@@ -87,7 +87,11 @@ def finalize(
87
87
  resolver_configuration.pip_configuration,
88
88
  targets,
89
89
  context,
90
- pip_version=pip_version or lock_file.pip_version,
90
+ pip_version=(
91
+ pip_version
92
+ or resolver_configuration.pip_configuration.version
93
+ or lock_file.pip_version
94
+ ),
91
95
  )
92
96
  )
93
97
  return cast(
@@ -17,8 +17,10 @@ from pex.resolve.resolver_configuration import (
17
17
  PexRepositoryConfiguration,
18
18
  PreResolvedConfiguration,
19
19
  PylockRepositoryConfiguration,
20
+ VenvRepositoryConfiguration,
20
21
  )
21
22
  from pex.resolve.resolvers import ResolveResult
23
+ from pex.resolve.venv_resolver import resolve_from_venvs
22
24
  from pex.resolver import resolve as resolve_via_pip
23
25
  from pex.result import try_
24
26
  from pex.targets import Targets
@@ -55,15 +57,13 @@ def resolve(
55
57
  requirement_files=requirement_configuration.requirement_files,
56
58
  constraint_files=requirement_configuration.constraint_files,
57
59
  transitive=pip_configuration.transitive,
58
- indexes=pip_configuration.repos_configuration.indexes,
59
- find_links=pip_configuration.repos_configuration.find_links,
60
+ repos_configuration=pip_configuration.repos_configuration,
60
61
  resolver_version=pip_configuration.resolver_version,
61
62
  network_configuration=pip_configuration.network_configuration,
62
- password_entries=pip_configuration.repos_configuration.password_entries,
63
63
  build_configuration=pip_configuration.build_configuration,
64
64
  compile=compile_pyc,
65
65
  max_parallel_jobs=pip_configuration.max_jobs,
66
- pip_version=lock.pip_version,
66
+ pip_version=pip_configuration.version or lock.pip_version,
67
67
  use_pip_config=pip_configuration.use_pip_config,
68
68
  extra_pip_requirements=pip_configuration.extra_requirements,
69
69
  keyring_provider=pip_configuration.keyring_provider,
@@ -88,11 +88,9 @@ def resolve(
88
88
  dependency_groups=resolver_configuration.dependency_groups,
89
89
  constraint_files=requirement_configuration.constraint_files,
90
90
  transitive=pip_configuration.transitive,
91
- indexes=pip_configuration.repos_configuration.indexes,
92
- find_links=pip_configuration.repos_configuration.find_links,
91
+ repos_configuration=pip_configuration.repos_configuration,
93
92
  resolver_version=pip_configuration.resolver_version,
94
93
  network_configuration=pip_configuration.network_configuration,
95
- password_entries=pip_configuration.repos_configuration.password_entries,
96
94
  build_configuration=pip_configuration.build_configuration,
97
95
  compile=compile_pyc,
98
96
  max_parallel_jobs=pip_configuration.max_jobs,
@@ -143,6 +141,32 @@ def resolve(
143
141
  result_type=result_type,
144
142
  dependency_configuration=dependency_configuration,
145
143
  )
144
+ elif isinstance(resolver_configuration, VenvRepositoryConfiguration):
145
+ with TRACER.timed(
146
+ "Resolving requirements from {count} {venvs} at:{paths}.".format(
147
+ count=len(resolver_configuration.venvs),
148
+ venvs=pluralize(resolver_configuration.venvs, "venv"),
149
+ paths=(
150
+ " {venv}".format(venv=resolver_configuration.venvs[0].venv_dir)
151
+ if len(resolver_configuration.venvs) == 1
152
+ else "\n {venvs}".format(
153
+ venvs="\n ".join(venv.venv_dir for venv in resolver_configuration.venvs)
154
+ )
155
+ ),
156
+ )
157
+ ):
158
+ return try_(
159
+ resolve_from_venvs(
160
+ targets=targets,
161
+ venvs=resolver_configuration.venvs,
162
+ requirement_configuration=requirement_configuration,
163
+ pip_configuration=resolver_configuration.pip_configuration,
164
+ compile=compile_pyc,
165
+ ignore_errors=ignore_errors,
166
+ result_type=result_type,
167
+ dependency_configuration=dependency_configuration,
168
+ )
169
+ )
146
170
  else:
147
171
  with TRACER.timed("Resolving requirements."):
148
172
  return resolve_via_pip(
@@ -152,11 +176,9 @@ def resolve(
152
176
  constraint_files=requirement_configuration.constraint_files,
153
177
  allow_prereleases=resolver_configuration.allow_prereleases,
154
178
  transitive=resolver_configuration.transitive,
155
- indexes=resolver_configuration.repos_configuration.indexes,
156
- find_links=resolver_configuration.repos_configuration.find_links,
179
+ repos_configuration=resolver_configuration.repos_configuration,
157
180
  resolver_version=resolver_configuration.resolver_version,
158
181
  network_configuration=resolver_configuration.network_configuration,
159
- password_entries=resolver_configuration.repos_configuration.password_entries,
160
182
  build_configuration=resolver_configuration.build_configuration,
161
183
  compile=compile_pyc,
162
184
  max_parallel_jobs=resolver_configuration.max_jobs,
@@ -7,11 +7,9 @@ from pex import resolver
7
7
  from pex.dist_metadata import Requirement
8
8
  from pex.pep_427 import InstallableType
9
9
  from pex.pip.version import PipVersion, PipVersionValue
10
- from pex.resolve import lock_resolver
11
- from pex.resolve.lockfile.model import Lockfile
12
- from pex.resolve.resolver_configuration import PipConfiguration, ReposConfiguration, ResolverVersion
10
+ from pex.resolve.package_repository import ReposConfiguration
11
+ from pex.resolve.resolver_configuration import PipConfiguration, ResolverVersion
13
12
  from pex.resolve.resolvers import Resolver, ResolveResult
14
- from pex.result import try_
15
13
  from pex.targets import Targets
16
14
  from pex.typing import TYPE_CHECKING
17
15
 
@@ -52,36 +50,6 @@ class ConfiguredResolver(Resolver):
52
50
  # type: () -> bool
53
51
  return self.pip_configuration.build_configuration.use_system_time
54
52
 
55
- def resolve_lock(
56
- self,
57
- lock, # type: Lockfile
58
- targets=Targets(), # type: Targets
59
- pip_version=None, # type: Optional[PipVersionValue]
60
- result_type=InstallableType.INSTALLED_WHEEL_CHROOT, # type: InstallableType.Value
61
- ):
62
- # type: (...) -> ResolveResult
63
- return try_(
64
- lock_resolver.resolve_from_pex_lock(
65
- targets=targets,
66
- lock=lock,
67
- resolver=self,
68
- indexes=self.pip_configuration.repos_configuration.indexes,
69
- find_links=self.pip_configuration.repos_configuration.find_links,
70
- resolver_version=self.pip_configuration.resolver_version,
71
- network_configuration=self.pip_configuration.network_configuration,
72
- build_configuration=self.pip_configuration.build_configuration,
73
- compile=False,
74
- transitive=self.pip_configuration.transitive,
75
- verify_wheels=True,
76
- max_parallel_jobs=self.pip_configuration.max_jobs,
77
- pip_version=pip_version or self.pip_configuration.version,
78
- use_pip_config=self.pip_configuration.use_pip_config,
79
- extra_pip_requirements=self.pip_configuration.extra_requirements,
80
- keyring_provider=self.pip_configuration.keyring_provider,
81
- result_type=result_type,
82
- )
83
- )
84
-
85
53
  def resolve_requirements(
86
54
  self,
87
55
  requirements, # type: Iterable[str]
@@ -90,21 +58,24 @@ class ConfiguredResolver(Resolver):
90
58
  transitive=None, # type: Optional[bool]
91
59
  extra_resolver_requirements=None, # type: Optional[Tuple[Requirement, ...]]
92
60
  result_type=InstallableType.INSTALLED_WHEEL_CHROOT, # type: InstallableType.Value
61
+ constraint_files=None, # type: Optional[Iterable[str]]
62
+ compile=False, # type: bool
63
+ ignore_errors=False, # type: bool
93
64
  ):
94
65
  # type: (...) -> ResolveResult
95
66
  return resolver.resolve(
96
67
  targets=targets,
97
68
  requirements=requirements,
98
- allow_prereleases=False,
69
+ constraint_files=constraint_files,
70
+ allow_prereleases=self.pip_configuration.allow_prereleases,
99
71
  transitive=transitive if transitive is not None else self.pip_configuration.transitive,
100
- indexes=self.pip_configuration.repos_configuration.indexes,
101
- find_links=self.pip_configuration.repos_configuration.find_links,
72
+ repos_configuration=self.pip_configuration.repos_configuration,
102
73
  resolver_version=self.pip_configuration.resolver_version,
103
74
  network_configuration=self.pip_configuration.network_configuration,
104
75
  build_configuration=self.pip_configuration.build_configuration,
105
- compile=False,
76
+ compile=compile,
106
77
  max_parallel_jobs=self.pip_configuration.max_jobs,
107
- ignore_errors=False,
78
+ ignore_errors=ignore_errors,
108
79
  verify_wheels=True,
109
80
  pip_version=pip_version or self.pip_configuration.version,
110
81
  resolver=self,
pex/resolve/downloads.py CHANGED
@@ -18,9 +18,10 @@ from pex.pip.download_observer import DownloadObserver
18
18
  from pex.pip.installation import get_pip
19
19
  from pex.pip.tool import PackageIndexConfiguration, Pip
20
20
  from pex.resolve import locker
21
- from pex.resolve.locked_resolve import Artifact, FileArtifact, LockConfiguration
21
+ from pex.resolve.locked_resolve import Artifact, FileArtifact
22
22
  from pex.resolve.resolved_requirement import PartialArtifact
23
23
  from pex.resolve.resolvers import Resolver
24
+ from pex.resolve.target_system import UniversalTarget
24
25
  from pex.result import Error
25
26
  from pex.targets import LocalInterpreter, Target
26
27
  from pex.typing import TYPE_CHECKING
@@ -38,7 +39,7 @@ else:
38
39
  @attr.s(frozen=True)
39
40
  class ArtifactDownloader(object):
40
41
  resolver = attr.ib() # type: Resolver
41
- lock_configuration = attr.ib() # type: LockConfiguration
42
+ universal_target = attr.ib(default=None) # type: Optional[UniversalTarget]
42
43
  target = attr.ib(factory=LocalInterpreter.create) # type: Target
43
44
  package_index_configuration = attr.ib(
44
45
  factory=PackageIndexConfiguration.create
@@ -103,7 +104,7 @@ class ArtifactDownloader(object):
103
104
  # generates no patches if the lock is not universal.
104
105
  download_observer = foreign_platform.patch(self.target) or DownloadObserver(
105
106
  analyzer=None,
106
- patch_set=locker.patch(lock_configuration=self.lock_configuration),
107
+ patch_set=locker.patch(universal_target=self.universal_target),
107
108
  )
108
109
  return self.pip.spawn_download_distributions(
109
110
  download_dir=download_dir,
@@ -9,7 +9,7 @@ from collections import OrderedDict
9
9
  from multiprocessing.pool import ThreadPool
10
10
 
11
11
  from pex import resolver
12
- from pex.auth import PasswordDatabase, PasswordEntry
12
+ from pex.auth import PasswordDatabase
13
13
  from pex.common import pluralize
14
14
  from pex.compatibility import cpu_count
15
15
  from pex.dist_metadata import Requirement
@@ -31,6 +31,7 @@ from pex.resolve.locked_resolve import (
31
31
  VCSArtifact,
32
32
  )
33
33
  from pex.resolve.lockfile.download_manager import DownloadedArtifact, DownloadManager
34
+ from pex.resolve.package_repository import ReposConfiguration
34
35
  from pex.resolve.resolver_configuration import BuildConfiguration, ResolverVersion
35
36
  from pex.resolve.resolvers import MAX_PARALLEL_DOWNLOADS, Resolver
36
37
  from pex.result import Error, catch
@@ -76,11 +77,9 @@ class VCSArtifactDownloadManager(DownloadManager[VCSArtifact]):
76
77
  self,
77
78
  target, # type: Target
78
79
  file_lock_style, # type: FileLockStyle.Value
79
- indexes=None, # type: Optional[Sequence[str]]
80
- find_links=None, # type: Optional[Sequence[str]]
80
+ repos_configuration=ReposConfiguration(), # type: ReposConfiguration
81
81
  resolver_version=None, # type: Optional[ResolverVersion.Value]
82
82
  network_configuration=None, # type: Optional[NetworkConfiguration]
83
- password_entries=(), # type: Iterable[PasswordEntry]
84
83
  cache=None, # type: Optional[str]
85
84
  build_configuration=BuildConfiguration(), # type: BuildConfiguration
86
85
  pex_root=ENV, # type: Union[str, Variables]
@@ -94,11 +93,9 @@ class VCSArtifactDownloadManager(DownloadManager[VCSArtifact]):
94
93
  pex_root=pex_root, file_lock_style=file_lock_style
95
94
  )
96
95
  self._target = target
97
- self._indexes = indexes
98
- self._find_links = find_links
96
+ self._repos_configuration = repos_configuration
99
97
  self._resolver_version = resolver_version
100
98
  self._network_configuration = network_configuration
101
- self._password_entries = password_entries
102
99
  self._cache = cache
103
100
 
104
101
  # Since a VCSArtifactDownloadManager is only used for VCS requirements, a build is both
@@ -127,11 +124,9 @@ class VCSArtifactDownloadManager(DownloadManager[VCSArtifact]):
127
124
  targets=Targets.from_target(self._target),
128
125
  requirements=[requirement],
129
126
  transitive=False,
130
- indexes=self._indexes,
131
- find_links=self._find_links,
127
+ repos_configuration=self._repos_configuration,
132
128
  resolver_version=self._resolver_version,
133
129
  network_configuration=self._network_configuration,
134
- password_entries=self._password_entries,
135
130
  build_configuration=self._build_configuration,
136
131
  max_parallel_jobs=1,
137
132
  pip_version=self._pip_version,
@@ -159,10 +154,10 @@ class VCSArtifactDownloadManager(DownloadManager[VCSArtifact]):
159
154
  local_distribution = downloaded_vcs.local_distributions[0]
160
155
  filename = os.path.basename(local_distribution.path)
161
156
  digest_vcs_archive(
157
+ project_name=project_name,
162
158
  archive_path=local_distribution.path,
163
159
  vcs=artifact.vcs,
164
160
  digest=digest,
165
- subdirectory=artifact.subdirectory,
166
161
  )
167
162
  shutil.move(local_distribution.path, os.path.join(dest_dir, filename))
168
163
  return filename
@@ -213,13 +208,11 @@ class LockDownloader(object):
213
208
  targets, # type: Iterable[Target]
214
209
  lock_configuration, # type: LockConfiguration
215
210
  resolver, # type: Resolver
216
- indexes=None, # type: Optional[Sequence[str]]
217
- find_links=None, # type: Optional[Sequence[str]]
211
+ repos_configuration=ReposConfiguration(), # type: ReposConfiguration
218
212
  max_parallel_jobs=None, # type: Optional[int]
219
213
  pip_version=None, # type: Optional[PipVersionValue]
220
214
  resolver_version=None, # type: Optional[ResolverVersion.Value]
221
215
  network_configuration=None, # type: Optional[NetworkConfiguration]
222
- password_entries=(), # type: Iterable[PasswordEntry]
223
216
  build_configuration=BuildConfiguration(), # type: BuildConfiguration
224
217
  use_pip_config=False, # type: bool
225
218
  extra_pip_requirements=(), # type: Tuple[Requirement, ...]
@@ -234,22 +227,24 @@ class LockDownloader(object):
234
227
  # errors under the right interleaving of processes and threads and download artifact targets.
235
228
  file_lock_style = FileLockStyle.BSD
236
229
 
230
+ password_database = PasswordDatabase.from_netrc().append(
231
+ repos_configuration.password_entries
232
+ )
233
+ repos_configuration = attr.evolve(
234
+ repos_configuration, password_entries=password_database.entries
235
+ )
237
236
  file_download_managers_by_target = {
238
237
  target: FileArtifactDownloadManager(
239
238
  file_lock_style=file_lock_style,
240
239
  downloader=ArtifactDownloader(
241
240
  resolver=resolver,
242
- lock_configuration=lock_configuration,
241
+ universal_target=lock_configuration.universal_target,
243
242
  target=target,
244
243
  package_index_configuration=PackageIndexConfiguration.create(
245
244
  pip_version=pip_version,
246
245
  resolver_version=resolver_version,
247
- indexes=indexes,
248
- find_links=find_links,
246
+ repos_configuration=repos_configuration,
249
247
  network_configuration=network_configuration,
250
- password_entries=(
251
- PasswordDatabase.from_netrc().append(password_entries).entries
252
- ),
253
248
  use_pip_config=use_pip_config,
254
249
  extra_pip_requirements=extra_pip_requirements,
255
250
  keyring_provider=keyring_provider,
@@ -264,11 +259,9 @@ class LockDownloader(object):
264
259
  target: VCSArtifactDownloadManager(
265
260
  target=target,
266
261
  file_lock_style=file_lock_style,
267
- indexes=indexes,
268
- find_links=find_links,
262
+ repos_configuration=repos_configuration,
269
263
  resolver_version=resolver_version,
270
264
  network_configuration=network_configuration,
271
- password_entries=password_entries,
272
265
  build_configuration=build_configuration,
273
266
  pip_version=pip_version,
274
267
  resolver=resolver,