Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/command_context.py +27 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/parser.py +292 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py +321 -0
- venv/lib/python3.10/site-packages/pip/_internal/cli/status_codes.py +6 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__init__.py +127 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/search.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/show.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-310.pyc +0 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/cache.py +223 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/check.py +53 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/completion.py +96 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/configuration.py +266 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/debug.py +202 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/download.py +140 -0
- venv/lib/python3.10/site-packages/pip/_internal/commands/freeze.py +97 -0
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (756 Bytes). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc
ADDED
|
Binary file (9.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc
ADDED
|
Binary file (8.38 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc
ADDED
|
Binary file (11.1 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc
ADDED
|
Binary file (23.1 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc
ADDED
|
Binary file (621 Bytes). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc
ADDED
|
Binary file (3.54 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc
ADDED
|
Binary file (4.58 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc
ADDED
|
Binary file (9.14 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (276 Bytes). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc
ADDED
|
Binary file (5.31 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc
ADDED
|
Binary file (6.25 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc
ADDED
|
Binary file (22.6 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc
ADDED
|
Binary file (1.31 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc
ADDED
|
Binary file (1.37 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc
ADDED
|
Binary file (2.16 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc
ADDED
|
Binary file (9.95 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc
ADDED
|
Binary file (9.24 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc
ADDED
|
Binary file (13.5 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc
ADDED
|
Binary file (4.95 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc
ADDED
|
Binary file (355 Bytes). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/cli/command_context.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from contextlib import ExitStack, contextmanager
|
| 2 |
+
from typing import ContextManager, Iterator, TypeVar
|
| 3 |
+
|
| 4 |
+
_T = TypeVar("_T", covariant=True)
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class CommandContextMixIn:
|
| 8 |
+
def __init__(self) -> None:
|
| 9 |
+
super().__init__()
|
| 10 |
+
self._in_main_context = False
|
| 11 |
+
self._main_context = ExitStack()
|
| 12 |
+
|
| 13 |
+
@contextmanager
|
| 14 |
+
def main_context(self) -> Iterator[None]:
|
| 15 |
+
assert not self._in_main_context
|
| 16 |
+
|
| 17 |
+
self._in_main_context = True
|
| 18 |
+
try:
|
| 19 |
+
with self._main_context:
|
| 20 |
+
yield
|
| 21 |
+
finally:
|
| 22 |
+
self._in_main_context = False
|
| 23 |
+
|
| 24 |
+
def enter_context(self, context_provider: ContextManager[_T]) -> _T:
|
| 25 |
+
assert self._in_main_context
|
| 26 |
+
|
| 27 |
+
return self._main_context.enter_context(context_provider)
|
venv/lib/python3.10/site-packages/pip/_internal/cli/parser.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Base option parser setup"""
|
| 2 |
+
|
| 3 |
+
import logging
|
| 4 |
+
import optparse
|
| 5 |
+
import shutil
|
| 6 |
+
import sys
|
| 7 |
+
import textwrap
|
| 8 |
+
from contextlib import suppress
|
| 9 |
+
from typing import Any, Dict, Iterator, List, Tuple
|
| 10 |
+
|
| 11 |
+
from pip._internal.cli.status_codes import UNKNOWN_ERROR
|
| 12 |
+
from pip._internal.configuration import Configuration, ConfigurationError
|
| 13 |
+
from pip._internal.utils.misc import redact_auth_from_url, strtobool
|
| 14 |
+
|
| 15 |
+
logger = logging.getLogger(__name__)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
| 19 |
+
"""A prettier/less verbose help formatter for optparse."""
|
| 20 |
+
|
| 21 |
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
| 22 |
+
# help position must be aligned with __init__.parseopts.description
|
| 23 |
+
kwargs["max_help_position"] = 30
|
| 24 |
+
kwargs["indent_increment"] = 1
|
| 25 |
+
kwargs["width"] = shutil.get_terminal_size()[0] - 2
|
| 26 |
+
super().__init__(*args, **kwargs)
|
| 27 |
+
|
| 28 |
+
def format_option_strings(self, option: optparse.Option) -> str:
|
| 29 |
+
return self._format_option_strings(option)
|
| 30 |
+
|
| 31 |
+
def _format_option_strings(
|
| 32 |
+
self, option: optparse.Option, mvarfmt: str = " <{}>", optsep: str = ", "
|
| 33 |
+
) -> str:
|
| 34 |
+
"""
|
| 35 |
+
Return a comma-separated list of option strings and metavars.
|
| 36 |
+
|
| 37 |
+
:param option: tuple of (short opt, long opt), e.g: ('-f', '--format')
|
| 38 |
+
:param mvarfmt: metavar format string
|
| 39 |
+
:param optsep: separator
|
| 40 |
+
"""
|
| 41 |
+
opts = []
|
| 42 |
+
|
| 43 |
+
if option._short_opts:
|
| 44 |
+
opts.append(option._short_opts[0])
|
| 45 |
+
if option._long_opts:
|
| 46 |
+
opts.append(option._long_opts[0])
|
| 47 |
+
if len(opts) > 1:
|
| 48 |
+
opts.insert(1, optsep)
|
| 49 |
+
|
| 50 |
+
if option.takes_value():
|
| 51 |
+
assert option.dest is not None
|
| 52 |
+
metavar = option.metavar or option.dest.lower()
|
| 53 |
+
opts.append(mvarfmt.format(metavar.lower()))
|
| 54 |
+
|
| 55 |
+
return "".join(opts)
|
| 56 |
+
|
| 57 |
+
def format_heading(self, heading: str) -> str:
|
| 58 |
+
if heading == "Options":
|
| 59 |
+
return ""
|
| 60 |
+
return heading + ":\n"
|
| 61 |
+
|
| 62 |
+
def format_usage(self, usage: str) -> str:
|
| 63 |
+
"""
|
| 64 |
+
Ensure there is only one newline between usage and the first heading
|
| 65 |
+
if there is no description.
|
| 66 |
+
"""
|
| 67 |
+
msg = "\nUsage: {}\n".format(self.indent_lines(textwrap.dedent(usage), " "))
|
| 68 |
+
return msg
|
| 69 |
+
|
| 70 |
+
def format_description(self, description: str) -> str:
|
| 71 |
+
# leave full control over description to us
|
| 72 |
+
if description:
|
| 73 |
+
if hasattr(self.parser, "main"):
|
| 74 |
+
label = "Commands"
|
| 75 |
+
else:
|
| 76 |
+
label = "Description"
|
| 77 |
+
# some doc strings have initial newlines, some don't
|
| 78 |
+
description = description.lstrip("\n")
|
| 79 |
+
# some doc strings have final newlines and spaces, some don't
|
| 80 |
+
description = description.rstrip()
|
| 81 |
+
# dedent, then reindent
|
| 82 |
+
description = self.indent_lines(textwrap.dedent(description), " ")
|
| 83 |
+
description = f"{label}:\n{description}\n"
|
| 84 |
+
return description
|
| 85 |
+
else:
|
| 86 |
+
return ""
|
| 87 |
+
|
| 88 |
+
def format_epilog(self, epilog: str) -> str:
|
| 89 |
+
# leave full control over epilog to us
|
| 90 |
+
if epilog:
|
| 91 |
+
return epilog
|
| 92 |
+
else:
|
| 93 |
+
return ""
|
| 94 |
+
|
| 95 |
+
def indent_lines(self, text: str, indent: str) -> str:
|
| 96 |
+
new_lines = [indent + line for line in text.split("\n")]
|
| 97 |
+
return "\n".join(new_lines)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter):
|
| 101 |
+
"""Custom help formatter for use in ConfigOptionParser.
|
| 102 |
+
|
| 103 |
+
This is updates the defaults before expanding them, allowing
|
| 104 |
+
them to show up correctly in the help listing.
|
| 105 |
+
|
| 106 |
+
Also redact auth from url type options
|
| 107 |
+
"""
|
| 108 |
+
|
| 109 |
+
def expand_default(self, option: optparse.Option) -> str:
|
| 110 |
+
default_values = None
|
| 111 |
+
if self.parser is not None:
|
| 112 |
+
assert isinstance(self.parser, ConfigOptionParser)
|
| 113 |
+
self.parser._update_defaults(self.parser.defaults)
|
| 114 |
+
assert option.dest is not None
|
| 115 |
+
default_values = self.parser.defaults.get(option.dest)
|
| 116 |
+
help_text = super().expand_default(option)
|
| 117 |
+
|
| 118 |
+
if default_values and option.metavar == "URL":
|
| 119 |
+
if isinstance(default_values, str):
|
| 120 |
+
default_values = [default_values]
|
| 121 |
+
|
| 122 |
+
# If its not a list, we should abort and just return the help text
|
| 123 |
+
if not isinstance(default_values, list):
|
| 124 |
+
default_values = []
|
| 125 |
+
|
| 126 |
+
for val in default_values:
|
| 127 |
+
help_text = help_text.replace(val, redact_auth_from_url(val))
|
| 128 |
+
|
| 129 |
+
return help_text
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
class CustomOptionParser(optparse.OptionParser):
|
| 133 |
+
def insert_option_group(
|
| 134 |
+
self, idx: int, *args: Any, **kwargs: Any
|
| 135 |
+
) -> optparse.OptionGroup:
|
| 136 |
+
"""Insert an OptionGroup at a given position."""
|
| 137 |
+
group = self.add_option_group(*args, **kwargs)
|
| 138 |
+
|
| 139 |
+
self.option_groups.pop()
|
| 140 |
+
self.option_groups.insert(idx, group)
|
| 141 |
+
|
| 142 |
+
return group
|
| 143 |
+
|
| 144 |
+
@property
|
| 145 |
+
def option_list_all(self) -> List[optparse.Option]:
|
| 146 |
+
"""Get a list of all options, including those in option groups."""
|
| 147 |
+
res = self.option_list[:]
|
| 148 |
+
for i in self.option_groups:
|
| 149 |
+
res.extend(i.option_list)
|
| 150 |
+
|
| 151 |
+
return res
|
| 152 |
+
|
| 153 |
+
|
| 154 |
+
class ConfigOptionParser(CustomOptionParser):
|
| 155 |
+
"""Custom option parser which updates its defaults by checking the
|
| 156 |
+
configuration files and environmental variables"""
|
| 157 |
+
|
| 158 |
+
def __init__(
|
| 159 |
+
self,
|
| 160 |
+
*args: Any,
|
| 161 |
+
name: str,
|
| 162 |
+
isolated: bool = False,
|
| 163 |
+
**kwargs: Any,
|
| 164 |
+
) -> None:
|
| 165 |
+
self.name = name
|
| 166 |
+
self.config = Configuration(isolated)
|
| 167 |
+
|
| 168 |
+
assert self.name
|
| 169 |
+
super().__init__(*args, **kwargs)
|
| 170 |
+
|
| 171 |
+
def check_default(self, option: optparse.Option, key: str, val: Any) -> Any:
|
| 172 |
+
try:
|
| 173 |
+
return option.check_value(key, val)
|
| 174 |
+
except optparse.OptionValueError as exc:
|
| 175 |
+
print(f"An error occurred during configuration: {exc}")
|
| 176 |
+
sys.exit(3)
|
| 177 |
+
|
| 178 |
+
def _get_ordered_configuration_items(self) -> Iterator[Tuple[str, Any]]:
|
| 179 |
+
# Configuration gives keys in an unordered manner. Order them.
|
| 180 |
+
override_order = ["global", self.name, ":env:"]
|
| 181 |
+
|
| 182 |
+
# Pool the options into different groups
|
| 183 |
+
section_items: Dict[str, List[Tuple[str, Any]]] = {
|
| 184 |
+
name: [] for name in override_order
|
| 185 |
+
}
|
| 186 |
+
for section_key, val in self.config.items():
|
| 187 |
+
# ignore empty values
|
| 188 |
+
if not val:
|
| 189 |
+
logger.debug(
|
| 190 |
+
"Ignoring configuration key '%s' as it's value is empty.",
|
| 191 |
+
section_key,
|
| 192 |
+
)
|
| 193 |
+
continue
|
| 194 |
+
|
| 195 |
+
section, key = section_key.split(".", 1)
|
| 196 |
+
if section in override_order:
|
| 197 |
+
section_items[section].append((key, val))
|
| 198 |
+
|
| 199 |
+
# Yield each group in their override order
|
| 200 |
+
for section in override_order:
|
| 201 |
+
for key, val in section_items[section]:
|
| 202 |
+
yield key, val
|
| 203 |
+
|
| 204 |
+
def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]:
|
| 205 |
+
"""Updates the given defaults with values from the config files and
|
| 206 |
+
the environ. Does a little special handling for certain types of
|
| 207 |
+
options (lists)."""
|
| 208 |
+
|
| 209 |
+
# Accumulate complex default state.
|
| 210 |
+
self.values = optparse.Values(self.defaults)
|
| 211 |
+
late_eval = set()
|
| 212 |
+
# Then set the options with those values
|
| 213 |
+
for key, val in self._get_ordered_configuration_items():
|
| 214 |
+
# '--' because configuration supports only long names
|
| 215 |
+
option = self.get_option("--" + key)
|
| 216 |
+
|
| 217 |
+
# Ignore options not present in this parser. E.g. non-globals put
|
| 218 |
+
# in [global] by users that want them to apply to all applicable
|
| 219 |
+
# commands.
|
| 220 |
+
if option is None:
|
| 221 |
+
continue
|
| 222 |
+
|
| 223 |
+
assert option.dest is not None
|
| 224 |
+
|
| 225 |
+
if option.action in ("store_true", "store_false"):
|
| 226 |
+
try:
|
| 227 |
+
val = strtobool(val)
|
| 228 |
+
except ValueError:
|
| 229 |
+
self.error(
|
| 230 |
+
"{} is not a valid value for {} option, " # noqa
|
| 231 |
+
"please specify a boolean value like yes/no, "
|
| 232 |
+
"true/false or 1/0 instead.".format(val, key)
|
| 233 |
+
)
|
| 234 |
+
elif option.action == "count":
|
| 235 |
+
with suppress(ValueError):
|
| 236 |
+
val = strtobool(val)
|
| 237 |
+
with suppress(ValueError):
|
| 238 |
+
val = int(val)
|
| 239 |
+
if not isinstance(val, int) or val < 0:
|
| 240 |
+
self.error(
|
| 241 |
+
"{} is not a valid value for {} option, " # noqa
|
| 242 |
+
"please instead specify either a non-negative integer "
|
| 243 |
+
"or a boolean value like yes/no or false/true "
|
| 244 |
+
"which is equivalent to 1/0.".format(val, key)
|
| 245 |
+
)
|
| 246 |
+
elif option.action == "append":
|
| 247 |
+
val = val.split()
|
| 248 |
+
val = [self.check_default(option, key, v) for v in val]
|
| 249 |
+
elif option.action == "callback":
|
| 250 |
+
assert option.callback is not None
|
| 251 |
+
late_eval.add(option.dest)
|
| 252 |
+
opt_str = option.get_opt_string()
|
| 253 |
+
val = option.convert_value(opt_str, val)
|
| 254 |
+
# From take_action
|
| 255 |
+
args = option.callback_args or ()
|
| 256 |
+
kwargs = option.callback_kwargs or {}
|
| 257 |
+
option.callback(option, opt_str, val, self, *args, **kwargs)
|
| 258 |
+
else:
|
| 259 |
+
val = self.check_default(option, key, val)
|
| 260 |
+
|
| 261 |
+
defaults[option.dest] = val
|
| 262 |
+
|
| 263 |
+
for key in late_eval:
|
| 264 |
+
defaults[key] = getattr(self.values, key)
|
| 265 |
+
self.values = None
|
| 266 |
+
return defaults
|
| 267 |
+
|
| 268 |
+
def get_default_values(self) -> optparse.Values:
|
| 269 |
+
"""Overriding to make updating the defaults after instantiation of
|
| 270 |
+
the option parser possible, _update_defaults() does the dirty work."""
|
| 271 |
+
if not self.process_default_values:
|
| 272 |
+
# Old, pre-Optik 1.5 behaviour.
|
| 273 |
+
return optparse.Values(self.defaults)
|
| 274 |
+
|
| 275 |
+
# Load the configuration, or error out in case of an error
|
| 276 |
+
try:
|
| 277 |
+
self.config.load()
|
| 278 |
+
except ConfigurationError as err:
|
| 279 |
+
self.exit(UNKNOWN_ERROR, str(err))
|
| 280 |
+
|
| 281 |
+
defaults = self._update_defaults(self.defaults.copy()) # ours
|
| 282 |
+
for option in self._get_all_options():
|
| 283 |
+
assert option.dest is not None
|
| 284 |
+
default = defaults.get(option.dest)
|
| 285 |
+
if isinstance(default, str):
|
| 286 |
+
opt_str = option.get_opt_string()
|
| 287 |
+
defaults[option.dest] = option.check_value(opt_str, default)
|
| 288 |
+
return optparse.Values(defaults)
|
| 289 |
+
|
| 290 |
+
def error(self, msg: str) -> None:
|
| 291 |
+
self.print_usage(sys.stderr)
|
| 292 |
+
self.exit(UNKNOWN_ERROR, f"{msg}\n")
|
venv/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import functools
|
| 2 |
+
import itertools
|
| 3 |
+
import sys
|
| 4 |
+
from signal import SIGINT, default_int_handler, signal
|
| 5 |
+
from typing import Any, Callable, Iterator, Optional, Tuple
|
| 6 |
+
|
| 7 |
+
from pip._vendor.progress.bar import Bar, FillingCirclesBar, IncrementalBar
|
| 8 |
+
from pip._vendor.progress.spinner import Spinner
|
| 9 |
+
from pip._vendor.rich.progress import (
|
| 10 |
+
BarColumn,
|
| 11 |
+
DownloadColumn,
|
| 12 |
+
FileSizeColumn,
|
| 13 |
+
Progress,
|
| 14 |
+
ProgressColumn,
|
| 15 |
+
SpinnerColumn,
|
| 16 |
+
TextColumn,
|
| 17 |
+
TimeElapsedColumn,
|
| 18 |
+
TimeRemainingColumn,
|
| 19 |
+
TransferSpeedColumn,
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
from pip._internal.utils.compat import WINDOWS
|
| 23 |
+
from pip._internal.utils.logging import get_indentation
|
| 24 |
+
from pip._internal.utils.misc import format_size
|
| 25 |
+
|
| 26 |
+
try:
|
| 27 |
+
from pip._vendor import colorama
|
| 28 |
+
# Lots of different errors can come from this, including SystemError and
|
| 29 |
+
# ImportError.
|
| 30 |
+
except Exception:
|
| 31 |
+
colorama = None
|
| 32 |
+
|
| 33 |
+
DownloadProgressRenderer = Callable[[Iterator[bytes]], Iterator[bytes]]
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def _select_progress_class(preferred: Bar, fallback: Bar) -> Bar:
|
| 37 |
+
encoding = getattr(preferred.file, "encoding", None)
|
| 38 |
+
|
| 39 |
+
# If we don't know what encoding this file is in, then we'll just assume
|
| 40 |
+
# that it doesn't support unicode and use the ASCII bar.
|
| 41 |
+
if not encoding:
|
| 42 |
+
return fallback
|
| 43 |
+
|
| 44 |
+
# Collect all of the possible characters we want to use with the preferred
|
| 45 |
+
# bar.
|
| 46 |
+
characters = [
|
| 47 |
+
getattr(preferred, "empty_fill", ""),
|
| 48 |
+
getattr(preferred, "fill", ""),
|
| 49 |
+
]
|
| 50 |
+
characters += list(getattr(preferred, "phases", []))
|
| 51 |
+
|
| 52 |
+
# Try to decode the characters we're using for the bar using the encoding
|
| 53 |
+
# of the given file, if this works then we'll assume that we can use the
|
| 54 |
+
# fancier bar and if not we'll fall back to the plaintext bar.
|
| 55 |
+
try:
|
| 56 |
+
"".join(characters).encode(encoding)
|
| 57 |
+
except UnicodeEncodeError:
|
| 58 |
+
return fallback
|
| 59 |
+
else:
|
| 60 |
+
return preferred
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
_BaseBar: Any = _select_progress_class(IncrementalBar, Bar)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
class InterruptibleMixin:
|
| 67 |
+
"""
|
| 68 |
+
Helper to ensure that self.finish() gets called on keyboard interrupt.
|
| 69 |
+
|
| 70 |
+
This allows downloads to be interrupted without leaving temporary state
|
| 71 |
+
(like hidden cursors) behind.
|
| 72 |
+
|
| 73 |
+
This class is similar to the progress library's existing SigIntMixin
|
| 74 |
+
helper, but as of version 1.2, that helper has the following problems:
|
| 75 |
+
|
| 76 |
+
1. It calls sys.exit().
|
| 77 |
+
2. It discards the existing SIGINT handler completely.
|
| 78 |
+
3. It leaves its own handler in place even after an uninterrupted finish,
|
| 79 |
+
which will have unexpected delayed effects if the user triggers an
|
| 80 |
+
unrelated keyboard interrupt some time after a progress-displaying
|
| 81 |
+
download has already completed, for example.
|
| 82 |
+
"""
|
| 83 |
+
|
| 84 |
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
| 85 |
+
"""
|
| 86 |
+
Save the original SIGINT handler for later.
|
| 87 |
+
"""
|
| 88 |
+
# https://github.com/python/mypy/issues/5887
|
| 89 |
+
super().__init__(*args, **kwargs) # type: ignore
|
| 90 |
+
|
| 91 |
+
self.original_handler = signal(SIGINT, self.handle_sigint)
|
| 92 |
+
|
| 93 |
+
# If signal() returns None, the previous handler was not installed from
|
| 94 |
+
# Python, and we cannot restore it. This probably should not happen,
|
| 95 |
+
# but if it does, we must restore something sensible instead, at least.
|
| 96 |
+
# The least bad option should be Python's default SIGINT handler, which
|
| 97 |
+
# just raises KeyboardInterrupt.
|
| 98 |
+
if self.original_handler is None:
|
| 99 |
+
self.original_handler = default_int_handler
|
| 100 |
+
|
| 101 |
+
def finish(self) -> None:
|
| 102 |
+
"""
|
| 103 |
+
Restore the original SIGINT handler after finishing.
|
| 104 |
+
|
| 105 |
+
This should happen regardless of whether the progress display finishes
|
| 106 |
+
normally, or gets interrupted.
|
| 107 |
+
"""
|
| 108 |
+
super().finish() # type: ignore
|
| 109 |
+
signal(SIGINT, self.original_handler)
|
| 110 |
+
|
| 111 |
+
def handle_sigint(self, signum, frame): # type: ignore
|
| 112 |
+
"""
|
| 113 |
+
Call self.finish() before delegating to the original SIGINT handler.
|
| 114 |
+
|
| 115 |
+
This handler should only be in place while the progress display is
|
| 116 |
+
active.
|
| 117 |
+
"""
|
| 118 |
+
self.finish()
|
| 119 |
+
self.original_handler(signum, frame)
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
class SilentBar(Bar):
|
| 123 |
+
def update(self) -> None:
|
| 124 |
+
pass
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
class BlueEmojiBar(IncrementalBar):
|
| 128 |
+
|
| 129 |
+
suffix = "%(percent)d%%"
|
| 130 |
+
bar_prefix = " "
|
| 131 |
+
bar_suffix = " "
|
| 132 |
+
phases = ("\U0001F539", "\U0001F537", "\U0001F535")
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
class DownloadProgressMixin:
|
| 136 |
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
| 137 |
+
# https://github.com/python/mypy/issues/5887
|
| 138 |
+
super().__init__(*args, **kwargs) # type: ignore
|
| 139 |
+
self.message: str = (" " * (get_indentation() + 2)) + self.message
|
| 140 |
+
|
| 141 |
+
@property
|
| 142 |
+
def downloaded(self) -> str:
|
| 143 |
+
return format_size(self.index) # type: ignore
|
| 144 |
+
|
| 145 |
+
@property
|
| 146 |
+
def download_speed(self) -> str:
|
| 147 |
+
# Avoid zero division errors...
|
| 148 |
+
if self.avg == 0.0: # type: ignore
|
| 149 |
+
return "..."
|
| 150 |
+
return format_size(1 / self.avg) + "/s" # type: ignore
|
| 151 |
+
|
| 152 |
+
@property
|
| 153 |
+
def pretty_eta(self) -> str:
|
| 154 |
+
if self.eta: # type: ignore
|
| 155 |
+
return f"eta {self.eta_td}" # type: ignore
|
| 156 |
+
return ""
|
| 157 |
+
|
| 158 |
+
def iter(self, it): # type: ignore
|
| 159 |
+
for x in it:
|
| 160 |
+
yield x
|
| 161 |
+
# B305 is incorrectly raised here
|
| 162 |
+
# https://github.com/PyCQA/flake8-bugbear/issues/59
|
| 163 |
+
self.next(len(x)) # noqa: B305
|
| 164 |
+
self.finish()
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
class WindowsMixin:
|
| 168 |
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
| 169 |
+
# The Windows terminal does not support the hide/show cursor ANSI codes
|
| 170 |
+
# even with colorama. So we'll ensure that hide_cursor is False on
|
| 171 |
+
# Windows.
|
| 172 |
+
# This call needs to go before the super() call, so that hide_cursor
|
| 173 |
+
# is set in time. The base progress bar class writes the "hide cursor"
|
| 174 |
+
# code to the terminal in its init, so if we don't set this soon
|
| 175 |
+
# enough, we get a "hide" with no corresponding "show"...
|
| 176 |
+
if WINDOWS and self.hide_cursor: # type: ignore
|
| 177 |
+
self.hide_cursor = False
|
| 178 |
+
|
| 179 |
+
# https://github.com/python/mypy/issues/5887
|
| 180 |
+
super().__init__(*args, **kwargs) # type: ignore
|
| 181 |
+
|
| 182 |
+
# Check if we are running on Windows and we have the colorama module,
|
| 183 |
+
# if we do then wrap our file with it.
|
| 184 |
+
if WINDOWS and colorama:
|
| 185 |
+
self.file = colorama.AnsiToWin32(self.file) # type: ignore
|
| 186 |
+
# The progress code expects to be able to call self.file.isatty()
|
| 187 |
+
# but the colorama.AnsiToWin32() object doesn't have that, so we'll
|
| 188 |
+
# add it.
|
| 189 |
+
self.file.isatty = lambda: self.file.wrapped.isatty()
|
| 190 |
+
# The progress code expects to be able to call self.file.flush()
|
| 191 |
+
# but the colorama.AnsiToWin32() object doesn't have that, so we'll
|
| 192 |
+
# add it.
|
| 193 |
+
self.file.flush = lambda: self.file.wrapped.flush()
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, DownloadProgressMixin):
|
| 197 |
+
|
| 198 |
+
file = sys.stdout
|
| 199 |
+
message = "%(percent)d%%"
|
| 200 |
+
suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s"
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
class DefaultDownloadProgressBar(BaseDownloadProgressBar, _BaseBar):
|
| 204 |
+
pass
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
class DownloadSilentBar(BaseDownloadProgressBar, SilentBar):
|
| 208 |
+
pass
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
class DownloadBar(BaseDownloadProgressBar, Bar):
|
| 212 |
+
pass
|
| 213 |
+
|
| 214 |
+
|
| 215 |
+
class DownloadFillingCirclesBar(BaseDownloadProgressBar, FillingCirclesBar):
|
| 216 |
+
pass
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, BlueEmojiBar):
|
| 220 |
+
pass
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
class DownloadProgressSpinner(
|
| 224 |
+
WindowsMixin, InterruptibleMixin, DownloadProgressMixin, Spinner
|
| 225 |
+
):
|
| 226 |
+
|
| 227 |
+
file = sys.stdout
|
| 228 |
+
suffix = "%(downloaded)s %(download_speed)s"
|
| 229 |
+
|
| 230 |
+
def next_phase(self) -> str:
|
| 231 |
+
if not hasattr(self, "_phaser"):
|
| 232 |
+
self._phaser = itertools.cycle(self.phases)
|
| 233 |
+
return next(self._phaser)
|
| 234 |
+
|
| 235 |
+
def update(self) -> None:
|
| 236 |
+
message = self.message % self
|
| 237 |
+
phase = self.next_phase()
|
| 238 |
+
suffix = self.suffix % self
|
| 239 |
+
line = "".join(
|
| 240 |
+
[
|
| 241 |
+
message,
|
| 242 |
+
" " if message else "",
|
| 243 |
+
phase,
|
| 244 |
+
" " if suffix else "",
|
| 245 |
+
suffix,
|
| 246 |
+
]
|
| 247 |
+
)
|
| 248 |
+
|
| 249 |
+
self.writeln(line)
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
BAR_TYPES = {
|
| 253 |
+
"off": (DownloadSilentBar, DownloadSilentBar),
|
| 254 |
+
"on": (DefaultDownloadProgressBar, DownloadProgressSpinner),
|
| 255 |
+
"ascii": (DownloadBar, DownloadProgressSpinner),
|
| 256 |
+
"pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner),
|
| 257 |
+
"emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner),
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
|
| 261 |
+
def _legacy_progress_bar(
|
| 262 |
+
progress_bar: str, max: Optional[int]
|
| 263 |
+
) -> DownloadProgressRenderer:
|
| 264 |
+
if max is None or max == 0:
|
| 265 |
+
return BAR_TYPES[progress_bar][1]().iter # type: ignore
|
| 266 |
+
else:
|
| 267 |
+
return BAR_TYPES[progress_bar][0](max=max).iter
|
| 268 |
+
|
| 269 |
+
|
| 270 |
+
#
|
| 271 |
+
# Modern replacement, for our legacy progress bars.
|
| 272 |
+
#
|
| 273 |
+
def _rich_progress_bar(
|
| 274 |
+
iterable: Iterator[bytes],
|
| 275 |
+
*,
|
| 276 |
+
bar_type: str,
|
| 277 |
+
size: int,
|
| 278 |
+
) -> Iterator[bytes]:
|
| 279 |
+
assert bar_type == "on", "This should only be used in the default mode."
|
| 280 |
+
|
| 281 |
+
if not size:
|
| 282 |
+
total = float("inf")
|
| 283 |
+
columns: Tuple[ProgressColumn, ...] = (
|
| 284 |
+
TextColumn("[progress.description]{task.description}"),
|
| 285 |
+
SpinnerColumn("line", speed=1.5),
|
| 286 |
+
FileSizeColumn(),
|
| 287 |
+
TransferSpeedColumn(),
|
| 288 |
+
TimeElapsedColumn(),
|
| 289 |
+
)
|
| 290 |
+
else:
|
| 291 |
+
total = size
|
| 292 |
+
columns = (
|
| 293 |
+
TextColumn("[progress.description]{task.description}"),
|
| 294 |
+
BarColumn(),
|
| 295 |
+
DownloadColumn(),
|
| 296 |
+
TransferSpeedColumn(),
|
| 297 |
+
TextColumn("eta"),
|
| 298 |
+
TimeRemainingColumn(),
|
| 299 |
+
)
|
| 300 |
+
|
| 301 |
+
progress = Progress(*columns, refresh_per_second=30)
|
| 302 |
+
task_id = progress.add_task(" " * (get_indentation() + 2), total=total)
|
| 303 |
+
with progress:
|
| 304 |
+
for chunk in iterable:
|
| 305 |
+
yield chunk
|
| 306 |
+
progress.update(task_id, advance=len(chunk))
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
def get_download_progress_renderer(
|
| 310 |
+
*, bar_type: str, size: Optional[int] = None
|
| 311 |
+
) -> DownloadProgressRenderer:
|
| 312 |
+
"""Get an object that can be used to render the download progress.
|
| 313 |
+
|
| 314 |
+
Returns a callable, that takes an iterable to "wrap".
|
| 315 |
+
"""
|
| 316 |
+
if bar_type == "on":
|
| 317 |
+
return functools.partial(_rich_progress_bar, bar_type=bar_type, size=size)
|
| 318 |
+
elif bar_type == "off":
|
| 319 |
+
return iter # no-op, when passed an iterator
|
| 320 |
+
else:
|
| 321 |
+
return _legacy_progress_bar(bar_type, size)
|
venv/lib/python3.10/site-packages/pip/_internal/cli/status_codes.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SUCCESS = 0
|
| 2 |
+
ERROR = 1
|
| 3 |
+
UNKNOWN_ERROR = 2
|
| 4 |
+
VIRTUALENV_NOT_FOUND = 3
|
| 5 |
+
PREVIOUS_BUILD_DIR_ERROR = 4
|
| 6 |
+
NO_MATCHES_FOUND = 23
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__init__.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Package containing all pip commands
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
import importlib
|
| 6 |
+
from collections import namedtuple
|
| 7 |
+
from typing import Any, Dict, Optional
|
| 8 |
+
|
| 9 |
+
from pip._internal.cli.base_command import Command
|
| 10 |
+
|
| 11 |
+
CommandInfo = namedtuple("CommandInfo", "module_path, class_name, summary")
|
| 12 |
+
|
| 13 |
+
# This dictionary does a bunch of heavy lifting for help output:
|
| 14 |
+
# - Enables avoiding additional (costly) imports for presenting `--help`.
|
| 15 |
+
# - The ordering matters for help display.
|
| 16 |
+
#
|
| 17 |
+
# Even though the module path starts with the same "pip._internal.commands"
|
| 18 |
+
# prefix, the full path makes testing easier (specifically when modifying
|
| 19 |
+
# `commands_dict` in test setup / teardown).
|
| 20 |
+
commands_dict: Dict[str, CommandInfo] = {
|
| 21 |
+
"install": CommandInfo(
|
| 22 |
+
"pip._internal.commands.install",
|
| 23 |
+
"InstallCommand",
|
| 24 |
+
"Install packages.",
|
| 25 |
+
),
|
| 26 |
+
"download": CommandInfo(
|
| 27 |
+
"pip._internal.commands.download",
|
| 28 |
+
"DownloadCommand",
|
| 29 |
+
"Download packages.",
|
| 30 |
+
),
|
| 31 |
+
"uninstall": CommandInfo(
|
| 32 |
+
"pip._internal.commands.uninstall",
|
| 33 |
+
"UninstallCommand",
|
| 34 |
+
"Uninstall packages.",
|
| 35 |
+
),
|
| 36 |
+
"freeze": CommandInfo(
|
| 37 |
+
"pip._internal.commands.freeze",
|
| 38 |
+
"FreezeCommand",
|
| 39 |
+
"Output installed packages in requirements format.",
|
| 40 |
+
),
|
| 41 |
+
"list": CommandInfo(
|
| 42 |
+
"pip._internal.commands.list",
|
| 43 |
+
"ListCommand",
|
| 44 |
+
"List installed packages.",
|
| 45 |
+
),
|
| 46 |
+
"show": CommandInfo(
|
| 47 |
+
"pip._internal.commands.show",
|
| 48 |
+
"ShowCommand",
|
| 49 |
+
"Show information about installed packages.",
|
| 50 |
+
),
|
| 51 |
+
"check": CommandInfo(
|
| 52 |
+
"pip._internal.commands.check",
|
| 53 |
+
"CheckCommand",
|
| 54 |
+
"Verify installed packages have compatible dependencies.",
|
| 55 |
+
),
|
| 56 |
+
"config": CommandInfo(
|
| 57 |
+
"pip._internal.commands.configuration",
|
| 58 |
+
"ConfigurationCommand",
|
| 59 |
+
"Manage local and global configuration.",
|
| 60 |
+
),
|
| 61 |
+
"search": CommandInfo(
|
| 62 |
+
"pip._internal.commands.search",
|
| 63 |
+
"SearchCommand",
|
| 64 |
+
"Search PyPI for packages.",
|
| 65 |
+
),
|
| 66 |
+
"cache": CommandInfo(
|
| 67 |
+
"pip._internal.commands.cache",
|
| 68 |
+
"CacheCommand",
|
| 69 |
+
"Inspect and manage pip's wheel cache.",
|
| 70 |
+
),
|
| 71 |
+
"index": CommandInfo(
|
| 72 |
+
"pip._internal.commands.index",
|
| 73 |
+
"IndexCommand",
|
| 74 |
+
"Inspect information available from package indexes.",
|
| 75 |
+
),
|
| 76 |
+
"wheel": CommandInfo(
|
| 77 |
+
"pip._internal.commands.wheel",
|
| 78 |
+
"WheelCommand",
|
| 79 |
+
"Build wheels from your requirements.",
|
| 80 |
+
),
|
| 81 |
+
"hash": CommandInfo(
|
| 82 |
+
"pip._internal.commands.hash",
|
| 83 |
+
"HashCommand",
|
| 84 |
+
"Compute hashes of package archives.",
|
| 85 |
+
),
|
| 86 |
+
"completion": CommandInfo(
|
| 87 |
+
"pip._internal.commands.completion",
|
| 88 |
+
"CompletionCommand",
|
| 89 |
+
"A helper command used for command completion.",
|
| 90 |
+
),
|
| 91 |
+
"debug": CommandInfo(
|
| 92 |
+
"pip._internal.commands.debug",
|
| 93 |
+
"DebugCommand",
|
| 94 |
+
"Show information useful for debugging.",
|
| 95 |
+
),
|
| 96 |
+
"help": CommandInfo(
|
| 97 |
+
"pip._internal.commands.help",
|
| 98 |
+
"HelpCommand",
|
| 99 |
+
"Show help for commands.",
|
| 100 |
+
),
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def create_command(name: str, **kwargs: Any) -> Command:
|
| 105 |
+
"""
|
| 106 |
+
Create an instance of the Command class with the given name.
|
| 107 |
+
"""
|
| 108 |
+
module_path, class_name, summary = commands_dict[name]
|
| 109 |
+
module = importlib.import_module(module_path)
|
| 110 |
+
command_class = getattr(module, class_name)
|
| 111 |
+
command = command_class(name=name, summary=summary, **kwargs)
|
| 112 |
+
|
| 113 |
+
return command
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
def get_similar_commands(name: str) -> Optional[str]:
|
| 117 |
+
"""Command name auto-correct."""
|
| 118 |
+
from difflib import get_close_matches
|
| 119 |
+
|
| 120 |
+
name = name.lower()
|
| 121 |
+
|
| 122 |
+
close_commands = get_close_matches(name, commands_dict.keys())
|
| 123 |
+
|
| 124 |
+
if close_commands:
|
| 125 |
+
return close_commands[0]
|
| 126 |
+
else:
|
| 127 |
+
return None
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (3.14 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc
ADDED
|
Binary file (6.18 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc
ADDED
|
Binary file (1.57 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc
ADDED
|
Binary file (3.14 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc
ADDED
|
Binary file (8.32 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc
ADDED
|
Binary file (6.68 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc
ADDED
|
Binary file (3.99 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc
ADDED
|
Binary file (2.65 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc
ADDED
|
Binary file (2.15 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc
ADDED
|
Binary file (1.31 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc
ADDED
|
Binary file (4.64 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc
ADDED
|
Binary file (17.8 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc
ADDED
|
Binary file (10.4 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/search.cpython-310.pyc
ADDED
|
Binary file (5.37 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/show.cpython-310.pyc
ADDED
|
Binary file (6.12 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc
ADDED
|
Binary file (3.11 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-310.pyc
ADDED
|
Binary file (4.84 kB). View file
|
|
|
venv/lib/python3.10/site-packages/pip/_internal/commands/cache.py
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import textwrap
|
| 3 |
+
from optparse import Values
|
| 4 |
+
from typing import Any, List
|
| 5 |
+
|
| 6 |
+
import pip._internal.utils.filesystem as filesystem
|
| 7 |
+
from pip._internal.cli.base_command import Command
|
| 8 |
+
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
| 9 |
+
from pip._internal.exceptions import CommandError, PipError
|
| 10 |
+
from pip._internal.utils.logging import getLogger
|
| 11 |
+
|
| 12 |
+
logger = getLogger(__name__)
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class CacheCommand(Command):
|
| 16 |
+
"""
|
| 17 |
+
Inspect and manage pip's wheel cache.
|
| 18 |
+
|
| 19 |
+
Subcommands:
|
| 20 |
+
|
| 21 |
+
- dir: Show the cache directory.
|
| 22 |
+
- info: Show information about the cache.
|
| 23 |
+
- list: List filenames of packages stored in the cache.
|
| 24 |
+
- remove: Remove one or more package from the cache.
|
| 25 |
+
- purge: Remove all items from the cache.
|
| 26 |
+
|
| 27 |
+
``<pattern>`` can be a glob expression or a package name.
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
ignore_require_venv = True
|
| 31 |
+
usage = """
|
| 32 |
+
%prog dir
|
| 33 |
+
%prog info
|
| 34 |
+
%prog list [<pattern>] [--format=[human, abspath]]
|
| 35 |
+
%prog remove <pattern>
|
| 36 |
+
%prog purge
|
| 37 |
+
"""
|
| 38 |
+
|
| 39 |
+
def add_options(self) -> None:
|
| 40 |
+
|
| 41 |
+
self.cmd_opts.add_option(
|
| 42 |
+
"--format",
|
| 43 |
+
action="store",
|
| 44 |
+
dest="list_format",
|
| 45 |
+
default="human",
|
| 46 |
+
choices=("human", "abspath"),
|
| 47 |
+
help="Select the output format among: human (default) or abspath",
|
| 48 |
+
)
|
| 49 |
+
|
| 50 |
+
self.parser.insert_option_group(0, self.cmd_opts)
|
| 51 |
+
|
| 52 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 53 |
+
handlers = {
|
| 54 |
+
"dir": self.get_cache_dir,
|
| 55 |
+
"info": self.get_cache_info,
|
| 56 |
+
"list": self.list_cache_items,
|
| 57 |
+
"remove": self.remove_cache_items,
|
| 58 |
+
"purge": self.purge_cache,
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
if not options.cache_dir:
|
| 62 |
+
logger.error("pip cache commands can not function since cache is disabled.")
|
| 63 |
+
return ERROR
|
| 64 |
+
|
| 65 |
+
# Determine action
|
| 66 |
+
if not args or args[0] not in handlers:
|
| 67 |
+
logger.error(
|
| 68 |
+
"Need an action (%s) to perform.",
|
| 69 |
+
", ".join(sorted(handlers)),
|
| 70 |
+
)
|
| 71 |
+
return ERROR
|
| 72 |
+
|
| 73 |
+
action = args[0]
|
| 74 |
+
|
| 75 |
+
# Error handling happens here, not in the action-handlers.
|
| 76 |
+
try:
|
| 77 |
+
handlers[action](options, args[1:])
|
| 78 |
+
except PipError as e:
|
| 79 |
+
logger.error(e.args[0])
|
| 80 |
+
return ERROR
|
| 81 |
+
|
| 82 |
+
return SUCCESS
|
| 83 |
+
|
| 84 |
+
def get_cache_dir(self, options: Values, args: List[Any]) -> None:
|
| 85 |
+
if args:
|
| 86 |
+
raise CommandError("Too many arguments")
|
| 87 |
+
|
| 88 |
+
logger.info(options.cache_dir)
|
| 89 |
+
|
| 90 |
+
def get_cache_info(self, options: Values, args: List[Any]) -> None:
|
| 91 |
+
if args:
|
| 92 |
+
raise CommandError("Too many arguments")
|
| 93 |
+
|
| 94 |
+
num_http_files = len(self._find_http_files(options))
|
| 95 |
+
num_packages = len(self._find_wheels(options, "*"))
|
| 96 |
+
|
| 97 |
+
http_cache_location = self._cache_dir(options, "http")
|
| 98 |
+
wheels_cache_location = self._cache_dir(options, "wheels")
|
| 99 |
+
http_cache_size = filesystem.format_directory_size(http_cache_location)
|
| 100 |
+
wheels_cache_size = filesystem.format_directory_size(wheels_cache_location)
|
| 101 |
+
|
| 102 |
+
message = (
|
| 103 |
+
textwrap.dedent(
|
| 104 |
+
"""
|
| 105 |
+
Package index page cache location: {http_cache_location}
|
| 106 |
+
Package index page cache size: {http_cache_size}
|
| 107 |
+
Number of HTTP files: {num_http_files}
|
| 108 |
+
Wheels location: {wheels_cache_location}
|
| 109 |
+
Wheels size: {wheels_cache_size}
|
| 110 |
+
Number of wheels: {package_count}
|
| 111 |
+
"""
|
| 112 |
+
)
|
| 113 |
+
.format(
|
| 114 |
+
http_cache_location=http_cache_location,
|
| 115 |
+
http_cache_size=http_cache_size,
|
| 116 |
+
num_http_files=num_http_files,
|
| 117 |
+
wheels_cache_location=wheels_cache_location,
|
| 118 |
+
package_count=num_packages,
|
| 119 |
+
wheels_cache_size=wheels_cache_size,
|
| 120 |
+
)
|
| 121 |
+
.strip()
|
| 122 |
+
)
|
| 123 |
+
|
| 124 |
+
logger.info(message)
|
| 125 |
+
|
| 126 |
+
def list_cache_items(self, options: Values, args: List[Any]) -> None:
|
| 127 |
+
if len(args) > 1:
|
| 128 |
+
raise CommandError("Too many arguments")
|
| 129 |
+
|
| 130 |
+
if args:
|
| 131 |
+
pattern = args[0]
|
| 132 |
+
else:
|
| 133 |
+
pattern = "*"
|
| 134 |
+
|
| 135 |
+
files = self._find_wheels(options, pattern)
|
| 136 |
+
if options.list_format == "human":
|
| 137 |
+
self.format_for_human(files)
|
| 138 |
+
else:
|
| 139 |
+
self.format_for_abspath(files)
|
| 140 |
+
|
| 141 |
+
def format_for_human(self, files: List[str]) -> None:
|
| 142 |
+
if not files:
|
| 143 |
+
logger.info("Nothing cached.")
|
| 144 |
+
return
|
| 145 |
+
|
| 146 |
+
results = []
|
| 147 |
+
for filename in files:
|
| 148 |
+
wheel = os.path.basename(filename)
|
| 149 |
+
size = filesystem.format_file_size(filename)
|
| 150 |
+
results.append(f" - {wheel} ({size})")
|
| 151 |
+
logger.info("Cache contents:\n")
|
| 152 |
+
logger.info("\n".join(sorted(results)))
|
| 153 |
+
|
| 154 |
+
def format_for_abspath(self, files: List[str]) -> None:
|
| 155 |
+
if not files:
|
| 156 |
+
return
|
| 157 |
+
|
| 158 |
+
results = []
|
| 159 |
+
for filename in files:
|
| 160 |
+
results.append(filename)
|
| 161 |
+
|
| 162 |
+
logger.info("\n".join(sorted(results)))
|
| 163 |
+
|
| 164 |
+
def remove_cache_items(self, options: Values, args: List[Any]) -> None:
|
| 165 |
+
if len(args) > 1:
|
| 166 |
+
raise CommandError("Too many arguments")
|
| 167 |
+
|
| 168 |
+
if not args:
|
| 169 |
+
raise CommandError("Please provide a pattern")
|
| 170 |
+
|
| 171 |
+
files = self._find_wheels(options, args[0])
|
| 172 |
+
|
| 173 |
+
no_matching_msg = "No matching packages"
|
| 174 |
+
if args[0] == "*":
|
| 175 |
+
# Only fetch http files if no specific pattern given
|
| 176 |
+
files += self._find_http_files(options)
|
| 177 |
+
else:
|
| 178 |
+
# Add the pattern to the log message
|
| 179 |
+
no_matching_msg += ' for pattern "{}"'.format(args[0])
|
| 180 |
+
|
| 181 |
+
if not files:
|
| 182 |
+
logger.warning(no_matching_msg)
|
| 183 |
+
|
| 184 |
+
for filename in files:
|
| 185 |
+
os.unlink(filename)
|
| 186 |
+
logger.verbose("Removed %s", filename)
|
| 187 |
+
logger.info("Files removed: %s", len(files))
|
| 188 |
+
|
| 189 |
+
def purge_cache(self, options: Values, args: List[Any]) -> None:
|
| 190 |
+
if args:
|
| 191 |
+
raise CommandError("Too many arguments")
|
| 192 |
+
|
| 193 |
+
return self.remove_cache_items(options, ["*"])
|
| 194 |
+
|
| 195 |
+
def _cache_dir(self, options: Values, subdir: str) -> str:
|
| 196 |
+
return os.path.join(options.cache_dir, subdir)
|
| 197 |
+
|
| 198 |
+
def _find_http_files(self, options: Values) -> List[str]:
|
| 199 |
+
http_dir = self._cache_dir(options, "http")
|
| 200 |
+
return filesystem.find_files(http_dir, "*")
|
| 201 |
+
|
| 202 |
+
def _find_wheels(self, options: Values, pattern: str) -> List[str]:
|
| 203 |
+
wheel_dir = self._cache_dir(options, "wheels")
|
| 204 |
+
|
| 205 |
+
# The wheel filename format, as specified in PEP 427, is:
|
| 206 |
+
# {distribution}-{version}(-{build})?-{python}-{abi}-{platform}.whl
|
| 207 |
+
#
|
| 208 |
+
# Additionally, non-alphanumeric values in the distribution are
|
| 209 |
+
# normalized to underscores (_), meaning hyphens can never occur
|
| 210 |
+
# before `-{version}`.
|
| 211 |
+
#
|
| 212 |
+
# Given that information:
|
| 213 |
+
# - If the pattern we're given contains a hyphen (-), the user is
|
| 214 |
+
# providing at least the version. Thus, we can just append `*.whl`
|
| 215 |
+
# to match the rest of it.
|
| 216 |
+
# - If the pattern we're given doesn't contain a hyphen (-), the
|
| 217 |
+
# user is only providing the name. Thus, we append `-*.whl` to
|
| 218 |
+
# match the hyphen before the version, followed by anything else.
|
| 219 |
+
#
|
| 220 |
+
# PEP 427: https://www.python.org/dev/peps/pep-0427/
|
| 221 |
+
pattern = pattern + ("*.whl" if "-" in pattern else "-*.whl")
|
| 222 |
+
|
| 223 |
+
return filesystem.find_files(wheel_dir, pattern)
|
venv/lib/python3.10/site-packages/pip/_internal/commands/check.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import logging
|
| 2 |
+
from optparse import Values
|
| 3 |
+
from typing import List
|
| 4 |
+
|
| 5 |
+
from pip._internal.cli.base_command import Command
|
| 6 |
+
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
| 7 |
+
from pip._internal.operations.check import (
|
| 8 |
+
check_package_set,
|
| 9 |
+
create_package_set_from_installed,
|
| 10 |
+
)
|
| 11 |
+
from pip._internal.utils.misc import write_output
|
| 12 |
+
|
| 13 |
+
logger = logging.getLogger(__name__)
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class CheckCommand(Command):
|
| 17 |
+
"""Verify installed packages have compatible dependencies."""
|
| 18 |
+
|
| 19 |
+
usage = """
|
| 20 |
+
%prog [options]"""
|
| 21 |
+
|
| 22 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 23 |
+
|
| 24 |
+
package_set, parsing_probs = create_package_set_from_installed()
|
| 25 |
+
missing, conflicting = check_package_set(package_set)
|
| 26 |
+
|
| 27 |
+
for project_name in missing:
|
| 28 |
+
version = package_set[project_name].version
|
| 29 |
+
for dependency in missing[project_name]:
|
| 30 |
+
write_output(
|
| 31 |
+
"%s %s requires %s, which is not installed.",
|
| 32 |
+
project_name,
|
| 33 |
+
version,
|
| 34 |
+
dependency[0],
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
for project_name in conflicting:
|
| 38 |
+
version = package_set[project_name].version
|
| 39 |
+
for dep_name, dep_version, req in conflicting[project_name]:
|
| 40 |
+
write_output(
|
| 41 |
+
"%s %s has requirement %s, but you have %s %s.",
|
| 42 |
+
project_name,
|
| 43 |
+
version,
|
| 44 |
+
req,
|
| 45 |
+
dep_name,
|
| 46 |
+
dep_version,
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
if missing or conflicting or parsing_probs:
|
| 50 |
+
return ERROR
|
| 51 |
+
else:
|
| 52 |
+
write_output("No broken requirements found.")
|
| 53 |
+
return SUCCESS
|
venv/lib/python3.10/site-packages/pip/_internal/commands/completion.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import textwrap
|
| 3 |
+
from optparse import Values
|
| 4 |
+
from typing import List
|
| 5 |
+
|
| 6 |
+
from pip._internal.cli.base_command import Command
|
| 7 |
+
from pip._internal.cli.status_codes import SUCCESS
|
| 8 |
+
from pip._internal.utils.misc import get_prog
|
| 9 |
+
|
| 10 |
+
BASE_COMPLETION = """
|
| 11 |
+
# pip {shell} completion start{script}# pip {shell} completion end
|
| 12 |
+
"""
|
| 13 |
+
|
| 14 |
+
COMPLETION_SCRIPTS = {
|
| 15 |
+
"bash": """
|
| 16 |
+
_pip_completion()
|
| 17 |
+
{{
|
| 18 |
+
COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\
|
| 19 |
+
COMP_CWORD=$COMP_CWORD \\
|
| 20 |
+
PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) )
|
| 21 |
+
}}
|
| 22 |
+
complete -o default -F _pip_completion {prog}
|
| 23 |
+
""",
|
| 24 |
+
"zsh": """
|
| 25 |
+
function _pip_completion {{
|
| 26 |
+
local words cword
|
| 27 |
+
read -Ac words
|
| 28 |
+
read -cn cword
|
| 29 |
+
reply=( $( COMP_WORDS="$words[*]" \\
|
| 30 |
+
COMP_CWORD=$(( cword-1 )) \\
|
| 31 |
+
PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null ))
|
| 32 |
+
}}
|
| 33 |
+
compctl -K _pip_completion {prog}
|
| 34 |
+
""",
|
| 35 |
+
"fish": """
|
| 36 |
+
function __fish_complete_pip
|
| 37 |
+
set -lx COMP_WORDS (commandline -o) ""
|
| 38 |
+
set -lx COMP_CWORD ( \\
|
| 39 |
+
math (contains -i -- (commandline -t) $COMP_WORDS)-1 \\
|
| 40 |
+
)
|
| 41 |
+
set -lx PIP_AUTO_COMPLETE 1
|
| 42 |
+
string split \\ -- (eval $COMP_WORDS[1])
|
| 43 |
+
end
|
| 44 |
+
complete -fa "(__fish_complete_pip)" -c {prog}
|
| 45 |
+
""",
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class CompletionCommand(Command):
|
| 50 |
+
"""A helper command to be used for command completion."""
|
| 51 |
+
|
| 52 |
+
ignore_require_venv = True
|
| 53 |
+
|
| 54 |
+
def add_options(self) -> None:
|
| 55 |
+
self.cmd_opts.add_option(
|
| 56 |
+
"--bash",
|
| 57 |
+
"-b",
|
| 58 |
+
action="store_const",
|
| 59 |
+
const="bash",
|
| 60 |
+
dest="shell",
|
| 61 |
+
help="Emit completion code for bash",
|
| 62 |
+
)
|
| 63 |
+
self.cmd_opts.add_option(
|
| 64 |
+
"--zsh",
|
| 65 |
+
"-z",
|
| 66 |
+
action="store_const",
|
| 67 |
+
const="zsh",
|
| 68 |
+
dest="shell",
|
| 69 |
+
help="Emit completion code for zsh",
|
| 70 |
+
)
|
| 71 |
+
self.cmd_opts.add_option(
|
| 72 |
+
"--fish",
|
| 73 |
+
"-f",
|
| 74 |
+
action="store_const",
|
| 75 |
+
const="fish",
|
| 76 |
+
dest="shell",
|
| 77 |
+
help="Emit completion code for fish",
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
self.parser.insert_option_group(0, self.cmd_opts)
|
| 81 |
+
|
| 82 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 83 |
+
"""Prints the completion code of the given shell"""
|
| 84 |
+
shells = COMPLETION_SCRIPTS.keys()
|
| 85 |
+
shell_options = ["--" + shell for shell in sorted(shells)]
|
| 86 |
+
if options.shell in shells:
|
| 87 |
+
script = textwrap.dedent(
|
| 88 |
+
COMPLETION_SCRIPTS.get(options.shell, "").format(prog=get_prog())
|
| 89 |
+
)
|
| 90 |
+
print(BASE_COMPLETION.format(script=script, shell=options.shell))
|
| 91 |
+
return SUCCESS
|
| 92 |
+
else:
|
| 93 |
+
sys.stderr.write(
|
| 94 |
+
"ERROR: You must pass {}\n".format(" or ".join(shell_options))
|
| 95 |
+
)
|
| 96 |
+
return SUCCESS
|
venv/lib/python3.10/site-packages/pip/_internal/commands/configuration.py
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import logging
|
| 2 |
+
import os
|
| 3 |
+
import subprocess
|
| 4 |
+
from optparse import Values
|
| 5 |
+
from typing import Any, List, Optional
|
| 6 |
+
|
| 7 |
+
from pip._internal.cli.base_command import Command
|
| 8 |
+
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
| 9 |
+
from pip._internal.configuration import (
|
| 10 |
+
Configuration,
|
| 11 |
+
Kind,
|
| 12 |
+
get_configuration_files,
|
| 13 |
+
kinds,
|
| 14 |
+
)
|
| 15 |
+
from pip._internal.exceptions import PipError
|
| 16 |
+
from pip._internal.utils.logging import indent_log
|
| 17 |
+
from pip._internal.utils.misc import get_prog, write_output
|
| 18 |
+
|
| 19 |
+
logger = logging.getLogger(__name__)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class ConfigurationCommand(Command):
|
| 23 |
+
"""
|
| 24 |
+
Manage local and global configuration.
|
| 25 |
+
|
| 26 |
+
Subcommands:
|
| 27 |
+
|
| 28 |
+
- list: List the active configuration (or from the file specified)
|
| 29 |
+
- edit: Edit the configuration file in an editor
|
| 30 |
+
- get: Get the value associated with name
|
| 31 |
+
- set: Set the name=value
|
| 32 |
+
- unset: Unset the value associated with name
|
| 33 |
+
- debug: List the configuration files and values defined under them
|
| 34 |
+
|
| 35 |
+
If none of --user, --global and --site are passed, a virtual
|
| 36 |
+
environment configuration file is used if one is active and the file
|
| 37 |
+
exists. Otherwise, all modifications happen to the user file by
|
| 38 |
+
default.
|
| 39 |
+
"""
|
| 40 |
+
|
| 41 |
+
ignore_require_venv = True
|
| 42 |
+
usage = """
|
| 43 |
+
%prog [<file-option>] list
|
| 44 |
+
%prog [<file-option>] [--editor <editor-path>] edit
|
| 45 |
+
|
| 46 |
+
%prog [<file-option>] get name
|
| 47 |
+
%prog [<file-option>] set name value
|
| 48 |
+
%prog [<file-option>] unset name
|
| 49 |
+
%prog [<file-option>] debug
|
| 50 |
+
"""
|
| 51 |
+
|
| 52 |
+
def add_options(self) -> None:
|
| 53 |
+
self.cmd_opts.add_option(
|
| 54 |
+
"--editor",
|
| 55 |
+
dest="editor",
|
| 56 |
+
action="store",
|
| 57 |
+
default=None,
|
| 58 |
+
help=(
|
| 59 |
+
"Editor to use to edit the file. Uses VISUAL or EDITOR "
|
| 60 |
+
"environment variables if not provided."
|
| 61 |
+
),
|
| 62 |
+
)
|
| 63 |
+
|
| 64 |
+
self.cmd_opts.add_option(
|
| 65 |
+
"--global",
|
| 66 |
+
dest="global_file",
|
| 67 |
+
action="store_true",
|
| 68 |
+
default=False,
|
| 69 |
+
help="Use the system-wide configuration file only",
|
| 70 |
+
)
|
| 71 |
+
|
| 72 |
+
self.cmd_opts.add_option(
|
| 73 |
+
"--user",
|
| 74 |
+
dest="user_file",
|
| 75 |
+
action="store_true",
|
| 76 |
+
default=False,
|
| 77 |
+
help="Use the user configuration file only",
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
self.cmd_opts.add_option(
|
| 81 |
+
"--site",
|
| 82 |
+
dest="site_file",
|
| 83 |
+
action="store_true",
|
| 84 |
+
default=False,
|
| 85 |
+
help="Use the current environment configuration file only",
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
self.parser.insert_option_group(0, self.cmd_opts)
|
| 89 |
+
|
| 90 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 91 |
+
handlers = {
|
| 92 |
+
"list": self.list_values,
|
| 93 |
+
"edit": self.open_in_editor,
|
| 94 |
+
"get": self.get_name,
|
| 95 |
+
"set": self.set_name_value,
|
| 96 |
+
"unset": self.unset_name,
|
| 97 |
+
"debug": self.list_config_values,
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
# Determine action
|
| 101 |
+
if not args or args[0] not in handlers:
|
| 102 |
+
logger.error(
|
| 103 |
+
"Need an action (%s) to perform.",
|
| 104 |
+
", ".join(sorted(handlers)),
|
| 105 |
+
)
|
| 106 |
+
return ERROR
|
| 107 |
+
|
| 108 |
+
action = args[0]
|
| 109 |
+
|
| 110 |
+
# Determine which configuration files are to be loaded
|
| 111 |
+
# Depends on whether the command is modifying.
|
| 112 |
+
try:
|
| 113 |
+
load_only = self._determine_file(
|
| 114 |
+
options, need_value=(action in ["get", "set", "unset", "edit"])
|
| 115 |
+
)
|
| 116 |
+
except PipError as e:
|
| 117 |
+
logger.error(e.args[0])
|
| 118 |
+
return ERROR
|
| 119 |
+
|
| 120 |
+
# Load a new configuration
|
| 121 |
+
self.configuration = Configuration(
|
| 122 |
+
isolated=options.isolated_mode, load_only=load_only
|
| 123 |
+
)
|
| 124 |
+
self.configuration.load()
|
| 125 |
+
|
| 126 |
+
# Error handling happens here, not in the action-handlers.
|
| 127 |
+
try:
|
| 128 |
+
handlers[action](options, args[1:])
|
| 129 |
+
except PipError as e:
|
| 130 |
+
logger.error(e.args[0])
|
| 131 |
+
return ERROR
|
| 132 |
+
|
| 133 |
+
return SUCCESS
|
| 134 |
+
|
| 135 |
+
def _determine_file(self, options: Values, need_value: bool) -> Optional[Kind]:
|
| 136 |
+
file_options = [
|
| 137 |
+
key
|
| 138 |
+
for key, value in (
|
| 139 |
+
(kinds.USER, options.user_file),
|
| 140 |
+
(kinds.GLOBAL, options.global_file),
|
| 141 |
+
(kinds.SITE, options.site_file),
|
| 142 |
+
)
|
| 143 |
+
if value
|
| 144 |
+
]
|
| 145 |
+
|
| 146 |
+
if not file_options:
|
| 147 |
+
if not need_value:
|
| 148 |
+
return None
|
| 149 |
+
# Default to user, unless there's a site file.
|
| 150 |
+
elif any(
|
| 151 |
+
os.path.exists(site_config_file)
|
| 152 |
+
for site_config_file in get_configuration_files()[kinds.SITE]
|
| 153 |
+
):
|
| 154 |
+
return kinds.SITE
|
| 155 |
+
else:
|
| 156 |
+
return kinds.USER
|
| 157 |
+
elif len(file_options) == 1:
|
| 158 |
+
return file_options[0]
|
| 159 |
+
|
| 160 |
+
raise PipError(
|
| 161 |
+
"Need exactly one file to operate upon "
|
| 162 |
+
"(--user, --site, --global) to perform."
|
| 163 |
+
)
|
| 164 |
+
|
| 165 |
+
def list_values(self, options: Values, args: List[str]) -> None:
|
| 166 |
+
self._get_n_args(args, "list", n=0)
|
| 167 |
+
|
| 168 |
+
for key, value in sorted(self.configuration.items()):
|
| 169 |
+
write_output("%s=%r", key, value)
|
| 170 |
+
|
| 171 |
+
def get_name(self, options: Values, args: List[str]) -> None:
|
| 172 |
+
key = self._get_n_args(args, "get [name]", n=1)
|
| 173 |
+
value = self.configuration.get_value(key)
|
| 174 |
+
|
| 175 |
+
write_output("%s", value)
|
| 176 |
+
|
| 177 |
+
def set_name_value(self, options: Values, args: List[str]) -> None:
|
| 178 |
+
key, value = self._get_n_args(args, "set [name] [value]", n=2)
|
| 179 |
+
self.configuration.set_value(key, value)
|
| 180 |
+
|
| 181 |
+
self._save_configuration()
|
| 182 |
+
|
| 183 |
+
def unset_name(self, options: Values, args: List[str]) -> None:
|
| 184 |
+
key = self._get_n_args(args, "unset [name]", n=1)
|
| 185 |
+
self.configuration.unset_value(key)
|
| 186 |
+
|
| 187 |
+
self._save_configuration()
|
| 188 |
+
|
| 189 |
+
def list_config_values(self, options: Values, args: List[str]) -> None:
|
| 190 |
+
"""List config key-value pairs across different config files"""
|
| 191 |
+
self._get_n_args(args, "debug", n=0)
|
| 192 |
+
|
| 193 |
+
self.print_env_var_values()
|
| 194 |
+
# Iterate over config files and print if they exist, and the
|
| 195 |
+
# key-value pairs present in them if they do
|
| 196 |
+
for variant, files in sorted(self.configuration.iter_config_files()):
|
| 197 |
+
write_output("%s:", variant)
|
| 198 |
+
for fname in files:
|
| 199 |
+
with indent_log():
|
| 200 |
+
file_exists = os.path.exists(fname)
|
| 201 |
+
write_output("%s, exists: %r", fname, file_exists)
|
| 202 |
+
if file_exists:
|
| 203 |
+
self.print_config_file_values(variant)
|
| 204 |
+
|
| 205 |
+
def print_config_file_values(self, variant: Kind) -> None:
|
| 206 |
+
"""Get key-value pairs from the file of a variant"""
|
| 207 |
+
for name, value in self.configuration.get_values_in_config(variant).items():
|
| 208 |
+
with indent_log():
|
| 209 |
+
write_output("%s: %s", name, value)
|
| 210 |
+
|
| 211 |
+
def print_env_var_values(self) -> None:
|
| 212 |
+
"""Get key-values pairs present as environment variables"""
|
| 213 |
+
write_output("%s:", "env_var")
|
| 214 |
+
with indent_log():
|
| 215 |
+
for key, value in sorted(self.configuration.get_environ_vars()):
|
| 216 |
+
env_var = f"PIP_{key.upper()}"
|
| 217 |
+
write_output("%s=%r", env_var, value)
|
| 218 |
+
|
| 219 |
+
def open_in_editor(self, options: Values, args: List[str]) -> None:
|
| 220 |
+
editor = self._determine_editor(options)
|
| 221 |
+
|
| 222 |
+
fname = self.configuration.get_file_to_edit()
|
| 223 |
+
if fname is None:
|
| 224 |
+
raise PipError("Could not determine appropriate file.")
|
| 225 |
+
|
| 226 |
+
try:
|
| 227 |
+
subprocess.check_call([editor, fname])
|
| 228 |
+
except subprocess.CalledProcessError as e:
|
| 229 |
+
raise PipError(
|
| 230 |
+
"Editor Subprocess exited with exit code {}".format(e.returncode)
|
| 231 |
+
)
|
| 232 |
+
|
| 233 |
+
def _get_n_args(self, args: List[str], example: str, n: int) -> Any:
|
| 234 |
+
"""Helper to make sure the command got the right number of arguments"""
|
| 235 |
+
if len(args) != n:
|
| 236 |
+
msg = (
|
| 237 |
+
"Got unexpected number of arguments, expected {}. "
|
| 238 |
+
'(example: "{} config {}")'
|
| 239 |
+
).format(n, get_prog(), example)
|
| 240 |
+
raise PipError(msg)
|
| 241 |
+
|
| 242 |
+
if n == 1:
|
| 243 |
+
return args[0]
|
| 244 |
+
else:
|
| 245 |
+
return args
|
| 246 |
+
|
| 247 |
+
def _save_configuration(self) -> None:
|
| 248 |
+
# We successfully ran a modifying command. Need to save the
|
| 249 |
+
# configuration.
|
| 250 |
+
try:
|
| 251 |
+
self.configuration.save()
|
| 252 |
+
except Exception:
|
| 253 |
+
logger.exception(
|
| 254 |
+
"Unable to save configuration. Please report this as a bug."
|
| 255 |
+
)
|
| 256 |
+
raise PipError("Internal Error.")
|
| 257 |
+
|
| 258 |
+
def _determine_editor(self, options: Values) -> str:
|
| 259 |
+
if options.editor is not None:
|
| 260 |
+
return options.editor
|
| 261 |
+
elif "VISUAL" in os.environ:
|
| 262 |
+
return os.environ["VISUAL"]
|
| 263 |
+
elif "EDITOR" in os.environ:
|
| 264 |
+
return os.environ["EDITOR"]
|
| 265 |
+
else:
|
| 266 |
+
raise PipError("Could not determine editor to use.")
|
venv/lib/python3.10/site-packages/pip/_internal/commands/debug.py
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import locale
|
| 2 |
+
import logging
|
| 3 |
+
import os
|
| 4 |
+
import sys
|
| 5 |
+
from optparse import Values
|
| 6 |
+
from types import ModuleType
|
| 7 |
+
from typing import Any, Dict, List, Optional
|
| 8 |
+
|
| 9 |
+
import pip._vendor
|
| 10 |
+
from pip._vendor.certifi import where
|
| 11 |
+
from pip._vendor.packaging.version import parse as parse_version
|
| 12 |
+
|
| 13 |
+
from pip import __file__ as pip_location
|
| 14 |
+
from pip._internal.cli import cmdoptions
|
| 15 |
+
from pip._internal.cli.base_command import Command
|
| 16 |
+
from pip._internal.cli.cmdoptions import make_target_python
|
| 17 |
+
from pip._internal.cli.status_codes import SUCCESS
|
| 18 |
+
from pip._internal.configuration import Configuration
|
| 19 |
+
from pip._internal.metadata import get_environment
|
| 20 |
+
from pip._internal.utils.logging import indent_log
|
| 21 |
+
from pip._internal.utils.misc import get_pip_version
|
| 22 |
+
|
| 23 |
+
logger = logging.getLogger(__name__)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def show_value(name: str, value: Any) -> None:
|
| 27 |
+
logger.info("%s: %s", name, value)
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def show_sys_implementation() -> None:
|
| 31 |
+
logger.info("sys.implementation:")
|
| 32 |
+
implementation_name = sys.implementation.name
|
| 33 |
+
with indent_log():
|
| 34 |
+
show_value("name", implementation_name)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def create_vendor_txt_map() -> Dict[str, str]:
|
| 38 |
+
vendor_txt_path = os.path.join(
|
| 39 |
+
os.path.dirname(pip_location), "_vendor", "vendor.txt"
|
| 40 |
+
)
|
| 41 |
+
|
| 42 |
+
with open(vendor_txt_path) as f:
|
| 43 |
+
# Purge non version specifying lines.
|
| 44 |
+
# Also, remove any space prefix or suffixes (including comments).
|
| 45 |
+
lines = [
|
| 46 |
+
line.strip().split(" ", 1)[0] for line in f.readlines() if "==" in line
|
| 47 |
+
]
|
| 48 |
+
|
| 49 |
+
# Transform into "module" -> version dict.
|
| 50 |
+
return dict(line.split("==", 1) for line in lines) # type: ignore
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def get_module_from_module_name(module_name: str) -> ModuleType:
|
| 54 |
+
# Module name can be uppercase in vendor.txt for some reason...
|
| 55 |
+
module_name = module_name.lower()
|
| 56 |
+
# PATCH: setuptools is actually only pkg_resources.
|
| 57 |
+
if module_name == "setuptools":
|
| 58 |
+
module_name = "pkg_resources"
|
| 59 |
+
|
| 60 |
+
__import__(f"pip._vendor.{module_name}", globals(), locals(), level=0)
|
| 61 |
+
return getattr(pip._vendor, module_name)
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def get_vendor_version_from_module(module_name: str) -> Optional[str]:
|
| 65 |
+
module = get_module_from_module_name(module_name)
|
| 66 |
+
version = getattr(module, "__version__", None)
|
| 67 |
+
|
| 68 |
+
if not version:
|
| 69 |
+
# Try to find version in debundled module info.
|
| 70 |
+
env = get_environment([os.path.dirname(module.__file__)])
|
| 71 |
+
dist = env.get_distribution(module_name)
|
| 72 |
+
if dist:
|
| 73 |
+
version = str(dist.version)
|
| 74 |
+
|
| 75 |
+
return version
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def show_actual_vendor_versions(vendor_txt_versions: Dict[str, str]) -> None:
|
| 79 |
+
"""Log the actual version and print extra info if there is
|
| 80 |
+
a conflict or if the actual version could not be imported.
|
| 81 |
+
"""
|
| 82 |
+
for module_name, expected_version in vendor_txt_versions.items():
|
| 83 |
+
extra_message = ""
|
| 84 |
+
actual_version = get_vendor_version_from_module(module_name)
|
| 85 |
+
if not actual_version:
|
| 86 |
+
extra_message = (
|
| 87 |
+
" (Unable to locate actual module version, using"
|
| 88 |
+
" vendor.txt specified version)"
|
| 89 |
+
)
|
| 90 |
+
actual_version = expected_version
|
| 91 |
+
elif parse_version(actual_version) != parse_version(expected_version):
|
| 92 |
+
extra_message = (
|
| 93 |
+
" (CONFLICT: vendor.txt suggests version should"
|
| 94 |
+
" be {})".format(expected_version)
|
| 95 |
+
)
|
| 96 |
+
logger.info("%s==%s%s", module_name, actual_version, extra_message)
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def show_vendor_versions() -> None:
|
| 100 |
+
logger.info("vendored library versions:")
|
| 101 |
+
|
| 102 |
+
vendor_txt_versions = create_vendor_txt_map()
|
| 103 |
+
with indent_log():
|
| 104 |
+
show_actual_vendor_versions(vendor_txt_versions)
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def show_tags(options: Values) -> None:
|
| 108 |
+
tag_limit = 10
|
| 109 |
+
|
| 110 |
+
target_python = make_target_python(options)
|
| 111 |
+
tags = target_python.get_tags()
|
| 112 |
+
|
| 113 |
+
# Display the target options that were explicitly provided.
|
| 114 |
+
formatted_target = target_python.format_given()
|
| 115 |
+
suffix = ""
|
| 116 |
+
if formatted_target:
|
| 117 |
+
suffix = f" (target: {formatted_target})"
|
| 118 |
+
|
| 119 |
+
msg = "Compatible tags: {}{}".format(len(tags), suffix)
|
| 120 |
+
logger.info(msg)
|
| 121 |
+
|
| 122 |
+
if options.verbose < 1 and len(tags) > tag_limit:
|
| 123 |
+
tags_limited = True
|
| 124 |
+
tags = tags[:tag_limit]
|
| 125 |
+
else:
|
| 126 |
+
tags_limited = False
|
| 127 |
+
|
| 128 |
+
with indent_log():
|
| 129 |
+
for tag in tags:
|
| 130 |
+
logger.info(str(tag))
|
| 131 |
+
|
| 132 |
+
if tags_limited:
|
| 133 |
+
msg = (
|
| 134 |
+
"...\n[First {tag_limit} tags shown. Pass --verbose to show all.]"
|
| 135 |
+
).format(tag_limit=tag_limit)
|
| 136 |
+
logger.info(msg)
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
def ca_bundle_info(config: Configuration) -> str:
|
| 140 |
+
levels = set()
|
| 141 |
+
for key, _ in config.items():
|
| 142 |
+
levels.add(key.split(".")[0])
|
| 143 |
+
|
| 144 |
+
if not levels:
|
| 145 |
+
return "Not specified"
|
| 146 |
+
|
| 147 |
+
levels_that_override_global = ["install", "wheel", "download"]
|
| 148 |
+
global_overriding_level = [
|
| 149 |
+
level for level in levels if level in levels_that_override_global
|
| 150 |
+
]
|
| 151 |
+
if not global_overriding_level:
|
| 152 |
+
return "global"
|
| 153 |
+
|
| 154 |
+
if "global" in levels:
|
| 155 |
+
levels.remove("global")
|
| 156 |
+
return ", ".join(levels)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
class DebugCommand(Command):
|
| 160 |
+
"""
|
| 161 |
+
Display debug information.
|
| 162 |
+
"""
|
| 163 |
+
|
| 164 |
+
usage = """
|
| 165 |
+
%prog <options>"""
|
| 166 |
+
ignore_require_venv = True
|
| 167 |
+
|
| 168 |
+
def add_options(self) -> None:
|
| 169 |
+
cmdoptions.add_target_python_options(self.cmd_opts)
|
| 170 |
+
self.parser.insert_option_group(0, self.cmd_opts)
|
| 171 |
+
self.parser.config.load()
|
| 172 |
+
|
| 173 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 174 |
+
logger.warning(
|
| 175 |
+
"This command is only meant for debugging. "
|
| 176 |
+
"Do not use this with automation for parsing and getting these "
|
| 177 |
+
"details, since the output and options of this command may "
|
| 178 |
+
"change without notice."
|
| 179 |
+
)
|
| 180 |
+
show_value("pip version", get_pip_version())
|
| 181 |
+
show_value("sys.version", sys.version)
|
| 182 |
+
show_value("sys.executable", sys.executable)
|
| 183 |
+
show_value("sys.getdefaultencoding", sys.getdefaultencoding())
|
| 184 |
+
show_value("sys.getfilesystemencoding", sys.getfilesystemencoding())
|
| 185 |
+
show_value(
|
| 186 |
+
"locale.getpreferredencoding",
|
| 187 |
+
locale.getpreferredencoding(),
|
| 188 |
+
)
|
| 189 |
+
show_value("sys.platform", sys.platform)
|
| 190 |
+
show_sys_implementation()
|
| 191 |
+
|
| 192 |
+
show_value("'cert' config value", ca_bundle_info(self.parser.config))
|
| 193 |
+
show_value("REQUESTS_CA_BUNDLE", os.environ.get("REQUESTS_CA_BUNDLE"))
|
| 194 |
+
show_value("CURL_CA_BUNDLE", os.environ.get("CURL_CA_BUNDLE"))
|
| 195 |
+
show_value("pip._vendor.certifi.where()", where())
|
| 196 |
+
show_value("pip._vendor.DEBUNDLED", pip._vendor.DEBUNDLED)
|
| 197 |
+
|
| 198 |
+
show_vendor_versions()
|
| 199 |
+
|
| 200 |
+
show_tags(options)
|
| 201 |
+
|
| 202 |
+
return SUCCESS
|
venv/lib/python3.10/site-packages/pip/_internal/commands/download.py
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import logging
|
| 2 |
+
import os
|
| 3 |
+
from optparse import Values
|
| 4 |
+
from typing import List
|
| 5 |
+
|
| 6 |
+
from pip._internal.cli import cmdoptions
|
| 7 |
+
from pip._internal.cli.cmdoptions import make_target_python
|
| 8 |
+
from pip._internal.cli.req_command import RequirementCommand, with_cleanup
|
| 9 |
+
from pip._internal.cli.status_codes import SUCCESS
|
| 10 |
+
from pip._internal.req.req_tracker import get_requirement_tracker
|
| 11 |
+
from pip._internal.utils.misc import ensure_dir, normalize_path, write_output
|
| 12 |
+
from pip._internal.utils.temp_dir import TempDirectory
|
| 13 |
+
|
| 14 |
+
logger = logging.getLogger(__name__)
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class DownloadCommand(RequirementCommand):
|
| 18 |
+
"""
|
| 19 |
+
Download packages from:
|
| 20 |
+
|
| 21 |
+
- PyPI (and other indexes) using requirement specifiers.
|
| 22 |
+
- VCS project urls.
|
| 23 |
+
- Local project directories.
|
| 24 |
+
- Local or remote source archives.
|
| 25 |
+
|
| 26 |
+
pip also supports downloading from "requirements files", which provide
|
| 27 |
+
an easy way to specify a whole environment to be downloaded.
|
| 28 |
+
"""
|
| 29 |
+
|
| 30 |
+
usage = """
|
| 31 |
+
%prog [options] <requirement specifier> [package-index-options] ...
|
| 32 |
+
%prog [options] -r <requirements file> [package-index-options] ...
|
| 33 |
+
%prog [options] <vcs project url> ...
|
| 34 |
+
%prog [options] <local project path> ...
|
| 35 |
+
%prog [options] <archive url/path> ..."""
|
| 36 |
+
|
| 37 |
+
def add_options(self) -> None:
|
| 38 |
+
self.cmd_opts.add_option(cmdoptions.constraints())
|
| 39 |
+
self.cmd_opts.add_option(cmdoptions.requirements())
|
| 40 |
+
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 |
+
self.cmd_opts.add_option(cmdoptions.src())
|
| 46 |
+
self.cmd_opts.add_option(cmdoptions.pre())
|
| 47 |
+
self.cmd_opts.add_option(cmdoptions.require_hashes())
|
| 48 |
+
self.cmd_opts.add_option(cmdoptions.progress_bar())
|
| 49 |
+
self.cmd_opts.add_option(cmdoptions.no_build_isolation())
|
| 50 |
+
self.cmd_opts.add_option(cmdoptions.use_pep517())
|
| 51 |
+
self.cmd_opts.add_option(cmdoptions.no_use_pep517())
|
| 52 |
+
self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
|
| 53 |
+
|
| 54 |
+
self.cmd_opts.add_option(
|
| 55 |
+
"-d",
|
| 56 |
+
"--dest",
|
| 57 |
+
"--destination-dir",
|
| 58 |
+
"--destination-directory",
|
| 59 |
+
dest="download_dir",
|
| 60 |
+
metavar="dir",
|
| 61 |
+
default=os.curdir,
|
| 62 |
+
help="Download packages into <dir>.",
|
| 63 |
+
)
|
| 64 |
+
|
| 65 |
+
cmdoptions.add_target_python_options(self.cmd_opts)
|
| 66 |
+
|
| 67 |
+
index_opts = cmdoptions.make_option_group(
|
| 68 |
+
cmdoptions.index_group,
|
| 69 |
+
self.parser,
|
| 70 |
+
)
|
| 71 |
+
|
| 72 |
+
self.parser.insert_option_group(0, index_opts)
|
| 73 |
+
self.parser.insert_option_group(0, self.cmd_opts)
|
| 74 |
+
|
| 75 |
+
@with_cleanup
|
| 76 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 77 |
+
|
| 78 |
+
options.ignore_installed = True
|
| 79 |
+
# editable doesn't really make sense for `pip download`, but the bowels
|
| 80 |
+
# of the RequirementSet code require that property.
|
| 81 |
+
options.editables = []
|
| 82 |
+
|
| 83 |
+
cmdoptions.check_dist_restriction(options)
|
| 84 |
+
|
| 85 |
+
options.download_dir = normalize_path(options.download_dir)
|
| 86 |
+
ensure_dir(options.download_dir)
|
| 87 |
+
|
| 88 |
+
session = self.get_default_session(options)
|
| 89 |
+
|
| 90 |
+
target_python = make_target_python(options)
|
| 91 |
+
finder = self._build_package_finder(
|
| 92 |
+
options=options,
|
| 93 |
+
session=session,
|
| 94 |
+
target_python=target_python,
|
| 95 |
+
ignore_requires_python=options.ignore_requires_python,
|
| 96 |
+
)
|
| 97 |
+
|
| 98 |
+
req_tracker = self.enter_context(get_requirement_tracker())
|
| 99 |
+
|
| 100 |
+
directory = TempDirectory(
|
| 101 |
+
delete=not options.no_clean,
|
| 102 |
+
kind="download",
|
| 103 |
+
globally_managed=True,
|
| 104 |
+
)
|
| 105 |
+
|
| 106 |
+
reqs = self.get_requirements(args, options, finder, session)
|
| 107 |
+
|
| 108 |
+
preparer = self.make_requirement_preparer(
|
| 109 |
+
temp_build_dir=directory,
|
| 110 |
+
options=options,
|
| 111 |
+
req_tracker=req_tracker,
|
| 112 |
+
session=session,
|
| 113 |
+
finder=finder,
|
| 114 |
+
download_dir=options.download_dir,
|
| 115 |
+
use_user_site=False,
|
| 116 |
+
verbosity=self.verbosity,
|
| 117 |
+
)
|
| 118 |
+
|
| 119 |
+
resolver = self.make_resolver(
|
| 120 |
+
preparer=preparer,
|
| 121 |
+
finder=finder,
|
| 122 |
+
options=options,
|
| 123 |
+
ignore_requires_python=options.ignore_requires_python,
|
| 124 |
+
py_version_info=options.python_version,
|
| 125 |
+
)
|
| 126 |
+
|
| 127 |
+
self.trace_basic_info(finder)
|
| 128 |
+
|
| 129 |
+
requirement_set = resolver.resolve(reqs, check_supported_wheels=True)
|
| 130 |
+
|
| 131 |
+
downloaded: List[str] = []
|
| 132 |
+
for req in requirement_set.requirements.values():
|
| 133 |
+
if req.satisfied_by is None:
|
| 134 |
+
assert req.name is not None
|
| 135 |
+
preparer.save_linked_requirement(req)
|
| 136 |
+
downloaded.append(req.name)
|
| 137 |
+
if downloaded:
|
| 138 |
+
write_output("Successfully downloaded %s", " ".join(downloaded))
|
| 139 |
+
|
| 140 |
+
return SUCCESS
|
venv/lib/python3.10/site-packages/pip/_internal/commands/freeze.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from optparse import Values
|
| 3 |
+
from typing import List
|
| 4 |
+
|
| 5 |
+
from pip._internal.cli import cmdoptions
|
| 6 |
+
from pip._internal.cli.base_command import Command
|
| 7 |
+
from pip._internal.cli.status_codes import SUCCESS
|
| 8 |
+
from pip._internal.operations.freeze import freeze
|
| 9 |
+
from pip._internal.utils.compat import stdlib_pkgs
|
| 10 |
+
|
| 11 |
+
DEV_PKGS = {"pip", "setuptools", "distribute", "wheel", "pkg-resources"}
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class FreezeCommand(Command):
|
| 15 |
+
"""
|
| 16 |
+
Output installed packages in requirements format.
|
| 17 |
+
|
| 18 |
+
packages are listed in a case-insensitive sorted order.
|
| 19 |
+
"""
|
| 20 |
+
|
| 21 |
+
usage = """
|
| 22 |
+
%prog [options]"""
|
| 23 |
+
log_streams = ("ext://sys.stderr", "ext://sys.stderr")
|
| 24 |
+
|
| 25 |
+
def add_options(self) -> None:
|
| 26 |
+
self.cmd_opts.add_option(
|
| 27 |
+
"-r",
|
| 28 |
+
"--requirement",
|
| 29 |
+
dest="requirements",
|
| 30 |
+
action="append",
|
| 31 |
+
default=[],
|
| 32 |
+
metavar="file",
|
| 33 |
+
help=(
|
| 34 |
+
"Use the order in the given requirements file and its "
|
| 35 |
+
"comments when generating output. This option can be "
|
| 36 |
+
"used multiple times."
|
| 37 |
+
),
|
| 38 |
+
)
|
| 39 |
+
self.cmd_opts.add_option(
|
| 40 |
+
"-l",
|
| 41 |
+
"--local",
|
| 42 |
+
dest="local",
|
| 43 |
+
action="store_true",
|
| 44 |
+
default=False,
|
| 45 |
+
help=(
|
| 46 |
+
"If in a virtualenv that has global access, do not output "
|
| 47 |
+
"globally-installed packages."
|
| 48 |
+
),
|
| 49 |
+
)
|
| 50 |
+
self.cmd_opts.add_option(
|
| 51 |
+
"--user",
|
| 52 |
+
dest="user",
|
| 53 |
+
action="store_true",
|
| 54 |
+
default=False,
|
| 55 |
+
help="Only output packages installed in user-site.",
|
| 56 |
+
)
|
| 57 |
+
self.cmd_opts.add_option(cmdoptions.list_path())
|
| 58 |
+
self.cmd_opts.add_option(
|
| 59 |
+
"--all",
|
| 60 |
+
dest="freeze_all",
|
| 61 |
+
action="store_true",
|
| 62 |
+
help=(
|
| 63 |
+
"Do not skip these packages in the output:"
|
| 64 |
+
" {}".format(", ".join(DEV_PKGS))
|
| 65 |
+
),
|
| 66 |
+
)
|
| 67 |
+
self.cmd_opts.add_option(
|
| 68 |
+
"--exclude-editable",
|
| 69 |
+
dest="exclude_editable",
|
| 70 |
+
action="store_true",
|
| 71 |
+
help="Exclude editable package from output.",
|
| 72 |
+
)
|
| 73 |
+
self.cmd_opts.add_option(cmdoptions.list_exclude())
|
| 74 |
+
|
| 75 |
+
self.parser.insert_option_group(0, self.cmd_opts)
|
| 76 |
+
|
| 77 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 78 |
+
skip = set(stdlib_pkgs)
|
| 79 |
+
if not options.freeze_all:
|
| 80 |
+
skip.update(DEV_PKGS)
|
| 81 |
+
|
| 82 |
+
if options.excludes:
|
| 83 |
+
skip.update(options.excludes)
|
| 84 |
+
|
| 85 |
+
cmdoptions.check_list_path_option(options)
|
| 86 |
+
|
| 87 |
+
for line in freeze(
|
| 88 |
+
requirement=options.requirements,
|
| 89 |
+
local_only=options.local,
|
| 90 |
+
user_only=options.user,
|
| 91 |
+
paths=options.path,
|
| 92 |
+
isolated=options.isolated_mode,
|
| 93 |
+
skip=skip,
|
| 94 |
+
exclude_editable=options.exclude_editable,
|
| 95 |
+
):
|
| 96 |
+
sys.stdout.write(line + "\n")
|
| 97 |
+
return SUCCESS
|