pip 25.1.1__py3-none-any.whl → 25.3__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.
Files changed (236) hide show
  1. pip/__init__.py +3 -3
  2. pip/_internal/__init__.py +2 -2
  3. pip/_internal/build_env.py +186 -94
  4. pip/_internal/cache.py +17 -15
  5. pip/_internal/cli/autocompletion.py +13 -4
  6. pip/_internal/cli/base_command.py +18 -7
  7. pip/_internal/cli/cmdoptions.py +57 -80
  8. pip/_internal/cli/command_context.py +4 -3
  9. pip/_internal/cli/index_command.py +11 -9
  10. pip/_internal/cli/main.py +3 -2
  11. pip/_internal/cli/main_parser.py +4 -3
  12. pip/_internal/cli/parser.py +24 -20
  13. pip/_internal/cli/progress_bars.py +19 -12
  14. pip/_internal/cli/req_command.py +57 -33
  15. pip/_internal/cli/spinners.py +81 -5
  16. pip/_internal/commands/__init__.py +5 -3
  17. pip/_internal/commands/cache.py +18 -15
  18. pip/_internal/commands/check.py +1 -2
  19. pip/_internal/commands/completion.py +1 -2
  20. pip/_internal/commands/configuration.py +26 -18
  21. pip/_internal/commands/debug.py +8 -6
  22. pip/_internal/commands/download.py +6 -10
  23. pip/_internal/commands/freeze.py +2 -3
  24. pip/_internal/commands/hash.py +1 -2
  25. pip/_internal/commands/help.py +1 -2
  26. pip/_internal/commands/index.py +15 -9
  27. pip/_internal/commands/inspect.py +4 -4
  28. pip/_internal/commands/install.py +63 -53
  29. pip/_internal/commands/list.py +35 -26
  30. pip/_internal/commands/lock.py +4 -8
  31. pip/_internal/commands/search.py +14 -12
  32. pip/_internal/commands/show.py +14 -11
  33. pip/_internal/commands/uninstall.py +1 -2
  34. pip/_internal/commands/wheel.py +7 -13
  35. pip/_internal/configuration.py +40 -27
  36. pip/_internal/distributions/base.py +6 -4
  37. pip/_internal/distributions/installed.py +8 -4
  38. pip/_internal/distributions/sdist.py +33 -27
  39. pip/_internal/distributions/wheel.py +6 -4
  40. pip/_internal/exceptions.py +78 -42
  41. pip/_internal/index/collector.py +24 -29
  42. pip/_internal/index/package_finder.py +73 -64
  43. pip/_internal/index/sources.py +17 -14
  44. pip/_internal/locations/__init__.py +18 -16
  45. pip/_internal/locations/_distutils.py +12 -11
  46. pip/_internal/locations/_sysconfig.py +5 -4
  47. pip/_internal/locations/base.py +4 -3
  48. pip/_internal/main.py +2 -2
  49. pip/_internal/metadata/__init__.py +14 -7
  50. pip/_internal/metadata/_json.py +5 -4
  51. pip/_internal/metadata/base.py +22 -27
  52. pip/_internal/metadata/importlib/_compat.py +6 -4
  53. pip/_internal/metadata/importlib/_dists.py +20 -19
  54. pip/_internal/metadata/importlib/_envs.py +9 -6
  55. pip/_internal/metadata/pkg_resources.py +11 -14
  56. pip/_internal/models/direct_url.py +24 -21
  57. pip/_internal/models/format_control.py +5 -5
  58. pip/_internal/models/installation_report.py +4 -3
  59. pip/_internal/models/link.py +39 -34
  60. pip/_internal/models/pylock.py +27 -22
  61. pip/_internal/models/search_scope.py +6 -7
  62. pip/_internal/models/selection_prefs.py +3 -3
  63. pip/_internal/models/target_python.py +10 -9
  64. pip/_internal/models/wheel.py +12 -71
  65. pip/_internal/network/auth.py +20 -22
  66. pip/_internal/network/cache.py +28 -17
  67. pip/_internal/network/download.py +169 -141
  68. pip/_internal/network/lazy_wheel.py +15 -10
  69. pip/_internal/network/session.py +32 -27
  70. pip/_internal/network/utils.py +2 -2
  71. pip/_internal/network/xmlrpc.py +2 -2
  72. pip/_internal/operations/build/build_tracker.py +10 -8
  73. pip/_internal/operations/build/wheel.py +7 -6
  74. pip/_internal/operations/build/wheel_editable.py +7 -6
  75. pip/_internal/operations/check.py +21 -26
  76. pip/_internal/operations/freeze.py +12 -9
  77. pip/_internal/operations/install/wheel.py +49 -41
  78. pip/_internal/operations/prepare.py +42 -31
  79. pip/_internal/pyproject.py +7 -69
  80. pip/_internal/req/__init__.py +12 -12
  81. pip/_internal/req/constructors.py +68 -62
  82. pip/_internal/req/req_dependency_group.py +7 -11
  83. pip/_internal/req/req_file.py +32 -36
  84. pip/_internal/req/req_install.py +64 -170
  85. pip/_internal/req/req_set.py +4 -5
  86. pip/_internal/req/req_uninstall.py +20 -17
  87. pip/_internal/resolution/base.py +3 -3
  88. pip/_internal/resolution/legacy/resolver.py +21 -20
  89. pip/_internal/resolution/resolvelib/base.py +16 -13
  90. pip/_internal/resolution/resolvelib/candidates.py +49 -37
  91. pip/_internal/resolution/resolvelib/factory.py +72 -50
  92. pip/_internal/resolution/resolvelib/found_candidates.py +11 -9
  93. pip/_internal/resolution/resolvelib/provider.py +24 -20
  94. pip/_internal/resolution/resolvelib/reporter.py +26 -11
  95. pip/_internal/resolution/resolvelib/requirements.py +8 -6
  96. pip/_internal/resolution/resolvelib/resolver.py +41 -29
  97. pip/_internal/self_outdated_check.py +19 -9
  98. pip/_internal/utils/appdirs.py +1 -2
  99. pip/_internal/utils/compat.py +7 -1
  100. pip/_internal/utils/compatibility_tags.py +17 -16
  101. pip/_internal/utils/deprecation.py +11 -9
  102. pip/_internal/utils/direct_url_helpers.py +2 -2
  103. pip/_internal/utils/egg_link.py +6 -5
  104. pip/_internal/utils/entrypoints.py +3 -2
  105. pip/_internal/utils/filesystem.py +20 -5
  106. pip/_internal/utils/filetypes.py +4 -6
  107. pip/_internal/utils/glibc.py +6 -5
  108. pip/_internal/utils/hashes.py +9 -6
  109. pip/_internal/utils/logging.py +8 -5
  110. pip/_internal/utils/misc.py +37 -45
  111. pip/_internal/utils/packaging.py +3 -2
  112. pip/_internal/utils/retry.py +7 -4
  113. pip/_internal/utils/subprocess.py +20 -17
  114. pip/_internal/utils/temp_dir.py +10 -12
  115. pip/_internal/utils/unpacking.py +31 -4
  116. pip/_internal/utils/urls.py +1 -1
  117. pip/_internal/utils/virtualenv.py +3 -2
  118. pip/_internal/utils/wheel.py +3 -4
  119. pip/_internal/vcs/bazaar.py +26 -8
  120. pip/_internal/vcs/git.py +59 -24
  121. pip/_internal/vcs/mercurial.py +34 -11
  122. pip/_internal/vcs/subversion.py +27 -16
  123. pip/_internal/vcs/versioncontrol.py +56 -51
  124. pip/_internal/wheel_builder.py +30 -101
  125. pip/_vendor/README.rst +180 -0
  126. pip/_vendor/cachecontrol/LICENSE.txt +13 -0
  127. pip/_vendor/cachecontrol/__init__.py +1 -1
  128. pip/_vendor/certifi/LICENSE +20 -0
  129. pip/_vendor/certifi/__init__.py +1 -1
  130. pip/_vendor/certifi/cacert.pem +164 -261
  131. pip/_vendor/certifi/core.py +1 -32
  132. pip/_vendor/dependency_groups/LICENSE.txt +9 -0
  133. pip/_vendor/distlib/LICENSE.txt +284 -0
  134. pip/_vendor/distlib/__init__.py +2 -2
  135. pip/_vendor/distlib/scripts.py +1 -1
  136. pip/_vendor/distro/LICENSE +202 -0
  137. pip/_vendor/idna/LICENSE.md +31 -0
  138. pip/_vendor/msgpack/COPYING +14 -0
  139. pip/_vendor/msgpack/__init__.py +2 -2
  140. pip/_vendor/packaging/LICENSE +3 -0
  141. pip/_vendor/packaging/LICENSE.APACHE +177 -0
  142. pip/_vendor/packaging/LICENSE.BSD +23 -0
  143. pip/_vendor/pkg_resources/LICENSE +17 -0
  144. pip/_vendor/pkg_resources/__init__.py +1 -1
  145. pip/_vendor/platformdirs/LICENSE +21 -0
  146. pip/_vendor/platformdirs/api.py +1 -1
  147. pip/_vendor/platformdirs/macos.py +10 -8
  148. pip/_vendor/platformdirs/version.py +16 -3
  149. pip/_vendor/pygments/LICENSE +25 -0
  150. pip/_vendor/pygments/__init__.py +1 -1
  151. pip/_vendor/pyproject_hooks/LICENSE +21 -0
  152. pip/_vendor/requests/LICENSE +175 -0
  153. pip/_vendor/requests/__version__.py +2 -2
  154. pip/_vendor/requests/adapters.py +17 -40
  155. pip/_vendor/requests/compat.py +12 -0
  156. pip/_vendor/requests/models.py +3 -1
  157. pip/_vendor/requests/sessions.py +1 -1
  158. pip/_vendor/requests/utils.py +6 -16
  159. pip/_vendor/resolvelib/LICENSE +13 -0
  160. pip/_vendor/resolvelib/__init__.py +3 -3
  161. pip/_vendor/resolvelib/reporters.py +1 -1
  162. pip/_vendor/resolvelib/resolvers/__init__.py +4 -4
  163. pip/_vendor/resolvelib/resolvers/abstract.py +3 -3
  164. pip/_vendor/resolvelib/resolvers/resolution.py +96 -10
  165. pip/_vendor/rich/LICENSE +19 -0
  166. pip/_vendor/rich/__main__.py +12 -40
  167. pip/_vendor/rich/_inspect.py +1 -1
  168. pip/_vendor/rich/_ratio.py +1 -7
  169. pip/_vendor/rich/align.py +1 -7
  170. pip/_vendor/rich/box.py +1 -7
  171. pip/_vendor/rich/console.py +25 -20
  172. pip/_vendor/rich/control.py +1 -7
  173. pip/_vendor/rich/diagnose.py +1 -0
  174. pip/_vendor/rich/emoji.py +1 -6
  175. pip/_vendor/rich/live.py +32 -7
  176. pip/_vendor/rich/live_render.py +1 -7
  177. pip/_vendor/rich/logging.py +1 -1
  178. pip/_vendor/rich/panel.py +3 -4
  179. pip/_vendor/rich/progress.py +15 -15
  180. pip/_vendor/rich/spinner.py +7 -13
  181. pip/_vendor/rich/style.py +7 -11
  182. pip/_vendor/rich/syntax.py +24 -5
  183. pip/_vendor/rich/traceback.py +32 -17
  184. pip/_vendor/tomli/LICENSE +21 -0
  185. pip/_vendor/tomli/__init__.py +1 -1
  186. pip/_vendor/tomli/_parser.py +28 -21
  187. pip/_vendor/tomli/_re.py +8 -5
  188. pip/_vendor/tomli_w/LICENSE +21 -0
  189. pip/_vendor/truststore/LICENSE +21 -0
  190. pip/_vendor/truststore/__init__.py +1 -1
  191. pip/_vendor/truststore/_api.py +15 -7
  192. pip/_vendor/truststore/_openssl.py +3 -1
  193. pip/_vendor/urllib3/LICENSE.txt +21 -0
  194. pip/_vendor/vendor.txt +11 -12
  195. {pip-25.1.1.dist-info → pip-25.3.dist-info}/METADATA +32 -11
  196. {pip-25.1.1.dist-info → pip-25.3.dist-info}/RECORD +221 -192
  197. {pip-25.1.1.dist-info → pip-25.3.dist-info}/WHEEL +1 -2
  198. pip-25.3.dist-info/entry_points.txt +4 -0
  199. {pip-25.1.1.dist-info → pip-25.3.dist-info}/licenses/AUTHORS.txt +21 -0
  200. pip-25.3.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +13 -0
  201. pip-25.3.dist-info/licenses/src/pip/_vendor/certifi/LICENSE +20 -0
  202. pip-25.3.dist-info/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +9 -0
  203. pip-25.3.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt +284 -0
  204. pip-25.3.dist-info/licenses/src/pip/_vendor/distro/LICENSE +202 -0
  205. pip-25.3.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md +31 -0
  206. pip-25.3.dist-info/licenses/src/pip/_vendor/msgpack/COPYING +14 -0
  207. pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE +3 -0
  208. pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +177 -0
  209. pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD +23 -0
  210. pip-25.3.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE +17 -0
  211. pip-25.3.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE +21 -0
  212. pip-25.3.dist-info/licenses/src/pip/_vendor/pygments/LICENSE +25 -0
  213. pip-25.3.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +21 -0
  214. pip-25.3.dist-info/licenses/src/pip/_vendor/requests/LICENSE +175 -0
  215. pip-25.3.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE +13 -0
  216. pip-25.3.dist-info/licenses/src/pip/_vendor/rich/LICENSE +19 -0
  217. pip-25.3.dist-info/licenses/src/pip/_vendor/tomli/LICENSE +21 -0
  218. pip-25.3.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE +21 -0
  219. pip-25.3.dist-info/licenses/src/pip/_vendor/truststore/LICENSE +21 -0
  220. pip-25.3.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt +21 -0
  221. pip/_internal/operations/build/metadata_legacy.py +0 -73
  222. pip/_internal/operations/build/wheel_legacy.py +0 -118
  223. pip/_internal/operations/install/editable_legacy.py +0 -46
  224. pip/_internal/utils/setuptools_build.py +0 -147
  225. pip/_vendor/distlib/database.py +0 -1329
  226. pip/_vendor/distlib/index.py +0 -508
  227. pip/_vendor/distlib/locators.py +0 -1295
  228. pip/_vendor/distlib/manifest.py +0 -384
  229. pip/_vendor/distlib/markers.py +0 -162
  230. pip/_vendor/distlib/metadata.py +0 -1031
  231. pip/_vendor/distlib/version.py +0 -750
  232. pip/_vendor/distlib/wheel.py +0 -1100
  233. pip/_vendor/typing_extensions.py +0 -4584
  234. pip-25.1.1.dist-info/entry_points.txt +0 -3
  235. pip-25.1.1.dist-info/top_level.txt +0 -1
  236. {pip-25.1.1.dist-info → pip-25.3.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,23 +1,18 @@
1
1
  """Handles all VCS (version control) support"""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import logging
4
6
  import os
5
7
  import shutil
6
8
  import sys
7
9
  import urllib.parse
10
+ from collections.abc import Iterable, Iterator, Mapping
8
11
  from dataclasses import dataclass, field
9
12
  from typing import (
10
13
  Any,
11
- Dict,
12
- Iterable,
13
- Iterator,
14
- List,
15
14
  Literal,
16
- Mapping,
17
15
  Optional,
18
- Tuple,
19
- Type,
20
- Union,
21
16
  )
22
17
 
23
18
  from pip._internal.cli.spinners import SpinnerInterface
@@ -44,7 +39,7 @@ __all__ = ["vcs"]
44
39
 
45
40
  logger = logging.getLogger(__name__)
46
41
 
47
- AuthInfo = Tuple[Optional[str], Optional[str]]
42
+ AuthInfo = tuple[Optional[str], Optional[str]]
48
43
 
49
44
 
50
45
  def is_url(name: str) -> bool:
@@ -58,7 +53,7 @@ def is_url(name: str) -> bool:
58
53
 
59
54
 
60
55
  def make_vcs_requirement_url(
61
- repo_url: str, rev: str, project_name: str, subdir: Optional[str] = None
56
+ repo_url: str, rev: str, project_name: str, subdir: str | None = None
62
57
  ) -> str:
63
58
  """
64
59
  Return the URL for a VCS requirement.
@@ -77,7 +72,7 @@ def make_vcs_requirement_url(
77
72
 
78
73
  def find_path_to_project_root_from_repo_root(
79
74
  location: str, repo_root: str
80
- ) -> Optional[str]:
75
+ ) -> str | None:
81
76
  """
82
77
  Find the the Python project's root by searching up the filesystem from
83
78
  `location`. Return the path to project root relative to `repo_root`.
@@ -126,16 +121,16 @@ class RevOptions:
126
121
  extra_args: a list of extra options.
127
122
  """
128
123
 
129
- vc_class: Type["VersionControl"]
130
- rev: Optional[str] = None
124
+ vc_class: type[VersionControl]
125
+ rev: str | None = None
131
126
  extra_args: CommandArgs = field(default_factory=list)
132
- branch_name: Optional[str] = None
127
+ branch_name: str | None = None
133
128
 
134
129
  def __repr__(self) -> str:
135
130
  return f"<RevOptions {self.vc_class.name}: rev={self.rev!r}>"
136
131
 
137
132
  @property
138
- def arg_rev(self) -> Optional[str]:
133
+ def arg_rev(self) -> str | None:
139
134
  if self.rev is None:
140
135
  return self.vc_class.default_arg_rev
141
136
 
@@ -159,7 +154,7 @@ class RevOptions:
159
154
 
160
155
  return f" (to revision {self.rev})"
161
156
 
162
- def make_new(self, rev: str) -> "RevOptions":
157
+ def make_new(self, rev: str) -> RevOptions:
163
158
  """
164
159
  Make a copy of the current instance, but with a new rev.
165
160
 
@@ -170,7 +165,7 @@ class RevOptions:
170
165
 
171
166
 
172
167
  class VcsSupport:
173
- _registry: Dict[str, "VersionControl"] = {}
168
+ _registry: dict[str, VersionControl] = {}
174
169
  schemes = ["ssh", "git", "hg", "bzr", "sftp", "svn"]
175
170
 
176
171
  def __init__(self) -> None:
@@ -183,21 +178,21 @@ class VcsSupport:
183
178
  return self._registry.__iter__()
184
179
 
185
180
  @property
186
- def backends(self) -> List["VersionControl"]:
181
+ def backends(self) -> list[VersionControl]:
187
182
  return list(self._registry.values())
188
183
 
189
184
  @property
190
- def dirnames(self) -> List[str]:
185
+ def dirnames(self) -> list[str]:
191
186
  return [backend.dirname for backend in self.backends]
192
187
 
193
188
  @property
194
- def all_schemes(self) -> List[str]:
195
- schemes: List[str] = []
189
+ def all_schemes(self) -> list[str]:
190
+ schemes: list[str] = []
196
191
  for backend in self.backends:
197
192
  schemes.extend(backend.schemes)
198
193
  return schemes
199
194
 
200
- def register(self, cls: Type["VersionControl"]) -> None:
195
+ def register(self, cls: type[VersionControl]) -> None:
201
196
  if not hasattr(cls, "name"):
202
197
  logger.warning("Cannot register VCS %s", cls.__name__)
203
198
  return
@@ -209,7 +204,7 @@ class VcsSupport:
209
204
  if name in self._registry:
210
205
  del self._registry[name]
211
206
 
212
- def get_backend_for_dir(self, location: str) -> Optional["VersionControl"]:
207
+ def get_backend_for_dir(self, location: str) -> VersionControl | None:
213
208
  """
214
209
  Return a VersionControl object if a repository of that type is found
215
210
  at the given directory.
@@ -232,7 +227,7 @@ class VcsSupport:
232
227
  inner_most_repo_path = max(vcs_backends, key=len)
233
228
  return vcs_backends[inner_most_repo_path]
234
229
 
235
- def get_backend_for_scheme(self, scheme: str) -> Optional["VersionControl"]:
230
+ def get_backend_for_scheme(self, scheme: str) -> VersionControl | None:
236
231
  """
237
232
  Return a VersionControl object or None.
238
233
  """
@@ -241,7 +236,7 @@ class VcsSupport:
241
236
  return vcs_backend
242
237
  return None
243
238
 
244
- def get_backend(self, name: str) -> Optional["VersionControl"]:
239
+ def get_backend(self, name: str) -> VersionControl | None:
245
240
  """
246
241
  Return a VersionControl object or None.
247
242
  """
@@ -257,10 +252,10 @@ class VersionControl:
257
252
  dirname = ""
258
253
  repo_name = ""
259
254
  # List of supported schemes for this Version Control
260
- schemes: Tuple[str, ...] = ()
255
+ schemes: tuple[str, ...] = ()
261
256
  # Iterable of environment variable names to pass to call_subprocess().
262
- unset_environ: Tuple[str, ...] = ()
263
- default_arg_rev: Optional[str] = None
257
+ unset_environ: tuple[str, ...] = ()
258
+ default_arg_rev: str | None = None
264
259
 
265
260
  @classmethod
266
261
  def should_add_vcs_url_prefix(cls, remote_url: str) -> bool:
@@ -271,7 +266,7 @@ class VersionControl:
271
266
  return not remote_url.lower().startswith(f"{cls.name}:")
272
267
 
273
268
  @classmethod
274
- def get_subdirectory(cls, location: str) -> Optional[str]:
269
+ def get_subdirectory(cls, location: str) -> str | None:
275
270
  """
276
271
  Return the path to Python project root, relative to the repo root.
277
272
  Return None if the project root is in the repo root.
@@ -310,7 +305,7 @@ class VersionControl:
310
305
  return req
311
306
 
312
307
  @staticmethod
313
- def get_base_rev_args(rev: str) -> List[str]:
308
+ def get_base_rev_args(rev: str) -> list[str]:
314
309
  """
315
310
  Return the base revision arguments for a vcs command.
316
311
 
@@ -334,7 +329,7 @@ class VersionControl:
334
329
 
335
330
  @classmethod
336
331
  def make_rev_options(
337
- cls, rev: Optional[str] = None, extra_args: Optional[CommandArgs] = None
332
+ cls, rev: str | None = None, extra_args: CommandArgs | None = None
338
333
  ) -> RevOptions:
339
334
  """
340
335
  Return a RevOptions object.
@@ -357,7 +352,7 @@ class VersionControl:
357
352
  @classmethod
358
353
  def get_netloc_and_auth(
359
354
  cls, netloc: str, scheme: str
360
- ) -> Tuple[str, Tuple[Optional[str], Optional[str]]]:
355
+ ) -> tuple[str, tuple[str | None, str | None]]:
361
356
  """
362
357
  Parse the repository URL's netloc, and return the new netloc to use
363
358
  along with auth information.
@@ -376,7 +371,7 @@ class VersionControl:
376
371
  return netloc, (None, None)
377
372
 
378
373
  @classmethod
379
- def get_url_rev_and_auth(cls, url: str) -> Tuple[str, Optional[str], AuthInfo]:
374
+ def get_url_rev_and_auth(cls, url: str) -> tuple[str, str | None, AuthInfo]:
380
375
  """
381
376
  Parse the repository URL to use, and return the URL, revision,
382
377
  and auth info to use.
@@ -406,22 +401,20 @@ class VersionControl:
406
401
  return url, rev, user_pass
407
402
 
408
403
  @staticmethod
409
- def make_rev_args(
410
- username: Optional[str], password: Optional[HiddenText]
411
- ) -> CommandArgs:
404
+ def make_rev_args(username: str | None, password: HiddenText | None) -> CommandArgs:
412
405
  """
413
406
  Return the RevOptions "extra arguments" to use in obtain().
414
407
  """
415
408
  return []
416
409
 
417
- def get_url_rev_options(self, url: HiddenText) -> Tuple[HiddenText, RevOptions]:
410
+ def get_url_rev_options(self, url: HiddenText) -> tuple[HiddenText, RevOptions]:
418
411
  """
419
412
  Return the URL and RevOptions object to use in obtain(),
420
413
  as a tuple (url, rev_options).
421
414
  """
422
415
  secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret)
423
416
  username, secret_password = user_pass
424
- password: Optional[HiddenText] = None
417
+ password: HiddenText | None = None
425
418
  if secret_password is not None:
426
419
  password = hide_value(secret_password)
427
420
  extra_args = self.make_rev_args(username, password)
@@ -458,7 +451,13 @@ class VersionControl:
458
451
  """
459
452
  raise NotImplementedError
460
453
 
461
- def switch(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
454
+ def switch(
455
+ self,
456
+ dest: str,
457
+ url: HiddenText,
458
+ rev_options: RevOptions,
459
+ verbosity: int = 0,
460
+ ) -> None:
462
461
  """
463
462
  Switch the repo at ``dest`` to point to ``URL``.
464
463
 
@@ -467,7 +466,13 @@ class VersionControl:
467
466
  """
468
467
  raise NotImplementedError
469
468
 
470
- def update(self, dest: str, url: HiddenText, rev_options: RevOptions) -> None:
469
+ def update(
470
+ self,
471
+ dest: str,
472
+ url: HiddenText,
473
+ rev_options: RevOptions,
474
+ verbosity: int = 0,
475
+ ) -> None:
471
476
  """
472
477
  Update an already-existing repo to the given ``rev_options``.
473
478
 
@@ -477,7 +482,7 @@ class VersionControl:
477
482
  raise NotImplementedError
478
483
 
479
484
  @classmethod
480
- def is_commit_id_equal(cls, dest: str, name: Optional[str]) -> bool:
485
+ def is_commit_id_equal(cls, dest: str, name: str | None) -> bool:
481
486
  """
482
487
  Return whether the id of the current commit equals the given name.
483
488
 
@@ -519,7 +524,7 @@ class VersionControl:
519
524
  self.repo_name,
520
525
  rev_display,
521
526
  )
522
- self.update(dest, url, rev_options)
527
+ self.update(dest, url, rev_options, verbosity=verbosity)
523
528
  else:
524
529
  logger.info("Skipping because already up-to-date.")
525
530
  return
@@ -574,7 +579,7 @@ class VersionControl:
574
579
  url,
575
580
  rev_display,
576
581
  )
577
- self.switch(dest, url, rev_options)
582
+ self.switch(dest, url, rev_options, verbosity=verbosity)
578
583
 
579
584
  def unpack(self, location: str, url: HiddenText, verbosity: int) -> None:
580
585
  """
@@ -608,14 +613,14 @@ class VersionControl:
608
613
  @classmethod
609
614
  def run_command(
610
615
  cls,
611
- cmd: Union[List[str], CommandArgs],
616
+ cmd: list[str] | CommandArgs,
612
617
  show_stdout: bool = True,
613
- cwd: Optional[str] = None,
614
- on_returncode: 'Literal["raise", "warn", "ignore"]' = "raise",
615
- extra_ok_returncodes: Optional[Iterable[int]] = None,
616
- command_desc: Optional[str] = None,
617
- extra_environ: Optional[Mapping[str, Any]] = None,
618
- spinner: Optional[SpinnerInterface] = None,
618
+ cwd: str | None = None,
619
+ on_returncode: Literal["raise", "warn", "ignore"] = "raise",
620
+ extra_ok_returncodes: Iterable[int] | None = None,
621
+ command_desc: str | None = None,
622
+ extra_environ: Mapping[str, Any] | None = None,
623
+ spinner: SpinnerInterface | None = None,
619
624
  log_failed_cmd: bool = True,
620
625
  stdout_only: bool = False,
621
626
  ) -> str:
@@ -672,7 +677,7 @@ class VersionControl:
672
677
  return os.path.exists(os.path.join(path, cls.dirname))
673
678
 
674
679
  @classmethod
675
- def get_repository_root(cls, location: str) -> Optional[str]:
680
+ def get_repository_root(cls, location: str) -> str | None:
676
681
  """
677
682
  Return the "root" (top-level) directory controlled by the vcs,
678
683
  or `None` if the directory is not in any.
@@ -1,10 +1,12 @@
1
1
  """Orchestrator for building wheels from InstallRequirements."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import logging
4
6
  import os.path
5
7
  import re
6
- import shutil
7
- from typing import Iterable, List, Optional, Tuple
8
+ from collections.abc import Iterable
9
+ from tempfile import TemporaryDirectory
8
10
 
9
11
  from pip._vendor.packaging.utils import canonicalize_name, canonicalize_version
10
12
  from pip._vendor.packaging.version import InvalidVersion, Version
@@ -16,13 +18,9 @@ from pip._internal.models.link import Link
16
18
  from pip._internal.models.wheel import Wheel
17
19
  from pip._internal.operations.build.wheel import build_wheel_pep517
18
20
  from pip._internal.operations.build.wheel_editable import build_wheel_editable
19
- from pip._internal.operations.build.wheel_legacy import build_wheel_legacy
20
21
  from pip._internal.req.req_install import InstallRequirement
21
22
  from pip._internal.utils.logging import indent_log
22
23
  from pip._internal.utils.misc import ensure_dir, hash_file
23
- from pip._internal.utils.setuptools_build import make_setuptools_clean_args
24
- from pip._internal.utils.subprocess import call_subprocess
25
- from pip._internal.utils.temp_dir import TempDirectory
26
24
  from pip._internal.utils.urls import path_to_url
27
25
  from pip._internal.vcs import vcs
28
26
 
@@ -30,7 +28,7 @@ logger = logging.getLogger(__name__)
30
28
 
31
29
  _egg_info_re = re.compile(r"([a-z0-9_.]+)-([a-z0-9_.!+-]+)", re.IGNORECASE)
32
30
 
33
- BuildResult = Tuple[List[InstallRequirement], List[InstallRequirement]]
31
+ BuildResult = tuple[list[InstallRequirement], list[InstallRequirement]]
34
32
 
35
33
 
36
34
  def _contains_egg_info(s: str) -> bool:
@@ -41,37 +39,12 @@ def _contains_egg_info(s: str) -> bool:
41
39
  return bool(_egg_info_re.search(s))
42
40
 
43
41
 
44
- def _should_build(
45
- req: InstallRequirement,
46
- ) -> bool:
47
- """Return whether an InstallRequirement should be built into a wheel."""
48
- assert not req.constraint
49
-
50
- if req.is_wheel:
51
- return False
52
-
53
- assert req.source_dir
54
-
55
- if req.editable:
56
- # we only build PEP 660 editable requirements
57
- return req.supports_pyproject_editable
58
-
59
- return True
60
-
61
-
62
- def should_build_for_install_command(
63
- req: InstallRequirement,
64
- ) -> bool:
65
- return _should_build(req)
66
-
67
-
68
42
  def _should_cache(
69
43
  req: InstallRequirement,
70
- ) -> Optional[bool]:
44
+ ) -> bool | None:
71
45
  """
72
46
  Return whether a built InstallRequirement can be stored in the persistent
73
- wheel cache, assuming the wheel cache is available, and _should_build()
74
- has determined a wheel needs to be built.
47
+ wheel cache, assuming the wheel cache is available.
75
48
  """
76
49
  if req.editable or not req.source_dir:
77
50
  # never cache editable requirements
@@ -116,7 +89,7 @@ def _get_cache_dir(
116
89
  def _verify_one(req: InstallRequirement, wheel_path: str) -> None:
117
90
  canonical_name = canonicalize_name(req.name or "")
118
91
  w = Wheel(os.path.basename(wheel_path))
119
- if canonicalize_name(w.name) != canonical_name:
92
+ if w.name != canonical_name:
120
93
  raise InvalidWheelFilename(
121
94
  f"Wheel has unexpected file name: expected {canonical_name!r}, "
122
95
  f"got {w.name!r}",
@@ -146,10 +119,8 @@ def _build_one(
146
119
  req: InstallRequirement,
147
120
  output_dir: str,
148
121
  verify: bool,
149
- build_options: List[str],
150
- global_options: List[str],
151
122
  editable: bool,
152
- ) -> Optional[str]:
123
+ ) -> str | None:
153
124
  """Build one wheel.
154
125
 
155
126
  :return: The filename of the built wheel, or None if the build failed.
@@ -168,9 +139,7 @@ def _build_one(
168
139
 
169
140
  # Install build deps into temporary directory (PEP 518)
170
141
  with req.build_env:
171
- wheel_path = _build_one_inside_env(
172
- req, output_dir, build_options, global_options, editable
173
- )
142
+ wheel_path = _build_one_inside_env(req, output_dir, editable)
174
143
  if wheel_path and verify:
175
144
  try:
176
145
  _verify_one(req, wheel_path)
@@ -183,45 +152,25 @@ def _build_one(
183
152
  def _build_one_inside_env(
184
153
  req: InstallRequirement,
185
154
  output_dir: str,
186
- build_options: List[str],
187
- global_options: List[str],
188
155
  editable: bool,
189
- ) -> Optional[str]:
190
- with TempDirectory(kind="wheel") as temp_dir:
156
+ ) -> str | None:
157
+ with TemporaryDirectory(dir=output_dir) as wheel_directory:
191
158
  assert req.name
192
- if req.use_pep517:
193
- assert req.metadata_directory
194
- assert req.pep517_backend
195
- if global_options:
196
- logger.warning(
197
- "Ignoring --global-option when building %s using PEP 517", req.name
198
- )
199
- if build_options:
200
- logger.warning(
201
- "Ignoring --build-option when building %s using PEP 517", req.name
202
- )
203
- if editable:
204
- wheel_path = build_wheel_editable(
205
- name=req.name,
206
- backend=req.pep517_backend,
207
- metadata_directory=req.metadata_directory,
208
- tempd=temp_dir.path,
209
- )
210
- else:
211
- wheel_path = build_wheel_pep517(
212
- name=req.name,
213
- backend=req.pep517_backend,
214
- metadata_directory=req.metadata_directory,
215
- tempd=temp_dir.path,
216
- )
159
+ assert req.metadata_directory
160
+ assert req.pep517_backend
161
+ if editable:
162
+ wheel_path = build_wheel_editable(
163
+ name=req.name,
164
+ backend=req.pep517_backend,
165
+ metadata_directory=req.metadata_directory,
166
+ wheel_directory=wheel_directory,
167
+ )
217
168
  else:
218
- wheel_path = build_wheel_legacy(
169
+ wheel_path = build_wheel_pep517(
219
170
  name=req.name,
220
- setup_py_path=req.setup_py_path,
221
- source_dir=req.unpacked_source_directory,
222
- global_options=global_options,
223
- build_options=build_options,
224
- tempd=temp_dir.path,
171
+ backend=req.pep517_backend,
172
+ metadata_directory=req.metadata_directory,
173
+ wheel_directory=wheel_directory,
225
174
  )
226
175
 
227
176
  if wheel_path is not None:
@@ -229,7 +178,11 @@ def _build_one_inside_env(
229
178
  dest_path = os.path.join(output_dir, wheel_name)
230
179
  try:
231
180
  wheel_hash, length = hash_file(wheel_path)
232
- shutil.move(wheel_path, dest_path)
181
+ # We can do a replace here because wheel_path is guaranteed to
182
+ # be in the same filesystem as output_dir. This will perform an
183
+ # atomic rename, which is necessary to avoid concurrency issues
184
+ # when populating the cache.
185
+ os.replace(wheel_path, dest_path)
233
186
  logger.info(
234
187
  "Created wheel for %s: filename=%s size=%d sha256=%s",
235
188
  req.name,
@@ -245,35 +198,13 @@ def _build_one_inside_env(
245
198
  req.name,
246
199
  e,
247
200
  )
248
- # Ignore return, we can't do anything else useful.
249
- if not req.use_pep517:
250
- _clean_one_legacy(req, global_options)
251
201
  return None
252
202
 
253
203
 
254
- def _clean_one_legacy(req: InstallRequirement, global_options: List[str]) -> bool:
255
- clean_args = make_setuptools_clean_args(
256
- req.setup_py_path,
257
- global_options=global_options,
258
- )
259
-
260
- logger.info("Running setup.py clean for %s", req.name)
261
- try:
262
- call_subprocess(
263
- clean_args, command_desc="python setup.py clean", cwd=req.source_dir
264
- )
265
- return True
266
- except Exception:
267
- logger.error("Failed cleaning build dir for %s", req.name)
268
- return False
269
-
270
-
271
204
  def build(
272
205
  requirements: Iterable[InstallRequirement],
273
206
  wheel_cache: WheelCache,
274
207
  verify: bool,
275
- build_options: List[str],
276
- global_options: List[str],
277
208
  ) -> BuildResult:
278
209
  """Build wheels.
279
210
 
@@ -298,8 +229,6 @@ def build(
298
229
  req,
299
230
  cache_dir,
300
231
  verify,
301
- build_options,
302
- global_options,
303
232
  req.editable and req.permit_editable_wheels,
304
233
  )
305
234
  if wheel_file: