pip 25.2__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 (167) hide show
  1. pip/__init__.py +1 -1
  2. pip/_internal/__init__.py +0 -0
  3. pip/_internal/build_env.py +265 -8
  4. pip/_internal/cache.py +1 -1
  5. pip/_internal/cli/base_command.py +11 -0
  6. pip/_internal/cli/cmdoptions.py +200 -71
  7. pip/_internal/cli/index_command.py +20 -0
  8. pip/_internal/cli/main.py +11 -6
  9. pip/_internal/cli/main_parser.py +3 -1
  10. pip/_internal/cli/parser.py +96 -36
  11. pip/_internal/cli/progress_bars.py +4 -2
  12. pip/_internal/cli/req_command.py +126 -30
  13. pip/_internal/commands/cache.py +24 -0
  14. pip/_internal/commands/completion.py +2 -1
  15. pip/_internal/commands/download.py +12 -11
  16. pip/_internal/commands/index.py +13 -6
  17. pip/_internal/commands/install.py +55 -43
  18. pip/_internal/commands/list.py +14 -16
  19. pip/_internal/commands/lock.py +19 -14
  20. pip/_internal/commands/wheel.py +13 -23
  21. pip/_internal/configuration.py +1 -2
  22. pip/_internal/distributions/sdist.py +13 -14
  23. pip/_internal/exceptions.py +96 -6
  24. pip/_internal/index/collector.py +2 -3
  25. pip/_internal/index/package_finder.py +87 -21
  26. pip/_internal/locations/__init__.py +1 -2
  27. pip/_internal/locations/_sysconfig.py +4 -1
  28. pip/_internal/metadata/__init__.py +7 -2
  29. pip/_internal/metadata/importlib/_dists.py +8 -2
  30. pip/_internal/models/link.py +18 -14
  31. pip/_internal/models/release_control.py +92 -0
  32. pip/_internal/models/selection_prefs.py +6 -3
  33. pip/_internal/models/wheel.py +5 -66
  34. pip/_internal/network/auth.py +6 -2
  35. pip/_internal/network/cache.py +6 -11
  36. pip/_internal/network/download.py +4 -5
  37. pip/_internal/network/lazy_wheel.py +5 -3
  38. pip/_internal/network/session.py +14 -10
  39. pip/_internal/operations/build/wheel.py +4 -4
  40. pip/_internal/operations/build/wheel_editable.py +4 -4
  41. pip/_internal/operations/install/wheel.py +1 -2
  42. pip/_internal/operations/prepare.py +9 -4
  43. pip/_internal/pyproject.py +2 -61
  44. pip/_internal/req/__init__.py +1 -3
  45. pip/_internal/req/constructors.py +45 -39
  46. pip/_internal/req/pep723.py +41 -0
  47. pip/_internal/req/req_file.py +10 -2
  48. pip/_internal/req/req_install.py +32 -141
  49. pip/_internal/resolution/resolvelib/candidates.py +20 -11
  50. pip/_internal/resolution/resolvelib/factory.py +43 -1
  51. pip/_internal/resolution/resolvelib/provider.py +9 -0
  52. pip/_internal/resolution/resolvelib/reporter.py +21 -8
  53. pip/_internal/resolution/resolvelib/requirements.py +7 -3
  54. pip/_internal/resolution/resolvelib/resolver.py +2 -6
  55. pip/_internal/self_outdated_check.py +17 -16
  56. pip/_internal/utils/datetime.py +18 -0
  57. pip/_internal/utils/filesystem.py +52 -1
  58. pip/_internal/utils/logging.py +34 -2
  59. pip/_internal/utils/misc.py +18 -12
  60. pip/_internal/utils/pylock.py +116 -0
  61. pip/_internal/utils/unpacking.py +26 -1
  62. pip/_internal/vcs/versioncontrol.py +3 -1
  63. pip/_internal/wheel_builder.py +23 -96
  64. pip/_vendor/README.rst +180 -0
  65. pip/_vendor/cachecontrol/LICENSE.txt +13 -0
  66. pip/_vendor/cachecontrol/__init__.py +6 -3
  67. pip/_vendor/cachecontrol/adapter.py +0 -1
  68. pip/_vendor/cachecontrol/controller.py +1 -1
  69. pip/_vendor/cachecontrol/filewrapper.py +3 -1
  70. pip/_vendor/certifi/LICENSE +20 -0
  71. pip/_vendor/certifi/__init__.py +1 -1
  72. pip/_vendor/certifi/cacert.pem +62 -372
  73. pip/_vendor/dependency_groups/LICENSE.txt +9 -0
  74. pip/_vendor/distlib/LICENSE.txt +284 -0
  75. pip/_vendor/distro/LICENSE +202 -0
  76. pip/_vendor/idna/LICENSE.md +31 -0
  77. pip/_vendor/idna/codec.py +1 -1
  78. pip/_vendor/idna/core.py +1 -1
  79. pip/_vendor/idna/idnadata.py +72 -6
  80. pip/_vendor/idna/package_data.py +1 -1
  81. pip/_vendor/idna/uts46data.py +891 -731
  82. pip/_vendor/msgpack/COPYING +14 -0
  83. pip/_vendor/msgpack/__init__.py +2 -2
  84. pip/_vendor/packaging/LICENSE +3 -0
  85. pip/_vendor/packaging/LICENSE.APACHE +177 -0
  86. pip/_vendor/packaging/LICENSE.BSD +23 -0
  87. pip/_vendor/packaging/__init__.py +1 -1
  88. pip/_vendor/packaging/_elffile.py +0 -1
  89. pip/_vendor/packaging/_manylinux.py +36 -36
  90. pip/_vendor/packaging/_musllinux.py +1 -1
  91. pip/_vendor/packaging/_parser.py +22 -10
  92. pip/_vendor/packaging/_structures.py +8 -0
  93. pip/_vendor/packaging/_tokenizer.py +23 -25
  94. pip/_vendor/packaging/licenses/__init__.py +13 -11
  95. pip/_vendor/packaging/licenses/_spdx.py +41 -1
  96. pip/_vendor/packaging/markers.py +64 -38
  97. pip/_vendor/packaging/metadata.py +143 -27
  98. pip/_vendor/packaging/pylock.py +635 -0
  99. pip/_vendor/packaging/requirements.py +5 -10
  100. pip/_vendor/packaging/specifiers.py +219 -170
  101. pip/_vendor/packaging/tags.py +15 -20
  102. pip/_vendor/packaging/utils.py +19 -24
  103. pip/_vendor/packaging/version.py +315 -105
  104. pip/_vendor/pkg_resources/LICENSE +17 -0
  105. pip/_vendor/platformdirs/LICENSE +21 -0
  106. pip/_vendor/platformdirs/api.py +1 -1
  107. pip/_vendor/platformdirs/macos.py +10 -8
  108. pip/_vendor/platformdirs/version.py +16 -3
  109. pip/_vendor/platformdirs/windows.py +7 -1
  110. pip/_vendor/pygments/LICENSE +25 -0
  111. pip/_vendor/pyproject_hooks/LICENSE +21 -0
  112. pip/_vendor/requests/LICENSE +175 -0
  113. pip/_vendor/requests/__version__.py +2 -2
  114. pip/_vendor/requests/adapters.py +17 -40
  115. pip/_vendor/requests/sessions.py +1 -1
  116. pip/_vendor/resolvelib/LICENSE +13 -0
  117. pip/_vendor/resolvelib/__init__.py +1 -1
  118. pip/_vendor/resolvelib/resolvers/abstract.py +3 -3
  119. pip/_vendor/resolvelib/resolvers/resolution.py +5 -0
  120. pip/_vendor/rich/LICENSE +19 -0
  121. pip/_vendor/rich/style.py +7 -11
  122. pip/_vendor/tomli/LICENSE +21 -0
  123. pip/_vendor/tomli/__init__.py +1 -1
  124. pip/_vendor/tomli/_parser.py +28 -21
  125. pip/_vendor/tomli/_re.py +8 -5
  126. pip/_vendor/tomli_w/LICENSE +21 -0
  127. pip/_vendor/truststore/LICENSE +21 -0
  128. pip/_vendor/truststore/__init__.py +1 -1
  129. pip/_vendor/truststore/_api.py +14 -6
  130. pip/_vendor/truststore/_openssl.py +3 -1
  131. pip/_vendor/urllib3/LICENSE.txt +21 -0
  132. pip/_vendor/vendor.txt +11 -11
  133. {pip-25.2.dist-info → pip-26.0.dist-info}/METADATA +10 -11
  134. {pip-25.2.dist-info → pip-26.0.dist-info}/RECORD +158 -139
  135. {pip-25.2.dist-info → pip-26.0.dist-info}/WHEEL +1 -2
  136. pip-26.0.dist-info/entry_points.txt +4 -0
  137. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/AUTHORS.txt +27 -0
  138. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/idna/LICENSE.md +1 -1
  139. pip/_internal/models/pylock.py +0 -188
  140. pip/_internal/operations/build/metadata_legacy.py +0 -73
  141. pip/_internal/operations/build/wheel_legacy.py +0 -119
  142. pip/_internal/operations/install/editable_legacy.py +0 -48
  143. pip/_internal/utils/setuptools_build.py +0 -149
  144. pip-25.2.dist-info/entry_points.txt +0 -3
  145. pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE-HEADER +0 -3
  146. pip-25.2.dist-info/top_level.txt +0 -1
  147. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/LICENSE.txt +0 -0
  148. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +0 -0
  149. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/certifi/LICENSE +0 -0
  150. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +0 -0
  151. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/distlib/LICENSE.txt +0 -0
  152. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/distro/LICENSE +0 -0
  153. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/msgpack/COPYING +0 -0
  154. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE +0 -0
  155. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +0 -0
  156. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.BSD +0 -0
  157. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pkg_resources/LICENSE +0 -0
  158. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/platformdirs/LICENSE +0 -0
  159. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pygments/LICENSE +0 -0
  160. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +0 -0
  161. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/requests/LICENSE +0 -0
  162. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/resolvelib/LICENSE +0 -0
  163. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/rich/LICENSE +0 -0
  164. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/tomli/LICENSE +0 -0
  165. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/tomli_w/LICENSE +0 -0
  166. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/truststore/LICENSE +0 -0
  167. {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/urllib3/LICENSE.txt +0 -0
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
  import functools
4
4
  import sys
5
5
  from collections.abc import Generator, Iterable, Iterator
6
- from typing import Callable, Literal, TypeVar
6
+ from typing import TYPE_CHECKING, Callable, Literal, TypeVar
7
7
 
8
8
  from pip._vendor.rich.progress import (
9
9
  BarColumn,
@@ -20,9 +20,11 @@ from pip._vendor.rich.progress import (
20
20
  )
21
21
 
22
22
  from pip._internal.cli.spinners import RateLimiter
23
- from pip._internal.req.req_install import InstallRequirement
24
23
  from pip._internal.utils.logging import get_console, get_indentation
25
24
 
25
+ if TYPE_CHECKING:
26
+ from pip._internal.req.req_install import InstallRequirement
27
+
26
28
  T = TypeVar("T")
27
29
  ProgressRenderer = Callable[[Iterable[T]], Iterator[T]]
28
30
  BarType = Literal["on", "off", "raw"]
@@ -8,16 +8,26 @@ PackageFinder machinery and all its vendored dependencies, etc.
8
8
  from __future__ import annotations
9
9
 
10
10
  import logging
11
+ import os
11
12
  from functools import partial
12
13
  from optparse import Values
13
- from typing import Any
14
+ from typing import Any, Callable, TypeVar
14
15
 
15
- from pip._internal.build_env import SubprocessBuildEnvironmentInstaller
16
+ from pip._internal.build_env import (
17
+ BuildEnvironmentInstaller,
18
+ InprocessBuildEnvironmentInstaller,
19
+ SubprocessBuildEnvironmentInstaller,
20
+ )
16
21
  from pip._internal.cache import WheelCache
17
22
  from pip._internal.cli import cmdoptions
23
+ from pip._internal.cli.cmdoptions import make_target_python
18
24
  from pip._internal.cli.index_command import IndexGroupCommand
19
25
  from pip._internal.cli.index_command import SessionCommandMixin as SessionCommandMixin
20
- from pip._internal.exceptions import CommandError, PreviousBuildDirError
26
+ from pip._internal.exceptions import (
27
+ CommandError,
28
+ PreviousBuildDirError,
29
+ UnsupportedPythonVersion,
30
+ )
21
31
  from pip._internal.index.collector import LinkCollector
22
32
  from pip._internal.index.package_finder import PackageFinder
23
33
  from pip._internal.models.selection_prefs import SelectionPreferences
@@ -31,10 +41,12 @@ from pip._internal.req.constructors import (
31
41
  install_req_from_parsed_requirement,
32
42
  install_req_from_req_string,
33
43
  )
44
+ from pip._internal.req.pep723 import PEP723Exception, pep723_metadata
34
45
  from pip._internal.req.req_dependency_group import parse_dependency_groups
35
46
  from pip._internal.req.req_file import parse_requirements
36
47
  from pip._internal.req.req_install import InstallRequirement
37
48
  from pip._internal.resolution.base import BaseResolver
49
+ from pip._internal.utils.packaging import check_requires_python
38
50
  from pip._internal.utils.temp_dir import (
39
51
  TempDirectory,
40
52
  TempDirectoryTypeRegistry,
@@ -44,6 +56,16 @@ from pip._internal.utils.temp_dir import (
44
56
  logger = logging.getLogger(__name__)
45
57
 
46
58
 
59
+ def should_ignore_regular_constraints(options: Values) -> bool:
60
+ """
61
+ Check if regular constraints should be ignored because
62
+ we are in a isolated build process and build constraints
63
+ feature is enabled but no build constraints were passed.
64
+ """
65
+
66
+ return os.environ.get("_PIP_IN_BUILD_IGNORE_CONSTRAINTS") == "1"
67
+
68
+
47
69
  KEEPABLE_TEMPDIR_TYPES = [
48
70
  tempdir_kinds.BUILD_ENV,
49
71
  tempdir_kinds.EPHEM_WHEEL_CACHE,
@@ -51,7 +73,12 @@ KEEPABLE_TEMPDIR_TYPES = [
51
73
  ]
52
74
 
53
75
 
54
- def with_cleanup(func: Any) -> Any:
76
+ _CommandT = TypeVar("_CommandT", bound="RequirementCommand")
77
+
78
+
79
+ def with_cleanup(
80
+ func: Callable[[_CommandT, Values, list[str]], int],
81
+ ) -> Callable[[_CommandT, Values, list[str]], int]:
55
82
  """Decorator for common logic related to managing temporary
56
83
  directories.
57
84
  """
@@ -60,9 +87,7 @@ def with_cleanup(func: Any) -> Any:
60
87
  for t in KEEPABLE_TEMPDIR_TYPES:
61
88
  registry.set_delete(t, False)
62
89
 
63
- def wrapper(
64
- self: RequirementCommand, options: Values, args: list[Any]
65
- ) -> int | None:
90
+ def wrapper(self: _CommandT, options: Values, args: list[str]) -> int:
66
91
  assert self.tempdir_registry is not None
67
92
  if options.no_clean:
68
93
  configure_tempdir_registry(self.tempdir_registry)
@@ -79,6 +104,31 @@ def with_cleanup(func: Any) -> Any:
79
104
  return wrapper
80
105
 
81
106
 
107
+ def parse_constraint_files(
108
+ constraint_files: list[str],
109
+ finder: PackageFinder,
110
+ options: Values,
111
+ session: PipSession,
112
+ ) -> list[InstallRequirement]:
113
+ requirements = []
114
+ for filename in constraint_files:
115
+ for parsed_req in parse_requirements(
116
+ filename,
117
+ constraint=True,
118
+ finder=finder,
119
+ options=options,
120
+ session=session,
121
+ ):
122
+ req_to_add = install_req_from_parsed_requirement(
123
+ parsed_req,
124
+ isolated=options.isolated_mode,
125
+ user_supplied=False,
126
+ )
127
+ requirements.append(req_to_add)
128
+
129
+ return requirements
130
+
131
+
82
132
  class RequirementCommand(IndexGroupCommand):
83
133
  def __init__(self, *args: Any, **kw: Any) -> None:
84
134
  super().__init__(*args, **kw)
@@ -132,12 +182,37 @@ class RequirementCommand(IndexGroupCommand):
132
182
  "fast-deps has no effect when used with the legacy resolver."
133
183
  )
134
184
 
185
+ # Handle build constraints
186
+ build_constraints = getattr(options, "build_constraints", [])
187
+ build_constraint_feature_enabled = (
188
+ "build-constraint" in options.features_enabled
189
+ )
190
+
191
+ env_installer: BuildEnvironmentInstaller
192
+ if "inprocess-build-deps" in options.features_enabled:
193
+ build_constraint_reqs = parse_constraint_files(
194
+ build_constraints, finder, options, session
195
+ )
196
+ env_installer = InprocessBuildEnvironmentInstaller(
197
+ finder=finder,
198
+ build_tracker=build_tracker,
199
+ build_constraints=build_constraint_reqs,
200
+ verbosity=verbosity,
201
+ wheel_cache=WheelCache(options.cache_dir),
202
+ )
203
+ else:
204
+ env_installer = SubprocessBuildEnvironmentInstaller(
205
+ finder,
206
+ build_constraints=build_constraints,
207
+ build_constraint_feature_enabled=build_constraint_feature_enabled,
208
+ )
209
+
135
210
  return RequirementPreparer(
136
211
  build_dir=temp_build_dir_path,
137
212
  src_dir=options.src_dir,
138
213
  download_dir=download_dir,
139
214
  build_isolation=options.build_isolation,
140
- build_isolation_installer=SubprocessBuildEnvironmentInstaller(finder),
215
+ build_isolation_installer=env_installer,
141
216
  check_build_deps=options.check_build_deps,
142
217
  build_tracker=build_tracker,
143
218
  session=session,
@@ -148,7 +223,6 @@ class RequirementCommand(IndexGroupCommand):
148
223
  lazy_wheel=lazy_wheel,
149
224
  verbosity=verbosity,
150
225
  legacy_resolver=legacy_resolver,
151
- resume_retries=options.resume_retries,
152
226
  )
153
227
 
154
228
  @classmethod
@@ -163,7 +237,6 @@ class RequirementCommand(IndexGroupCommand):
163
237
  ignore_requires_python: bool = False,
164
238
  force_reinstall: bool = False,
165
239
  upgrade_strategy: str = "to-satisfy-only",
166
- use_pep517: bool | None = None,
167
240
  py_version_info: tuple[int, ...] | None = None,
168
241
  ) -> BaseResolver:
169
242
  """
@@ -172,7 +245,6 @@ class RequirementCommand(IndexGroupCommand):
172
245
  make_install_req = partial(
173
246
  install_req_from_req_string,
174
247
  isolated=options.isolated_mode,
175
- use_pep517=use_pep517,
176
248
  )
177
249
  resolver_variant = cls.determine_resolver_variant(options)
178
250
  # The long import name and duplicated invocation is needed to convince
@@ -221,27 +293,20 @@ class RequirementCommand(IndexGroupCommand):
221
293
  Parse command-line arguments into the corresponding requirements.
222
294
  """
223
295
  requirements: list[InstallRequirement] = []
224
- for filename in options.constraints:
225
- for parsed_req in parse_requirements(
226
- filename,
227
- constraint=True,
228
- finder=finder,
229
- options=options,
230
- session=session,
231
- ):
232
- req_to_add = install_req_from_parsed_requirement(
233
- parsed_req,
234
- isolated=options.isolated_mode,
235
- user_supplied=False,
236
- )
237
- requirements.append(req_to_add)
296
+
297
+ if not should_ignore_regular_constraints(options):
298
+ constraints = parse_constraint_files(
299
+ options.constraints, finder, options, session
300
+ )
301
+ requirements.extend(constraints)
238
302
 
239
303
  for req in args:
304
+ if not req.strip():
305
+ continue
240
306
  req_to_add = install_req_from_line(
241
307
  req,
242
308
  comes_from=None,
243
309
  isolated=options.isolated_mode,
244
- use_pep517=options.use_pep517,
245
310
  user_supplied=True,
246
311
  config_settings=getattr(options, "config_settings", None),
247
312
  )
@@ -252,7 +317,6 @@ class RequirementCommand(IndexGroupCommand):
252
317
  req_to_add = install_req_from_req_string(
253
318
  req,
254
319
  isolated=options.isolated_mode,
255
- use_pep517=options.use_pep517,
256
320
  user_supplied=True,
257
321
  )
258
322
  requirements.append(req_to_add)
@@ -262,7 +326,6 @@ class RequirementCommand(IndexGroupCommand):
262
326
  req,
263
327
  user_supplied=True,
264
328
  isolated=options.isolated_mode,
265
- use_pep517=options.use_pep517,
266
329
  config_settings=getattr(options, "config_settings", None),
267
330
  )
268
331
  requirements.append(req_to_add)
@@ -275,7 +338,6 @@ class RequirementCommand(IndexGroupCommand):
275
338
  req_to_add = install_req_from_parsed_requirement(
276
339
  parsed_req,
277
340
  isolated=options.isolated_mode,
278
- use_pep517=options.use_pep517,
279
341
  user_supplied=True,
280
342
  config_settings=(
281
343
  parsed_req.options.get("config_settings")
@@ -285,6 +347,38 @@ class RequirementCommand(IndexGroupCommand):
285
347
  )
286
348
  requirements.append(req_to_add)
287
349
 
350
+ if options.requirements_from_scripts:
351
+ if len(options.requirements_from_scripts) > 1:
352
+ raise CommandError("--requirements-from-script can only be given once")
353
+
354
+ script = options.requirements_from_scripts[0]
355
+ try:
356
+ script_metadata = pep723_metadata(script)
357
+ except PEP723Exception as exc:
358
+ raise CommandError(exc.msg)
359
+
360
+ script_requires_python = script_metadata.get("requires-python", "")
361
+
362
+ if script_requires_python and not options.ignore_requires_python:
363
+ target_python = make_target_python(options)
364
+
365
+ if not check_requires_python(
366
+ requires_python=script_requires_python,
367
+ version_info=target_python.py_version_info,
368
+ ):
369
+ raise UnsupportedPythonVersion(
370
+ f"Script {script!r} requires a different Python: "
371
+ f"{target_python.py_version} not in {script_requires_python!r}"
372
+ )
373
+
374
+ for req in script_metadata.get("dependencies", []):
375
+ req_to_add = install_req_from_req_string(
376
+ req,
377
+ isolated=options.isolated_mode,
378
+ user_supplied=True,
379
+ )
380
+ requirements.append(req_to_add)
381
+
288
382
  # If any requirement has hash options, enable hash checking.
289
383
  if any(req.has_hash_options for req in requirements):
290
384
  options.require_hashes = True
@@ -294,6 +388,7 @@ class RequirementCommand(IndexGroupCommand):
294
388
  or options.editables
295
389
  or options.requirements
296
390
  or options.dependency_groups
391
+ or options.requirements_from_scripts
297
392
  ):
298
393
  opts = {"name": self.name}
299
394
  if options.find_links:
@@ -339,7 +434,7 @@ class RequirementCommand(IndexGroupCommand):
339
434
  selection_prefs = SelectionPreferences(
340
435
  allow_yanked=True,
341
436
  format_control=options.format_control,
342
- allow_all_prereleases=options.pre,
437
+ release_control=options.release_control,
343
438
  prefer_binary=options.prefer_binary,
344
439
  ignore_requires_python=ignore_requires_python,
345
440
  )
@@ -348,4 +443,5 @@ class RequirementCommand(IndexGroupCommand):
348
443
  link_collector=link_collector,
349
444
  selection_prefs=selection_prefs,
350
445
  target_python=target_python,
446
+ uploaded_prior_to=options.uploaded_prior_to,
351
447
  )
@@ -189,7 +189,31 @@ class CacheCommand(Command):
189
189
  bytes_removed += os.stat(filename).st_size
190
190
  os.unlink(filename)
191
191
  logger.verbose("Removed %s", filename)
192
+
193
+ http_dirs = filesystem.subdirs_without_files(self._cache_dir(options, "http"))
194
+ wheel_dirs = filesystem.subdirs_without_wheels(
195
+ self._cache_dir(options, "wheels")
196
+ )
197
+ dirs = [*http_dirs, *wheel_dirs]
198
+
199
+ for subdir in dirs:
200
+ try:
201
+ for file in subdir.iterdir():
202
+ file.unlink(missing_ok=True)
203
+ subdir.rmdir()
204
+ except FileNotFoundError:
205
+ # If the directory is already gone, that's fine.
206
+ pass
207
+ logger.verbose("Removed %s", subdir)
208
+
209
+ # selfcheck.json is no longer used by pip.
210
+ selfcheck_json = self._cache_dir(options, "selfcheck.json")
211
+ if os.path.isfile(selfcheck_json):
212
+ os.remove(selfcheck_json)
213
+ logger.verbose("Removed legacy selfcheck.json file")
214
+
192
215
  logger.info("Files removed: %s (%s)", len(files), format_size(bytes_removed))
216
+ logger.info("Directories removed: %s", len(dirs))
193
217
 
194
218
  def purge_cache(self, options: Values, args: list[str]) -> None:
195
219
  if args:
@@ -14,9 +14,10 @@ COMPLETION_SCRIPTS = {
14
14
  "bash": """
15
15
  _pip_completion()
16
16
  {{
17
+ local IFS=$' \\t\\n'
17
18
  COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\
18
19
  COMP_CWORD=$COMP_CWORD \\
19
- PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) )
20
+ PIP_AUTO_COMPLETE=1 "$1" 2>/dev/null ) )
20
21
  }}
21
22
  complete -o default -F _pip_completion {prog}
22
23
  """,
@@ -7,7 +7,6 @@ from pip._internal.cli.cmdoptions import make_target_python
7
7
  from pip._internal.cli.req_command import RequirementCommand, with_cleanup
8
8
  from pip._internal.cli.status_codes import SUCCESS
9
9
  from pip._internal.operations.build.build_tracker import get_build_tracker
10
- from pip._internal.req.req_install import check_legacy_setup_py_options
11
10
  from pip._internal.utils.misc import ensure_dir, normalize_path, write_output
12
11
  from pip._internal.utils.temp_dir import TempDirectory
13
12
 
@@ -36,19 +35,15 @@ class DownloadCommand(RequirementCommand):
36
35
 
37
36
  def add_options(self) -> None:
38
37
  self.cmd_opts.add_option(cmdoptions.constraints())
38
+ self.cmd_opts.add_option(cmdoptions.build_constraints())
39
39
  self.cmd_opts.add_option(cmdoptions.requirements())
40
+ self.cmd_opts.add_option(cmdoptions.requirements_from_scripts())
40
41
  self.cmd_opts.add_option(cmdoptions.no_deps())
41
- self.cmd_opts.add_option(cmdoptions.global_options())
42
- self.cmd_opts.add_option(cmdoptions.no_binary())
43
- self.cmd_opts.add_option(cmdoptions.only_binary())
44
- self.cmd_opts.add_option(cmdoptions.prefer_binary())
45
42
  self.cmd_opts.add_option(cmdoptions.src())
46
- self.cmd_opts.add_option(cmdoptions.pre())
47
43
  self.cmd_opts.add_option(cmdoptions.require_hashes())
48
44
  self.cmd_opts.add_option(cmdoptions.progress_bar())
49
45
  self.cmd_opts.add_option(cmdoptions.no_build_isolation())
50
46
  self.cmd_opts.add_option(cmdoptions.use_pep517())
51
- self.cmd_opts.add_option(cmdoptions.no_use_pep517())
52
47
  self.cmd_opts.add_option(cmdoptions.check_build_deps())
53
48
  self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
54
49
 
@@ -70,7 +65,13 @@ class DownloadCommand(RequirementCommand):
70
65
  self.parser,
71
66
  )
72
67
 
68
+ selection_opts = cmdoptions.make_option_group(
69
+ cmdoptions.package_selection_group,
70
+ self.parser,
71
+ )
72
+
73
73
  self.parser.insert_option_group(0, index_opts)
74
+ self.parser.insert_option_group(0, selection_opts)
74
75
  self.parser.insert_option_group(0, self.cmd_opts)
75
76
 
76
77
  @with_cleanup
@@ -81,6 +82,8 @@ class DownloadCommand(RequirementCommand):
81
82
  options.editables = []
82
83
 
83
84
  cmdoptions.check_dist_restriction(options)
85
+ cmdoptions.check_build_constraints(options)
86
+ cmdoptions.check_release_control_exclusive(options)
84
87
 
85
88
  options.download_dir = normalize_path(options.download_dir)
86
89
  ensure_dir(options.download_dir)
@@ -104,7 +107,6 @@ class DownloadCommand(RequirementCommand):
104
107
  )
105
108
 
106
109
  reqs = self.get_requirements(args, options, finder, session)
107
- check_legacy_setup_py_options(options, reqs)
108
110
 
109
111
  preparer = self.make_requirement_preparer(
110
112
  temp_build_dir=directory,
@@ -122,7 +124,6 @@ class DownloadCommand(RequirementCommand):
122
124
  finder=finder,
123
125
  options=options,
124
126
  ignore_requires_python=options.ignore_requires_python,
125
- use_pep517=options.use_pep517,
126
127
  py_version_info=options.python_version,
127
128
  )
128
129
 
@@ -130,6 +131,8 @@ class DownloadCommand(RequirementCommand):
130
131
 
131
132
  requirement_set = resolver.resolve(reqs, check_supported_wheels=True)
132
133
 
134
+ preparer.prepare_linked_requirements_more(requirement_set.requirements.values())
135
+
133
136
  downloaded: list[str] = []
134
137
  for req in requirement_set.requirements.values():
135
138
  if req.satisfied_by is None:
@@ -137,8 +140,6 @@ class DownloadCommand(RequirementCommand):
137
140
  preparer.save_linked_requirement(req)
138
141
  downloaded.append(req.name)
139
142
 
140
- preparer.prepare_linked_requirements_more(requirement_set.requirements.values())
141
-
142
143
  if downloaded:
143
144
  write_output("Successfully downloaded %s", " ".join(downloaded))
144
145
 
@@ -6,6 +6,7 @@ from collections.abc import Iterable
6
6
  from optparse import Values
7
7
  from typing import Any, Callable
8
8
 
9
+ from pip._vendor.packaging.utils import canonicalize_name
9
10
  from pip._vendor.packaging.version import Version
10
11
 
11
12
  from pip._internal.cli import cmdoptions
@@ -40,17 +41,20 @@ class IndexCommand(IndexGroupCommand):
40
41
  cmdoptions.add_target_python_options(self.cmd_opts)
41
42
 
42
43
  self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
43
- self.cmd_opts.add_option(cmdoptions.pre())
44
44
  self.cmd_opts.add_option(cmdoptions.json())
45
- self.cmd_opts.add_option(cmdoptions.no_binary())
46
- self.cmd_opts.add_option(cmdoptions.only_binary())
47
45
 
48
46
  index_opts = cmdoptions.make_option_group(
49
47
  cmdoptions.index_group,
50
48
  self.parser,
51
49
  )
52
50
 
51
+ selection_opts = cmdoptions.make_option_group(
52
+ cmdoptions.package_selection_group,
53
+ self.parser,
54
+ )
55
+
53
56
  self.parser.insert_option_group(0, index_opts)
57
+ self.parser.insert_option_group(0, selection_opts)
54
58
  self.parser.insert_option_group(0, self.cmd_opts)
55
59
 
56
60
  def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]:
@@ -59,6 +63,8 @@ class IndexCommand(IndexGroupCommand):
59
63
  }
60
64
 
61
65
  def run(self, options: Values, args: list[str]) -> int:
66
+ cmdoptions.check_release_control_exclusive(options)
67
+
62
68
  handler_map = self.handler_map()
63
69
 
64
70
  # Determine action
@@ -95,7 +101,8 @@ class IndexCommand(IndexGroupCommand):
95
101
  # Pass allow_yanked=False to ignore yanked versions.
96
102
  selection_prefs = SelectionPreferences(
97
103
  allow_yanked=False,
98
- allow_all_prereleases=options.pre,
104
+ release_control=options.release_control,
105
+ format_control=options.format_control,
99
106
  ignore_requires_python=ignore_requires_python,
100
107
  )
101
108
 
@@ -103,6 +110,7 @@ class IndexCommand(IndexGroupCommand):
103
110
  link_collector=link_collector,
104
111
  selection_prefs=selection_prefs,
105
112
  target_python=target_python,
113
+ uploaded_prior_to=options.uploaded_prior_to,
106
114
  )
107
115
 
108
116
  def get_available_package_versions(self, options: Values, args: list[Any]) -> None:
@@ -124,8 +132,7 @@ class IndexCommand(IndexGroupCommand):
124
132
  candidate.version for candidate in finder.find_all_candidates(query)
125
133
  )
126
134
 
127
- if not options.pre:
128
- # Remove prereleases
135
+ if self.should_exclude_prerelease(options, canonicalize_name(query)):
129
136
  versions = (
130
137
  version for version in versions if not version.is_prerelease
131
138
  )