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.
- pip/__init__.py +3 -3
- pip/_internal/__init__.py +2 -2
- pip/_internal/build_env.py +186 -94
- pip/_internal/cache.py +17 -15
- pip/_internal/cli/autocompletion.py +13 -4
- pip/_internal/cli/base_command.py +18 -7
- pip/_internal/cli/cmdoptions.py +57 -80
- pip/_internal/cli/command_context.py +4 -3
- pip/_internal/cli/index_command.py +11 -9
- pip/_internal/cli/main.py +3 -2
- pip/_internal/cli/main_parser.py +4 -3
- pip/_internal/cli/parser.py +24 -20
- pip/_internal/cli/progress_bars.py +19 -12
- pip/_internal/cli/req_command.py +57 -33
- pip/_internal/cli/spinners.py +81 -5
- pip/_internal/commands/__init__.py +5 -3
- pip/_internal/commands/cache.py +18 -15
- pip/_internal/commands/check.py +1 -2
- pip/_internal/commands/completion.py +1 -2
- pip/_internal/commands/configuration.py +26 -18
- pip/_internal/commands/debug.py +8 -6
- pip/_internal/commands/download.py +6 -10
- pip/_internal/commands/freeze.py +2 -3
- pip/_internal/commands/hash.py +1 -2
- pip/_internal/commands/help.py +1 -2
- pip/_internal/commands/index.py +15 -9
- pip/_internal/commands/inspect.py +4 -4
- pip/_internal/commands/install.py +63 -53
- pip/_internal/commands/list.py +35 -26
- pip/_internal/commands/lock.py +4 -8
- pip/_internal/commands/search.py +14 -12
- pip/_internal/commands/show.py +14 -11
- pip/_internal/commands/uninstall.py +1 -2
- pip/_internal/commands/wheel.py +7 -13
- pip/_internal/configuration.py +40 -27
- pip/_internal/distributions/base.py +6 -4
- pip/_internal/distributions/installed.py +8 -4
- pip/_internal/distributions/sdist.py +33 -27
- pip/_internal/distributions/wheel.py +6 -4
- pip/_internal/exceptions.py +78 -42
- pip/_internal/index/collector.py +24 -29
- pip/_internal/index/package_finder.py +73 -64
- pip/_internal/index/sources.py +17 -14
- pip/_internal/locations/__init__.py +18 -16
- pip/_internal/locations/_distutils.py +12 -11
- pip/_internal/locations/_sysconfig.py +5 -4
- pip/_internal/locations/base.py +4 -3
- pip/_internal/main.py +2 -2
- pip/_internal/metadata/__init__.py +14 -7
- pip/_internal/metadata/_json.py +5 -4
- pip/_internal/metadata/base.py +22 -27
- pip/_internal/metadata/importlib/_compat.py +6 -4
- pip/_internal/metadata/importlib/_dists.py +20 -19
- pip/_internal/metadata/importlib/_envs.py +9 -6
- pip/_internal/metadata/pkg_resources.py +11 -14
- pip/_internal/models/direct_url.py +24 -21
- pip/_internal/models/format_control.py +5 -5
- pip/_internal/models/installation_report.py +4 -3
- pip/_internal/models/link.py +39 -34
- pip/_internal/models/pylock.py +27 -22
- pip/_internal/models/search_scope.py +6 -7
- pip/_internal/models/selection_prefs.py +3 -3
- pip/_internal/models/target_python.py +10 -9
- pip/_internal/models/wheel.py +12 -71
- pip/_internal/network/auth.py +20 -22
- pip/_internal/network/cache.py +28 -17
- pip/_internal/network/download.py +169 -141
- pip/_internal/network/lazy_wheel.py +15 -10
- pip/_internal/network/session.py +32 -27
- pip/_internal/network/utils.py +2 -2
- pip/_internal/network/xmlrpc.py +2 -2
- pip/_internal/operations/build/build_tracker.py +10 -8
- pip/_internal/operations/build/wheel.py +7 -6
- pip/_internal/operations/build/wheel_editable.py +7 -6
- pip/_internal/operations/check.py +21 -26
- pip/_internal/operations/freeze.py +12 -9
- pip/_internal/operations/install/wheel.py +49 -41
- pip/_internal/operations/prepare.py +42 -31
- pip/_internal/pyproject.py +7 -69
- pip/_internal/req/__init__.py +12 -12
- pip/_internal/req/constructors.py +68 -62
- pip/_internal/req/req_dependency_group.py +7 -11
- pip/_internal/req/req_file.py +32 -36
- pip/_internal/req/req_install.py +64 -170
- pip/_internal/req/req_set.py +4 -5
- pip/_internal/req/req_uninstall.py +20 -17
- pip/_internal/resolution/base.py +3 -3
- pip/_internal/resolution/legacy/resolver.py +21 -20
- pip/_internal/resolution/resolvelib/base.py +16 -13
- pip/_internal/resolution/resolvelib/candidates.py +49 -37
- pip/_internal/resolution/resolvelib/factory.py +72 -50
- pip/_internal/resolution/resolvelib/found_candidates.py +11 -9
- pip/_internal/resolution/resolvelib/provider.py +24 -20
- pip/_internal/resolution/resolvelib/reporter.py +26 -11
- pip/_internal/resolution/resolvelib/requirements.py +8 -6
- pip/_internal/resolution/resolvelib/resolver.py +41 -29
- pip/_internal/self_outdated_check.py +19 -9
- pip/_internal/utils/appdirs.py +1 -2
- pip/_internal/utils/compat.py +7 -1
- pip/_internal/utils/compatibility_tags.py +17 -16
- pip/_internal/utils/deprecation.py +11 -9
- pip/_internal/utils/direct_url_helpers.py +2 -2
- pip/_internal/utils/egg_link.py +6 -5
- pip/_internal/utils/entrypoints.py +3 -2
- pip/_internal/utils/filesystem.py +20 -5
- pip/_internal/utils/filetypes.py +4 -6
- pip/_internal/utils/glibc.py +6 -5
- pip/_internal/utils/hashes.py +9 -6
- pip/_internal/utils/logging.py +8 -5
- pip/_internal/utils/misc.py +37 -45
- pip/_internal/utils/packaging.py +3 -2
- pip/_internal/utils/retry.py +7 -4
- pip/_internal/utils/subprocess.py +20 -17
- pip/_internal/utils/temp_dir.py +10 -12
- pip/_internal/utils/unpacking.py +31 -4
- pip/_internal/utils/urls.py +1 -1
- pip/_internal/utils/virtualenv.py +3 -2
- pip/_internal/utils/wheel.py +3 -4
- pip/_internal/vcs/bazaar.py +26 -8
- pip/_internal/vcs/git.py +59 -24
- pip/_internal/vcs/mercurial.py +34 -11
- pip/_internal/vcs/subversion.py +27 -16
- pip/_internal/vcs/versioncontrol.py +56 -51
- pip/_internal/wheel_builder.py +30 -101
- pip/_vendor/README.rst +180 -0
- pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip/_vendor/cachecontrol/__init__.py +1 -1
- pip/_vendor/certifi/LICENSE +20 -0
- pip/_vendor/certifi/__init__.py +1 -1
- pip/_vendor/certifi/cacert.pem +164 -261
- pip/_vendor/certifi/core.py +1 -32
- pip/_vendor/dependency_groups/LICENSE.txt +9 -0
- pip/_vendor/distlib/LICENSE.txt +284 -0
- pip/_vendor/distlib/__init__.py +2 -2
- pip/_vendor/distlib/scripts.py +1 -1
- pip/_vendor/distro/LICENSE +202 -0
- pip/_vendor/idna/LICENSE.md +31 -0
- pip/_vendor/msgpack/COPYING +14 -0
- pip/_vendor/msgpack/__init__.py +2 -2
- pip/_vendor/packaging/LICENSE +3 -0
- pip/_vendor/packaging/LICENSE.APACHE +177 -0
- pip/_vendor/packaging/LICENSE.BSD +23 -0
- pip/_vendor/pkg_resources/LICENSE +17 -0
- pip/_vendor/pkg_resources/__init__.py +1 -1
- pip/_vendor/platformdirs/LICENSE +21 -0
- pip/_vendor/platformdirs/api.py +1 -1
- pip/_vendor/platformdirs/macos.py +10 -8
- pip/_vendor/platformdirs/version.py +16 -3
- pip/_vendor/pygments/LICENSE +25 -0
- pip/_vendor/pygments/__init__.py +1 -1
- pip/_vendor/pyproject_hooks/LICENSE +21 -0
- pip/_vendor/requests/LICENSE +175 -0
- pip/_vendor/requests/__version__.py +2 -2
- pip/_vendor/requests/adapters.py +17 -40
- pip/_vendor/requests/compat.py +12 -0
- pip/_vendor/requests/models.py +3 -1
- pip/_vendor/requests/sessions.py +1 -1
- pip/_vendor/requests/utils.py +6 -16
- pip/_vendor/resolvelib/LICENSE +13 -0
- pip/_vendor/resolvelib/__init__.py +3 -3
- pip/_vendor/resolvelib/reporters.py +1 -1
- pip/_vendor/resolvelib/resolvers/__init__.py +4 -4
- pip/_vendor/resolvelib/resolvers/abstract.py +3 -3
- pip/_vendor/resolvelib/resolvers/resolution.py +96 -10
- pip/_vendor/rich/LICENSE +19 -0
- pip/_vendor/rich/__main__.py +12 -40
- pip/_vendor/rich/_inspect.py +1 -1
- pip/_vendor/rich/_ratio.py +1 -7
- pip/_vendor/rich/align.py +1 -7
- pip/_vendor/rich/box.py +1 -7
- pip/_vendor/rich/console.py +25 -20
- pip/_vendor/rich/control.py +1 -7
- pip/_vendor/rich/diagnose.py +1 -0
- pip/_vendor/rich/emoji.py +1 -6
- pip/_vendor/rich/live.py +32 -7
- pip/_vendor/rich/live_render.py +1 -7
- pip/_vendor/rich/logging.py +1 -1
- pip/_vendor/rich/panel.py +3 -4
- pip/_vendor/rich/progress.py +15 -15
- pip/_vendor/rich/spinner.py +7 -13
- pip/_vendor/rich/style.py +7 -11
- pip/_vendor/rich/syntax.py +24 -5
- pip/_vendor/rich/traceback.py +32 -17
- pip/_vendor/tomli/LICENSE +21 -0
- pip/_vendor/tomli/__init__.py +1 -1
- pip/_vendor/tomli/_parser.py +28 -21
- pip/_vendor/tomli/_re.py +8 -5
- pip/_vendor/tomli_w/LICENSE +21 -0
- pip/_vendor/truststore/LICENSE +21 -0
- pip/_vendor/truststore/__init__.py +1 -1
- pip/_vendor/truststore/_api.py +15 -7
- pip/_vendor/truststore/_openssl.py +3 -1
- pip/_vendor/urllib3/LICENSE.txt +21 -0
- pip/_vendor/vendor.txt +11 -12
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/METADATA +32 -11
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/RECORD +221 -192
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/WHEEL +1 -2
- pip-25.3.dist-info/entry_points.txt +4 -0
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/licenses/AUTHORS.txt +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/certifi/LICENSE +20 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +9 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt +284 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/distro/LICENSE +202 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md +31 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/msgpack/COPYING +14 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE +3 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +177 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD +23 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE +17 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/pygments/LICENSE +25 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/requests/LICENSE +175 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE +13 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/rich/LICENSE +19 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/tomli/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/truststore/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt +21 -0
- pip/_internal/operations/build/metadata_legacy.py +0 -73
- pip/_internal/operations/build/wheel_legacy.py +0 -118
- pip/_internal/operations/install/editable_legacy.py +0 -46
- pip/_internal/utils/setuptools_build.py +0 -147
- pip/_vendor/distlib/database.py +0 -1329
- pip/_vendor/distlib/index.py +0 -508
- pip/_vendor/distlib/locators.py +0 -1295
- pip/_vendor/distlib/manifest.py +0 -384
- pip/_vendor/distlib/markers.py +0 -162
- pip/_vendor/distlib/metadata.py +0 -1031
- pip/_vendor/distlib/version.py +0 -750
- pip/_vendor/distlib/wheel.py +0 -1100
- pip/_vendor/typing_extensions.py +0 -4584
- pip-25.1.1.dist-info/entry_points.txt +0 -3
- pip-25.1.1.dist-info/top_level.txt +0 -1
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/licenses/LICENSE.txt +0 -0
pip/_internal/cli/cmdoptions.py
CHANGED
|
@@ -9,8 +9,8 @@ pass on state. To be consistent, all options will follow this design.
|
|
|
9
9
|
|
|
10
10
|
# The following comment should be removed at some point in the future.
|
|
11
11
|
# mypy: strict-optional=False
|
|
12
|
+
from __future__ import annotations
|
|
12
13
|
|
|
13
|
-
import importlib.util
|
|
14
14
|
import logging
|
|
15
15
|
import os
|
|
16
16
|
import pathlib
|
|
@@ -18,7 +18,7 @@ import textwrap
|
|
|
18
18
|
from functools import partial
|
|
19
19
|
from optparse import SUPPRESS_HELP, Option, OptionGroup, OptionParser, Values
|
|
20
20
|
from textwrap import dedent
|
|
21
|
-
from typing import Any, Callable
|
|
21
|
+
from typing import Any, Callable
|
|
22
22
|
|
|
23
23
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
24
24
|
|
|
@@ -48,7 +48,7 @@ def raise_option_error(parser: OptionParser, option: Option, msg: str) -> None:
|
|
|
48
48
|
parser.error(msg)
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
def make_option_group(group:
|
|
51
|
+
def make_option_group(group: dict[str, Any], parser: ConfigOptionParser) -> OptionGroup:
|
|
52
52
|
"""
|
|
53
53
|
Return an OptionGroup object
|
|
54
54
|
group -- assumed to be dict with 'name' and 'options' keys
|
|
@@ -100,6 +100,29 @@ def check_dist_restriction(options: Values, check_target: bool = False) -> None:
|
|
|
100
100
|
)
|
|
101
101
|
|
|
102
102
|
|
|
103
|
+
def check_build_constraints(options: Values) -> None:
|
|
104
|
+
"""Function for validating build constraints options.
|
|
105
|
+
|
|
106
|
+
:param options: The OptionParser options.
|
|
107
|
+
"""
|
|
108
|
+
if hasattr(options, "build_constraints") and options.build_constraints:
|
|
109
|
+
if not options.build_isolation:
|
|
110
|
+
raise CommandError(
|
|
111
|
+
"--build-constraint cannot be used with --no-build-isolation."
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Import here to avoid circular imports
|
|
115
|
+
from pip._internal.network.session import PipSession
|
|
116
|
+
from pip._internal.req.req_file import get_file_content
|
|
117
|
+
|
|
118
|
+
# Eagerly check build constraints file contents
|
|
119
|
+
# is valid so that we don't fail in when trying
|
|
120
|
+
# to check constraints in isolated build process
|
|
121
|
+
with PipSession() as session:
|
|
122
|
+
for constraint_file in options.build_constraints:
|
|
123
|
+
get_file_content(constraint_file, session)
|
|
124
|
+
|
|
125
|
+
|
|
103
126
|
def _path_option_check(option: Option, opt: str, value: str) -> str:
|
|
104
127
|
return os.path.expanduser(value)
|
|
105
128
|
|
|
@@ -160,8 +183,7 @@ require_virtualenv: Callable[..., Option] = partial(
|
|
|
160
183
|
action="store_true",
|
|
161
184
|
default=False,
|
|
162
185
|
help=(
|
|
163
|
-
"Allow pip to only run in a virtual environment; "
|
|
164
|
-
"exit with an error otherwise."
|
|
186
|
+
"Allow pip to only run in a virtual environment; exit with an error otherwise."
|
|
165
187
|
),
|
|
166
188
|
)
|
|
167
189
|
|
|
@@ -227,9 +249,13 @@ progress_bar: Callable[..., Option] = partial(
|
|
|
227
249
|
"--progress-bar",
|
|
228
250
|
dest="progress_bar",
|
|
229
251
|
type="choice",
|
|
230
|
-
choices=["on", "off", "raw"],
|
|
231
|
-
default="
|
|
232
|
-
help=
|
|
252
|
+
choices=["auto", "on", "off", "raw"],
|
|
253
|
+
default="auto",
|
|
254
|
+
help=(
|
|
255
|
+
"Specify whether the progress bar should be used. In 'auto'"
|
|
256
|
+
" mode, --quiet will suppress all progress bars."
|
|
257
|
+
" [auto, on, off, raw] (default: auto)"
|
|
258
|
+
),
|
|
233
259
|
)
|
|
234
260
|
|
|
235
261
|
log: Callable[..., Option] = partial(
|
|
@@ -289,7 +315,7 @@ resume_retries: Callable[..., Option] = partial(
|
|
|
289
315
|
"--resume-retries",
|
|
290
316
|
dest="resume_retries",
|
|
291
317
|
type="int",
|
|
292
|
-
default=
|
|
318
|
+
default=5,
|
|
293
319
|
help="Maximum attempts to resume or restart an incomplete download. "
|
|
294
320
|
"(default: %default)",
|
|
295
321
|
)
|
|
@@ -425,6 +451,21 @@ def constraints() -> Option:
|
|
|
425
451
|
)
|
|
426
452
|
|
|
427
453
|
|
|
454
|
+
def build_constraints() -> Option:
|
|
455
|
+
return Option(
|
|
456
|
+
"--build-constraint",
|
|
457
|
+
dest="build_constraints",
|
|
458
|
+
action="append",
|
|
459
|
+
type="str",
|
|
460
|
+
default=[],
|
|
461
|
+
metavar="file",
|
|
462
|
+
help=(
|
|
463
|
+
"Constrain build dependencies using the given constraints file. "
|
|
464
|
+
"This option can be used multiple times."
|
|
465
|
+
),
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
|
|
428
469
|
def requirements() -> Option:
|
|
429
470
|
return Option(
|
|
430
471
|
"-r",
|
|
@@ -555,7 +596,7 @@ platforms: Callable[..., Option] = partial(
|
|
|
555
596
|
|
|
556
597
|
|
|
557
598
|
# This was made a separate function for unit-testing purposes.
|
|
558
|
-
def _convert_python_version(value: str) ->
|
|
599
|
+
def _convert_python_version(value: str) -> tuple[tuple[int, ...], str | None]:
|
|
559
600
|
"""
|
|
560
601
|
Convert a version string like "3", "37", or "3.7.3" into a tuple of ints.
|
|
561
602
|
|
|
@@ -808,62 +849,16 @@ check_build_deps: Callable[..., Option] = partial(
|
|
|
808
849
|
dest="check_build_deps",
|
|
809
850
|
action="store_true",
|
|
810
851
|
default=False,
|
|
811
|
-
help="Check the build dependencies
|
|
852
|
+
help="Check the build dependencies.",
|
|
812
853
|
)
|
|
813
854
|
|
|
814
855
|
|
|
815
|
-
def _handle_no_use_pep517(
|
|
816
|
-
option: Option, opt: str, value: str, parser: OptionParser
|
|
817
|
-
) -> None:
|
|
818
|
-
"""
|
|
819
|
-
Process a value provided for the --no-use-pep517 option.
|
|
820
|
-
|
|
821
|
-
This is an optparse.Option callback for the no_use_pep517 option.
|
|
822
|
-
"""
|
|
823
|
-
# Since --no-use-pep517 doesn't accept arguments, the value argument
|
|
824
|
-
# will be None if --no-use-pep517 is passed via the command-line.
|
|
825
|
-
# However, the value can be non-None if the option is triggered e.g.
|
|
826
|
-
# by an environment variable, for example "PIP_NO_USE_PEP517=true".
|
|
827
|
-
if value is not None:
|
|
828
|
-
msg = """A value was passed for --no-use-pep517,
|
|
829
|
-
probably using either the PIP_NO_USE_PEP517 environment variable
|
|
830
|
-
or the "no-use-pep517" config file option. Use an appropriate value
|
|
831
|
-
of the PIP_USE_PEP517 environment variable or the "use-pep517"
|
|
832
|
-
config file option instead.
|
|
833
|
-
"""
|
|
834
|
-
raise_option_error(parser, option=option, msg=msg)
|
|
835
|
-
|
|
836
|
-
# If user doesn't wish to use pep517, we check if setuptools is installed
|
|
837
|
-
# and raise error if it is not.
|
|
838
|
-
packages = ("setuptools",)
|
|
839
|
-
if not all(importlib.util.find_spec(package) for package in packages):
|
|
840
|
-
msg = (
|
|
841
|
-
f"It is not possible to use --no-use-pep517 "
|
|
842
|
-
f"without {' and '.join(packages)} installed."
|
|
843
|
-
)
|
|
844
|
-
raise_option_error(parser, option=option, msg=msg)
|
|
845
|
-
|
|
846
|
-
# Otherwise, --no-use-pep517 was passed via the command-line.
|
|
847
|
-
parser.values.use_pep517 = False
|
|
848
|
-
|
|
849
|
-
|
|
850
856
|
use_pep517: Any = partial(
|
|
851
857
|
Option,
|
|
852
858
|
"--use-pep517",
|
|
853
859
|
dest="use_pep517",
|
|
854
860
|
action="store_true",
|
|
855
|
-
default=
|
|
856
|
-
help="Use PEP 517 for building source distributions "
|
|
857
|
-
"(use --no-use-pep517 to force legacy behaviour).",
|
|
858
|
-
)
|
|
859
|
-
|
|
860
|
-
no_use_pep517: Any = partial(
|
|
861
|
-
Option,
|
|
862
|
-
"--no-use-pep517",
|
|
863
|
-
dest="use_pep517",
|
|
864
|
-
action="callback",
|
|
865
|
-
callback=_handle_no_use_pep517,
|
|
866
|
-
default=None,
|
|
861
|
+
default=True,
|
|
867
862
|
help=SUPPRESS_HELP,
|
|
868
863
|
)
|
|
869
864
|
|
|
@@ -896,30 +891,11 @@ config_settings: Callable[..., Option] = partial(
|
|
|
896
891
|
action="callback",
|
|
897
892
|
callback=_handle_config_settings,
|
|
898
893
|
metavar="settings",
|
|
899
|
-
help="Configuration settings to be passed to the
|
|
894
|
+
help="Configuration settings to be passed to the build backend. "
|
|
900
895
|
"Settings take the form KEY=VALUE. Use multiple --config-settings options "
|
|
901
896
|
"to pass multiple keys to the backend.",
|
|
902
897
|
)
|
|
903
898
|
|
|
904
|
-
build_options: Callable[..., Option] = partial(
|
|
905
|
-
Option,
|
|
906
|
-
"--build-option",
|
|
907
|
-
dest="build_options",
|
|
908
|
-
metavar="options",
|
|
909
|
-
action="append",
|
|
910
|
-
help="Extra arguments to be supplied to 'setup.py bdist_wheel'.",
|
|
911
|
-
)
|
|
912
|
-
|
|
913
|
-
global_options: Callable[..., Option] = partial(
|
|
914
|
-
Option,
|
|
915
|
-
"--global-option",
|
|
916
|
-
dest="global_options",
|
|
917
|
-
action="append",
|
|
918
|
-
metavar="options",
|
|
919
|
-
help="Extra global options to be supplied to the setup.py "
|
|
920
|
-
"call before the install or bdist_wheel command.",
|
|
921
|
-
)
|
|
922
|
-
|
|
923
899
|
no_clean: Callable[..., Option] = partial(
|
|
924
900
|
Option,
|
|
925
901
|
"--no-clean",
|
|
@@ -1067,6 +1043,7 @@ use_new_feature: Callable[..., Option] = partial(
|
|
|
1067
1043
|
default=[],
|
|
1068
1044
|
choices=[
|
|
1069
1045
|
"fast-deps",
|
|
1046
|
+
"build-constraint",
|
|
1070
1047
|
]
|
|
1071
1048
|
+ ALWAYS_ENABLED_FEATURES,
|
|
1072
1049
|
help="Enable new functionality, that may be backward incompatible.",
|
|
@@ -1090,7 +1067,7 @@ use_deprecated_feature: Callable[..., Option] = partial(
|
|
|
1090
1067
|
# groups #
|
|
1091
1068
|
##########
|
|
1092
1069
|
|
|
1093
|
-
general_group:
|
|
1070
|
+
general_group: dict[str, Any] = {
|
|
1094
1071
|
"name": "General Options",
|
|
1095
1072
|
"options": [
|
|
1096
1073
|
help_,
|
|
@@ -1122,7 +1099,7 @@ general_group: Dict[str, Any] = {
|
|
|
1122
1099
|
],
|
|
1123
1100
|
}
|
|
1124
1101
|
|
|
1125
|
-
index_group:
|
|
1102
|
+
index_group: dict[str, Any] = {
|
|
1126
1103
|
"name": "Package Index Options",
|
|
1127
1104
|
"options": [
|
|
1128
1105
|
index_url,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
1
|
+
from collections.abc import Generator
|
|
2
|
+
from contextlib import AbstractContextManager, ExitStack, contextmanager
|
|
3
|
+
from typing import TypeVar
|
|
3
4
|
|
|
4
5
|
_T = TypeVar("_T", covariant=True)
|
|
5
6
|
|
|
@@ -21,7 +22,7 @@ class CommandContextMixIn:
|
|
|
21
22
|
finally:
|
|
22
23
|
self._in_main_context = False
|
|
23
24
|
|
|
24
|
-
def enter_context(self, context_provider:
|
|
25
|
+
def enter_context(self, context_provider: AbstractContextManager[_T]) -> _T:
|
|
25
26
|
assert self._in_main_context
|
|
26
27
|
|
|
27
28
|
return self._main_context.enter_context(context_provider)
|
|
@@ -6,12 +6,14 @@ so commands which don't always hit the network (e.g. list w/o --outdated or
|
|
|
6
6
|
--uptodate) don't need waste time importing PipSession and friends.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
9
11
|
import logging
|
|
10
12
|
import os
|
|
11
13
|
import sys
|
|
12
14
|
from functools import lru_cache
|
|
13
15
|
from optparse import Values
|
|
14
|
-
from typing import TYPE_CHECKING
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
15
17
|
|
|
16
18
|
from pip._vendor import certifi
|
|
17
19
|
|
|
@@ -27,7 +29,7 @@ logger = logging.getLogger(__name__)
|
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
@lru_cache
|
|
30
|
-
def _create_truststore_ssl_context() ->
|
|
32
|
+
def _create_truststore_ssl_context() -> SSLContext | None:
|
|
31
33
|
if sys.version_info < (3, 10):
|
|
32
34
|
logger.debug("Disabling truststore because Python version isn't 3.10+")
|
|
33
35
|
return None
|
|
@@ -56,10 +58,10 @@ class SessionCommandMixin(CommandContextMixIn):
|
|
|
56
58
|
|
|
57
59
|
def __init__(self) -> None:
|
|
58
60
|
super().__init__()
|
|
59
|
-
self._session:
|
|
61
|
+
self._session: PipSession | None = None
|
|
60
62
|
|
|
61
63
|
@classmethod
|
|
62
|
-
def _get_index_urls(cls, options: Values) ->
|
|
64
|
+
def _get_index_urls(cls, options: Values) -> list[str] | None:
|
|
63
65
|
"""Return a list of index urls from user-provided options."""
|
|
64
66
|
index_urls = []
|
|
65
67
|
if not getattr(options, "no_index", False):
|
|
@@ -72,7 +74,7 @@ class SessionCommandMixin(CommandContextMixIn):
|
|
|
72
74
|
# Return None rather than an empty list
|
|
73
75
|
return index_urls or None
|
|
74
76
|
|
|
75
|
-
def get_default_session(self, options: Values) ->
|
|
77
|
+
def get_default_session(self, options: Values) -> PipSession:
|
|
76
78
|
"""Get a default-managed session."""
|
|
77
79
|
if self._session is None:
|
|
78
80
|
self._session = self.enter_context(self._build_session(options))
|
|
@@ -85,9 +87,9 @@ class SessionCommandMixin(CommandContextMixIn):
|
|
|
85
87
|
def _build_session(
|
|
86
88
|
self,
|
|
87
89
|
options: Values,
|
|
88
|
-
retries:
|
|
89
|
-
timeout:
|
|
90
|
-
) ->
|
|
90
|
+
retries: int | None = None,
|
|
91
|
+
timeout: int | None = None,
|
|
92
|
+
) -> PipSession:
|
|
91
93
|
from pip._internal.network.session import PipSession
|
|
92
94
|
|
|
93
95
|
cache_dir = options.cache_dir
|
|
@@ -134,7 +136,7 @@ class SessionCommandMixin(CommandContextMixIn):
|
|
|
134
136
|
return session
|
|
135
137
|
|
|
136
138
|
|
|
137
|
-
def _pip_self_version_check(session:
|
|
139
|
+
def _pip_self_version_check(session: PipSession, options: Values) -> None:
|
|
138
140
|
from pip._internal.self_outdated_check import pip_self_version_check as check
|
|
139
141
|
|
|
140
142
|
check(session, options)
|
pip/_internal/cli/main.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"""Primary application entrypoint."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import locale
|
|
4
6
|
import logging
|
|
5
7
|
import os
|
|
6
8
|
import sys
|
|
7
9
|
import warnings
|
|
8
|
-
from typing import List, Optional
|
|
9
10
|
|
|
10
11
|
from pip._internal.cli.autocompletion import autocomplete
|
|
11
12
|
from pip._internal.cli.main_parser import parse_command
|
|
@@ -43,7 +44,7 @@ logger = logging.getLogger(__name__)
|
|
|
43
44
|
# main, this should not be an issue in practice.
|
|
44
45
|
|
|
45
46
|
|
|
46
|
-
def main(args:
|
|
47
|
+
def main(args: list[str] | None = None) -> int:
|
|
47
48
|
if args is None:
|
|
48
49
|
args = sys.argv[1:]
|
|
49
50
|
|
pip/_internal/cli/main_parser.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""A single place for constructing and exposing the main parser"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import os
|
|
4
6
|
import subprocess
|
|
5
7
|
import sys
|
|
6
|
-
from typing import List, Optional, Tuple
|
|
7
8
|
|
|
8
9
|
from pip._internal.build_env import get_runnable_pip
|
|
9
10
|
from pip._internal.cli import cmdoptions
|
|
@@ -46,7 +47,7 @@ def create_main_parser() -> ConfigOptionParser:
|
|
|
46
47
|
return parser
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
def identify_python_interpreter(python: str) ->
|
|
50
|
+
def identify_python_interpreter(python: str) -> str | None:
|
|
50
51
|
# If the named file exists, use it.
|
|
51
52
|
# If it's a directory, assume it's a virtual environment and
|
|
52
53
|
# look for the environment's Python executable.
|
|
@@ -65,7 +66,7 @@ def identify_python_interpreter(python: str) -> Optional[str]:
|
|
|
65
66
|
return None
|
|
66
67
|
|
|
67
68
|
|
|
68
|
-
def parse_command(args:
|
|
69
|
+
def parse_command(args: list[str]) -> tuple[str, list[str]]:
|
|
69
70
|
parser = create_main_parser()
|
|
70
71
|
|
|
71
72
|
# Note: parser calls disable_interspersed_args(), so the result of this
|
pip/_internal/cli/parser.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
"""Base option parser setup"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging
|
|
4
6
|
import optparse
|
|
5
7
|
import shutil
|
|
6
8
|
import sys
|
|
7
9
|
import textwrap
|
|
10
|
+
from collections.abc import Generator
|
|
8
11
|
from contextlib import suppress
|
|
9
|
-
from typing import Any,
|
|
12
|
+
from typing import Any, NoReturn
|
|
10
13
|
|
|
11
14
|
from pip._internal.cli.status_codes import UNKNOWN_ERROR
|
|
12
15
|
from pip._internal.configuration import Configuration, ConfigurationError
|
|
@@ -67,7 +70,7 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
|
|
67
70
|
msg = "\nUsage: {}\n".format(self.indent_lines(textwrap.dedent(usage), " "))
|
|
68
71
|
return msg
|
|
69
72
|
|
|
70
|
-
def format_description(self, description:
|
|
73
|
+
def format_description(self, description: str | None) -> str:
|
|
71
74
|
# leave full control over description to us
|
|
72
75
|
if description:
|
|
73
76
|
if hasattr(self.parser, "main"):
|
|
@@ -85,7 +88,7 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
|
|
85
88
|
else:
|
|
86
89
|
return ""
|
|
87
90
|
|
|
88
|
-
def format_epilog(self, epilog:
|
|
91
|
+
def format_epilog(self, epilog: str | None) -> str:
|
|
89
92
|
# leave full control over epilog to us
|
|
90
93
|
if epilog:
|
|
91
94
|
return epilog
|
|
@@ -142,7 +145,7 @@ class CustomOptionParser(optparse.OptionParser):
|
|
|
142
145
|
return group
|
|
143
146
|
|
|
144
147
|
@property
|
|
145
|
-
def option_list_all(self) ->
|
|
148
|
+
def option_list_all(self) -> list[optparse.Option]:
|
|
146
149
|
"""Get a list of all options, including those in option groups."""
|
|
147
150
|
res = self.option_list[:]
|
|
148
151
|
for i in self.option_groups:
|
|
@@ -177,33 +180,34 @@ class ConfigOptionParser(CustomOptionParser):
|
|
|
177
180
|
|
|
178
181
|
def _get_ordered_configuration_items(
|
|
179
182
|
self,
|
|
180
|
-
) -> Generator[
|
|
183
|
+
) -> Generator[tuple[str, Any], None, None]:
|
|
181
184
|
# Configuration gives keys in an unordered manner. Order them.
|
|
182
185
|
override_order = ["global", self.name, ":env:"]
|
|
183
186
|
|
|
184
187
|
# Pool the options into different groups
|
|
185
|
-
section_items:
|
|
188
|
+
section_items: dict[str, list[tuple[str, Any]]] = {
|
|
186
189
|
name: [] for name in override_order
|
|
187
190
|
}
|
|
188
|
-
for section_key, val in self.config.items():
|
|
189
|
-
# ignore empty values
|
|
190
|
-
if not val:
|
|
191
|
-
logger.debug(
|
|
192
|
-
"Ignoring configuration key '%s' as it's value is empty.",
|
|
193
|
-
section_key,
|
|
194
|
-
)
|
|
195
|
-
continue
|
|
196
191
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
192
|
+
for _, value in self.config.items(): # noqa: PERF102
|
|
193
|
+
for section_key, val in value.items():
|
|
194
|
+
# ignore empty values
|
|
195
|
+
if not val:
|
|
196
|
+
logger.debug(
|
|
197
|
+
"Ignoring configuration key '%s' as its value is empty.",
|
|
198
|
+
section_key,
|
|
199
|
+
)
|
|
200
|
+
continue
|
|
201
|
+
|
|
202
|
+
section, key = section_key.split(".", 1)
|
|
203
|
+
if section in override_order:
|
|
204
|
+
section_items[section].append((key, val))
|
|
200
205
|
|
|
201
206
|
# Yield each group in their override order
|
|
202
207
|
for section in override_order:
|
|
203
|
-
|
|
204
|
-
yield key, val
|
|
208
|
+
yield from section_items[section]
|
|
205
209
|
|
|
206
|
-
def _update_defaults(self, defaults:
|
|
210
|
+
def _update_defaults(self, defaults: dict[str, Any]) -> dict[str, Any]:
|
|
207
211
|
"""Updates the given defaults with values from the config files and
|
|
208
212
|
the environ. Does a little special handling for certain types of
|
|
209
213
|
options (lists)."""
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import functools
|
|
2
4
|
import sys
|
|
3
|
-
from
|
|
5
|
+
from collections.abc import Generator, Iterable, Iterator
|
|
6
|
+
from typing import Callable, Literal, TypeVar
|
|
4
7
|
|
|
5
8
|
from pip._vendor.rich.progress import (
|
|
6
9
|
BarColumn,
|
|
@@ -22,20 +25,21 @@ from pip._internal.utils.logging import get_console, get_indentation
|
|
|
22
25
|
|
|
23
26
|
T = TypeVar("T")
|
|
24
27
|
ProgressRenderer = Callable[[Iterable[T]], Iterator[T]]
|
|
28
|
+
BarType = Literal["on", "off", "raw"]
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
def _rich_download_progress_bar(
|
|
28
32
|
iterable: Iterable[bytes],
|
|
29
33
|
*,
|
|
30
|
-
bar_type:
|
|
31
|
-
size:
|
|
32
|
-
initial_progress:
|
|
34
|
+
bar_type: BarType,
|
|
35
|
+
size: int | None,
|
|
36
|
+
initial_progress: int | None = None,
|
|
33
37
|
) -> Generator[bytes, None, None]:
|
|
34
38
|
assert bar_type == "on", "This should only be used in the default mode."
|
|
35
39
|
|
|
36
40
|
if not size:
|
|
37
41
|
total = float("inf")
|
|
38
|
-
columns:
|
|
42
|
+
columns: tuple[ProgressColumn, ...] = (
|
|
39
43
|
TextColumn("[progress.description]{task.description}"),
|
|
40
44
|
SpinnerColumn("line", speed=1.5),
|
|
41
45
|
FileSizeColumn(),
|
|
@@ -49,18 +53,21 @@ def _rich_download_progress_bar(
|
|
|
49
53
|
BarColumn(),
|
|
50
54
|
DownloadColumn(),
|
|
51
55
|
TransferSpeedColumn(),
|
|
52
|
-
TextColumn("
|
|
53
|
-
TimeRemainingColumn(),
|
|
56
|
+
TextColumn("{task.fields[time_description]}"),
|
|
57
|
+
TimeRemainingColumn(elapsed_when_finished=True),
|
|
54
58
|
)
|
|
55
59
|
|
|
56
60
|
progress = Progress(*columns, refresh_per_second=5)
|
|
57
|
-
task_id = progress.add_task(
|
|
61
|
+
task_id = progress.add_task(
|
|
62
|
+
" " * (get_indentation() + 2), total=total, time_description="eta"
|
|
63
|
+
)
|
|
58
64
|
if initial_progress is not None:
|
|
59
65
|
progress.update(task_id, advance=initial_progress)
|
|
60
66
|
with progress:
|
|
61
67
|
for chunk in iterable:
|
|
62
68
|
yield chunk
|
|
63
69
|
progress.update(task_id, advance=len(chunk))
|
|
70
|
+
progress.update(task_id, time_description="")
|
|
64
71
|
|
|
65
72
|
|
|
66
73
|
def _rich_install_progress_bar(
|
|
@@ -88,8 +95,8 @@ def _rich_install_progress_bar(
|
|
|
88
95
|
def _raw_progress_bar(
|
|
89
96
|
iterable: Iterable[bytes],
|
|
90
97
|
*,
|
|
91
|
-
size:
|
|
92
|
-
initial_progress:
|
|
98
|
+
size: int | None,
|
|
99
|
+
initial_progress: int | None = None,
|
|
93
100
|
) -> Generator[bytes, None, None]:
|
|
94
101
|
def write_progress(current: int, total: int) -> None:
|
|
95
102
|
sys.stdout.write(f"Progress {current} of {total}\n")
|
|
@@ -109,7 +116,7 @@ def _raw_progress_bar(
|
|
|
109
116
|
|
|
110
117
|
|
|
111
118
|
def get_download_progress_renderer(
|
|
112
|
-
*, bar_type:
|
|
119
|
+
*, bar_type: BarType, size: int | None = None, initial_progress: int | None = None
|
|
113
120
|
) -> ProgressRenderer[bytes]:
|
|
114
121
|
"""Get an object that can be used to render the download progress.
|
|
115
122
|
|
|
@@ -133,7 +140,7 @@ def get_download_progress_renderer(
|
|
|
133
140
|
|
|
134
141
|
|
|
135
142
|
def get_install_progress_renderer(
|
|
136
|
-
*, bar_type:
|
|
143
|
+
*, bar_type: BarType, total: int
|
|
137
144
|
) -> ProgressRenderer[InstallRequirement]:
|
|
138
145
|
"""Get an object that can be used to render the install progress.
|
|
139
146
|
Returns a callable, that takes an iterable to "wrap".
|