pip 25.1.1__py3-none-any.whl → 25.2__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 (202) hide show
  1. pip/__init__.py +3 -3
  2. pip/_internal/__init__.py +2 -2
  3. pip/_internal/build_env.py +118 -94
  4. pip/_internal/cache.py +16 -14
  5. pip/_internal/cli/autocompletion.py +13 -4
  6. pip/_internal/cli/base_command.py +18 -7
  7. pip/_internal/cli/cmdoptions.py +14 -9
  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 +26 -22
  13. pip/_internal/cli/progress_bars.py +19 -12
  14. pip/_internal/cli/req_command.py +16 -12
  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 +2 -3
  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 +44 -39
  29. pip/_internal/commands/list.py +35 -26
  30. pip/_internal/commands/lock.py +1 -2
  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 +2 -3
  35. pip/_internal/configuration.py +39 -25
  36. pip/_internal/distributions/base.py +6 -4
  37. pip/_internal/distributions/installed.py +8 -4
  38. pip/_internal/distributions/sdist.py +20 -13
  39. pip/_internal/distributions/wheel.py +6 -4
  40. pip/_internal/exceptions.py +58 -39
  41. pip/_internal/index/collector.py +24 -29
  42. pip/_internal/index/package_finder.py +70 -61
  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 +8 -6
  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 +12 -17
  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 +7 -5
  65. pip/_internal/network/auth.py +20 -22
  66. pip/_internal/network/cache.py +22 -6
  67. pip/_internal/network/download.py +169 -141
  68. pip/_internal/network/lazy_wheel.py +10 -7
  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 +3 -2
  74. pip/_internal/operations/build/wheel_editable.py +3 -2
  75. pip/_internal/operations/build/wheel_legacy.py +9 -8
  76. pip/_internal/operations/check.py +21 -26
  77. pip/_internal/operations/freeze.py +12 -9
  78. pip/_internal/operations/install/editable_legacy.py +5 -3
  79. pip/_internal/operations/install/wheel.py +49 -41
  80. pip/_internal/operations/prepare.py +35 -30
  81. pip/_internal/pyproject.py +7 -10
  82. pip/_internal/req/__init__.py +12 -10
  83. pip/_internal/req/constructors.py +33 -31
  84. pip/_internal/req/req_dependency_group.py +7 -11
  85. pip/_internal/req/req_file.py +32 -35
  86. pip/_internal/req/req_install.py +37 -34
  87. pip/_internal/req/req_set.py +4 -5
  88. pip/_internal/req/req_uninstall.py +20 -17
  89. pip/_internal/resolution/base.py +3 -3
  90. pip/_internal/resolution/legacy/resolver.py +21 -20
  91. pip/_internal/resolution/resolvelib/base.py +16 -13
  92. pip/_internal/resolution/resolvelib/candidates.py +29 -26
  93. pip/_internal/resolution/resolvelib/factory.py +41 -50
  94. pip/_internal/resolution/resolvelib/found_candidates.py +11 -9
  95. pip/_internal/resolution/resolvelib/provider.py +15 -20
  96. pip/_internal/resolution/resolvelib/reporter.py +5 -3
  97. pip/_internal/resolution/resolvelib/requirements.py +8 -6
  98. pip/_internal/resolution/resolvelib/resolver.py +39 -23
  99. pip/_internal/self_outdated_check.py +8 -6
  100. pip/_internal/utils/appdirs.py +1 -2
  101. pip/_internal/utils/compat.py +7 -1
  102. pip/_internal/utils/compatibility_tags.py +17 -16
  103. pip/_internal/utils/deprecation.py +11 -9
  104. pip/_internal/utils/direct_url_helpers.py +2 -2
  105. pip/_internal/utils/egg_link.py +6 -5
  106. pip/_internal/utils/entrypoints.py +3 -2
  107. pip/_internal/utils/filesystem.py +8 -5
  108. pip/_internal/utils/filetypes.py +4 -6
  109. pip/_internal/utils/glibc.py +6 -5
  110. pip/_internal/utils/hashes.py +9 -6
  111. pip/_internal/utils/logging.py +8 -5
  112. pip/_internal/utils/misc.py +37 -45
  113. pip/_internal/utils/packaging.py +3 -2
  114. pip/_internal/utils/retry.py +7 -4
  115. pip/_internal/utils/setuptools_build.py +12 -10
  116. pip/_internal/utils/subprocess.py +20 -17
  117. pip/_internal/utils/temp_dir.py +10 -12
  118. pip/_internal/utils/unpacking.py +6 -4
  119. pip/_internal/utils/urls.py +1 -1
  120. pip/_internal/utils/virtualenv.py +3 -2
  121. pip/_internal/utils/wheel.py +3 -4
  122. pip/_internal/vcs/bazaar.py +26 -8
  123. pip/_internal/vcs/git.py +59 -24
  124. pip/_internal/vcs/mercurial.py +34 -11
  125. pip/_internal/vcs/subversion.py +27 -16
  126. pip/_internal/vcs/versioncontrol.py +56 -51
  127. pip/_internal/wheel_builder.py +14 -12
  128. pip/_vendor/cachecontrol/__init__.py +1 -1
  129. pip/_vendor/certifi/__init__.py +1 -1
  130. pip/_vendor/certifi/cacert.pem +102 -221
  131. pip/_vendor/certifi/core.py +1 -32
  132. pip/_vendor/distlib/__init__.py +2 -2
  133. pip/_vendor/distlib/scripts.py +1 -1
  134. pip/_vendor/msgpack/__init__.py +2 -2
  135. pip/_vendor/pkg_resources/__init__.py +1 -1
  136. pip/_vendor/platformdirs/version.py +2 -2
  137. pip/_vendor/pygments/__init__.py +1 -1
  138. pip/_vendor/requests/__version__.py +2 -2
  139. pip/_vendor/requests/compat.py +12 -0
  140. pip/_vendor/requests/models.py +3 -1
  141. pip/_vendor/requests/utils.py +6 -16
  142. pip/_vendor/resolvelib/__init__.py +3 -3
  143. pip/_vendor/resolvelib/reporters.py +1 -1
  144. pip/_vendor/resolvelib/resolvers/__init__.py +4 -4
  145. pip/_vendor/resolvelib/resolvers/resolution.py +91 -10
  146. pip/_vendor/rich/__main__.py +12 -40
  147. pip/_vendor/rich/_inspect.py +1 -1
  148. pip/_vendor/rich/_ratio.py +1 -7
  149. pip/_vendor/rich/align.py +1 -7
  150. pip/_vendor/rich/box.py +1 -7
  151. pip/_vendor/rich/console.py +25 -20
  152. pip/_vendor/rich/control.py +1 -7
  153. pip/_vendor/rich/diagnose.py +1 -0
  154. pip/_vendor/rich/emoji.py +1 -6
  155. pip/_vendor/rich/live.py +32 -7
  156. pip/_vendor/rich/live_render.py +1 -7
  157. pip/_vendor/rich/logging.py +1 -1
  158. pip/_vendor/rich/panel.py +3 -4
  159. pip/_vendor/rich/progress.py +15 -15
  160. pip/_vendor/rich/spinner.py +7 -13
  161. pip/_vendor/rich/syntax.py +24 -5
  162. pip/_vendor/rich/traceback.py +32 -17
  163. pip/_vendor/truststore/_api.py +1 -1
  164. pip/_vendor/vendor.txt +9 -10
  165. {pip-25.1.1.dist-info → pip-25.2.dist-info}/METADATA +26 -4
  166. {pip-25.1.1.dist-info → pip-25.2.dist-info}/RECORD +193 -180
  167. {pip-25.1.1.dist-info → pip-25.2.dist-info}/WHEEL +1 -1
  168. {pip-25.1.1.dist-info → pip-25.2.dist-info}/licenses/AUTHORS.txt +12 -0
  169. pip-25.2.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +13 -0
  170. pip-25.2.dist-info/licenses/src/pip/_vendor/certifi/LICENSE +20 -0
  171. pip-25.2.dist-info/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +9 -0
  172. pip-25.2.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt +284 -0
  173. pip-25.2.dist-info/licenses/src/pip/_vendor/distro/LICENSE +202 -0
  174. pip-25.2.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md +31 -0
  175. pip-25.2.dist-info/licenses/src/pip/_vendor/msgpack/COPYING +14 -0
  176. pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE +3 -0
  177. pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +177 -0
  178. pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD +23 -0
  179. pip-25.2.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE +17 -0
  180. pip-25.2.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE +21 -0
  181. pip-25.2.dist-info/licenses/src/pip/_vendor/pygments/LICENSE +25 -0
  182. pip-25.2.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +21 -0
  183. pip-25.2.dist-info/licenses/src/pip/_vendor/requests/LICENSE +175 -0
  184. pip-25.2.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE +13 -0
  185. pip-25.2.dist-info/licenses/src/pip/_vendor/rich/LICENSE +19 -0
  186. pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE +21 -0
  187. pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE-HEADER +3 -0
  188. pip-25.2.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE +21 -0
  189. pip-25.2.dist-info/licenses/src/pip/_vendor/truststore/LICENSE +21 -0
  190. pip-25.2.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt +21 -0
  191. pip/_vendor/distlib/database.py +0 -1329
  192. pip/_vendor/distlib/index.py +0 -508
  193. pip/_vendor/distlib/locators.py +0 -1295
  194. pip/_vendor/distlib/manifest.py +0 -384
  195. pip/_vendor/distlib/markers.py +0 -162
  196. pip/_vendor/distlib/metadata.py +0 -1031
  197. pip/_vendor/distlib/version.py +0 -750
  198. pip/_vendor/distlib/wheel.py +0 -1100
  199. pip/_vendor/typing_extensions.py +0 -4584
  200. {pip-25.1.1.dist-info → pip-25.2.dist-info}/entry_points.txt +0 -0
  201. {pip-25.1.1.dist-info → pip-25.2.dist-info}/licenses/LICENSE.txt +0 -0
  202. {pip-25.1.1.dist-info → pip-25.2.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import errno
2
4
  import getpass
3
5
  import hashlib
@@ -9,6 +11,7 @@ import stat
9
11
  import sys
10
12
  import sysconfig
11
13
  import urllib.parse
14
+ from collections.abc import Generator, Iterable, Iterator, Mapping, Sequence
12
15
  from dataclasses import dataclass
13
16
  from functools import partial
14
17
  from io import StringIO
@@ -19,18 +22,9 @@ from typing import (
19
22
  Any,
20
23
  BinaryIO,
21
24
  Callable,
22
- Generator,
23
- Iterable,
24
- Iterator,
25
- List,
26
- Mapping,
27
25
  Optional,
28
- Sequence,
29
26
  TextIO,
30
- Tuple,
31
- Type,
32
27
  TypeVar,
33
- Union,
34
28
  cast,
35
29
  )
36
30
 
@@ -64,9 +58,9 @@ __all__ = [
64
58
  logger = logging.getLogger(__name__)
65
59
 
66
60
  T = TypeVar("T")
67
- ExcInfo = Tuple[Type[BaseException], BaseException, TracebackType]
68
- VersionInfo = Tuple[int, int, int]
69
- NetlocTuple = Tuple[str, Tuple[Optional[str], Optional[str]]]
61
+ ExcInfo = tuple[type[BaseException], BaseException, TracebackType]
62
+ VersionInfo = tuple[int, int, int]
63
+ NetlocTuple = tuple[str, tuple[Optional[str], Optional[str]]]
70
64
  OnExc = Callable[[FunctionType, Path, BaseException], Any]
71
65
  OnErr = Callable[[FunctionType, Path, ExcInfo], Any]
72
66
 
@@ -80,7 +74,7 @@ def get_pip_version() -> str:
80
74
  return f"pip {__version__} from {pip_pkg_dir} (python {get_major_minor_version()})"
81
75
 
82
76
 
83
- def normalize_version_info(py_version_info: Tuple[int, ...]) -> Tuple[int, int, int]:
77
+ def normalize_version_info(py_version_info: tuple[int, ...]) -> tuple[int, int, int]:
84
78
  """
85
79
  Convert a tuple of ints representing a Python version to one of length
86
80
  three.
@@ -123,9 +117,7 @@ def get_prog() -> str:
123
117
 
124
118
  # Retry every half second for up to 3 seconds
125
119
  @retry(stop_after_delay=3, wait=0.5)
126
- def rmtree(
127
- dir: str, ignore_errors: bool = False, onexc: Optional[OnExc] = None
128
- ) -> None:
120
+ def rmtree(dir: str, ignore_errors: bool = False, onexc: OnExc | None = None) -> None:
129
121
  if ignore_errors:
130
122
  onexc = _onerror_ignore
131
123
  if onexc is None:
@@ -149,7 +141,7 @@ def _onerror_reraise(*_args: Any) -> None:
149
141
  def rmtree_errorhandler(
150
142
  func: FunctionType,
151
143
  path: Path,
152
- exc_info: Union[ExcInfo, BaseException],
144
+ exc_info: ExcInfo | BaseException,
153
145
  *,
154
146
  onexc: OnExc = _onerror_reraise,
155
147
  ) -> None:
@@ -276,7 +268,7 @@ def format_size(bytes: float) -> str:
276
268
  return f"{int(bytes)} bytes"
277
269
 
278
270
 
279
- def tabulate(rows: Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]]:
271
+ def tabulate(rows: Iterable[Iterable[Any]]) -> tuple[list[str], list[int]]:
280
272
  """Return a list of formatted rows and a list of column sizes.
281
273
 
282
274
  For example::
@@ -331,7 +323,7 @@ def normalize_path(path: str, resolve_symlinks: bool = True) -> str:
331
323
  return os.path.normcase(path)
332
324
 
333
325
 
334
- def splitext(path: str) -> Tuple[str, str]:
326
+ def splitext(path: str) -> tuple[str, str]:
335
327
  """Like os.path.splitext, but take off .tar too"""
336
328
  base, ext = posixpath.splitext(path)
337
329
  if base.lower().endswith(".tar"):
@@ -379,7 +371,7 @@ class StreamWrapper(StringIO):
379
371
  orig_stream: TextIO
380
372
 
381
373
  @classmethod
382
- def from_stream(cls, orig_stream: TextIO) -> "StreamWrapper":
374
+ def from_stream(cls, orig_stream: TextIO) -> StreamWrapper:
383
375
  ret = cls()
384
376
  ret.orig_stream = orig_stream
385
377
  return ret
@@ -392,14 +384,14 @@ class StreamWrapper(StringIO):
392
384
 
393
385
 
394
386
  # Simulates an enum
395
- def enum(*sequential: Any, **named: Any) -> Type[Any]:
387
+ def enum(*sequential: Any, **named: Any) -> type[Any]:
396
388
  enums = dict(zip(sequential, range(len(sequential))), **named)
397
389
  reverse = {value: key for key, value in enums.items()}
398
390
  enums["reverse_mapping"] = reverse
399
391
  return type("Enum", (), enums)
400
392
 
401
393
 
402
- def build_netloc(host: str, port: Optional[int]) -> str:
394
+ def build_netloc(host: str, port: int | None) -> str:
403
395
  """
404
396
  Build a netloc from a host-port pair
405
397
  """
@@ -421,7 +413,7 @@ def build_url_from_netloc(netloc: str, scheme: str = "https") -> str:
421
413
  return f"{scheme}://{netloc}"
422
414
 
423
415
 
424
- def parse_netloc(netloc: str) -> Tuple[Optional[str], Optional[int]]:
416
+ def parse_netloc(netloc: str) -> tuple[str | None, int | None]:
425
417
  """
426
418
  Return the host-port pair from a netloc.
427
419
  """
@@ -443,7 +435,7 @@ def split_auth_from_netloc(netloc: str) -> NetlocTuple:
443
435
  # behaves if more than one @ is present (which can be checked using
444
436
  # the password attribute of urlsplit()'s return value).
445
437
  auth, netloc = netloc.rsplit("@", 1)
446
- pw: Optional[str] = None
438
+ pw: str | None = None
447
439
  if ":" in auth:
448
440
  # Split from the left because that's how urllib.parse.urlsplit()
449
441
  # behaves if more than one : is present (which again can be checked
@@ -480,8 +472,8 @@ def redact_netloc(netloc: str) -> str:
480
472
 
481
473
 
482
474
  def _transform_url(
483
- url: str, transform_netloc: Callable[[str], Tuple[Any, ...]]
484
- ) -> Tuple[str, NetlocTuple]:
475
+ url: str, transform_netloc: Callable[[str], tuple[Any, ...]]
476
+ ) -> tuple[str, NetlocTuple]:
485
477
  """Transform and replace netloc in a url.
486
478
 
487
479
  transform_netloc is a function taking the netloc and returning a
@@ -503,13 +495,13 @@ def _get_netloc(netloc: str) -> NetlocTuple:
503
495
  return split_auth_from_netloc(netloc)
504
496
 
505
497
 
506
- def _redact_netloc(netloc: str) -> Tuple[str]:
498
+ def _redact_netloc(netloc: str) -> tuple[str]:
507
499
  return (redact_netloc(netloc),)
508
500
 
509
501
 
510
502
  def split_auth_netloc_from_url(
511
503
  url: str,
512
- ) -> Tuple[str, str, Tuple[Optional[str], Optional[str]]]:
504
+ ) -> tuple[str, str, tuple[str | None, str | None]]:
513
505
  """
514
506
  Parse a url into separate netloc, auth, and url with no auth.
515
507
 
@@ -614,7 +606,7 @@ def is_console_interactive() -> bool:
614
606
  return sys.stdin is not None and sys.stdin.isatty()
615
607
 
616
608
 
617
- def hash_file(path: str, blocksize: int = 1 << 20) -> Tuple[Any, int]:
609
+ def hash_file(path: str, blocksize: int = 1 << 20) -> tuple[Any, int]:
618
610
  """Return (hash, length) for path using hashlib.sha256()"""
619
611
 
620
612
  h = hashlib.sha256()
@@ -626,7 +618,7 @@ def hash_file(path: str, blocksize: int = 1 << 20) -> Tuple[Any, int]:
626
618
  return h, length
627
619
 
628
620
 
629
- def pairwise(iterable: Iterable[Any]) -> Iterator[Tuple[Any, Any]]:
621
+ def pairwise(iterable: Iterable[Any]) -> Iterator[tuple[Any, Any]]:
630
622
  """
631
623
  Return paired elements.
632
624
 
@@ -639,7 +631,7 @@ def pairwise(iterable: Iterable[Any]) -> Iterator[Tuple[Any, Any]]:
639
631
 
640
632
  def partition(
641
633
  pred: Callable[[T], bool], iterable: Iterable[T]
642
- ) -> Tuple[Iterable[T], Iterable[T]]:
634
+ ) -> tuple[Iterable[T], Iterable[T]]:
643
635
  """
644
636
  Use a predicate to partition entries into false entries and true entries,
645
637
  like
@@ -656,9 +648,9 @@ class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
656
648
  config_holder: Any,
657
649
  source_dir: str,
658
650
  build_backend: str,
659
- backend_path: Optional[str] = None,
660
- runner: Optional[Callable[..., None]] = None,
661
- python_executable: Optional[str] = None,
651
+ backend_path: str | None = None,
652
+ runner: Callable[..., None] | None = None,
653
+ python_executable: str | None = None,
662
654
  ):
663
655
  super().__init__(
664
656
  source_dir, build_backend, backend_path, runner, python_executable
@@ -668,8 +660,8 @@ class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
668
660
  def build_wheel(
669
661
  self,
670
662
  wheel_directory: str,
671
- config_settings: Optional[Mapping[str, Any]] = None,
672
- metadata_directory: Optional[str] = None,
663
+ config_settings: Mapping[str, Any] | None = None,
664
+ metadata_directory: str | None = None,
673
665
  ) -> str:
674
666
  cs = self.config_holder.config_settings
675
667
  return super().build_wheel(
@@ -679,7 +671,7 @@ class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
679
671
  def build_sdist(
680
672
  self,
681
673
  sdist_directory: str,
682
- config_settings: Optional[Mapping[str, Any]] = None,
674
+ config_settings: Mapping[str, Any] | None = None,
683
675
  ) -> str:
684
676
  cs = self.config_holder.config_settings
685
677
  return super().build_sdist(sdist_directory, config_settings=cs)
@@ -687,8 +679,8 @@ class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
687
679
  def build_editable(
688
680
  self,
689
681
  wheel_directory: str,
690
- config_settings: Optional[Mapping[str, Any]] = None,
691
- metadata_directory: Optional[str] = None,
682
+ config_settings: Mapping[str, Any] | None = None,
683
+ metadata_directory: str | None = None,
692
684
  ) -> str:
693
685
  cs = self.config_holder.config_settings
694
686
  return super().build_editable(
@@ -696,19 +688,19 @@ class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
696
688
  )
697
689
 
698
690
  def get_requires_for_build_wheel(
699
- self, config_settings: Optional[Mapping[str, Any]] = None
691
+ self, config_settings: Mapping[str, Any] | None = None
700
692
  ) -> Sequence[str]:
701
693
  cs = self.config_holder.config_settings
702
694
  return super().get_requires_for_build_wheel(config_settings=cs)
703
695
 
704
696
  def get_requires_for_build_sdist(
705
- self, config_settings: Optional[Mapping[str, Any]] = None
697
+ self, config_settings: Mapping[str, Any] | None = None
706
698
  ) -> Sequence[str]:
707
699
  cs = self.config_holder.config_settings
708
700
  return super().get_requires_for_build_sdist(config_settings=cs)
709
701
 
710
702
  def get_requires_for_build_editable(
711
- self, config_settings: Optional[Mapping[str, Any]] = None
703
+ self, config_settings: Mapping[str, Any] | None = None
712
704
  ) -> Sequence[str]:
713
705
  cs = self.config_holder.config_settings
714
706
  return super().get_requires_for_build_editable(config_settings=cs)
@@ -716,7 +708,7 @@ class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
716
708
  def prepare_metadata_for_build_wheel(
717
709
  self,
718
710
  metadata_directory: str,
719
- config_settings: Optional[Mapping[str, Any]] = None,
711
+ config_settings: Mapping[str, Any] | None = None,
720
712
  _allow_fallback: bool = True,
721
713
  ) -> str:
722
714
  cs = self.config_holder.config_settings
@@ -729,9 +721,9 @@ class ConfiguredBuildBackendHookCaller(BuildBackendHookCaller):
729
721
  def prepare_metadata_for_build_editable(
730
722
  self,
731
723
  metadata_directory: str,
732
- config_settings: Optional[Mapping[str, Any]] = None,
724
+ config_settings: Mapping[str, Any] | None = None,
733
725
  _allow_fallback: bool = True,
734
- ) -> Optional[str]:
726
+ ) -> str | None:
735
727
  cs = self.config_holder.config_settings
736
728
  return super().prepare_metadata_for_build_editable(
737
729
  metadata_directory=metadata_directory,
@@ -1,6 +1,7 @@
1
+ from __future__ import annotations
2
+
1
3
  import functools
2
4
  import logging
3
- from typing import Optional, Tuple
4
5
 
5
6
  from pip._vendor.packaging import specifiers, version
6
7
  from pip._vendor.packaging.requirements import Requirement
@@ -10,7 +11,7 @@ logger = logging.getLogger(__name__)
10
11
 
11
12
  @functools.lru_cache(maxsize=32)
12
13
  def check_requires_python(
13
- requires_python: Optional[str], version_info: Tuple[int, ...]
14
+ requires_python: str | None, version_info: tuple[int, ...]
14
15
  ) -> bool:
15
16
  """
16
17
  Check if the given Python version matches a "Requires-Python" specifier.
@@ -1,11 +1,14 @@
1
+ from __future__ import annotations
2
+
1
3
  import functools
2
4
  from time import perf_counter, sleep
3
- from typing import Callable, TypeVar
5
+ from typing import TYPE_CHECKING, Callable, TypeVar
4
6
 
5
- from pip._vendor.typing_extensions import ParamSpec
7
+ if TYPE_CHECKING:
8
+ from typing_extensions import ParamSpec
6
9
 
7
- T = TypeVar("T")
8
- P = ParamSpec("P")
10
+ T = TypeVar("T")
11
+ P = ParamSpec("P")
9
12
 
10
13
 
11
14
  def retry(
@@ -1,6 +1,8 @@
1
+ from __future__ import annotations
2
+
1
3
  import sys
2
4
  import textwrap
3
- from typing import List, Optional, Sequence
5
+ from collections.abc import Sequence
4
6
 
5
7
  # Shim to wrap setup.py invocation with setuptools
6
8
  # Note that __file__ is handled via two {!r} *and* %r, to ensure that paths on
@@ -49,10 +51,10 @@ _SETUPTOOLS_SHIM = textwrap.dedent(
49
51
 
50
52
  def make_setuptools_shim_args(
51
53
  setup_py_path: str,
52
- global_options: Optional[Sequence[str]] = None,
54
+ global_options: Sequence[str] | None = None,
53
55
  no_user_config: bool = False,
54
56
  unbuffered_output: bool = False,
55
- ) -> List[str]:
57
+ ) -> list[str]:
56
58
  """
57
59
  Get setuptools command arguments with shim wrapped setup file invocation.
58
60
 
@@ -78,7 +80,7 @@ def make_setuptools_bdist_wheel_args(
78
80
  global_options: Sequence[str],
79
81
  build_options: Sequence[str],
80
82
  destination_dir: str,
81
- ) -> List[str]:
83
+ ) -> list[str]:
82
84
  # NOTE: Eventually, we'd want to also -S to the flags here, when we're
83
85
  # isolating. Currently, it breaks Python in virtualenvs, because it
84
86
  # relies on site.py to find parts of the standard library outside the
@@ -94,7 +96,7 @@ def make_setuptools_bdist_wheel_args(
94
96
  def make_setuptools_clean_args(
95
97
  setup_py_path: str,
96
98
  global_options: Sequence[str],
97
- ) -> List[str]:
99
+ ) -> list[str]:
98
100
  args = make_setuptools_shim_args(
99
101
  setup_py_path, global_options=global_options, unbuffered_output=True
100
102
  )
@@ -107,10 +109,10 @@ def make_setuptools_develop_args(
107
109
  *,
108
110
  global_options: Sequence[str],
109
111
  no_user_config: bool,
110
- prefix: Optional[str],
111
- home: Optional[str],
112
+ prefix: str | None,
113
+ home: str | None,
112
114
  use_user_site: bool,
113
- ) -> List[str]:
115
+ ) -> list[str]:
114
116
  assert not (use_user_site and prefix)
115
117
 
116
118
  args = make_setuptools_shim_args(
@@ -134,9 +136,9 @@ def make_setuptools_develop_args(
134
136
 
135
137
  def make_setuptools_egg_info_args(
136
138
  setup_py_path: str,
137
- egg_info_dir: Optional[str],
139
+ egg_info_dir: str | None,
138
140
  no_user_config: bool,
139
- ) -> List[str]:
141
+ ) -> list[str]:
140
142
  args = make_setuptools_shim_args(setup_py_path, no_user_config=no_user_config)
141
143
 
142
144
  args += ["egg_info"]
@@ -1,8 +1,11 @@
1
+ from __future__ import annotations
2
+
1
3
  import logging
2
4
  import os
3
5
  import shlex
4
6
  import subprocess
5
- from typing import Any, Callable, Iterable, List, Literal, Mapping, Optional, Union
7
+ from collections.abc import Iterable, Mapping
8
+ from typing import Any, Callable, Literal, Union
6
9
 
7
10
  from pip._vendor.rich.markup import escape
8
11
 
@@ -11,10 +14,10 @@ from pip._internal.exceptions import InstallationSubprocessError
11
14
  from pip._internal.utils.logging import VERBOSE, subprocess_logger
12
15
  from pip._internal.utils.misc import HiddenText
13
16
 
14
- CommandArgs = List[Union[str, HiddenText]]
17
+ CommandArgs = list[Union[str, HiddenText]]
15
18
 
16
19
 
17
- def make_command(*args: Union[str, HiddenText, CommandArgs]) -> CommandArgs:
20
+ def make_command(*args: str | HiddenText | CommandArgs) -> CommandArgs:
18
21
  """
19
22
  Create a CommandArgs object.
20
23
  """
@@ -31,7 +34,7 @@ def make_command(*args: Union[str, HiddenText, CommandArgs]) -> CommandArgs:
31
34
  return command_args
32
35
 
33
36
 
34
- def format_command_args(args: Union[List[str], CommandArgs]) -> str:
37
+ def format_command_args(args: list[str] | CommandArgs) -> str:
35
38
  """
36
39
  Format command arguments for display.
37
40
  """
@@ -46,7 +49,7 @@ def format_command_args(args: Union[List[str], CommandArgs]) -> str:
46
49
  )
47
50
 
48
51
 
49
- def reveal_command_args(args: Union[List[str], CommandArgs]) -> List[str]:
52
+ def reveal_command_args(args: list[str] | CommandArgs) -> list[str]:
50
53
  """
51
54
  Return the arguments in their raw, unredacted form.
52
55
  """
@@ -54,16 +57,16 @@ def reveal_command_args(args: Union[List[str], CommandArgs]) -> List[str]:
54
57
 
55
58
 
56
59
  def call_subprocess(
57
- cmd: Union[List[str], CommandArgs],
60
+ cmd: list[str] | CommandArgs,
58
61
  show_stdout: bool = False,
59
- cwd: Optional[str] = None,
60
- on_returncode: 'Literal["raise", "warn", "ignore"]' = "raise",
61
- extra_ok_returncodes: Optional[Iterable[int]] = None,
62
- extra_environ: Optional[Mapping[str, Any]] = None,
63
- unset_environ: Optional[Iterable[str]] = None,
64
- spinner: Optional[SpinnerInterface] = None,
65
- log_failed_cmd: Optional[bool] = True,
66
- stdout_only: Optional[bool] = False,
62
+ cwd: str | None = None,
63
+ on_returncode: Literal["raise", "warn", "ignore"] = "raise",
64
+ extra_ok_returncodes: Iterable[int] | None = None,
65
+ extra_environ: Mapping[str, Any] | None = None,
66
+ unset_environ: Iterable[str] | None = None,
67
+ spinner: SpinnerInterface | None = None,
68
+ log_failed_cmd: bool | None = True,
69
+ stdout_only: bool | None = False,
67
70
  *,
68
71
  command_desc: str,
69
72
  ) -> str:
@@ -229,9 +232,9 @@ def runner_with_spinner_message(message: str) -> Callable[..., None]:
229
232
  """
230
233
 
231
234
  def runner(
232
- cmd: List[str],
233
- cwd: Optional[str] = None,
234
- extra_environ: Optional[Mapping[str, Any]] = None,
235
+ cmd: list[str],
236
+ cwd: str | None = None,
237
+ extra_environ: Mapping[str, Any] | None = None,
235
238
  ) -> None:
236
239
  with open_spinner(message) as spinner:
237
240
  call_subprocess(
@@ -1,20 +1,18 @@
1
+ from __future__ import annotations
2
+
1
3
  import errno
2
4
  import itertools
3
5
  import logging
4
6
  import os.path
5
7
  import tempfile
6
8
  import traceback
9
+ from collections.abc import Generator
7
10
  from contextlib import ExitStack, contextmanager
8
11
  from pathlib import Path
9
12
  from typing import (
10
13
  Any,
11
14
  Callable,
12
- Dict,
13
- Generator,
14
- List,
15
- Optional,
16
15
  TypeVar,
17
- Union,
18
16
  )
19
17
 
20
18
  from pip._internal.utils.misc import enum, rmtree
@@ -33,7 +31,7 @@ tempdir_kinds = enum(
33
31
  )
34
32
 
35
33
 
36
- _tempdir_manager: Optional[ExitStack] = None
34
+ _tempdir_manager: ExitStack | None = None
37
35
 
38
36
 
39
37
  @contextmanager
@@ -51,7 +49,7 @@ class TempDirectoryTypeRegistry:
51
49
  """Manages temp directory behavior"""
52
50
 
53
51
  def __init__(self) -> None:
54
- self._should_delete: Dict[str, bool] = {}
52
+ self._should_delete: dict[str, bool] = {}
55
53
 
56
54
  def set_delete(self, kind: str, value: bool) -> None:
57
55
  """Indicate whether a TempDirectory of the given kind should be
@@ -66,7 +64,7 @@ class TempDirectoryTypeRegistry:
66
64
  return self._should_delete.get(kind, True)
67
65
 
68
66
 
69
- _tempdir_registry: Optional[TempDirectoryTypeRegistry] = None
67
+ _tempdir_registry: TempDirectoryTypeRegistry | None = None
70
68
 
71
69
 
72
70
  @contextmanager
@@ -113,8 +111,8 @@ class TempDirectory:
113
111
 
114
112
  def __init__(
115
113
  self,
116
- path: Optional[str] = None,
117
- delete: Union[bool, None, _Default] = _default,
114
+ path: str | None = None,
115
+ delete: bool | None | _Default = _default,
118
116
  kind: str = "temp",
119
117
  globally_managed: bool = False,
120
118
  ignore_cleanup_errors: bool = True,
@@ -184,7 +182,7 @@ class TempDirectory:
184
182
  if not os.path.exists(self._path):
185
183
  return
186
184
 
187
- errors: List[BaseException] = []
185
+ errors: list[BaseException] = []
188
186
 
189
187
  def onerror(
190
188
  func: Callable[..., Any],
@@ -245,7 +243,7 @@ class AdjacentTempDirectory(TempDirectory):
245
243
  # with leading '-' and invalid metadata
246
244
  LEADING_CHARS = "-~.=%0123456789"
247
245
 
248
- def __init__(self, original: str, delete: Optional[bool] = None) -> None:
246
+ def __init__(self, original: str, delete: bool | None = None) -> None:
249
247
  self.original = original.rstrip("/\\")
250
248
  super().__init__(delete=delete)
251
249
 
@@ -1,5 +1,7 @@
1
1
  """Utilities related archives."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import logging
4
6
  import os
5
7
  import shutil
@@ -7,7 +9,7 @@ import stat
7
9
  import sys
8
10
  import tarfile
9
11
  import zipfile
10
- from typing import Iterable, List, Optional
12
+ from collections.abc import Iterable
11
13
  from zipfile import ZipInfo
12
14
 
13
15
  from pip._internal.exceptions import InstallationError
@@ -47,7 +49,7 @@ def current_umask() -> int:
47
49
  return mask
48
50
 
49
51
 
50
- def split_leading_dir(path: str) -> List[str]:
52
+ def split_leading_dir(path: str) -> list[str]:
51
53
  path = path.lstrip("/").lstrip("\\")
52
54
  if "/" in path and (
53
55
  ("\\" in path and path.find("/") < path.find("\\")) or "\\" not in path
@@ -131,7 +133,7 @@ def unzip_file(filename: str, location: str, flatten: bool = True) -> None:
131
133
  "outside target directory ({})"
132
134
  )
133
135
  raise InstallationError(message.format(filename, fn, location))
134
- if fn.endswith("/") or fn.endswith("\\"):
136
+ if fn.endswith(("/", "\\")):
135
137
  # A directory
136
138
  ensure_dir(fn)
137
139
  else:
@@ -307,7 +309,7 @@ def _untar_without_filter(
307
309
  def unpack_file(
308
310
  filename: str,
309
311
  location: str,
310
- content_type: Optional[str] = None,
312
+ content_type: str | None = None,
311
313
  ) -> None:
312
314
  filename = os.path.realpath(filename)
313
315
  if (
@@ -12,7 +12,7 @@ def path_to_url(path: str) -> str:
12
12
  quoted path parts.
13
13
  """
14
14
  path = os.path.normpath(os.path.abspath(path))
15
- url = urllib.parse.urljoin("file:", urllib.request.pathname2url(path))
15
+ url = urllib.parse.urljoin("file://", urllib.request.pathname2url(path))
16
16
  return url
17
17
 
18
18
 
@@ -1,9 +1,10 @@
1
+ from __future__ import annotations
2
+
1
3
  import logging
2
4
  import os
3
5
  import re
4
6
  import site
5
7
  import sys
6
- from typing import List, Optional
7
8
 
8
9
  logger = logging.getLogger(__name__)
9
10
  _INCLUDE_SYSTEM_SITE_PACKAGES_REGEX = re.compile(
@@ -33,7 +34,7 @@ def running_under_virtualenv() -> bool:
33
34
  return _running_under_venv() or _running_under_legacy_virtualenv()
34
35
 
35
36
 
36
- def _get_pyvenv_cfg_lines() -> Optional[List[str]]:
37
+ def _get_pyvenv_cfg_lines() -> list[str] | None:
37
38
  """Reads {sys.prefix}/pyvenv.cfg and returns its contents as list of lines
38
39
 
39
40
  Returns None, if it could not read/access the file.
@@ -3,7 +3,6 @@
3
3
  import logging
4
4
  from email.message import Message
5
5
  from email.parser import Parser
6
- from typing import Tuple
7
6
  from zipfile import BadZipFile, ZipFile
8
7
 
9
8
  from pip._vendor.packaging.utils import canonicalize_name
@@ -16,7 +15,7 @@ VERSION_COMPATIBLE = (1, 0)
16
15
  logger = logging.getLogger(__name__)
17
16
 
18
17
 
19
- def parse_wheel(wheel_zip: ZipFile, name: str) -> Tuple[str, Message]:
18
+ def parse_wheel(wheel_zip: ZipFile, name: str) -> tuple[str, Message]:
20
19
  """Extract information from the provided wheel, ensuring it meets basic
21
20
  standards.
22
21
 
@@ -93,7 +92,7 @@ def wheel_metadata(source: ZipFile, dist_info_dir: str) -> Message:
93
92
  return Parser().parsestr(wheel_text)
94
93
 
95
94
 
96
- def wheel_version(wheel_data: Message) -> Tuple[int, ...]:
95
+ def wheel_version(wheel_data: Message) -> tuple[int, ...]:
97
96
  """Given WHEEL metadata, return the parsed Wheel-Version.
98
97
  Otherwise, raise UnsupportedWheel.
99
98
  """
@@ -109,7 +108,7 @@ def wheel_version(wheel_data: Message) -> Tuple[int, ...]:
109
108
  raise UnsupportedWheel(f"invalid Wheel-Version: {version!r}")
110
109
 
111
110
 
112
- def check_compatibility(version: Tuple[int, ...], name: str) -> None:
111
+ def check_compatibility(version: tuple[int, ...], name: str) -> None:
113
112
  """Raises errors or warns if called with an incompatible Wheel-Version.
114
113
 
115
114
  pip should refuse to install a Wheel-Version that's a major series