pip 25.3__py3-none-any.whl → 26.0__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 (104) hide show
  1. pip/__init__.py +1 -1
  2. pip/_internal/build_env.py +194 -5
  3. pip/_internal/cli/base_command.py +11 -0
  4. pip/_internal/cli/cmdoptions.py +157 -0
  5. pip/_internal/cli/index_command.py +20 -0
  6. pip/_internal/cli/main.py +11 -6
  7. pip/_internal/cli/main_parser.py +3 -1
  8. pip/_internal/cli/parser.py +93 -33
  9. pip/_internal/cli/progress_bars.py +4 -2
  10. pip/_internal/cli/req_command.py +99 -23
  11. pip/_internal/commands/cache.py +24 -0
  12. pip/_internal/commands/completion.py +2 -1
  13. pip/_internal/commands/download.py +8 -4
  14. pip/_internal/commands/index.py +13 -6
  15. pip/_internal/commands/install.py +36 -29
  16. pip/_internal/commands/list.py +14 -16
  17. pip/_internal/commands/lock.py +16 -8
  18. pip/_internal/commands/wheel.py +8 -13
  19. pip/_internal/exceptions.py +76 -3
  20. pip/_internal/index/collector.py +2 -3
  21. pip/_internal/index/package_finder.py +84 -18
  22. pip/_internal/locations/__init__.py +1 -2
  23. pip/_internal/locations/_sysconfig.py +4 -1
  24. pip/_internal/models/link.py +18 -14
  25. pip/_internal/models/release_control.py +92 -0
  26. pip/_internal/models/selection_prefs.py +6 -3
  27. pip/_internal/network/auth.py +6 -2
  28. pip/_internal/network/download.py +4 -5
  29. pip/_internal/network/session.py +14 -10
  30. pip/_internal/operations/install/wheel.py +1 -2
  31. pip/_internal/operations/prepare.py +2 -3
  32. pip/_internal/req/constructors.py +3 -1
  33. pip/_internal/req/pep723.py +41 -0
  34. pip/_internal/req/req_file.py +10 -1
  35. pip/_internal/resolution/resolvelib/factory.py +12 -1
  36. pip/_internal/resolution/resolvelib/requirements.py +7 -3
  37. pip/_internal/self_outdated_check.py +6 -13
  38. pip/_internal/utils/datetime.py +18 -0
  39. pip/_internal/utils/filesystem.py +40 -1
  40. pip/_internal/utils/logging.py +34 -2
  41. pip/_internal/utils/misc.py +18 -12
  42. pip/_internal/utils/pylock.py +116 -0
  43. pip/_internal/utils/unpacking.py +1 -1
  44. pip/_internal/vcs/versioncontrol.py +3 -1
  45. pip/_vendor/cachecontrol/__init__.py +6 -3
  46. pip/_vendor/cachecontrol/adapter.py +0 -1
  47. pip/_vendor/cachecontrol/controller.py +1 -1
  48. pip/_vendor/cachecontrol/filewrapper.py +3 -1
  49. pip/_vendor/certifi/__init__.py +1 -1
  50. pip/_vendor/certifi/cacert.pem +0 -332
  51. pip/_vendor/idna/LICENSE.md +1 -1
  52. pip/_vendor/idna/codec.py +1 -1
  53. pip/_vendor/idna/core.py +1 -1
  54. pip/_vendor/idna/idnadata.py +72 -6
  55. pip/_vendor/idna/package_data.py +1 -1
  56. pip/_vendor/idna/uts46data.py +891 -731
  57. pip/_vendor/packaging/__init__.py +1 -1
  58. pip/_vendor/packaging/_elffile.py +0 -1
  59. pip/_vendor/packaging/_manylinux.py +36 -36
  60. pip/_vendor/packaging/_musllinux.py +1 -1
  61. pip/_vendor/packaging/_parser.py +22 -10
  62. pip/_vendor/packaging/_structures.py +8 -0
  63. pip/_vendor/packaging/_tokenizer.py +23 -25
  64. pip/_vendor/packaging/licenses/__init__.py +13 -11
  65. pip/_vendor/packaging/licenses/_spdx.py +41 -1
  66. pip/_vendor/packaging/markers.py +64 -38
  67. pip/_vendor/packaging/metadata.py +143 -27
  68. pip/_vendor/packaging/pylock.py +635 -0
  69. pip/_vendor/packaging/requirements.py +5 -10
  70. pip/_vendor/packaging/specifiers.py +219 -170
  71. pip/_vendor/packaging/tags.py +15 -20
  72. pip/_vendor/packaging/utils.py +19 -24
  73. pip/_vendor/packaging/version.py +315 -105
  74. pip/_vendor/platformdirs/version.py +2 -2
  75. pip/_vendor/platformdirs/windows.py +7 -1
  76. pip/_vendor/vendor.txt +5 -5
  77. {pip-25.3.dist-info → pip-26.0.dist-info}/METADATA +2 -2
  78. {pip-25.3.dist-info → pip-26.0.dist-info}/RECORD +103 -100
  79. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/AUTHORS.txt +18 -0
  80. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/idna/LICENSE.md +1 -1
  81. pip/_internal/models/pylock.py +0 -188
  82. {pip-25.3.dist-info → pip-26.0.dist-info}/WHEEL +0 -0
  83. {pip-25.3.dist-info → pip-26.0.dist-info}/entry_points.txt +0 -0
  84. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/LICENSE.txt +0 -0
  85. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +0 -0
  86. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/certifi/LICENSE +0 -0
  87. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +0 -0
  88. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/distlib/LICENSE.txt +0 -0
  89. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/distro/LICENSE +0 -0
  90. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/msgpack/COPYING +0 -0
  91. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE +0 -0
  92. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +0 -0
  93. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.BSD +0 -0
  94. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pkg_resources/LICENSE +0 -0
  95. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/platformdirs/LICENSE +0 -0
  96. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pygments/LICENSE +0 -0
  97. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +0 -0
  98. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/requests/LICENSE +0 -0
  99. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/resolvelib/LICENSE +0 -0
  100. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/rich/LICENSE +0 -0
  101. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/tomli/LICENSE +0 -0
  102. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/tomli_w/LICENSE +0 -0
  103. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/truststore/LICENSE +0 -0
  104. {pip-25.3.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/urllib3/LICENSE.txt +0 -0
@@ -13,6 +13,7 @@ import sys
13
13
  import sysconfig
14
14
  from importlib.machinery import EXTENSION_SUFFIXES
15
15
  from typing import (
16
+ Any,
16
17
  Iterable,
17
18
  Iterator,
18
19
  Sequence,
@@ -92,6 +93,13 @@ class Tag:
92
93
  def __repr__(self) -> str:
93
94
  return f"<{self} @ {id(self)}>"
94
95
 
96
+ def __setstate__(self, state: tuple[None, dict[str, Any]]) -> None:
97
+ # The cached _hash is wrong when unpickling.
98
+ _, slots = state
99
+ for k, v in slots.items():
100
+ setattr(self, k, v)
101
+ self._hash = hash((self._interpreter, self._abi, self._platform))
102
+
95
103
 
96
104
  def parse_tag(tag: str) -> frozenset[Tag]:
97
105
  """
@@ -209,16 +217,13 @@ def cpython_tags(
209
217
  interpreter = f"cp{_version_nodot(python_version[:2])}"
210
218
 
211
219
  if abis is None:
212
- if len(python_version) > 1:
213
- abis = _cpython_abis(python_version, warn)
214
- else:
215
- abis = []
220
+ abis = _cpython_abis(python_version, warn) if len(python_version) > 1 else []
216
221
  abis = list(abis)
217
222
  # 'abi3' and 'none' are explicitly handled later.
218
223
  for explicit_abi in ("abi3", "none"):
219
224
  try:
220
225
  abis.remove(explicit_abi)
221
- except ValueError:
226
+ except ValueError: # noqa: PERF203
222
227
  pass
223
228
 
224
229
  platforms = list(platforms or platform_tags())
@@ -299,11 +304,8 @@ def generic_tags(
299
304
  if not interpreter:
300
305
  interp_name = interpreter_name()
301
306
  interp_version = interpreter_version(warn=warn)
302
- interpreter = "".join([interp_name, interp_version])
303
- if abis is None:
304
- abis = _generic_abi()
305
- else:
306
- abis = list(abis)
307
+ interpreter = f"{interp_name}{interp_version}"
308
+ abis = _generic_abi() if abis is None else list(abis)
307
309
  platforms = list(platforms or platform_tags())
308
310
  if "none" not in abis:
309
311
  abis.append("none")
@@ -424,14 +426,11 @@ def mac_platforms(
424
426
  text=True,
425
427
  ).stdout
426
428
  version = cast("AppleVersion", tuple(map(int, version_str.split(".")[:2])))
427
- else:
428
- version = version
429
+
429
430
  if arch is None:
430
431
  arch = _mac_arch(cpu_arch)
431
- else:
432
- arch = arch
433
432
 
434
- if (10, 0) <= version and version < (11, 0):
433
+ if (10, 0) <= version < (11, 0):
435
434
  # Prior to Mac OS 11, each yearly release of Mac OS bumped the
436
435
  # "minor" version number. The major version was always 10.
437
436
  major_version = 10
@@ -622,11 +621,7 @@ def interpreter_version(*, warn: bool = False) -> str:
622
621
  Returns the version of the running interpreter.
623
622
  """
624
623
  version = _get_config_var("py_version_nodot", warn=warn)
625
- if version:
626
- version = str(version)
627
- else:
628
- version = _version_nodot(sys.version_info[:2])
629
- return version
624
+ return str(version) if version else _version_nodot(sys.version_info[:2])
630
625
 
631
626
 
632
627
  def _version_nodot(version: PythonVersion) -> str:
@@ -4,7 +4,6 @@
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- import functools
8
7
  import re
9
8
  from typing import NewType, Tuple, Union, cast
10
9
 
@@ -34,28 +33,29 @@ class InvalidSdistFilename(ValueError):
34
33
 
35
34
 
36
35
  # Core metadata spec for `Name`
37
- _validate_regex = re.compile(
38
- r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
39
- )
40
- _canonicalize_regex = re.compile(r"[-_.]+")
41
- _normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
36
+ _validate_regex = re.compile(r"[A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9]", re.IGNORECASE)
37
+ _normalized_regex = re.compile(r"[a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9]")
42
38
  # PEP 427: The build number must start with a digit.
43
39
  _build_tag_regex = re.compile(r"(\d+)(.*)")
44
40
 
45
41
 
46
42
  def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
47
- if validate and not _validate_regex.match(name):
43
+ if validate and not _validate_regex.fullmatch(name):
48
44
  raise InvalidName(f"name is invalid: {name!r}")
49
- # This is taken from PEP 503.
50
- value = _canonicalize_regex.sub("-", name).lower()
51
- return cast(NormalizedName, value)
45
+ # Ensure all ``.`` and ``_`` are ``-``
46
+ # Emulates ``re.sub(r"[-_.]+", "-", name).lower()`` from PEP 503
47
+ # Much faster than re, and even faster than str.translate
48
+ value = name.lower().replace("_", "-").replace(".", "-")
49
+ # Condense repeats (faster than regex)
50
+ while "--" in value:
51
+ value = value.replace("--", "-")
52
+ return cast("NormalizedName", value)
52
53
 
53
54
 
54
55
  def is_normalized_name(name: str) -> bool:
55
- return _normalized_regex.match(name) is not None
56
+ return _normalized_regex.fullmatch(name) is not None
56
57
 
57
58
 
58
- @functools.singledispatch
59
59
  def canonicalize_version(
60
60
  version: Version | str, *, strip_trailing_zero: bool = True
61
61
  ) -> str:
@@ -78,17 +78,12 @@ def canonicalize_version(
78
78
  >>> canonicalize_version('foo bar baz')
79
79
  'foo bar baz'
80
80
  """
81
- return str(_TrimmedRelease(str(version)) if strip_trailing_zero else version)
82
-
83
-
84
- @canonicalize_version.register
85
- def _(version: str, *, strip_trailing_zero: bool = True) -> str:
86
- try:
87
- parsed = Version(version)
88
- except InvalidVersion:
89
- # Legacy versions cannot be normalized
90
- return version
91
- return canonicalize_version(parsed, strip_trailing_zero=strip_trailing_zero)
81
+ if isinstance(version, str):
82
+ try:
83
+ version = Version(version)
84
+ except InvalidVersion:
85
+ return str(version)
86
+ return str(_TrimmedRelease(version) if strip_trailing_zero else version)
92
87
 
93
88
 
94
89
  def parse_wheel_filename(
@@ -127,7 +122,7 @@ def parse_wheel_filename(
127
122
  raise InvalidWheelFilename(
128
123
  f"Invalid build number: {build_part} in {filename!r}"
129
124
  )
130
- build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
125
+ build = cast("BuildTag", (int(build_match.group(1)), build_match.group(2)))
131
126
  else:
132
127
  build = ()
133
128
  tags = parse_tag(parts[-1])