Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__init__.py +3 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/index_command.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/autocompletion.py +175 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/base_command.py +233 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/cmdoptions.py +1133 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/command_context.py +27 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/index_command.py +173 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/main.py +79 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/main_parser.py +133 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/parser.py +294 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py +144 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/req_command.py +347 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/spinners.py +159 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/status_codes.py +6 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__init__.py +137 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc +0 -0
- ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc +0 -0
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (704 Bytes). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc
ADDED
|
Binary file (9.92 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc
ADDED
|
Binary file (9.05 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc
ADDED
|
Binary file (11.7 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc
ADDED
|
Binary file (30.1 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc
ADDED
|
Binary file (628 Bytes). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc
ADDED
|
Binary file (3.77 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc
ADDED
|
Binary file (6.87 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc
ADDED
|
Binary file (8.37 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__init__.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Subpackage containing all of pip's command line interface related code"""
|
| 2 |
+
|
| 3 |
+
# This file intentionally does not import submodules
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (282 Bytes). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc
ADDED
|
Binary file (5.46 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc
ADDED
|
Binary file (6.35 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc
ADDED
|
Binary file (25 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc
ADDED
|
Binary file (1.32 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/index_command.cpython-310.pyc
ADDED
|
Binary file (5.02 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc
ADDED
|
Binary file (1.52 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc
ADDED
|
Binary file (3.01 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc
ADDED
|
Binary file (9.99 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc
ADDED
|
Binary file (3.87 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc
ADDED
|
Binary file (8.99 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc
ADDED
|
Binary file (4.97 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc
ADDED
|
Binary file (362 Bytes). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/autocompletion.py
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Logic that powers autocompletion installed by ``pip completion``."""
|
| 2 |
+
|
| 3 |
+
import optparse
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
from itertools import chain
|
| 7 |
+
from typing import Any, Iterable, List, Optional
|
| 8 |
+
|
| 9 |
+
from pip._internal.cli.main_parser import create_main_parser
|
| 10 |
+
from pip._internal.commands import commands_dict, create_command
|
| 11 |
+
from pip._internal.metadata import get_default_environment
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def autocomplete() -> None:
|
| 15 |
+
"""Entry Point for completion of main and subcommand options."""
|
| 16 |
+
# Don't complete if user hasn't sourced bash_completion file.
|
| 17 |
+
if "PIP_AUTO_COMPLETE" not in os.environ:
|
| 18 |
+
return
|
| 19 |
+
# Don't complete if autocompletion environment variables
|
| 20 |
+
# are not present
|
| 21 |
+
if not os.environ.get("COMP_WORDS") or not os.environ.get("COMP_CWORD"):
|
| 22 |
+
return
|
| 23 |
+
cwords = os.environ["COMP_WORDS"].split()[1:]
|
| 24 |
+
cword = int(os.environ["COMP_CWORD"])
|
| 25 |
+
try:
|
| 26 |
+
current = cwords[cword - 1]
|
| 27 |
+
except IndexError:
|
| 28 |
+
current = ""
|
| 29 |
+
|
| 30 |
+
parser = create_main_parser()
|
| 31 |
+
subcommands = list(commands_dict)
|
| 32 |
+
options = []
|
| 33 |
+
|
| 34 |
+
# subcommand
|
| 35 |
+
subcommand_name: Optional[str] = None
|
| 36 |
+
for word in cwords:
|
| 37 |
+
if word in subcommands:
|
| 38 |
+
subcommand_name = word
|
| 39 |
+
break
|
| 40 |
+
# subcommand options
|
| 41 |
+
if subcommand_name is not None:
|
| 42 |
+
# special case: 'help' subcommand has no options
|
| 43 |
+
if subcommand_name == "help":
|
| 44 |
+
sys.exit(1)
|
| 45 |
+
# special case: list locally installed dists for show and uninstall
|
| 46 |
+
should_list_installed = not current.startswith("-") and subcommand_name in [
|
| 47 |
+
"show",
|
| 48 |
+
"uninstall",
|
| 49 |
+
]
|
| 50 |
+
if should_list_installed:
|
| 51 |
+
env = get_default_environment()
|
| 52 |
+
lc = current.lower()
|
| 53 |
+
installed = [
|
| 54 |
+
dist.canonical_name
|
| 55 |
+
for dist in env.iter_installed_distributions(local_only=True)
|
| 56 |
+
if dist.canonical_name.startswith(lc)
|
| 57 |
+
and dist.canonical_name not in cwords[1:]
|
| 58 |
+
]
|
| 59 |
+
# if there are no dists installed, fall back to option completion
|
| 60 |
+
if installed:
|
| 61 |
+
for dist in installed:
|
| 62 |
+
print(dist)
|
| 63 |
+
sys.exit(1)
|
| 64 |
+
|
| 65 |
+
should_list_installables = (
|
| 66 |
+
not current.startswith("-") and subcommand_name == "install"
|
| 67 |
+
)
|
| 68 |
+
if should_list_installables:
|
| 69 |
+
for path in auto_complete_paths(current, "path"):
|
| 70 |
+
print(path)
|
| 71 |
+
sys.exit(1)
|
| 72 |
+
|
| 73 |
+
subcommand = create_command(subcommand_name)
|
| 74 |
+
|
| 75 |
+
for opt in subcommand.parser.option_list_all:
|
| 76 |
+
if opt.help != optparse.SUPPRESS_HELP:
|
| 77 |
+
options += [
|
| 78 |
+
(opt_str, opt.nargs) for opt_str in opt._long_opts + opt._short_opts
|
| 79 |
+
]
|
| 80 |
+
|
| 81 |
+
# filter out previously specified options from available options
|
| 82 |
+
prev_opts = [x.split("=")[0] for x in cwords[1 : cword - 1]]
|
| 83 |
+
options = [(x, v) for (x, v) in options if x not in prev_opts]
|
| 84 |
+
# filter options by current input
|
| 85 |
+
options = [(k, v) for k, v in options if k.startswith(current)]
|
| 86 |
+
# get completion type given cwords and available subcommand options
|
| 87 |
+
completion_type = get_path_completion_type(
|
| 88 |
+
cwords,
|
| 89 |
+
cword,
|
| 90 |
+
subcommand.parser.option_list_all,
|
| 91 |
+
)
|
| 92 |
+
# get completion files and directories if ``completion_type`` is
|
| 93 |
+
# ``<file>``, ``<dir>`` or ``<path>``
|
| 94 |
+
if completion_type:
|
| 95 |
+
paths = auto_complete_paths(current, completion_type)
|
| 96 |
+
options = [(path, 0) for path in paths]
|
| 97 |
+
for option in options:
|
| 98 |
+
opt_label = option[0]
|
| 99 |
+
# append '=' to options which require args
|
| 100 |
+
if option[1] and option[0][:2] == "--":
|
| 101 |
+
opt_label += "="
|
| 102 |
+
print(opt_label)
|
| 103 |
+
else:
|
| 104 |
+
# show main parser options only when necessary
|
| 105 |
+
|
| 106 |
+
opts = [i.option_list for i in parser.option_groups]
|
| 107 |
+
opts.append(parser.option_list)
|
| 108 |
+
flattened_opts = chain.from_iterable(opts)
|
| 109 |
+
if current.startswith("-"):
|
| 110 |
+
for opt in flattened_opts:
|
| 111 |
+
if opt.help != optparse.SUPPRESS_HELP:
|
| 112 |
+
subcommands += opt._long_opts + opt._short_opts
|
| 113 |
+
else:
|
| 114 |
+
# get completion type given cwords and all available options
|
| 115 |
+
completion_type = get_path_completion_type(cwords, cword, flattened_opts)
|
| 116 |
+
if completion_type:
|
| 117 |
+
subcommands = list(auto_complete_paths(current, completion_type))
|
| 118 |
+
|
| 119 |
+
print(" ".join([x for x in subcommands if x.startswith(current)]))
|
| 120 |
+
sys.exit(1)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def get_path_completion_type(
|
| 124 |
+
cwords: List[str], cword: int, opts: Iterable[Any]
|
| 125 |
+
) -> Optional[str]:
|
| 126 |
+
"""Get the type of path completion (``file``, ``dir``, ``path`` or None)
|
| 127 |
+
|
| 128 |
+
:param cwords: same as the environmental variable ``COMP_WORDS``
|
| 129 |
+
:param cword: same as the environmental variable ``COMP_CWORD``
|
| 130 |
+
:param opts: The available options to check
|
| 131 |
+
:return: path completion type (``file``, ``dir``, ``path`` or None)
|
| 132 |
+
"""
|
| 133 |
+
if cword < 2 or not cwords[cword - 2].startswith("-"):
|
| 134 |
+
return None
|
| 135 |
+
for opt in opts:
|
| 136 |
+
if opt.help == optparse.SUPPRESS_HELP:
|
| 137 |
+
continue
|
| 138 |
+
for o in str(opt).split("/"):
|
| 139 |
+
if cwords[cword - 2].split("=")[0] == o:
|
| 140 |
+
if not opt.metavar or any(
|
| 141 |
+
x in ("path", "file", "dir") for x in opt.metavar.split("/")
|
| 142 |
+
):
|
| 143 |
+
return opt.metavar
|
| 144 |
+
return None
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def auto_complete_paths(current: str, completion_type: str) -> Iterable[str]:
|
| 148 |
+
"""If ``completion_type`` is ``file`` or ``path``, list all regular files
|
| 149 |
+
and directories starting with ``current``; otherwise only list directories
|
| 150 |
+
starting with ``current``.
|
| 151 |
+
|
| 152 |
+
:param current: The word to be completed
|
| 153 |
+
:param completion_type: path completion type(``file``, ``path`` or ``dir``)
|
| 154 |
+
:return: A generator of regular files and/or directories
|
| 155 |
+
"""
|
| 156 |
+
directory, filename = os.path.split(current)
|
| 157 |
+
current_path = os.path.abspath(directory)
|
| 158 |
+
# Don't complete paths if they can't be accessed
|
| 159 |
+
if not os.access(current_path, os.R_OK):
|
| 160 |
+
return
|
| 161 |
+
filename = os.path.normcase(filename)
|
| 162 |
+
# list all files that start with ``filename``
|
| 163 |
+
file_list = (
|
| 164 |
+
x for x in os.listdir(current_path) if os.path.normcase(x).startswith(filename)
|
| 165 |
+
)
|
| 166 |
+
for f in file_list:
|
| 167 |
+
opt = os.path.join(current_path, f)
|
| 168 |
+
comp_file = os.path.normcase(os.path.join(directory, f))
|
| 169 |
+
# complete regular files when there is not ``<dir>`` after option
|
| 170 |
+
# complete directories when there is ``<file>``, ``<path>`` or
|
| 171 |
+
# ``<dir>``after option
|
| 172 |
+
if completion_type != "dir" and os.path.isfile(opt):
|
| 173 |
+
yield comp_file
|
| 174 |
+
elif os.path.isdir(opt):
|
| 175 |
+
yield os.path.join(comp_file, "")
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/base_command.py
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Base Command class, and related routines"""
|
| 2 |
+
|
| 3 |
+
import logging
|
| 4 |
+
import logging.config
|
| 5 |
+
import optparse
|
| 6 |
+
import os
|
| 7 |
+
import sys
|
| 8 |
+
import traceback
|
| 9 |
+
from optparse import Values
|
| 10 |
+
from typing import List, Optional, Tuple
|
| 11 |
+
|
| 12 |
+
from pip._vendor.rich import reconfigure
|
| 13 |
+
from pip._vendor.rich import traceback as rich_traceback
|
| 14 |
+
|
| 15 |
+
from pip._internal.cli import cmdoptions
|
| 16 |
+
from pip._internal.cli.command_context import CommandContextMixIn
|
| 17 |
+
from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
|
| 18 |
+
from pip._internal.cli.status_codes import (
|
| 19 |
+
ERROR,
|
| 20 |
+
PREVIOUS_BUILD_DIR_ERROR,
|
| 21 |
+
UNKNOWN_ERROR,
|
| 22 |
+
VIRTUALENV_NOT_FOUND,
|
| 23 |
+
)
|
| 24 |
+
from pip._internal.exceptions import (
|
| 25 |
+
BadCommand,
|
| 26 |
+
CommandError,
|
| 27 |
+
DiagnosticPipError,
|
| 28 |
+
InstallationError,
|
| 29 |
+
NetworkConnectionError,
|
| 30 |
+
PreviousBuildDirError,
|
| 31 |
+
)
|
| 32 |
+
from pip._internal.utils.filesystem import check_path_owner
|
| 33 |
+
from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging
|
| 34 |
+
from pip._internal.utils.misc import get_prog, normalize_path
|
| 35 |
+
from pip._internal.utils.temp_dir import TempDirectoryTypeRegistry as TempDirRegistry
|
| 36 |
+
from pip._internal.utils.temp_dir import global_tempdir_manager, tempdir_registry
|
| 37 |
+
from pip._internal.utils.virtualenv import running_under_virtualenv
|
| 38 |
+
|
| 39 |
+
__all__ = ["Command"]
|
| 40 |
+
|
| 41 |
+
logger = logging.getLogger(__name__)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class Command(CommandContextMixIn):
|
| 45 |
+
usage: str = ""
|
| 46 |
+
ignore_require_venv: bool = False
|
| 47 |
+
|
| 48 |
+
def __init__(self, name: str, summary: str, isolated: bool = False) -> None:
|
| 49 |
+
super().__init__()
|
| 50 |
+
|
| 51 |
+
self.name = name
|
| 52 |
+
self.summary = summary
|
| 53 |
+
self.parser = ConfigOptionParser(
|
| 54 |
+
usage=self.usage,
|
| 55 |
+
prog=f"{get_prog()} {name}",
|
| 56 |
+
formatter=UpdatingDefaultsHelpFormatter(),
|
| 57 |
+
add_help_option=False,
|
| 58 |
+
name=name,
|
| 59 |
+
description=self.__doc__,
|
| 60 |
+
isolated=isolated,
|
| 61 |
+
)
|
| 62 |
+
|
| 63 |
+
self.tempdir_registry: Optional[TempDirRegistry] = None
|
| 64 |
+
|
| 65 |
+
# Commands should add options to this option group
|
| 66 |
+
optgroup_name = f"{self.name.capitalize()} Options"
|
| 67 |
+
self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name)
|
| 68 |
+
|
| 69 |
+
# Add the general options
|
| 70 |
+
gen_opts = cmdoptions.make_option_group(
|
| 71 |
+
cmdoptions.general_group,
|
| 72 |
+
self.parser,
|
| 73 |
+
)
|
| 74 |
+
self.parser.add_option_group(gen_opts)
|
| 75 |
+
|
| 76 |
+
self.add_options()
|
| 77 |
+
|
| 78 |
+
def add_options(self) -> None:
|
| 79 |
+
pass
|
| 80 |
+
|
| 81 |
+
def handle_pip_version_check(self, options: Values) -> None:
|
| 82 |
+
"""
|
| 83 |
+
This is a no-op so that commands by default do not do the pip version
|
| 84 |
+
check.
|
| 85 |
+
"""
|
| 86 |
+
# Make sure we do the pip version check if the index_group options
|
| 87 |
+
# are present.
|
| 88 |
+
assert not hasattr(options, "no_index")
|
| 89 |
+
|
| 90 |
+
def run(self, options: Values, args: List[str]) -> int:
|
| 91 |
+
raise NotImplementedError
|
| 92 |
+
|
| 93 |
+
def _run_wrapper(self, level_number: int, options: Values, args: List[str]) -> int:
|
| 94 |
+
def _inner_run() -> int:
|
| 95 |
+
try:
|
| 96 |
+
return self.run(options, args)
|
| 97 |
+
finally:
|
| 98 |
+
self.handle_pip_version_check(options)
|
| 99 |
+
|
| 100 |
+
if options.debug_mode:
|
| 101 |
+
rich_traceback.install(show_locals=True)
|
| 102 |
+
return _inner_run()
|
| 103 |
+
|
| 104 |
+
try:
|
| 105 |
+
status = _inner_run()
|
| 106 |
+
assert isinstance(status, int)
|
| 107 |
+
return status
|
| 108 |
+
except DiagnosticPipError as exc:
|
| 109 |
+
logger.error("%s", exc, extra={"rich": True})
|
| 110 |
+
logger.debug("Exception information:", exc_info=True)
|
| 111 |
+
|
| 112 |
+
return ERROR
|
| 113 |
+
except PreviousBuildDirError as exc:
|
| 114 |
+
logger.critical(str(exc))
|
| 115 |
+
logger.debug("Exception information:", exc_info=True)
|
| 116 |
+
|
| 117 |
+
return PREVIOUS_BUILD_DIR_ERROR
|
| 118 |
+
except (
|
| 119 |
+
InstallationError,
|
| 120 |
+
BadCommand,
|
| 121 |
+
NetworkConnectionError,
|
| 122 |
+
) as exc:
|
| 123 |
+
logger.critical(str(exc))
|
| 124 |
+
logger.debug("Exception information:", exc_info=True)
|
| 125 |
+
|
| 126 |
+
return ERROR
|
| 127 |
+
except CommandError as exc:
|
| 128 |
+
logger.critical("%s", exc)
|
| 129 |
+
logger.debug("Exception information:", exc_info=True)
|
| 130 |
+
|
| 131 |
+
return ERROR
|
| 132 |
+
except BrokenStdoutLoggingError:
|
| 133 |
+
# Bypass our logger and write any remaining messages to
|
| 134 |
+
# stderr because stdout no longer works.
|
| 135 |
+
print("ERROR: Pipe to stdout was broken", file=sys.stderr)
|
| 136 |
+
if level_number <= logging.DEBUG:
|
| 137 |
+
traceback.print_exc(file=sys.stderr)
|
| 138 |
+
|
| 139 |
+
return ERROR
|
| 140 |
+
except KeyboardInterrupt:
|
| 141 |
+
logger.critical("Operation cancelled by user")
|
| 142 |
+
logger.debug("Exception information:", exc_info=True)
|
| 143 |
+
|
| 144 |
+
return ERROR
|
| 145 |
+
except BaseException:
|
| 146 |
+
logger.critical("Exception:", exc_info=True)
|
| 147 |
+
|
| 148 |
+
return UNKNOWN_ERROR
|
| 149 |
+
|
| 150 |
+
def parse_args(self, args: List[str]) -> Tuple[Values, List[str]]:
|
| 151 |
+
# factored out for testability
|
| 152 |
+
return self.parser.parse_args(args)
|
| 153 |
+
|
| 154 |
+
def main(self, args: List[str]) -> int:
|
| 155 |
+
try:
|
| 156 |
+
with self.main_context():
|
| 157 |
+
return self._main(args)
|
| 158 |
+
finally:
|
| 159 |
+
logging.shutdown()
|
| 160 |
+
|
| 161 |
+
def _main(self, args: List[str]) -> int:
|
| 162 |
+
# We must initialize this before the tempdir manager, otherwise the
|
| 163 |
+
# configuration would not be accessible by the time we clean up the
|
| 164 |
+
# tempdir manager.
|
| 165 |
+
self.tempdir_registry = self.enter_context(tempdir_registry())
|
| 166 |
+
# Intentionally set as early as possible so globally-managed temporary
|
| 167 |
+
# directories are available to the rest of the code.
|
| 168 |
+
self.enter_context(global_tempdir_manager())
|
| 169 |
+
|
| 170 |
+
options, args = self.parse_args(args)
|
| 171 |
+
|
| 172 |
+
# Set verbosity so that it can be used elsewhere.
|
| 173 |
+
self.verbosity = options.verbose - options.quiet
|
| 174 |
+
if options.debug_mode:
|
| 175 |
+
self.verbosity = 2
|
| 176 |
+
|
| 177 |
+
reconfigure(no_color=options.no_color)
|
| 178 |
+
level_number = setup_logging(
|
| 179 |
+
verbosity=self.verbosity,
|
| 180 |
+
no_color=options.no_color,
|
| 181 |
+
user_log_file=options.log,
|
| 182 |
+
)
|
| 183 |
+
|
| 184 |
+
always_enabled_features = set(options.features_enabled) & set(
|
| 185 |
+
cmdoptions.ALWAYS_ENABLED_FEATURES
|
| 186 |
+
)
|
| 187 |
+
if always_enabled_features:
|
| 188 |
+
logger.warning(
|
| 189 |
+
"The following features are always enabled: %s. ",
|
| 190 |
+
", ".join(sorted(always_enabled_features)),
|
| 191 |
+
)
|
| 192 |
+
|
| 193 |
+
# Make sure that the --python argument isn't specified after the
|
| 194 |
+
# subcommand. We can tell, because if --python was specified,
|
| 195 |
+
# we should only reach this point if we're running in the created
|
| 196 |
+
# subprocess, which has the _PIP_RUNNING_IN_SUBPROCESS environment
|
| 197 |
+
# variable set.
|
| 198 |
+
if options.python and "_PIP_RUNNING_IN_SUBPROCESS" not in os.environ:
|
| 199 |
+
logger.critical(
|
| 200 |
+
"The --python option must be placed before the pip subcommand name"
|
| 201 |
+
)
|
| 202 |
+
sys.exit(ERROR)
|
| 203 |
+
|
| 204 |
+
# TODO: Try to get these passing down from the command?
|
| 205 |
+
# without resorting to os.environ to hold these.
|
| 206 |
+
# This also affects isolated builds and it should.
|
| 207 |
+
|
| 208 |
+
if options.no_input:
|
| 209 |
+
os.environ["PIP_NO_INPUT"] = "1"
|
| 210 |
+
|
| 211 |
+
if options.exists_action:
|
| 212 |
+
os.environ["PIP_EXISTS_ACTION"] = " ".join(options.exists_action)
|
| 213 |
+
|
| 214 |
+
if options.require_venv and not self.ignore_require_venv:
|
| 215 |
+
# If a venv is required check if it can really be found
|
| 216 |
+
if not running_under_virtualenv():
|
| 217 |
+
logger.critical("Could not find an activated virtualenv (required).")
|
| 218 |
+
sys.exit(VIRTUALENV_NOT_FOUND)
|
| 219 |
+
|
| 220 |
+
if options.cache_dir:
|
| 221 |
+
options.cache_dir = normalize_path(options.cache_dir)
|
| 222 |
+
if not check_path_owner(options.cache_dir):
|
| 223 |
+
logger.warning(
|
| 224 |
+
"The directory '%s' or its parent directory is not owned "
|
| 225 |
+
"or is not writable by the current user. The cache "
|
| 226 |
+
"has been disabled. Check the permissions and owner of "
|
| 227 |
+
"that directory. If executing pip with sudo, you should "
|
| 228 |
+
"use sudo's -H flag.",
|
| 229 |
+
options.cache_dir,
|
| 230 |
+
)
|
| 231 |
+
options.cache_dir = None
|
| 232 |
+
|
| 233 |
+
return self._run_wrapper(level_number, options, args)
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/cmdoptions.py
ADDED
|
@@ -0,0 +1,1133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
shared options and groups
|
| 3 |
+
|
| 4 |
+
The principle here is to define options once, but *not* instantiate them
|
| 5 |
+
globally. One reason being that options with action='append' can carry state
|
| 6 |
+
between parses. pip parses general options twice internally, and shouldn't
|
| 7 |
+
pass on state. To be consistent, all options will follow this design.
|
| 8 |
+
"""
|
| 9 |
+
|
| 10 |
+
# The following comment should be removed at some point in the future.
|
| 11 |
+
# mypy: strict-optional=False
|
| 12 |
+
|
| 13 |
+
import importlib.util
|
| 14 |
+
import logging
|
| 15 |
+
import os
|
| 16 |
+
import pathlib
|
| 17 |
+
import textwrap
|
| 18 |
+
from functools import partial
|
| 19 |
+
from optparse import SUPPRESS_HELP, Option, OptionGroup, OptionParser, Values
|
| 20 |
+
from textwrap import dedent
|
| 21 |
+
from typing import Any, Callable, Dict, Optional, Tuple
|
| 22 |
+
|
| 23 |
+
from pip._vendor.packaging.utils import canonicalize_name
|
| 24 |
+
|
| 25 |
+
from pip._internal.cli.parser import ConfigOptionParser
|
| 26 |
+
from pip._internal.exceptions import CommandError
|
| 27 |
+
from pip._internal.locations import USER_CACHE_DIR, get_src_prefix
|
| 28 |
+
from pip._internal.models.format_control import FormatControl
|
| 29 |
+
from pip._internal.models.index import PyPI
|
| 30 |
+
from pip._internal.models.target_python import TargetPython
|
| 31 |
+
from pip._internal.utils.hashes import STRONG_HASHES
|
| 32 |
+
from pip._internal.utils.misc import strtobool
|
| 33 |
+
|
| 34 |
+
logger = logging.getLogger(__name__)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def raise_option_error(parser: OptionParser, option: Option, msg: str) -> None:
|
| 38 |
+
"""
|
| 39 |
+
Raise an option parsing error using parser.error().
|
| 40 |
+
|
| 41 |
+
Args:
|
| 42 |
+
parser: an OptionParser instance.
|
| 43 |
+
option: an Option instance.
|
| 44 |
+
msg: the error text.
|
| 45 |
+
"""
|
| 46 |
+
msg = f"{option} error: {msg}"
|
| 47 |
+
msg = textwrap.fill(" ".join(msg.split()))
|
| 48 |
+
parser.error(msg)
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def make_option_group(group: Dict[str, Any], parser: ConfigOptionParser) -> OptionGroup:
|
| 52 |
+
"""
|
| 53 |
+
Return an OptionGroup object
|
| 54 |
+
group -- assumed to be dict with 'name' and 'options' keys
|
| 55 |
+
parser -- an optparse Parser
|
| 56 |
+
"""
|
| 57 |
+
option_group = OptionGroup(parser, group["name"])
|
| 58 |
+
for option in group["options"]:
|
| 59 |
+
option_group.add_option(option())
|
| 60 |
+
return option_group
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def check_dist_restriction(options: Values, check_target: bool = False) -> None:
|
| 64 |
+
"""Function for determining if custom platform options are allowed.
|
| 65 |
+
|
| 66 |
+
:param options: The OptionParser options.
|
| 67 |
+
:param check_target: Whether or not to check if --target is being used.
|
| 68 |
+
"""
|
| 69 |
+
dist_restriction_set = any(
|
| 70 |
+
[
|
| 71 |
+
options.python_version,
|
| 72 |
+
options.platforms,
|
| 73 |
+
options.abis,
|
| 74 |
+
options.implementation,
|
| 75 |
+
]
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
binary_only = FormatControl(set(), {":all:"})
|
| 79 |
+
sdist_dependencies_allowed = (
|
| 80 |
+
options.format_control != binary_only and not options.ignore_dependencies
|
| 81 |
+
)
|
| 82 |
+
|
| 83 |
+
# Installations or downloads using dist restrictions must not combine
|
| 84 |
+
# source distributions and dist-specific wheels, as they are not
|
| 85 |
+
# guaranteed to be locally compatible.
|
| 86 |
+
if dist_restriction_set and sdist_dependencies_allowed:
|
| 87 |
+
raise CommandError(
|
| 88 |
+
"When restricting platform and interpreter constraints using "
|
| 89 |
+
"--python-version, --platform, --abi, or --implementation, "
|
| 90 |
+
"either --no-deps must be set, or --only-binary=:all: must be "
|
| 91 |
+
"set and --no-binary must not be set (or must be set to "
|
| 92 |
+
":none:)."
|
| 93 |
+
)
|
| 94 |
+
|
| 95 |
+
if check_target:
|
| 96 |
+
if not options.dry_run and dist_restriction_set and not options.target_dir:
|
| 97 |
+
raise CommandError(
|
| 98 |
+
"Can not use any platform or abi specific options unless "
|
| 99 |
+
"installing via '--target' or using '--dry-run'"
|
| 100 |
+
)
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def _path_option_check(option: Option, opt: str, value: str) -> str:
|
| 104 |
+
return os.path.expanduser(value)
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def _package_name_option_check(option: Option, opt: str, value: str) -> str:
|
| 108 |
+
return canonicalize_name(value)
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
class PipOption(Option):
|
| 112 |
+
TYPES = Option.TYPES + ("path", "package_name")
|
| 113 |
+
TYPE_CHECKER = Option.TYPE_CHECKER.copy()
|
| 114 |
+
TYPE_CHECKER["package_name"] = _package_name_option_check
|
| 115 |
+
TYPE_CHECKER["path"] = _path_option_check
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
###########
|
| 119 |
+
# options #
|
| 120 |
+
###########
|
| 121 |
+
|
| 122 |
+
help_: Callable[..., Option] = partial(
|
| 123 |
+
Option,
|
| 124 |
+
"-h",
|
| 125 |
+
"--help",
|
| 126 |
+
dest="help",
|
| 127 |
+
action="help",
|
| 128 |
+
help="Show help.",
|
| 129 |
+
)
|
| 130 |
+
|
| 131 |
+
debug_mode: Callable[..., Option] = partial(
|
| 132 |
+
Option,
|
| 133 |
+
"--debug",
|
| 134 |
+
dest="debug_mode",
|
| 135 |
+
action="store_true",
|
| 136 |
+
default=False,
|
| 137 |
+
help=(
|
| 138 |
+
"Let unhandled exceptions propagate outside the main subroutine, "
|
| 139 |
+
"instead of logging them to stderr."
|
| 140 |
+
),
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
isolated_mode: Callable[..., Option] = partial(
|
| 144 |
+
Option,
|
| 145 |
+
"--isolated",
|
| 146 |
+
dest="isolated_mode",
|
| 147 |
+
action="store_true",
|
| 148 |
+
default=False,
|
| 149 |
+
help=(
|
| 150 |
+
"Run pip in an isolated mode, ignoring environment variables and user "
|
| 151 |
+
"configuration."
|
| 152 |
+
),
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
require_virtualenv: Callable[..., Option] = partial(
|
| 156 |
+
Option,
|
| 157 |
+
"--require-virtualenv",
|
| 158 |
+
"--require-venv",
|
| 159 |
+
dest="require_venv",
|
| 160 |
+
action="store_true",
|
| 161 |
+
default=False,
|
| 162 |
+
help=(
|
| 163 |
+
"Allow pip to only run in a virtual environment; "
|
| 164 |
+
"exit with an error otherwise."
|
| 165 |
+
),
|
| 166 |
+
)
|
| 167 |
+
|
| 168 |
+
override_externally_managed: Callable[..., Option] = partial(
|
| 169 |
+
Option,
|
| 170 |
+
"--break-system-packages",
|
| 171 |
+
dest="override_externally_managed",
|
| 172 |
+
action="store_true",
|
| 173 |
+
help="Allow pip to modify an EXTERNALLY-MANAGED Python installation",
|
| 174 |
+
)
|
| 175 |
+
|
| 176 |
+
python: Callable[..., Option] = partial(
|
| 177 |
+
Option,
|
| 178 |
+
"--python",
|
| 179 |
+
dest="python",
|
| 180 |
+
help="Run pip with the specified Python interpreter.",
|
| 181 |
+
)
|
| 182 |
+
|
| 183 |
+
verbose: Callable[..., Option] = partial(
|
| 184 |
+
Option,
|
| 185 |
+
"-v",
|
| 186 |
+
"--verbose",
|
| 187 |
+
dest="verbose",
|
| 188 |
+
action="count",
|
| 189 |
+
default=0,
|
| 190 |
+
help="Give more output. Option is additive, and can be used up to 3 times.",
|
| 191 |
+
)
|
| 192 |
+
|
| 193 |
+
no_color: Callable[..., Option] = partial(
|
| 194 |
+
Option,
|
| 195 |
+
"--no-color",
|
| 196 |
+
dest="no_color",
|
| 197 |
+
action="store_true",
|
| 198 |
+
default=False,
|
| 199 |
+
help="Suppress colored output.",
|
| 200 |
+
)
|
| 201 |
+
|
| 202 |
+
version: Callable[..., Option] = partial(
|
| 203 |
+
Option,
|
| 204 |
+
"-V",
|
| 205 |
+
"--version",
|
| 206 |
+
dest="version",
|
| 207 |
+
action="store_true",
|
| 208 |
+
help="Show version and exit.",
|
| 209 |
+
)
|
| 210 |
+
|
| 211 |
+
quiet: Callable[..., Option] = partial(
|
| 212 |
+
Option,
|
| 213 |
+
"-q",
|
| 214 |
+
"--quiet",
|
| 215 |
+
dest="quiet",
|
| 216 |
+
action="count",
|
| 217 |
+
default=0,
|
| 218 |
+
help=(
|
| 219 |
+
"Give less output. Option is additive, and can be used up to 3"
|
| 220 |
+
" times (corresponding to WARNING, ERROR, and CRITICAL logging"
|
| 221 |
+
" levels)."
|
| 222 |
+
),
|
| 223 |
+
)
|
| 224 |
+
|
| 225 |
+
progress_bar: Callable[..., Option] = partial(
|
| 226 |
+
Option,
|
| 227 |
+
"--progress-bar",
|
| 228 |
+
dest="progress_bar",
|
| 229 |
+
type="choice",
|
| 230 |
+
choices=["on", "off", "raw"],
|
| 231 |
+
default="on",
|
| 232 |
+
help="Specify whether the progress bar should be used [on, off, raw] (default: on)",
|
| 233 |
+
)
|
| 234 |
+
|
| 235 |
+
log: Callable[..., Option] = partial(
|
| 236 |
+
PipOption,
|
| 237 |
+
"--log",
|
| 238 |
+
"--log-file",
|
| 239 |
+
"--local-log",
|
| 240 |
+
dest="log",
|
| 241 |
+
metavar="path",
|
| 242 |
+
type="path",
|
| 243 |
+
help="Path to a verbose appending log.",
|
| 244 |
+
)
|
| 245 |
+
|
| 246 |
+
no_input: Callable[..., Option] = partial(
|
| 247 |
+
Option,
|
| 248 |
+
# Don't ask for input
|
| 249 |
+
"--no-input",
|
| 250 |
+
dest="no_input",
|
| 251 |
+
action="store_true",
|
| 252 |
+
default=False,
|
| 253 |
+
help="Disable prompting for input.",
|
| 254 |
+
)
|
| 255 |
+
|
| 256 |
+
keyring_provider: Callable[..., Option] = partial(
|
| 257 |
+
Option,
|
| 258 |
+
"--keyring-provider",
|
| 259 |
+
dest="keyring_provider",
|
| 260 |
+
choices=["auto", "disabled", "import", "subprocess"],
|
| 261 |
+
default="auto",
|
| 262 |
+
help=(
|
| 263 |
+
"Enable the credential lookup via the keyring library if user input is allowed."
|
| 264 |
+
" Specify which mechanism to use [auto, disabled, import, subprocess]."
|
| 265 |
+
" (default: %default)"
|
| 266 |
+
),
|
| 267 |
+
)
|
| 268 |
+
|
| 269 |
+
proxy: Callable[..., Option] = partial(
|
| 270 |
+
Option,
|
| 271 |
+
"--proxy",
|
| 272 |
+
dest="proxy",
|
| 273 |
+
type="str",
|
| 274 |
+
default="",
|
| 275 |
+
help="Specify a proxy in the form scheme://[user:passwd@]proxy.server:port.",
|
| 276 |
+
)
|
| 277 |
+
|
| 278 |
+
retries: Callable[..., Option] = partial(
|
| 279 |
+
Option,
|
| 280 |
+
"--retries",
|
| 281 |
+
dest="retries",
|
| 282 |
+
type="int",
|
| 283 |
+
default=5,
|
| 284 |
+
help="Maximum attempts to establish a new HTTP connection. (default: %default)",
|
| 285 |
+
)
|
| 286 |
+
|
| 287 |
+
resume_retries: Callable[..., Option] = partial(
|
| 288 |
+
Option,
|
| 289 |
+
"--resume-retries",
|
| 290 |
+
dest="resume_retries",
|
| 291 |
+
type="int",
|
| 292 |
+
default=0,
|
| 293 |
+
help="Maximum attempts to resume or restart an incomplete download. "
|
| 294 |
+
"(default: %default)",
|
| 295 |
+
)
|
| 296 |
+
|
| 297 |
+
timeout: Callable[..., Option] = partial(
|
| 298 |
+
Option,
|
| 299 |
+
"--timeout",
|
| 300 |
+
"--default-timeout",
|
| 301 |
+
metavar="sec",
|
| 302 |
+
dest="timeout",
|
| 303 |
+
type="float",
|
| 304 |
+
default=15,
|
| 305 |
+
help="Set the socket timeout (default %default seconds).",
|
| 306 |
+
)
|
| 307 |
+
|
| 308 |
+
|
| 309 |
+
def exists_action() -> Option:
|
| 310 |
+
return Option(
|
| 311 |
+
# Option when path already exist
|
| 312 |
+
"--exists-action",
|
| 313 |
+
dest="exists_action",
|
| 314 |
+
type="choice",
|
| 315 |
+
choices=["s", "i", "w", "b", "a"],
|
| 316 |
+
default=[],
|
| 317 |
+
action="append",
|
| 318 |
+
metavar="action",
|
| 319 |
+
help="Default action when a path already exists: "
|
| 320 |
+
"(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort.",
|
| 321 |
+
)
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
cert: Callable[..., Option] = partial(
|
| 325 |
+
PipOption,
|
| 326 |
+
"--cert",
|
| 327 |
+
dest="cert",
|
| 328 |
+
type="path",
|
| 329 |
+
metavar="path",
|
| 330 |
+
help=(
|
| 331 |
+
"Path to PEM-encoded CA certificate bundle. "
|
| 332 |
+
"If provided, overrides the default. "
|
| 333 |
+
"See 'SSL Certificate Verification' in pip documentation "
|
| 334 |
+
"for more information."
|
| 335 |
+
),
|
| 336 |
+
)
|
| 337 |
+
|
| 338 |
+
client_cert: Callable[..., Option] = partial(
|
| 339 |
+
PipOption,
|
| 340 |
+
"--client-cert",
|
| 341 |
+
dest="client_cert",
|
| 342 |
+
type="path",
|
| 343 |
+
default=None,
|
| 344 |
+
metavar="path",
|
| 345 |
+
help="Path to SSL client certificate, a single file containing the "
|
| 346 |
+
"private key and the certificate in PEM format.",
|
| 347 |
+
)
|
| 348 |
+
|
| 349 |
+
index_url: Callable[..., Option] = partial(
|
| 350 |
+
Option,
|
| 351 |
+
"-i",
|
| 352 |
+
"--index-url",
|
| 353 |
+
"--pypi-url",
|
| 354 |
+
dest="index_url",
|
| 355 |
+
metavar="URL",
|
| 356 |
+
default=PyPI.simple_url,
|
| 357 |
+
help="Base URL of the Python Package Index (default %default). "
|
| 358 |
+
"This should point to a repository compliant with PEP 503 "
|
| 359 |
+
"(the simple repository API) or a local directory laid out "
|
| 360 |
+
"in the same format.",
|
| 361 |
+
)
|
| 362 |
+
|
| 363 |
+
|
| 364 |
+
def extra_index_url() -> Option:
|
| 365 |
+
return Option(
|
| 366 |
+
"--extra-index-url",
|
| 367 |
+
dest="extra_index_urls",
|
| 368 |
+
metavar="URL",
|
| 369 |
+
action="append",
|
| 370 |
+
default=[],
|
| 371 |
+
help="Extra URLs of package indexes to use in addition to "
|
| 372 |
+
"--index-url. Should follow the same rules as "
|
| 373 |
+
"--index-url.",
|
| 374 |
+
)
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
no_index: Callable[..., Option] = partial(
|
| 378 |
+
Option,
|
| 379 |
+
"--no-index",
|
| 380 |
+
dest="no_index",
|
| 381 |
+
action="store_true",
|
| 382 |
+
default=False,
|
| 383 |
+
help="Ignore package index (only looking at --find-links URLs instead).",
|
| 384 |
+
)
|
| 385 |
+
|
| 386 |
+
|
| 387 |
+
def find_links() -> Option:
|
| 388 |
+
return Option(
|
| 389 |
+
"-f",
|
| 390 |
+
"--find-links",
|
| 391 |
+
dest="find_links",
|
| 392 |
+
action="append",
|
| 393 |
+
default=[],
|
| 394 |
+
metavar="url",
|
| 395 |
+
help="If a URL or path to an html file, then parse for links to "
|
| 396 |
+
"archives such as sdist (.tar.gz) or wheel (.whl) files. "
|
| 397 |
+
"If a local path or file:// URL that's a directory, "
|
| 398 |
+
"then look for archives in the directory listing. "
|
| 399 |
+
"Links to VCS project URLs are not supported.",
|
| 400 |
+
)
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
def trusted_host() -> Option:
|
| 404 |
+
return Option(
|
| 405 |
+
"--trusted-host",
|
| 406 |
+
dest="trusted_hosts",
|
| 407 |
+
action="append",
|
| 408 |
+
metavar="HOSTNAME",
|
| 409 |
+
default=[],
|
| 410 |
+
help="Mark this host or host:port pair as trusted, even though it "
|
| 411 |
+
"does not have valid or any HTTPS.",
|
| 412 |
+
)
|
| 413 |
+
|
| 414 |
+
|
| 415 |
+
def constraints() -> Option:
|
| 416 |
+
return Option(
|
| 417 |
+
"-c",
|
| 418 |
+
"--constraint",
|
| 419 |
+
dest="constraints",
|
| 420 |
+
action="append",
|
| 421 |
+
default=[],
|
| 422 |
+
metavar="file",
|
| 423 |
+
help="Constrain versions using the given constraints file. "
|
| 424 |
+
"This option can be used multiple times.",
|
| 425 |
+
)
|
| 426 |
+
|
| 427 |
+
|
| 428 |
+
def requirements() -> Option:
|
| 429 |
+
return Option(
|
| 430 |
+
"-r",
|
| 431 |
+
"--requirement",
|
| 432 |
+
dest="requirements",
|
| 433 |
+
action="append",
|
| 434 |
+
default=[],
|
| 435 |
+
metavar="file",
|
| 436 |
+
help="Install from the given requirements file. "
|
| 437 |
+
"This option can be used multiple times.",
|
| 438 |
+
)
|
| 439 |
+
|
| 440 |
+
|
| 441 |
+
def editable() -> Option:
|
| 442 |
+
return Option(
|
| 443 |
+
"-e",
|
| 444 |
+
"--editable",
|
| 445 |
+
dest="editables",
|
| 446 |
+
action="append",
|
| 447 |
+
default=[],
|
| 448 |
+
metavar="path/url",
|
| 449 |
+
help=(
|
| 450 |
+
"Install a project in editable mode (i.e. setuptools "
|
| 451 |
+
'"develop mode") from a local project path or a VCS url.'
|
| 452 |
+
),
|
| 453 |
+
)
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
def _handle_src(option: Option, opt_str: str, value: str, parser: OptionParser) -> None:
|
| 457 |
+
value = os.path.abspath(value)
|
| 458 |
+
setattr(parser.values, option.dest, value)
|
| 459 |
+
|
| 460 |
+
|
| 461 |
+
src: Callable[..., Option] = partial(
|
| 462 |
+
PipOption,
|
| 463 |
+
"--src",
|
| 464 |
+
"--source",
|
| 465 |
+
"--source-dir",
|
| 466 |
+
"--source-directory",
|
| 467 |
+
dest="src_dir",
|
| 468 |
+
type="path",
|
| 469 |
+
metavar="dir",
|
| 470 |
+
default=get_src_prefix(),
|
| 471 |
+
action="callback",
|
| 472 |
+
callback=_handle_src,
|
| 473 |
+
help="Directory to check out editable projects into. "
|
| 474 |
+
'The default in a virtualenv is "<venv path>/src". '
|
| 475 |
+
'The default for global installs is "<current dir>/src".',
|
| 476 |
+
)
|
| 477 |
+
|
| 478 |
+
|
| 479 |
+
def _get_format_control(values: Values, option: Option) -> Any:
|
| 480 |
+
"""Get a format_control object."""
|
| 481 |
+
return getattr(values, option.dest)
|
| 482 |
+
|
| 483 |
+
|
| 484 |
+
def _handle_no_binary(
|
| 485 |
+
option: Option, opt_str: str, value: str, parser: OptionParser
|
| 486 |
+
) -> None:
|
| 487 |
+
existing = _get_format_control(parser.values, option)
|
| 488 |
+
FormatControl.handle_mutual_excludes(
|
| 489 |
+
value,
|
| 490 |
+
existing.no_binary,
|
| 491 |
+
existing.only_binary,
|
| 492 |
+
)
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
def _handle_only_binary(
|
| 496 |
+
option: Option, opt_str: str, value: str, parser: OptionParser
|
| 497 |
+
) -> None:
|
| 498 |
+
existing = _get_format_control(parser.values, option)
|
| 499 |
+
FormatControl.handle_mutual_excludes(
|
| 500 |
+
value,
|
| 501 |
+
existing.only_binary,
|
| 502 |
+
existing.no_binary,
|
| 503 |
+
)
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
def no_binary() -> Option:
|
| 507 |
+
format_control = FormatControl(set(), set())
|
| 508 |
+
return Option(
|
| 509 |
+
"--no-binary",
|
| 510 |
+
dest="format_control",
|
| 511 |
+
action="callback",
|
| 512 |
+
callback=_handle_no_binary,
|
| 513 |
+
type="str",
|
| 514 |
+
default=format_control,
|
| 515 |
+
help="Do not use binary packages. Can be supplied multiple times, and "
|
| 516 |
+
'each time adds to the existing value. Accepts either ":all:" to '
|
| 517 |
+
'disable all binary packages, ":none:" to empty the set (notice '
|
| 518 |
+
"the colons), or one or more package names with commas between "
|
| 519 |
+
"them (no colons). Note that some packages are tricky to compile "
|
| 520 |
+
"and may fail to install when this option is used on them.",
|
| 521 |
+
)
|
| 522 |
+
|
| 523 |
+
|
| 524 |
+
def only_binary() -> Option:
|
| 525 |
+
format_control = FormatControl(set(), set())
|
| 526 |
+
return Option(
|
| 527 |
+
"--only-binary",
|
| 528 |
+
dest="format_control",
|
| 529 |
+
action="callback",
|
| 530 |
+
callback=_handle_only_binary,
|
| 531 |
+
type="str",
|
| 532 |
+
default=format_control,
|
| 533 |
+
help="Do not use source packages. Can be supplied multiple times, and "
|
| 534 |
+
'each time adds to the existing value. Accepts either ":all:" to '
|
| 535 |
+
'disable all source packages, ":none:" to empty the set, or one '
|
| 536 |
+
"or more package names with commas between them. Packages "
|
| 537 |
+
"without binary distributions will fail to install when this "
|
| 538 |
+
"option is used on them.",
|
| 539 |
+
)
|
| 540 |
+
|
| 541 |
+
|
| 542 |
+
platforms: Callable[..., Option] = partial(
|
| 543 |
+
Option,
|
| 544 |
+
"--platform",
|
| 545 |
+
dest="platforms",
|
| 546 |
+
metavar="platform",
|
| 547 |
+
action="append",
|
| 548 |
+
default=None,
|
| 549 |
+
help=(
|
| 550 |
+
"Only use wheels compatible with <platform>. Defaults to the "
|
| 551 |
+
"platform of the running system. Use this option multiple times to "
|
| 552 |
+
"specify multiple platforms supported by the target interpreter."
|
| 553 |
+
),
|
| 554 |
+
)
|
| 555 |
+
|
| 556 |
+
|
| 557 |
+
# This was made a separate function for unit-testing purposes.
|
| 558 |
+
def _convert_python_version(value: str) -> Tuple[Tuple[int, ...], Optional[str]]:
|
| 559 |
+
"""
|
| 560 |
+
Convert a version string like "3", "37", or "3.7.3" into a tuple of ints.
|
| 561 |
+
|
| 562 |
+
:return: A 2-tuple (version_info, error_msg), where `error_msg` is
|
| 563 |
+
non-None if and only if there was a parsing error.
|
| 564 |
+
"""
|
| 565 |
+
if not value:
|
| 566 |
+
# The empty string is the same as not providing a value.
|
| 567 |
+
return (None, None)
|
| 568 |
+
|
| 569 |
+
parts = value.split(".")
|
| 570 |
+
if len(parts) > 3:
|
| 571 |
+
return ((), "at most three version parts are allowed")
|
| 572 |
+
|
| 573 |
+
if len(parts) == 1:
|
| 574 |
+
# Then we are in the case of "3" or "37".
|
| 575 |
+
value = parts[0]
|
| 576 |
+
if len(value) > 1:
|
| 577 |
+
parts = [value[0], value[1:]]
|
| 578 |
+
|
| 579 |
+
try:
|
| 580 |
+
version_info = tuple(int(part) for part in parts)
|
| 581 |
+
except ValueError:
|
| 582 |
+
return ((), "each version part must be an integer")
|
| 583 |
+
|
| 584 |
+
return (version_info, None)
|
| 585 |
+
|
| 586 |
+
|
| 587 |
+
def _handle_python_version(
|
| 588 |
+
option: Option, opt_str: str, value: str, parser: OptionParser
|
| 589 |
+
) -> None:
|
| 590 |
+
"""
|
| 591 |
+
Handle a provided --python-version value.
|
| 592 |
+
"""
|
| 593 |
+
version_info, error_msg = _convert_python_version(value)
|
| 594 |
+
if error_msg is not None:
|
| 595 |
+
msg = f"invalid --python-version value: {value!r}: {error_msg}"
|
| 596 |
+
raise_option_error(parser, option=option, msg=msg)
|
| 597 |
+
|
| 598 |
+
parser.values.python_version = version_info
|
| 599 |
+
|
| 600 |
+
|
| 601 |
+
python_version: Callable[..., Option] = partial(
|
| 602 |
+
Option,
|
| 603 |
+
"--python-version",
|
| 604 |
+
dest="python_version",
|
| 605 |
+
metavar="python_version",
|
| 606 |
+
action="callback",
|
| 607 |
+
callback=_handle_python_version,
|
| 608 |
+
type="str",
|
| 609 |
+
default=None,
|
| 610 |
+
help=dedent(
|
| 611 |
+
"""\
|
| 612 |
+
The Python interpreter version to use for wheel and "Requires-Python"
|
| 613 |
+
compatibility checks. Defaults to a version derived from the running
|
| 614 |
+
interpreter. The version can be specified using up to three dot-separated
|
| 615 |
+
integers (e.g. "3" for 3.0.0, "3.7" for 3.7.0, or "3.7.3"). A major-minor
|
| 616 |
+
version can also be given as a string without dots (e.g. "37" for 3.7.0).
|
| 617 |
+
"""
|
| 618 |
+
),
|
| 619 |
+
)
|
| 620 |
+
|
| 621 |
+
|
| 622 |
+
implementation: Callable[..., Option] = partial(
|
| 623 |
+
Option,
|
| 624 |
+
"--implementation",
|
| 625 |
+
dest="implementation",
|
| 626 |
+
metavar="implementation",
|
| 627 |
+
default=None,
|
| 628 |
+
help=(
|
| 629 |
+
"Only use wheels compatible with Python "
|
| 630 |
+
"implementation <implementation>, e.g. 'pp', 'jy', 'cp', "
|
| 631 |
+
" or 'ip'. If not specified, then the current "
|
| 632 |
+
"interpreter implementation is used. Use 'py' to force "
|
| 633 |
+
"implementation-agnostic wheels."
|
| 634 |
+
),
|
| 635 |
+
)
|
| 636 |
+
|
| 637 |
+
|
| 638 |
+
abis: Callable[..., Option] = partial(
|
| 639 |
+
Option,
|
| 640 |
+
"--abi",
|
| 641 |
+
dest="abis",
|
| 642 |
+
metavar="abi",
|
| 643 |
+
action="append",
|
| 644 |
+
default=None,
|
| 645 |
+
help=(
|
| 646 |
+
"Only use wheels compatible with Python abi <abi>, e.g. 'pypy_41'. "
|
| 647 |
+
"If not specified, then the current interpreter abi tag is used. "
|
| 648 |
+
"Use this option multiple times to specify multiple abis supported "
|
| 649 |
+
"by the target interpreter. Generally you will need to specify "
|
| 650 |
+
"--implementation, --platform, and --python-version when using this "
|
| 651 |
+
"option."
|
| 652 |
+
),
|
| 653 |
+
)
|
| 654 |
+
|
| 655 |
+
|
| 656 |
+
def add_target_python_options(cmd_opts: OptionGroup) -> None:
|
| 657 |
+
cmd_opts.add_option(platforms())
|
| 658 |
+
cmd_opts.add_option(python_version())
|
| 659 |
+
cmd_opts.add_option(implementation())
|
| 660 |
+
cmd_opts.add_option(abis())
|
| 661 |
+
|
| 662 |
+
|
| 663 |
+
def make_target_python(options: Values) -> TargetPython:
|
| 664 |
+
target_python = TargetPython(
|
| 665 |
+
platforms=options.platforms,
|
| 666 |
+
py_version_info=options.python_version,
|
| 667 |
+
abis=options.abis,
|
| 668 |
+
implementation=options.implementation,
|
| 669 |
+
)
|
| 670 |
+
|
| 671 |
+
return target_python
|
| 672 |
+
|
| 673 |
+
|
| 674 |
+
def prefer_binary() -> Option:
|
| 675 |
+
return Option(
|
| 676 |
+
"--prefer-binary",
|
| 677 |
+
dest="prefer_binary",
|
| 678 |
+
action="store_true",
|
| 679 |
+
default=False,
|
| 680 |
+
help=(
|
| 681 |
+
"Prefer binary packages over source packages, even if the "
|
| 682 |
+
"source packages are newer."
|
| 683 |
+
),
|
| 684 |
+
)
|
| 685 |
+
|
| 686 |
+
|
| 687 |
+
cache_dir: Callable[..., Option] = partial(
|
| 688 |
+
PipOption,
|
| 689 |
+
"--cache-dir",
|
| 690 |
+
dest="cache_dir",
|
| 691 |
+
default=USER_CACHE_DIR,
|
| 692 |
+
metavar="dir",
|
| 693 |
+
type="path",
|
| 694 |
+
help="Store the cache data in <dir>.",
|
| 695 |
+
)
|
| 696 |
+
|
| 697 |
+
|
| 698 |
+
def _handle_no_cache_dir(
|
| 699 |
+
option: Option, opt: str, value: str, parser: OptionParser
|
| 700 |
+
) -> None:
|
| 701 |
+
"""
|
| 702 |
+
Process a value provided for the --no-cache-dir option.
|
| 703 |
+
|
| 704 |
+
This is an optparse.Option callback for the --no-cache-dir option.
|
| 705 |
+
"""
|
| 706 |
+
# The value argument will be None if --no-cache-dir is passed via the
|
| 707 |
+
# command-line, since the option doesn't accept arguments. However,
|
| 708 |
+
# the value can be non-None if the option is triggered e.g. by an
|
| 709 |
+
# environment variable, like PIP_NO_CACHE_DIR=true.
|
| 710 |
+
if value is not None:
|
| 711 |
+
# Then parse the string value to get argument error-checking.
|
| 712 |
+
try:
|
| 713 |
+
strtobool(value)
|
| 714 |
+
except ValueError as exc:
|
| 715 |
+
raise_option_error(parser, option=option, msg=str(exc))
|
| 716 |
+
|
| 717 |
+
# Originally, setting PIP_NO_CACHE_DIR to a value that strtobool()
|
| 718 |
+
# converted to 0 (like "false" or "no") caused cache_dir to be disabled
|
| 719 |
+
# rather than enabled (logic would say the latter). Thus, we disable
|
| 720 |
+
# the cache directory not just on values that parse to True, but (for
|
| 721 |
+
# backwards compatibility reasons) also on values that parse to False.
|
| 722 |
+
# In other words, always set it to False if the option is provided in
|
| 723 |
+
# some (valid) form.
|
| 724 |
+
parser.values.cache_dir = False
|
| 725 |
+
|
| 726 |
+
|
| 727 |
+
no_cache: Callable[..., Option] = partial(
|
| 728 |
+
Option,
|
| 729 |
+
"--no-cache-dir",
|
| 730 |
+
dest="cache_dir",
|
| 731 |
+
action="callback",
|
| 732 |
+
callback=_handle_no_cache_dir,
|
| 733 |
+
help="Disable the cache.",
|
| 734 |
+
)
|
| 735 |
+
|
| 736 |
+
no_deps: Callable[..., Option] = partial(
|
| 737 |
+
Option,
|
| 738 |
+
"--no-deps",
|
| 739 |
+
"--no-dependencies",
|
| 740 |
+
dest="ignore_dependencies",
|
| 741 |
+
action="store_true",
|
| 742 |
+
default=False,
|
| 743 |
+
help="Don't install package dependencies.",
|
| 744 |
+
)
|
| 745 |
+
|
| 746 |
+
|
| 747 |
+
def _handle_dependency_group(
|
| 748 |
+
option: Option, opt: str, value: str, parser: OptionParser
|
| 749 |
+
) -> None:
|
| 750 |
+
"""
|
| 751 |
+
Process a value provided for the --group option.
|
| 752 |
+
|
| 753 |
+
Splits on the rightmost ":", and validates that the path (if present) ends
|
| 754 |
+
in `pyproject.toml`. Defaults the path to `pyproject.toml` when one is not given.
|
| 755 |
+
|
| 756 |
+
`:` cannot appear in dependency group names, so this is a safe and simple parse.
|
| 757 |
+
|
| 758 |
+
This is an optparse.Option callback for the dependency_groups option.
|
| 759 |
+
"""
|
| 760 |
+
path, sep, groupname = value.rpartition(":")
|
| 761 |
+
if not sep:
|
| 762 |
+
path = "pyproject.toml"
|
| 763 |
+
else:
|
| 764 |
+
# check for 'pyproject.toml' filenames using pathlib
|
| 765 |
+
if pathlib.PurePath(path).name != "pyproject.toml":
|
| 766 |
+
msg = "group paths use 'pyproject.toml' filenames"
|
| 767 |
+
raise_option_error(parser, option=option, msg=msg)
|
| 768 |
+
|
| 769 |
+
parser.values.dependency_groups.append((path, groupname))
|
| 770 |
+
|
| 771 |
+
|
| 772 |
+
dependency_groups: Callable[..., Option] = partial(
|
| 773 |
+
Option,
|
| 774 |
+
"--group",
|
| 775 |
+
dest="dependency_groups",
|
| 776 |
+
default=[],
|
| 777 |
+
type=str,
|
| 778 |
+
action="callback",
|
| 779 |
+
callback=_handle_dependency_group,
|
| 780 |
+
metavar="[path:]group",
|
| 781 |
+
help='Install a named dependency-group from a "pyproject.toml" file. '
|
| 782 |
+
'If a path is given, the name of the file must be "pyproject.toml". '
|
| 783 |
+
'Defaults to using "pyproject.toml" in the current directory.',
|
| 784 |
+
)
|
| 785 |
+
|
| 786 |
+
ignore_requires_python: Callable[..., Option] = partial(
|
| 787 |
+
Option,
|
| 788 |
+
"--ignore-requires-python",
|
| 789 |
+
dest="ignore_requires_python",
|
| 790 |
+
action="store_true",
|
| 791 |
+
help="Ignore the Requires-Python information.",
|
| 792 |
+
)
|
| 793 |
+
|
| 794 |
+
no_build_isolation: Callable[..., Option] = partial(
|
| 795 |
+
Option,
|
| 796 |
+
"--no-build-isolation",
|
| 797 |
+
dest="build_isolation",
|
| 798 |
+
action="store_false",
|
| 799 |
+
default=True,
|
| 800 |
+
help="Disable isolation when building a modern source distribution. "
|
| 801 |
+
"Build dependencies specified by PEP 518 must be already installed "
|
| 802 |
+
"if this option is used.",
|
| 803 |
+
)
|
| 804 |
+
|
| 805 |
+
check_build_deps: Callable[..., Option] = partial(
|
| 806 |
+
Option,
|
| 807 |
+
"--check-build-dependencies",
|
| 808 |
+
dest="check_build_deps",
|
| 809 |
+
action="store_true",
|
| 810 |
+
default=False,
|
| 811 |
+
help="Check the build dependencies when PEP517 is used.",
|
| 812 |
+
)
|
| 813 |
+
|
| 814 |
+
|
| 815 |
+
def _handle_no_use_pep517(
|
| 816 |
+
option: Option, opt: str, value: str, parser: OptionParser
|
| 817 |
+
) -> None:
|
| 818 |
+
"""
|
| 819 |
+
Process a value provided for the --no-use-pep517 option.
|
| 820 |
+
|
| 821 |
+
This is an optparse.Option callback for the no_use_pep517 option.
|
| 822 |
+
"""
|
| 823 |
+
# Since --no-use-pep517 doesn't accept arguments, the value argument
|
| 824 |
+
# will be None if --no-use-pep517 is passed via the command-line.
|
| 825 |
+
# However, the value can be non-None if the option is triggered e.g.
|
| 826 |
+
# by an environment variable, for example "PIP_NO_USE_PEP517=true".
|
| 827 |
+
if value is not None:
|
| 828 |
+
msg = """A value was passed for --no-use-pep517,
|
| 829 |
+
probably using either the PIP_NO_USE_PEP517 environment variable
|
| 830 |
+
or the "no-use-pep517" config file option. Use an appropriate value
|
| 831 |
+
of the PIP_USE_PEP517 environment variable or the "use-pep517"
|
| 832 |
+
config file option instead.
|
| 833 |
+
"""
|
| 834 |
+
raise_option_error(parser, option=option, msg=msg)
|
| 835 |
+
|
| 836 |
+
# If user doesn't wish to use pep517, we check if setuptools is installed
|
| 837 |
+
# and raise error if it is not.
|
| 838 |
+
packages = ("setuptools",)
|
| 839 |
+
if not all(importlib.util.find_spec(package) for package in packages):
|
| 840 |
+
msg = (
|
| 841 |
+
f"It is not possible to use --no-use-pep517 "
|
| 842 |
+
f"without {' and '.join(packages)} installed."
|
| 843 |
+
)
|
| 844 |
+
raise_option_error(parser, option=option, msg=msg)
|
| 845 |
+
|
| 846 |
+
# Otherwise, --no-use-pep517 was passed via the command-line.
|
| 847 |
+
parser.values.use_pep517 = False
|
| 848 |
+
|
| 849 |
+
|
| 850 |
+
use_pep517: Any = partial(
|
| 851 |
+
Option,
|
| 852 |
+
"--use-pep517",
|
| 853 |
+
dest="use_pep517",
|
| 854 |
+
action="store_true",
|
| 855 |
+
default=None,
|
| 856 |
+
help="Use PEP 517 for building source distributions "
|
| 857 |
+
"(use --no-use-pep517 to force legacy behaviour).",
|
| 858 |
+
)
|
| 859 |
+
|
| 860 |
+
no_use_pep517: Any = partial(
|
| 861 |
+
Option,
|
| 862 |
+
"--no-use-pep517",
|
| 863 |
+
dest="use_pep517",
|
| 864 |
+
action="callback",
|
| 865 |
+
callback=_handle_no_use_pep517,
|
| 866 |
+
default=None,
|
| 867 |
+
help=SUPPRESS_HELP,
|
| 868 |
+
)
|
| 869 |
+
|
| 870 |
+
|
| 871 |
+
def _handle_config_settings(
|
| 872 |
+
option: Option, opt_str: str, value: str, parser: OptionParser
|
| 873 |
+
) -> None:
|
| 874 |
+
key, sep, val = value.partition("=")
|
| 875 |
+
if sep != "=":
|
| 876 |
+
parser.error(f"Arguments to {opt_str} must be of the form KEY=VAL")
|
| 877 |
+
dest = getattr(parser.values, option.dest)
|
| 878 |
+
if dest is None:
|
| 879 |
+
dest = {}
|
| 880 |
+
setattr(parser.values, option.dest, dest)
|
| 881 |
+
if key in dest:
|
| 882 |
+
if isinstance(dest[key], list):
|
| 883 |
+
dest[key].append(val)
|
| 884 |
+
else:
|
| 885 |
+
dest[key] = [dest[key], val]
|
| 886 |
+
else:
|
| 887 |
+
dest[key] = val
|
| 888 |
+
|
| 889 |
+
|
| 890 |
+
config_settings: Callable[..., Option] = partial(
|
| 891 |
+
Option,
|
| 892 |
+
"-C",
|
| 893 |
+
"--config-settings",
|
| 894 |
+
dest="config_settings",
|
| 895 |
+
type=str,
|
| 896 |
+
action="callback",
|
| 897 |
+
callback=_handle_config_settings,
|
| 898 |
+
metavar="settings",
|
| 899 |
+
help="Configuration settings to be passed to the PEP 517 build backend. "
|
| 900 |
+
"Settings take the form KEY=VALUE. Use multiple --config-settings options "
|
| 901 |
+
"to pass multiple keys to the backend.",
|
| 902 |
+
)
|
| 903 |
+
|
| 904 |
+
build_options: Callable[..., Option] = partial(
|
| 905 |
+
Option,
|
| 906 |
+
"--build-option",
|
| 907 |
+
dest="build_options",
|
| 908 |
+
metavar="options",
|
| 909 |
+
action="append",
|
| 910 |
+
help="Extra arguments to be supplied to 'setup.py bdist_wheel'.",
|
| 911 |
+
)
|
| 912 |
+
|
| 913 |
+
global_options: Callable[..., Option] = partial(
|
| 914 |
+
Option,
|
| 915 |
+
"--global-option",
|
| 916 |
+
dest="global_options",
|
| 917 |
+
action="append",
|
| 918 |
+
metavar="options",
|
| 919 |
+
help="Extra global options to be supplied to the setup.py "
|
| 920 |
+
"call before the install or bdist_wheel command.",
|
| 921 |
+
)
|
| 922 |
+
|
| 923 |
+
no_clean: Callable[..., Option] = partial(
|
| 924 |
+
Option,
|
| 925 |
+
"--no-clean",
|
| 926 |
+
action="store_true",
|
| 927 |
+
default=False,
|
| 928 |
+
help="Don't clean up build directories.",
|
| 929 |
+
)
|
| 930 |
+
|
| 931 |
+
pre: Callable[..., Option] = partial(
|
| 932 |
+
Option,
|
| 933 |
+
"--pre",
|
| 934 |
+
action="store_true",
|
| 935 |
+
default=False,
|
| 936 |
+
help="Include pre-release and development versions. By default, "
|
| 937 |
+
"pip only finds stable versions.",
|
| 938 |
+
)
|
| 939 |
+
|
| 940 |
+
json: Callable[..., Option] = partial(
|
| 941 |
+
Option,
|
| 942 |
+
"--json",
|
| 943 |
+
action="store_true",
|
| 944 |
+
default=False,
|
| 945 |
+
help="Output data in a machine-readable JSON format.",
|
| 946 |
+
)
|
| 947 |
+
|
| 948 |
+
disable_pip_version_check: Callable[..., Option] = partial(
|
| 949 |
+
Option,
|
| 950 |
+
"--disable-pip-version-check",
|
| 951 |
+
dest="disable_pip_version_check",
|
| 952 |
+
action="store_true",
|
| 953 |
+
default=False,
|
| 954 |
+
help="Don't periodically check PyPI to determine whether a new version "
|
| 955 |
+
"of pip is available for download. Implied with --no-index.",
|
| 956 |
+
)
|
| 957 |
+
|
| 958 |
+
root_user_action: Callable[..., Option] = partial(
|
| 959 |
+
Option,
|
| 960 |
+
"--root-user-action",
|
| 961 |
+
dest="root_user_action",
|
| 962 |
+
default="warn",
|
| 963 |
+
choices=["warn", "ignore"],
|
| 964 |
+
help="Action if pip is run as a root user [warn, ignore] (default: warn)",
|
| 965 |
+
)
|
| 966 |
+
|
| 967 |
+
|
| 968 |
+
def _handle_merge_hash(
|
| 969 |
+
option: Option, opt_str: str, value: str, parser: OptionParser
|
| 970 |
+
) -> None:
|
| 971 |
+
"""Given a value spelled "algo:digest", append the digest to a list
|
| 972 |
+
pointed to in a dict by the algo name."""
|
| 973 |
+
if not parser.values.hashes:
|
| 974 |
+
parser.values.hashes = {}
|
| 975 |
+
try:
|
| 976 |
+
algo, digest = value.split(":", 1)
|
| 977 |
+
except ValueError:
|
| 978 |
+
parser.error(
|
| 979 |
+
f"Arguments to {opt_str} must be a hash name "
|
| 980 |
+
"followed by a value, like --hash=sha256:"
|
| 981 |
+
"abcde..."
|
| 982 |
+
)
|
| 983 |
+
if algo not in STRONG_HASHES:
|
| 984 |
+
parser.error(
|
| 985 |
+
"Allowed hash algorithms for {} are {}.".format(
|
| 986 |
+
opt_str, ", ".join(STRONG_HASHES)
|
| 987 |
+
)
|
| 988 |
+
)
|
| 989 |
+
parser.values.hashes.setdefault(algo, []).append(digest)
|
| 990 |
+
|
| 991 |
+
|
| 992 |
+
hash: Callable[..., Option] = partial(
|
| 993 |
+
Option,
|
| 994 |
+
"--hash",
|
| 995 |
+
# Hash values eventually end up in InstallRequirement.hashes due to
|
| 996 |
+
# __dict__ copying in process_line().
|
| 997 |
+
dest="hashes",
|
| 998 |
+
action="callback",
|
| 999 |
+
callback=_handle_merge_hash,
|
| 1000 |
+
type="string",
|
| 1001 |
+
help="Verify that the package's archive matches this "
|
| 1002 |
+
"hash before installing. Example: --hash=sha256:abcdef...",
|
| 1003 |
+
)
|
| 1004 |
+
|
| 1005 |
+
|
| 1006 |
+
require_hashes: Callable[..., Option] = partial(
|
| 1007 |
+
Option,
|
| 1008 |
+
"--require-hashes",
|
| 1009 |
+
dest="require_hashes",
|
| 1010 |
+
action="store_true",
|
| 1011 |
+
default=False,
|
| 1012 |
+
help="Require a hash to check each requirement against, for "
|
| 1013 |
+
"repeatable installs. This option is implied when any package in a "
|
| 1014 |
+
"requirements file has a --hash option.",
|
| 1015 |
+
)
|
| 1016 |
+
|
| 1017 |
+
|
| 1018 |
+
list_path: Callable[..., Option] = partial(
|
| 1019 |
+
PipOption,
|
| 1020 |
+
"--path",
|
| 1021 |
+
dest="path",
|
| 1022 |
+
type="path",
|
| 1023 |
+
action="append",
|
| 1024 |
+
help="Restrict to the specified installation path for listing "
|
| 1025 |
+
"packages (can be used multiple times).",
|
| 1026 |
+
)
|
| 1027 |
+
|
| 1028 |
+
|
| 1029 |
+
def check_list_path_option(options: Values) -> None:
|
| 1030 |
+
if options.path and (options.user or options.local):
|
| 1031 |
+
raise CommandError("Cannot combine '--path' with '--user' or '--local'")
|
| 1032 |
+
|
| 1033 |
+
|
| 1034 |
+
list_exclude: Callable[..., Option] = partial(
|
| 1035 |
+
PipOption,
|
| 1036 |
+
"--exclude",
|
| 1037 |
+
dest="excludes",
|
| 1038 |
+
action="append",
|
| 1039 |
+
metavar="package",
|
| 1040 |
+
type="package_name",
|
| 1041 |
+
help="Exclude specified package from the output",
|
| 1042 |
+
)
|
| 1043 |
+
|
| 1044 |
+
|
| 1045 |
+
no_python_version_warning: Callable[..., Option] = partial(
|
| 1046 |
+
Option,
|
| 1047 |
+
"--no-python-version-warning",
|
| 1048 |
+
dest="no_python_version_warning",
|
| 1049 |
+
action="store_true",
|
| 1050 |
+
default=False,
|
| 1051 |
+
help=SUPPRESS_HELP, # No-op, a hold-over from the Python 2->3 transition.
|
| 1052 |
+
)
|
| 1053 |
+
|
| 1054 |
+
|
| 1055 |
+
# Features that are now always on. A warning is printed if they are used.
|
| 1056 |
+
ALWAYS_ENABLED_FEATURES = [
|
| 1057 |
+
"truststore", # always on since 24.2
|
| 1058 |
+
"no-binary-enable-wheel-cache", # always on since 23.1
|
| 1059 |
+
]
|
| 1060 |
+
|
| 1061 |
+
use_new_feature: Callable[..., Option] = partial(
|
| 1062 |
+
Option,
|
| 1063 |
+
"--use-feature",
|
| 1064 |
+
dest="features_enabled",
|
| 1065 |
+
metavar="feature",
|
| 1066 |
+
action="append",
|
| 1067 |
+
default=[],
|
| 1068 |
+
choices=[
|
| 1069 |
+
"fast-deps",
|
| 1070 |
+
]
|
| 1071 |
+
+ ALWAYS_ENABLED_FEATURES,
|
| 1072 |
+
help="Enable new functionality, that may be backward incompatible.",
|
| 1073 |
+
)
|
| 1074 |
+
|
| 1075 |
+
use_deprecated_feature: Callable[..., Option] = partial(
|
| 1076 |
+
Option,
|
| 1077 |
+
"--use-deprecated",
|
| 1078 |
+
dest="deprecated_features_enabled",
|
| 1079 |
+
metavar="feature",
|
| 1080 |
+
action="append",
|
| 1081 |
+
default=[],
|
| 1082 |
+
choices=[
|
| 1083 |
+
"legacy-resolver",
|
| 1084 |
+
"legacy-certs",
|
| 1085 |
+
],
|
| 1086 |
+
help=("Enable deprecated functionality, that will be removed in the future."),
|
| 1087 |
+
)
|
| 1088 |
+
|
| 1089 |
+
##########
|
| 1090 |
+
# groups #
|
| 1091 |
+
##########
|
| 1092 |
+
|
| 1093 |
+
general_group: Dict[str, Any] = {
|
| 1094 |
+
"name": "General Options",
|
| 1095 |
+
"options": [
|
| 1096 |
+
help_,
|
| 1097 |
+
debug_mode,
|
| 1098 |
+
isolated_mode,
|
| 1099 |
+
require_virtualenv,
|
| 1100 |
+
python,
|
| 1101 |
+
verbose,
|
| 1102 |
+
version,
|
| 1103 |
+
quiet,
|
| 1104 |
+
log,
|
| 1105 |
+
no_input,
|
| 1106 |
+
keyring_provider,
|
| 1107 |
+
proxy,
|
| 1108 |
+
retries,
|
| 1109 |
+
timeout,
|
| 1110 |
+
exists_action,
|
| 1111 |
+
trusted_host,
|
| 1112 |
+
cert,
|
| 1113 |
+
client_cert,
|
| 1114 |
+
cache_dir,
|
| 1115 |
+
no_cache,
|
| 1116 |
+
disable_pip_version_check,
|
| 1117 |
+
no_color,
|
| 1118 |
+
no_python_version_warning,
|
| 1119 |
+
use_new_feature,
|
| 1120 |
+
use_deprecated_feature,
|
| 1121 |
+
resume_retries,
|
| 1122 |
+
],
|
| 1123 |
+
}
|
| 1124 |
+
|
| 1125 |
+
index_group: Dict[str, Any] = {
|
| 1126 |
+
"name": "Package Index Options",
|
| 1127 |
+
"options": [
|
| 1128 |
+
index_url,
|
| 1129 |
+
extra_index_url,
|
| 1130 |
+
no_index,
|
| 1131 |
+
find_links,
|
| 1132 |
+
],
|
| 1133 |
+
}
|
ACE_plus/flashenv/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, Generator, 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) -> Generator[None, None, 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)
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/index_command.py
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Contains command classes which may interact with an index / the network.
|
| 3 |
+
|
| 4 |
+
Unlike its sister module, req_command, this module still uses lazy imports
|
| 5 |
+
so commands which don't always hit the network (e.g. list w/o --outdated or
|
| 6 |
+
--uptodate) don't need waste time importing PipSession and friends.
|
| 7 |
+
"""
|
| 8 |
+
|
| 9 |
+
import logging
|
| 10 |
+
import os
|
| 11 |
+
import sys
|
| 12 |
+
from functools import lru_cache
|
| 13 |
+
from optparse import Values
|
| 14 |
+
from typing import TYPE_CHECKING, List, Optional
|
| 15 |
+
|
| 16 |
+
from pip._vendor import certifi
|
| 17 |
+
|
| 18 |
+
from pip._internal.cli.base_command import Command
|
| 19 |
+
from pip._internal.cli.command_context import CommandContextMixIn
|
| 20 |
+
|
| 21 |
+
if TYPE_CHECKING:
|
| 22 |
+
from ssl import SSLContext
|
| 23 |
+
|
| 24 |
+
from pip._internal.network.session import PipSession
|
| 25 |
+
|
| 26 |
+
logger = logging.getLogger(__name__)
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
@lru_cache
|
| 30 |
+
def _create_truststore_ssl_context() -> Optional["SSLContext"]:
|
| 31 |
+
if sys.version_info < (3, 10):
|
| 32 |
+
logger.debug("Disabling truststore because Python version isn't 3.10+")
|
| 33 |
+
return None
|
| 34 |
+
|
| 35 |
+
try:
|
| 36 |
+
import ssl
|
| 37 |
+
except ImportError:
|
| 38 |
+
logger.warning("Disabling truststore since ssl support is missing")
|
| 39 |
+
return None
|
| 40 |
+
|
| 41 |
+
try:
|
| 42 |
+
from pip._vendor import truststore
|
| 43 |
+
except ImportError:
|
| 44 |
+
logger.warning("Disabling truststore because platform isn't supported")
|
| 45 |
+
return None
|
| 46 |
+
|
| 47 |
+
ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
| 48 |
+
ctx.load_verify_locations(certifi.where())
|
| 49 |
+
return ctx
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class SessionCommandMixin(CommandContextMixIn):
|
| 53 |
+
"""
|
| 54 |
+
A class mixin for command classes needing _build_session().
|
| 55 |
+
"""
|
| 56 |
+
|
| 57 |
+
def __init__(self) -> None:
|
| 58 |
+
super().__init__()
|
| 59 |
+
self._session: Optional[PipSession] = None
|
| 60 |
+
|
| 61 |
+
@classmethod
|
| 62 |
+
def _get_index_urls(cls, options: Values) -> Optional[List[str]]:
|
| 63 |
+
"""Return a list of index urls from user-provided options."""
|
| 64 |
+
index_urls = []
|
| 65 |
+
if not getattr(options, "no_index", False):
|
| 66 |
+
url = getattr(options, "index_url", None)
|
| 67 |
+
if url:
|
| 68 |
+
index_urls.append(url)
|
| 69 |
+
urls = getattr(options, "extra_index_urls", None)
|
| 70 |
+
if urls:
|
| 71 |
+
index_urls.extend(urls)
|
| 72 |
+
# Return None rather than an empty list
|
| 73 |
+
return index_urls or None
|
| 74 |
+
|
| 75 |
+
def get_default_session(self, options: Values) -> "PipSession":
|
| 76 |
+
"""Get a default-managed session."""
|
| 77 |
+
if self._session is None:
|
| 78 |
+
self._session = self.enter_context(self._build_session(options))
|
| 79 |
+
# there's no type annotation on requests.Session, so it's
|
| 80 |
+
# automatically ContextManager[Any] and self._session becomes Any,
|
| 81 |
+
# then https://github.com/python/mypy/issues/7696 kicks in
|
| 82 |
+
assert self._session is not None
|
| 83 |
+
return self._session
|
| 84 |
+
|
| 85 |
+
def _build_session(
|
| 86 |
+
self,
|
| 87 |
+
options: Values,
|
| 88 |
+
retries: Optional[int] = None,
|
| 89 |
+
timeout: Optional[int] = None,
|
| 90 |
+
) -> "PipSession":
|
| 91 |
+
from pip._internal.network.session import PipSession
|
| 92 |
+
|
| 93 |
+
cache_dir = options.cache_dir
|
| 94 |
+
assert not cache_dir or os.path.isabs(cache_dir)
|
| 95 |
+
|
| 96 |
+
if "legacy-certs" not in options.deprecated_features_enabled:
|
| 97 |
+
ssl_context = _create_truststore_ssl_context()
|
| 98 |
+
else:
|
| 99 |
+
ssl_context = None
|
| 100 |
+
|
| 101 |
+
session = PipSession(
|
| 102 |
+
cache=os.path.join(cache_dir, "http-v2") if cache_dir else None,
|
| 103 |
+
retries=retries if retries is not None else options.retries,
|
| 104 |
+
trusted_hosts=options.trusted_hosts,
|
| 105 |
+
index_urls=self._get_index_urls(options),
|
| 106 |
+
ssl_context=ssl_context,
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
# Handle custom ca-bundles from the user
|
| 110 |
+
if options.cert:
|
| 111 |
+
session.verify = options.cert
|
| 112 |
+
|
| 113 |
+
# Handle SSL client certificate
|
| 114 |
+
if options.client_cert:
|
| 115 |
+
session.cert = options.client_cert
|
| 116 |
+
|
| 117 |
+
# Handle timeouts
|
| 118 |
+
if options.timeout or timeout:
|
| 119 |
+
session.timeout = timeout if timeout is not None else options.timeout
|
| 120 |
+
|
| 121 |
+
# Handle configured proxies
|
| 122 |
+
if options.proxy:
|
| 123 |
+
session.proxies = {
|
| 124 |
+
"http": options.proxy,
|
| 125 |
+
"https": options.proxy,
|
| 126 |
+
}
|
| 127 |
+
session.trust_env = False
|
| 128 |
+
session.pip_proxy = options.proxy
|
| 129 |
+
|
| 130 |
+
# Determine if we can prompt the user for authentication or not
|
| 131 |
+
session.auth.prompting = not options.no_input
|
| 132 |
+
session.auth.keyring_provider = options.keyring_provider
|
| 133 |
+
|
| 134 |
+
return session
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
def _pip_self_version_check(session: "PipSession", options: Values) -> None:
|
| 138 |
+
from pip._internal.self_outdated_check import pip_self_version_check as check
|
| 139 |
+
|
| 140 |
+
check(session, options)
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
class IndexGroupCommand(Command, SessionCommandMixin):
|
| 144 |
+
"""
|
| 145 |
+
Abstract base class for commands with the index_group options.
|
| 146 |
+
|
| 147 |
+
This also corresponds to the commands that permit the pip version check.
|
| 148 |
+
"""
|
| 149 |
+
|
| 150 |
+
def handle_pip_version_check(self, options: Values) -> None:
|
| 151 |
+
"""
|
| 152 |
+
Do the pip version check if not disabled.
|
| 153 |
+
|
| 154 |
+
This overrides the default behavior of not doing the check.
|
| 155 |
+
"""
|
| 156 |
+
# Make sure the index_group options are present.
|
| 157 |
+
assert hasattr(options, "no_index")
|
| 158 |
+
|
| 159 |
+
if options.disable_pip_version_check or options.no_index:
|
| 160 |
+
return
|
| 161 |
+
|
| 162 |
+
try:
|
| 163 |
+
# Otherwise, check if we're using the latest version of pip available.
|
| 164 |
+
session = self._build_session(
|
| 165 |
+
options,
|
| 166 |
+
retries=0,
|
| 167 |
+
timeout=min(5, options.timeout),
|
| 168 |
+
)
|
| 169 |
+
with session:
|
| 170 |
+
_pip_self_version_check(session, options)
|
| 171 |
+
except Exception:
|
| 172 |
+
logger.warning("There was an error checking the latest version of pip.")
|
| 173 |
+
logger.debug("See below for error", exc_info=True)
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/main.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Primary application entrypoint."""
|
| 2 |
+
|
| 3 |
+
import locale
|
| 4 |
+
import logging
|
| 5 |
+
import os
|
| 6 |
+
import sys
|
| 7 |
+
import warnings
|
| 8 |
+
from typing import List, Optional
|
| 9 |
+
|
| 10 |
+
from pip._internal.cli.autocompletion import autocomplete
|
| 11 |
+
from pip._internal.cli.main_parser import parse_command
|
| 12 |
+
from pip._internal.commands import create_command
|
| 13 |
+
from pip._internal.exceptions import PipError
|
| 14 |
+
from pip._internal.utils import deprecation
|
| 15 |
+
|
| 16 |
+
logger = logging.getLogger(__name__)
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
# Do not import and use main() directly! Using it directly is actively
|
| 20 |
+
# discouraged by pip's maintainers. The name, location and behavior of
|
| 21 |
+
# this function is subject to change, so calling it directly is not
|
| 22 |
+
# portable across different pip versions.
|
| 23 |
+
|
| 24 |
+
# In addition, running pip in-process is unsupported and unsafe. This is
|
| 25 |
+
# elaborated in detail at
|
| 26 |
+
# https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program.
|
| 27 |
+
# That document also provides suggestions that should work for nearly
|
| 28 |
+
# all users that are considering importing and using main() directly.
|
| 29 |
+
|
| 30 |
+
# However, we know that certain users will still want to invoke pip
|
| 31 |
+
# in-process. If you understand and accept the implications of using pip
|
| 32 |
+
# in an unsupported manner, the best approach is to use runpy to avoid
|
| 33 |
+
# depending on the exact location of this entry point.
|
| 34 |
+
|
| 35 |
+
# The following example shows how to use runpy to invoke pip in that
|
| 36 |
+
# case:
|
| 37 |
+
#
|
| 38 |
+
# sys.argv = ["pip", your, args, here]
|
| 39 |
+
# runpy.run_module("pip", run_name="__main__")
|
| 40 |
+
#
|
| 41 |
+
# Note that this will exit the process after running, unlike a direct
|
| 42 |
+
# call to main. As it is not safe to do any processing after calling
|
| 43 |
+
# main, this should not be an issue in practice.
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def main(args: Optional[List[str]] = None) -> int:
|
| 47 |
+
if args is None:
|
| 48 |
+
args = sys.argv[1:]
|
| 49 |
+
|
| 50 |
+
# Suppress the pkg_resources deprecation warning
|
| 51 |
+
# Note - we use a module of .*pkg_resources to cover
|
| 52 |
+
# the normal case (pip._vendor.pkg_resources) and the
|
| 53 |
+
# devendored case (a bare pkg_resources)
|
| 54 |
+
warnings.filterwarnings(
|
| 55 |
+
action="ignore", category=DeprecationWarning, module=".*pkg_resources"
|
| 56 |
+
)
|
| 57 |
+
|
| 58 |
+
# Configure our deprecation warnings to be sent through loggers
|
| 59 |
+
deprecation.install_warning_logger()
|
| 60 |
+
|
| 61 |
+
autocomplete()
|
| 62 |
+
|
| 63 |
+
try:
|
| 64 |
+
cmd_name, cmd_args = parse_command(args)
|
| 65 |
+
except PipError as exc:
|
| 66 |
+
sys.stderr.write(f"ERROR: {exc}")
|
| 67 |
+
sys.stderr.write(os.linesep)
|
| 68 |
+
sys.exit(1)
|
| 69 |
+
|
| 70 |
+
# Needed for locale.getpreferredencoding(False) to work
|
| 71 |
+
# in pip._internal.utils.encoding.auto_decode
|
| 72 |
+
try:
|
| 73 |
+
locale.setlocale(locale.LC_ALL, "")
|
| 74 |
+
except locale.Error as e:
|
| 75 |
+
# setlocale can apparently crash if locale are uninitialized
|
| 76 |
+
logger.debug("Ignoring error %s when setting locale", e)
|
| 77 |
+
command = create_command(cmd_name, isolated=("--isolated" in cmd_args))
|
| 78 |
+
|
| 79 |
+
return command.main(cmd_args)
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/main_parser.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""A single place for constructing and exposing the main parser"""
|
| 2 |
+
|
| 3 |
+
import os
|
| 4 |
+
import subprocess
|
| 5 |
+
import sys
|
| 6 |
+
from typing import List, Optional, Tuple
|
| 7 |
+
|
| 8 |
+
from pip._internal.build_env import get_runnable_pip
|
| 9 |
+
from pip._internal.cli import cmdoptions
|
| 10 |
+
from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
|
| 11 |
+
from pip._internal.commands import commands_dict, get_similar_commands
|
| 12 |
+
from pip._internal.exceptions import CommandError
|
| 13 |
+
from pip._internal.utils.misc import get_pip_version, get_prog
|
| 14 |
+
|
| 15 |
+
__all__ = ["create_main_parser", "parse_command"]
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def create_main_parser() -> ConfigOptionParser:
|
| 19 |
+
"""Creates and returns the main parser for pip's CLI"""
|
| 20 |
+
|
| 21 |
+
parser = ConfigOptionParser(
|
| 22 |
+
usage="\n%prog <command> [options]",
|
| 23 |
+
add_help_option=False,
|
| 24 |
+
formatter=UpdatingDefaultsHelpFormatter(),
|
| 25 |
+
name="global",
|
| 26 |
+
prog=get_prog(),
|
| 27 |
+
)
|
| 28 |
+
parser.disable_interspersed_args()
|
| 29 |
+
|
| 30 |
+
parser.version = get_pip_version()
|
| 31 |
+
|
| 32 |
+
# add the general options
|
| 33 |
+
gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser)
|
| 34 |
+
parser.add_option_group(gen_opts)
|
| 35 |
+
|
| 36 |
+
# so the help formatter knows
|
| 37 |
+
parser.main = True # type: ignore
|
| 38 |
+
|
| 39 |
+
# create command listing for description
|
| 40 |
+
description = [""] + [
|
| 41 |
+
f"{name:27} {command_info.summary}"
|
| 42 |
+
for name, command_info in commands_dict.items()
|
| 43 |
+
]
|
| 44 |
+
parser.description = "\n".join(description)
|
| 45 |
+
|
| 46 |
+
return parser
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
def identify_python_interpreter(python: str) -> Optional[str]:
|
| 50 |
+
# If the named file exists, use it.
|
| 51 |
+
# If it's a directory, assume it's a virtual environment and
|
| 52 |
+
# look for the environment's Python executable.
|
| 53 |
+
if os.path.exists(python):
|
| 54 |
+
if os.path.isdir(python):
|
| 55 |
+
# bin/python for Unix, Scripts/python.exe for Windows
|
| 56 |
+
# Try both in case of odd cases like cygwin.
|
| 57 |
+
for exe in ("bin/python", "Scripts/python.exe"):
|
| 58 |
+
py = os.path.join(python, exe)
|
| 59 |
+
if os.path.exists(py):
|
| 60 |
+
return py
|
| 61 |
+
else:
|
| 62 |
+
return python
|
| 63 |
+
|
| 64 |
+
# Could not find the interpreter specified
|
| 65 |
+
return None
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def parse_command(args: List[str]) -> Tuple[str, List[str]]:
|
| 69 |
+
parser = create_main_parser()
|
| 70 |
+
|
| 71 |
+
# Note: parser calls disable_interspersed_args(), so the result of this
|
| 72 |
+
# call is to split the initial args into the general options before the
|
| 73 |
+
# subcommand and everything else.
|
| 74 |
+
# For example:
|
| 75 |
+
# args: ['--timeout=5', 'install', '--user', 'INITools']
|
| 76 |
+
# general_options: ['--timeout==5']
|
| 77 |
+
# args_else: ['install', '--user', 'INITools']
|
| 78 |
+
general_options, args_else = parser.parse_args(args)
|
| 79 |
+
|
| 80 |
+
# --python
|
| 81 |
+
if general_options.python and "_PIP_RUNNING_IN_SUBPROCESS" not in os.environ:
|
| 82 |
+
# Re-invoke pip using the specified Python interpreter
|
| 83 |
+
interpreter = identify_python_interpreter(general_options.python)
|
| 84 |
+
if interpreter is None:
|
| 85 |
+
raise CommandError(
|
| 86 |
+
f"Could not locate Python interpreter {general_options.python}"
|
| 87 |
+
)
|
| 88 |
+
|
| 89 |
+
pip_cmd = [
|
| 90 |
+
interpreter,
|
| 91 |
+
get_runnable_pip(),
|
| 92 |
+
]
|
| 93 |
+
pip_cmd.extend(args)
|
| 94 |
+
|
| 95 |
+
# Set a flag so the child doesn't re-invoke itself, causing
|
| 96 |
+
# an infinite loop.
|
| 97 |
+
os.environ["_PIP_RUNNING_IN_SUBPROCESS"] = "1"
|
| 98 |
+
returncode = 0
|
| 99 |
+
try:
|
| 100 |
+
proc = subprocess.run(pip_cmd)
|
| 101 |
+
returncode = proc.returncode
|
| 102 |
+
except (subprocess.SubprocessError, OSError) as exc:
|
| 103 |
+
raise CommandError(f"Failed to run pip under {interpreter}: {exc}")
|
| 104 |
+
sys.exit(returncode)
|
| 105 |
+
|
| 106 |
+
# --version
|
| 107 |
+
if general_options.version:
|
| 108 |
+
sys.stdout.write(parser.version)
|
| 109 |
+
sys.stdout.write(os.linesep)
|
| 110 |
+
sys.exit()
|
| 111 |
+
|
| 112 |
+
# pip || pip help -> print_help()
|
| 113 |
+
if not args_else or (args_else[0] == "help" and len(args_else) == 1):
|
| 114 |
+
parser.print_help()
|
| 115 |
+
sys.exit()
|
| 116 |
+
|
| 117 |
+
# the subcommand name
|
| 118 |
+
cmd_name = args_else[0]
|
| 119 |
+
|
| 120 |
+
if cmd_name not in commands_dict:
|
| 121 |
+
guess = get_similar_commands(cmd_name)
|
| 122 |
+
|
| 123 |
+
msg = [f'unknown command "{cmd_name}"']
|
| 124 |
+
if guess:
|
| 125 |
+
msg.append(f'maybe you meant "{guess}"')
|
| 126 |
+
|
| 127 |
+
raise CommandError(" - ".join(msg))
|
| 128 |
+
|
| 129 |
+
# all the args without the subcommand
|
| 130 |
+
cmd_args = args[:]
|
| 131 |
+
cmd_args.remove(cmd_name)
|
| 132 |
+
|
| 133 |
+
return cmd_name, cmd_args
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/parser.py
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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, Generator, List, NoReturn, Optional, 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: Optional[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: Optional[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(
|
| 179 |
+
self,
|
| 180 |
+
) -> Generator[Tuple[str, Any], None, None]:
|
| 181 |
+
# Configuration gives keys in an unordered manner. Order them.
|
| 182 |
+
override_order = ["global", self.name, ":env:"]
|
| 183 |
+
|
| 184 |
+
# Pool the options into different groups
|
| 185 |
+
section_items: Dict[str, List[Tuple[str, Any]]] = {
|
| 186 |
+
name: [] for name in override_order
|
| 187 |
+
}
|
| 188 |
+
for section_key, val in self.config.items():
|
| 189 |
+
# ignore empty values
|
| 190 |
+
if not val:
|
| 191 |
+
logger.debug(
|
| 192 |
+
"Ignoring configuration key '%s' as it's value is empty.",
|
| 193 |
+
section_key,
|
| 194 |
+
)
|
| 195 |
+
continue
|
| 196 |
+
|
| 197 |
+
section, key = section_key.split(".", 1)
|
| 198 |
+
if section in override_order:
|
| 199 |
+
section_items[section].append((key, val))
|
| 200 |
+
|
| 201 |
+
# Yield each group in their override order
|
| 202 |
+
for section in override_order:
|
| 203 |
+
for key, val in section_items[section]:
|
| 204 |
+
yield key, val
|
| 205 |
+
|
| 206 |
+
def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]:
|
| 207 |
+
"""Updates the given defaults with values from the config files and
|
| 208 |
+
the environ. Does a little special handling for certain types of
|
| 209 |
+
options (lists)."""
|
| 210 |
+
|
| 211 |
+
# Accumulate complex default state.
|
| 212 |
+
self.values = optparse.Values(self.defaults)
|
| 213 |
+
late_eval = set()
|
| 214 |
+
# Then set the options with those values
|
| 215 |
+
for key, val in self._get_ordered_configuration_items():
|
| 216 |
+
# '--' because configuration supports only long names
|
| 217 |
+
option = self.get_option("--" + key)
|
| 218 |
+
|
| 219 |
+
# Ignore options not present in this parser. E.g. non-globals put
|
| 220 |
+
# in [global] by users that want them to apply to all applicable
|
| 221 |
+
# commands.
|
| 222 |
+
if option is None:
|
| 223 |
+
continue
|
| 224 |
+
|
| 225 |
+
assert option.dest is not None
|
| 226 |
+
|
| 227 |
+
if option.action in ("store_true", "store_false"):
|
| 228 |
+
try:
|
| 229 |
+
val = strtobool(val)
|
| 230 |
+
except ValueError:
|
| 231 |
+
self.error(
|
| 232 |
+
f"{val} is not a valid value for {key} option, "
|
| 233 |
+
"please specify a boolean value like yes/no, "
|
| 234 |
+
"true/false or 1/0 instead."
|
| 235 |
+
)
|
| 236 |
+
elif option.action == "count":
|
| 237 |
+
with suppress(ValueError):
|
| 238 |
+
val = strtobool(val)
|
| 239 |
+
with suppress(ValueError):
|
| 240 |
+
val = int(val)
|
| 241 |
+
if not isinstance(val, int) or val < 0:
|
| 242 |
+
self.error(
|
| 243 |
+
f"{val} is not a valid value for {key} option, "
|
| 244 |
+
"please instead specify either a non-negative integer "
|
| 245 |
+
"or a boolean value like yes/no or false/true "
|
| 246 |
+
"which is equivalent to 1/0."
|
| 247 |
+
)
|
| 248 |
+
elif option.action == "append":
|
| 249 |
+
val = val.split()
|
| 250 |
+
val = [self.check_default(option, key, v) for v in val]
|
| 251 |
+
elif option.action == "callback":
|
| 252 |
+
assert option.callback is not None
|
| 253 |
+
late_eval.add(option.dest)
|
| 254 |
+
opt_str = option.get_opt_string()
|
| 255 |
+
val = option.convert_value(opt_str, val)
|
| 256 |
+
# From take_action
|
| 257 |
+
args = option.callback_args or ()
|
| 258 |
+
kwargs = option.callback_kwargs or {}
|
| 259 |
+
option.callback(option, opt_str, val, self, *args, **kwargs)
|
| 260 |
+
else:
|
| 261 |
+
val = self.check_default(option, key, val)
|
| 262 |
+
|
| 263 |
+
defaults[option.dest] = val
|
| 264 |
+
|
| 265 |
+
for key in late_eval:
|
| 266 |
+
defaults[key] = getattr(self.values, key)
|
| 267 |
+
self.values = None
|
| 268 |
+
return defaults
|
| 269 |
+
|
| 270 |
+
def get_default_values(self) -> optparse.Values:
|
| 271 |
+
"""Overriding to make updating the defaults after instantiation of
|
| 272 |
+
the option parser possible, _update_defaults() does the dirty work."""
|
| 273 |
+
if not self.process_default_values:
|
| 274 |
+
# Old, pre-Optik 1.5 behaviour.
|
| 275 |
+
return optparse.Values(self.defaults)
|
| 276 |
+
|
| 277 |
+
# Load the configuration, or error out in case of an error
|
| 278 |
+
try:
|
| 279 |
+
self.config.load()
|
| 280 |
+
except ConfigurationError as err:
|
| 281 |
+
self.exit(UNKNOWN_ERROR, str(err))
|
| 282 |
+
|
| 283 |
+
defaults = self._update_defaults(self.defaults.copy()) # ours
|
| 284 |
+
for option in self._get_all_options():
|
| 285 |
+
assert option.dest is not None
|
| 286 |
+
default = defaults.get(option.dest)
|
| 287 |
+
if isinstance(default, str):
|
| 288 |
+
opt_str = option.get_opt_string()
|
| 289 |
+
defaults[option.dest] = option.check_value(opt_str, default)
|
| 290 |
+
return optparse.Values(defaults)
|
| 291 |
+
|
| 292 |
+
def error(self, msg: str) -> NoReturn:
|
| 293 |
+
self.print_usage(sys.stderr)
|
| 294 |
+
self.exit(UNKNOWN_ERROR, f"{msg}\n")
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import functools
|
| 2 |
+
import sys
|
| 3 |
+
from typing import Callable, Generator, Iterable, Iterator, Optional, Tuple, TypeVar
|
| 4 |
+
|
| 5 |
+
from pip._vendor.rich.progress import (
|
| 6 |
+
BarColumn,
|
| 7 |
+
DownloadColumn,
|
| 8 |
+
FileSizeColumn,
|
| 9 |
+
MofNCompleteColumn,
|
| 10 |
+
Progress,
|
| 11 |
+
ProgressColumn,
|
| 12 |
+
SpinnerColumn,
|
| 13 |
+
TextColumn,
|
| 14 |
+
TimeElapsedColumn,
|
| 15 |
+
TimeRemainingColumn,
|
| 16 |
+
TransferSpeedColumn,
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
from pip._internal.cli.spinners import RateLimiter
|
| 20 |
+
from pip._internal.req.req_install import InstallRequirement
|
| 21 |
+
from pip._internal.utils.logging import get_console, get_indentation
|
| 22 |
+
|
| 23 |
+
T = TypeVar("T")
|
| 24 |
+
ProgressRenderer = Callable[[Iterable[T]], Iterator[T]]
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def _rich_download_progress_bar(
|
| 28 |
+
iterable: Iterable[bytes],
|
| 29 |
+
*,
|
| 30 |
+
bar_type: str,
|
| 31 |
+
size: Optional[int],
|
| 32 |
+
initial_progress: Optional[int] = None,
|
| 33 |
+
) -> Generator[bytes, None, None]:
|
| 34 |
+
assert bar_type == "on", "This should only be used in the default mode."
|
| 35 |
+
|
| 36 |
+
if not size:
|
| 37 |
+
total = float("inf")
|
| 38 |
+
columns: Tuple[ProgressColumn, ...] = (
|
| 39 |
+
TextColumn("[progress.description]{task.description}"),
|
| 40 |
+
SpinnerColumn("line", speed=1.5),
|
| 41 |
+
FileSizeColumn(),
|
| 42 |
+
TransferSpeedColumn(),
|
| 43 |
+
TimeElapsedColumn(),
|
| 44 |
+
)
|
| 45 |
+
else:
|
| 46 |
+
total = size
|
| 47 |
+
columns = (
|
| 48 |
+
TextColumn("[progress.description]{task.description}"),
|
| 49 |
+
BarColumn(),
|
| 50 |
+
DownloadColumn(),
|
| 51 |
+
TransferSpeedColumn(),
|
| 52 |
+
TextColumn("eta"),
|
| 53 |
+
TimeRemainingColumn(),
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
progress = Progress(*columns, refresh_per_second=5)
|
| 57 |
+
task_id = progress.add_task(" " * (get_indentation() + 2), total=total)
|
| 58 |
+
if initial_progress is not None:
|
| 59 |
+
progress.update(task_id, advance=initial_progress)
|
| 60 |
+
with progress:
|
| 61 |
+
for chunk in iterable:
|
| 62 |
+
yield chunk
|
| 63 |
+
progress.update(task_id, advance=len(chunk))
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def _rich_install_progress_bar(
|
| 67 |
+
iterable: Iterable[InstallRequirement], *, total: int
|
| 68 |
+
) -> Iterator[InstallRequirement]:
|
| 69 |
+
columns = (
|
| 70 |
+
TextColumn("{task.fields[indent]}"),
|
| 71 |
+
BarColumn(),
|
| 72 |
+
MofNCompleteColumn(),
|
| 73 |
+
TextColumn("{task.description}"),
|
| 74 |
+
)
|
| 75 |
+
console = get_console()
|
| 76 |
+
|
| 77 |
+
bar = Progress(*columns, refresh_per_second=6, console=console, transient=True)
|
| 78 |
+
# Hiding the progress bar at initialization forces a refresh cycle to occur
|
| 79 |
+
# until the bar appears, avoiding very short flashes.
|
| 80 |
+
task = bar.add_task("", total=total, indent=" " * get_indentation(), visible=False)
|
| 81 |
+
with bar:
|
| 82 |
+
for req in iterable:
|
| 83 |
+
bar.update(task, description=rf"\[{req.name}]", visible=True)
|
| 84 |
+
yield req
|
| 85 |
+
bar.advance(task)
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def _raw_progress_bar(
|
| 89 |
+
iterable: Iterable[bytes],
|
| 90 |
+
*,
|
| 91 |
+
size: Optional[int],
|
| 92 |
+
initial_progress: Optional[int] = None,
|
| 93 |
+
) -> Generator[bytes, None, None]:
|
| 94 |
+
def write_progress(current: int, total: int) -> None:
|
| 95 |
+
sys.stdout.write(f"Progress {current} of {total}\n")
|
| 96 |
+
sys.stdout.flush()
|
| 97 |
+
|
| 98 |
+
current = initial_progress or 0
|
| 99 |
+
total = size or 0
|
| 100 |
+
rate_limiter = RateLimiter(0.25)
|
| 101 |
+
|
| 102 |
+
write_progress(current, total)
|
| 103 |
+
for chunk in iterable:
|
| 104 |
+
current += len(chunk)
|
| 105 |
+
if rate_limiter.ready() or current == total:
|
| 106 |
+
write_progress(current, total)
|
| 107 |
+
rate_limiter.reset()
|
| 108 |
+
yield chunk
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def get_download_progress_renderer(
|
| 112 |
+
*, bar_type: str, size: Optional[int] = None, initial_progress: Optional[int] = None
|
| 113 |
+
) -> ProgressRenderer[bytes]:
|
| 114 |
+
"""Get an object that can be used to render the download progress.
|
| 115 |
+
|
| 116 |
+
Returns a callable, that takes an iterable to "wrap".
|
| 117 |
+
"""
|
| 118 |
+
if bar_type == "on":
|
| 119 |
+
return functools.partial(
|
| 120 |
+
_rich_download_progress_bar,
|
| 121 |
+
bar_type=bar_type,
|
| 122 |
+
size=size,
|
| 123 |
+
initial_progress=initial_progress,
|
| 124 |
+
)
|
| 125 |
+
elif bar_type == "raw":
|
| 126 |
+
return functools.partial(
|
| 127 |
+
_raw_progress_bar,
|
| 128 |
+
size=size,
|
| 129 |
+
initial_progress=initial_progress,
|
| 130 |
+
)
|
| 131 |
+
else:
|
| 132 |
+
return iter # no-op, when passed an iterator
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def get_install_progress_renderer(
|
| 136 |
+
*, bar_type: str, total: int
|
| 137 |
+
) -> ProgressRenderer[InstallRequirement]:
|
| 138 |
+
"""Get an object that can be used to render the install progress.
|
| 139 |
+
Returns a callable, that takes an iterable to "wrap".
|
| 140 |
+
"""
|
| 141 |
+
if bar_type == "on":
|
| 142 |
+
return functools.partial(_rich_install_progress_bar, total=total)
|
| 143 |
+
else:
|
| 144 |
+
return iter
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/req_command.py
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Contains the RequirementCommand base class.
|
| 2 |
+
|
| 3 |
+
This class is in a separate module so the commands that do not always
|
| 4 |
+
need PackageFinder capability don't unnecessarily import the
|
| 5 |
+
PackageFinder machinery and all its vendored dependencies, etc.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import logging
|
| 9 |
+
from functools import partial
|
| 10 |
+
from optparse import Values
|
| 11 |
+
from typing import Any, List, Optional, Tuple
|
| 12 |
+
|
| 13 |
+
from pip._internal.cache import WheelCache
|
| 14 |
+
from pip._internal.cli import cmdoptions
|
| 15 |
+
from pip._internal.cli.index_command import IndexGroupCommand
|
| 16 |
+
from pip._internal.cli.index_command import SessionCommandMixin as SessionCommandMixin
|
| 17 |
+
from pip._internal.exceptions import CommandError, PreviousBuildDirError
|
| 18 |
+
from pip._internal.index.collector import LinkCollector
|
| 19 |
+
from pip._internal.index.package_finder import PackageFinder
|
| 20 |
+
from pip._internal.models.selection_prefs import SelectionPreferences
|
| 21 |
+
from pip._internal.models.target_python import TargetPython
|
| 22 |
+
from pip._internal.network.session import PipSession
|
| 23 |
+
from pip._internal.operations.build.build_tracker import BuildTracker
|
| 24 |
+
from pip._internal.operations.prepare import RequirementPreparer
|
| 25 |
+
from pip._internal.req.constructors import (
|
| 26 |
+
install_req_from_editable,
|
| 27 |
+
install_req_from_line,
|
| 28 |
+
install_req_from_parsed_requirement,
|
| 29 |
+
install_req_from_req_string,
|
| 30 |
+
)
|
| 31 |
+
from pip._internal.req.req_dependency_group import parse_dependency_groups
|
| 32 |
+
from pip._internal.req.req_file import parse_requirements
|
| 33 |
+
from pip._internal.req.req_install import InstallRequirement
|
| 34 |
+
from pip._internal.resolution.base import BaseResolver
|
| 35 |
+
from pip._internal.utils.temp_dir import (
|
| 36 |
+
TempDirectory,
|
| 37 |
+
TempDirectoryTypeRegistry,
|
| 38 |
+
tempdir_kinds,
|
| 39 |
+
)
|
| 40 |
+
|
| 41 |
+
logger = logging.getLogger(__name__)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
KEEPABLE_TEMPDIR_TYPES = [
|
| 45 |
+
tempdir_kinds.BUILD_ENV,
|
| 46 |
+
tempdir_kinds.EPHEM_WHEEL_CACHE,
|
| 47 |
+
tempdir_kinds.REQ_BUILD,
|
| 48 |
+
]
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def with_cleanup(func: Any) -> Any:
|
| 52 |
+
"""Decorator for common logic related to managing temporary
|
| 53 |
+
directories.
|
| 54 |
+
"""
|
| 55 |
+
|
| 56 |
+
def configure_tempdir_registry(registry: TempDirectoryTypeRegistry) -> None:
|
| 57 |
+
for t in KEEPABLE_TEMPDIR_TYPES:
|
| 58 |
+
registry.set_delete(t, False)
|
| 59 |
+
|
| 60 |
+
def wrapper(
|
| 61 |
+
self: RequirementCommand, options: Values, args: List[Any]
|
| 62 |
+
) -> Optional[int]:
|
| 63 |
+
assert self.tempdir_registry is not None
|
| 64 |
+
if options.no_clean:
|
| 65 |
+
configure_tempdir_registry(self.tempdir_registry)
|
| 66 |
+
|
| 67 |
+
try:
|
| 68 |
+
return func(self, options, args)
|
| 69 |
+
except PreviousBuildDirError:
|
| 70 |
+
# This kind of conflict can occur when the user passes an explicit
|
| 71 |
+
# build directory with a pre-existing folder. In that case we do
|
| 72 |
+
# not want to accidentally remove it.
|
| 73 |
+
configure_tempdir_registry(self.tempdir_registry)
|
| 74 |
+
raise
|
| 75 |
+
|
| 76 |
+
return wrapper
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
class RequirementCommand(IndexGroupCommand):
|
| 80 |
+
def __init__(self, *args: Any, **kw: Any) -> None:
|
| 81 |
+
super().__init__(*args, **kw)
|
| 82 |
+
|
| 83 |
+
self.cmd_opts.add_option(cmdoptions.dependency_groups())
|
| 84 |
+
self.cmd_opts.add_option(cmdoptions.no_clean())
|
| 85 |
+
|
| 86 |
+
@staticmethod
|
| 87 |
+
def determine_resolver_variant(options: Values) -> str:
|
| 88 |
+
"""Determines which resolver should be used, based on the given options."""
|
| 89 |
+
if "legacy-resolver" in options.deprecated_features_enabled:
|
| 90 |
+
return "legacy"
|
| 91 |
+
|
| 92 |
+
return "resolvelib"
|
| 93 |
+
|
| 94 |
+
@classmethod
|
| 95 |
+
def make_requirement_preparer(
|
| 96 |
+
cls,
|
| 97 |
+
temp_build_dir: TempDirectory,
|
| 98 |
+
options: Values,
|
| 99 |
+
build_tracker: BuildTracker,
|
| 100 |
+
session: PipSession,
|
| 101 |
+
finder: PackageFinder,
|
| 102 |
+
use_user_site: bool,
|
| 103 |
+
download_dir: Optional[str] = None,
|
| 104 |
+
verbosity: int = 0,
|
| 105 |
+
) -> RequirementPreparer:
|
| 106 |
+
"""
|
| 107 |
+
Create a RequirementPreparer instance for the given parameters.
|
| 108 |
+
"""
|
| 109 |
+
temp_build_dir_path = temp_build_dir.path
|
| 110 |
+
assert temp_build_dir_path is not None
|
| 111 |
+
legacy_resolver = False
|
| 112 |
+
|
| 113 |
+
resolver_variant = cls.determine_resolver_variant(options)
|
| 114 |
+
if resolver_variant == "resolvelib":
|
| 115 |
+
lazy_wheel = "fast-deps" in options.features_enabled
|
| 116 |
+
if lazy_wheel:
|
| 117 |
+
logger.warning(
|
| 118 |
+
"pip is using lazily downloaded wheels using HTTP "
|
| 119 |
+
"range requests to obtain dependency information. "
|
| 120 |
+
"This experimental feature is enabled through "
|
| 121 |
+
"--use-feature=fast-deps and it is not ready for "
|
| 122 |
+
"production."
|
| 123 |
+
)
|
| 124 |
+
else:
|
| 125 |
+
legacy_resolver = True
|
| 126 |
+
lazy_wheel = False
|
| 127 |
+
if "fast-deps" in options.features_enabled:
|
| 128 |
+
logger.warning(
|
| 129 |
+
"fast-deps has no effect when used with the legacy resolver."
|
| 130 |
+
)
|
| 131 |
+
|
| 132 |
+
return RequirementPreparer(
|
| 133 |
+
build_dir=temp_build_dir_path,
|
| 134 |
+
src_dir=options.src_dir,
|
| 135 |
+
download_dir=download_dir,
|
| 136 |
+
build_isolation=options.build_isolation,
|
| 137 |
+
check_build_deps=options.check_build_deps,
|
| 138 |
+
build_tracker=build_tracker,
|
| 139 |
+
session=session,
|
| 140 |
+
progress_bar=options.progress_bar,
|
| 141 |
+
finder=finder,
|
| 142 |
+
require_hashes=options.require_hashes,
|
| 143 |
+
use_user_site=use_user_site,
|
| 144 |
+
lazy_wheel=lazy_wheel,
|
| 145 |
+
verbosity=verbosity,
|
| 146 |
+
legacy_resolver=legacy_resolver,
|
| 147 |
+
resume_retries=options.resume_retries,
|
| 148 |
+
)
|
| 149 |
+
|
| 150 |
+
@classmethod
|
| 151 |
+
def make_resolver(
|
| 152 |
+
cls,
|
| 153 |
+
preparer: RequirementPreparer,
|
| 154 |
+
finder: PackageFinder,
|
| 155 |
+
options: Values,
|
| 156 |
+
wheel_cache: Optional[WheelCache] = None,
|
| 157 |
+
use_user_site: bool = False,
|
| 158 |
+
ignore_installed: bool = True,
|
| 159 |
+
ignore_requires_python: bool = False,
|
| 160 |
+
force_reinstall: bool = False,
|
| 161 |
+
upgrade_strategy: str = "to-satisfy-only",
|
| 162 |
+
use_pep517: Optional[bool] = None,
|
| 163 |
+
py_version_info: Optional[Tuple[int, ...]] = None,
|
| 164 |
+
) -> BaseResolver:
|
| 165 |
+
"""
|
| 166 |
+
Create a Resolver instance for the given parameters.
|
| 167 |
+
"""
|
| 168 |
+
make_install_req = partial(
|
| 169 |
+
install_req_from_req_string,
|
| 170 |
+
isolated=options.isolated_mode,
|
| 171 |
+
use_pep517=use_pep517,
|
| 172 |
+
)
|
| 173 |
+
resolver_variant = cls.determine_resolver_variant(options)
|
| 174 |
+
# The long import name and duplicated invocation is needed to convince
|
| 175 |
+
# Mypy into correctly typechecking. Otherwise it would complain the
|
| 176 |
+
# "Resolver" class being redefined.
|
| 177 |
+
if resolver_variant == "resolvelib":
|
| 178 |
+
import pip._internal.resolution.resolvelib.resolver
|
| 179 |
+
|
| 180 |
+
return pip._internal.resolution.resolvelib.resolver.Resolver(
|
| 181 |
+
preparer=preparer,
|
| 182 |
+
finder=finder,
|
| 183 |
+
wheel_cache=wheel_cache,
|
| 184 |
+
make_install_req=make_install_req,
|
| 185 |
+
use_user_site=use_user_site,
|
| 186 |
+
ignore_dependencies=options.ignore_dependencies,
|
| 187 |
+
ignore_installed=ignore_installed,
|
| 188 |
+
ignore_requires_python=ignore_requires_python,
|
| 189 |
+
force_reinstall=force_reinstall,
|
| 190 |
+
upgrade_strategy=upgrade_strategy,
|
| 191 |
+
py_version_info=py_version_info,
|
| 192 |
+
)
|
| 193 |
+
import pip._internal.resolution.legacy.resolver
|
| 194 |
+
|
| 195 |
+
return pip._internal.resolution.legacy.resolver.Resolver(
|
| 196 |
+
preparer=preparer,
|
| 197 |
+
finder=finder,
|
| 198 |
+
wheel_cache=wheel_cache,
|
| 199 |
+
make_install_req=make_install_req,
|
| 200 |
+
use_user_site=use_user_site,
|
| 201 |
+
ignore_dependencies=options.ignore_dependencies,
|
| 202 |
+
ignore_installed=ignore_installed,
|
| 203 |
+
ignore_requires_python=ignore_requires_python,
|
| 204 |
+
force_reinstall=force_reinstall,
|
| 205 |
+
upgrade_strategy=upgrade_strategy,
|
| 206 |
+
py_version_info=py_version_info,
|
| 207 |
+
)
|
| 208 |
+
|
| 209 |
+
def get_requirements(
|
| 210 |
+
self,
|
| 211 |
+
args: List[str],
|
| 212 |
+
options: Values,
|
| 213 |
+
finder: PackageFinder,
|
| 214 |
+
session: PipSession,
|
| 215 |
+
) -> List[InstallRequirement]:
|
| 216 |
+
"""
|
| 217 |
+
Parse command-line arguments into the corresponding requirements.
|
| 218 |
+
"""
|
| 219 |
+
requirements: List[InstallRequirement] = []
|
| 220 |
+
for filename in options.constraints:
|
| 221 |
+
for parsed_req in parse_requirements(
|
| 222 |
+
filename,
|
| 223 |
+
constraint=True,
|
| 224 |
+
finder=finder,
|
| 225 |
+
options=options,
|
| 226 |
+
session=session,
|
| 227 |
+
):
|
| 228 |
+
req_to_add = install_req_from_parsed_requirement(
|
| 229 |
+
parsed_req,
|
| 230 |
+
isolated=options.isolated_mode,
|
| 231 |
+
user_supplied=False,
|
| 232 |
+
)
|
| 233 |
+
requirements.append(req_to_add)
|
| 234 |
+
|
| 235 |
+
for req in args:
|
| 236 |
+
req_to_add = install_req_from_line(
|
| 237 |
+
req,
|
| 238 |
+
comes_from=None,
|
| 239 |
+
isolated=options.isolated_mode,
|
| 240 |
+
use_pep517=options.use_pep517,
|
| 241 |
+
user_supplied=True,
|
| 242 |
+
config_settings=getattr(options, "config_settings", None),
|
| 243 |
+
)
|
| 244 |
+
requirements.append(req_to_add)
|
| 245 |
+
|
| 246 |
+
if options.dependency_groups:
|
| 247 |
+
for req in parse_dependency_groups(options.dependency_groups):
|
| 248 |
+
req_to_add = install_req_from_req_string(
|
| 249 |
+
req,
|
| 250 |
+
isolated=options.isolated_mode,
|
| 251 |
+
use_pep517=options.use_pep517,
|
| 252 |
+
user_supplied=True,
|
| 253 |
+
)
|
| 254 |
+
requirements.append(req_to_add)
|
| 255 |
+
|
| 256 |
+
for req in options.editables:
|
| 257 |
+
req_to_add = install_req_from_editable(
|
| 258 |
+
req,
|
| 259 |
+
user_supplied=True,
|
| 260 |
+
isolated=options.isolated_mode,
|
| 261 |
+
use_pep517=options.use_pep517,
|
| 262 |
+
config_settings=getattr(options, "config_settings", None),
|
| 263 |
+
)
|
| 264 |
+
requirements.append(req_to_add)
|
| 265 |
+
|
| 266 |
+
# NOTE: options.require_hashes may be set if --require-hashes is True
|
| 267 |
+
for filename in options.requirements:
|
| 268 |
+
for parsed_req in parse_requirements(
|
| 269 |
+
filename, finder=finder, options=options, session=session
|
| 270 |
+
):
|
| 271 |
+
req_to_add = install_req_from_parsed_requirement(
|
| 272 |
+
parsed_req,
|
| 273 |
+
isolated=options.isolated_mode,
|
| 274 |
+
use_pep517=options.use_pep517,
|
| 275 |
+
user_supplied=True,
|
| 276 |
+
config_settings=(
|
| 277 |
+
parsed_req.options.get("config_settings")
|
| 278 |
+
if parsed_req.options
|
| 279 |
+
else None
|
| 280 |
+
),
|
| 281 |
+
)
|
| 282 |
+
requirements.append(req_to_add)
|
| 283 |
+
|
| 284 |
+
# If any requirement has hash options, enable hash checking.
|
| 285 |
+
if any(req.has_hash_options for req in requirements):
|
| 286 |
+
options.require_hashes = True
|
| 287 |
+
|
| 288 |
+
if not (
|
| 289 |
+
args
|
| 290 |
+
or options.editables
|
| 291 |
+
or options.requirements
|
| 292 |
+
or options.dependency_groups
|
| 293 |
+
):
|
| 294 |
+
opts = {"name": self.name}
|
| 295 |
+
if options.find_links:
|
| 296 |
+
raise CommandError(
|
| 297 |
+
"You must give at least one requirement to {name} "
|
| 298 |
+
'(maybe you meant "pip {name} {links}"?)'.format(
|
| 299 |
+
**dict(opts, links=" ".join(options.find_links))
|
| 300 |
+
)
|
| 301 |
+
)
|
| 302 |
+
else:
|
| 303 |
+
raise CommandError(
|
| 304 |
+
"You must give at least one requirement to {name} "
|
| 305 |
+
'(see "pip help {name}")'.format(**opts)
|
| 306 |
+
)
|
| 307 |
+
|
| 308 |
+
return requirements
|
| 309 |
+
|
| 310 |
+
@staticmethod
|
| 311 |
+
def trace_basic_info(finder: PackageFinder) -> None:
|
| 312 |
+
"""
|
| 313 |
+
Trace basic information about the provided objects.
|
| 314 |
+
"""
|
| 315 |
+
# Display where finder is looking for packages
|
| 316 |
+
search_scope = finder.search_scope
|
| 317 |
+
locations = search_scope.get_formatted_locations()
|
| 318 |
+
if locations:
|
| 319 |
+
logger.info(locations)
|
| 320 |
+
|
| 321 |
+
def _build_package_finder(
|
| 322 |
+
self,
|
| 323 |
+
options: Values,
|
| 324 |
+
session: PipSession,
|
| 325 |
+
target_python: Optional[TargetPython] = None,
|
| 326 |
+
ignore_requires_python: Optional[bool] = None,
|
| 327 |
+
) -> PackageFinder:
|
| 328 |
+
"""
|
| 329 |
+
Create a package finder appropriate to this requirement command.
|
| 330 |
+
|
| 331 |
+
:param ignore_requires_python: Whether to ignore incompatible
|
| 332 |
+
"Requires-Python" values in links. Defaults to False.
|
| 333 |
+
"""
|
| 334 |
+
link_collector = LinkCollector.create(session, options=options)
|
| 335 |
+
selection_prefs = SelectionPreferences(
|
| 336 |
+
allow_yanked=True,
|
| 337 |
+
format_control=options.format_control,
|
| 338 |
+
allow_all_prereleases=options.pre,
|
| 339 |
+
prefer_binary=options.prefer_binary,
|
| 340 |
+
ignore_requires_python=ignore_requires_python,
|
| 341 |
+
)
|
| 342 |
+
|
| 343 |
+
return PackageFinder.create(
|
| 344 |
+
link_collector=link_collector,
|
| 345 |
+
selection_prefs=selection_prefs,
|
| 346 |
+
target_python=target_python,
|
| 347 |
+
)
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/cli/spinners.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import contextlib
|
| 2 |
+
import itertools
|
| 3 |
+
import logging
|
| 4 |
+
import sys
|
| 5 |
+
import time
|
| 6 |
+
from typing import IO, Generator, Optional
|
| 7 |
+
|
| 8 |
+
from pip._internal.utils.compat import WINDOWS
|
| 9 |
+
from pip._internal.utils.logging import get_indentation
|
| 10 |
+
|
| 11 |
+
logger = logging.getLogger(__name__)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
class SpinnerInterface:
|
| 15 |
+
def spin(self) -> None:
|
| 16 |
+
raise NotImplementedError()
|
| 17 |
+
|
| 18 |
+
def finish(self, final_status: str) -> None:
|
| 19 |
+
raise NotImplementedError()
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class InteractiveSpinner(SpinnerInterface):
|
| 23 |
+
def __init__(
|
| 24 |
+
self,
|
| 25 |
+
message: str,
|
| 26 |
+
file: Optional[IO[str]] = None,
|
| 27 |
+
spin_chars: str = "-\\|/",
|
| 28 |
+
# Empirically, 8 updates/second looks nice
|
| 29 |
+
min_update_interval_seconds: float = 0.125,
|
| 30 |
+
):
|
| 31 |
+
self._message = message
|
| 32 |
+
if file is None:
|
| 33 |
+
file = sys.stdout
|
| 34 |
+
self._file = file
|
| 35 |
+
self._rate_limiter = RateLimiter(min_update_interval_seconds)
|
| 36 |
+
self._finished = False
|
| 37 |
+
|
| 38 |
+
self._spin_cycle = itertools.cycle(spin_chars)
|
| 39 |
+
|
| 40 |
+
self._file.write(" " * get_indentation() + self._message + " ... ")
|
| 41 |
+
self._width = 0
|
| 42 |
+
|
| 43 |
+
def _write(self, status: str) -> None:
|
| 44 |
+
assert not self._finished
|
| 45 |
+
# Erase what we wrote before by backspacing to the beginning, writing
|
| 46 |
+
# spaces to overwrite the old text, and then backspacing again
|
| 47 |
+
backup = "\b" * self._width
|
| 48 |
+
self._file.write(backup + " " * self._width + backup)
|
| 49 |
+
# Now we have a blank slate to add our status
|
| 50 |
+
self._file.write(status)
|
| 51 |
+
self._width = len(status)
|
| 52 |
+
self._file.flush()
|
| 53 |
+
self._rate_limiter.reset()
|
| 54 |
+
|
| 55 |
+
def spin(self) -> None:
|
| 56 |
+
if self._finished:
|
| 57 |
+
return
|
| 58 |
+
if not self._rate_limiter.ready():
|
| 59 |
+
return
|
| 60 |
+
self._write(next(self._spin_cycle))
|
| 61 |
+
|
| 62 |
+
def finish(self, final_status: str) -> None:
|
| 63 |
+
if self._finished:
|
| 64 |
+
return
|
| 65 |
+
self._write(final_status)
|
| 66 |
+
self._file.write("\n")
|
| 67 |
+
self._file.flush()
|
| 68 |
+
self._finished = True
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
# Used for dumb terminals, non-interactive installs (no tty), etc.
|
| 72 |
+
# We still print updates occasionally (once every 60 seconds by default) to
|
| 73 |
+
# act as a keep-alive for systems like Travis-CI that take lack-of-output as
|
| 74 |
+
# an indication that a task has frozen.
|
| 75 |
+
class NonInteractiveSpinner(SpinnerInterface):
|
| 76 |
+
def __init__(self, message: str, min_update_interval_seconds: float = 60.0) -> None:
|
| 77 |
+
self._message = message
|
| 78 |
+
self._finished = False
|
| 79 |
+
self._rate_limiter = RateLimiter(min_update_interval_seconds)
|
| 80 |
+
self._update("started")
|
| 81 |
+
|
| 82 |
+
def _update(self, status: str) -> None:
|
| 83 |
+
assert not self._finished
|
| 84 |
+
self._rate_limiter.reset()
|
| 85 |
+
logger.info("%s: %s", self._message, status)
|
| 86 |
+
|
| 87 |
+
def spin(self) -> None:
|
| 88 |
+
if self._finished:
|
| 89 |
+
return
|
| 90 |
+
if not self._rate_limiter.ready():
|
| 91 |
+
return
|
| 92 |
+
self._update("still running...")
|
| 93 |
+
|
| 94 |
+
def finish(self, final_status: str) -> None:
|
| 95 |
+
if self._finished:
|
| 96 |
+
return
|
| 97 |
+
self._update(f"finished with status '{final_status}'")
|
| 98 |
+
self._finished = True
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
class RateLimiter:
|
| 102 |
+
def __init__(self, min_update_interval_seconds: float) -> None:
|
| 103 |
+
self._min_update_interval_seconds = min_update_interval_seconds
|
| 104 |
+
self._last_update: float = 0
|
| 105 |
+
|
| 106 |
+
def ready(self) -> bool:
|
| 107 |
+
now = time.time()
|
| 108 |
+
delta = now - self._last_update
|
| 109 |
+
return delta >= self._min_update_interval_seconds
|
| 110 |
+
|
| 111 |
+
def reset(self) -> None:
|
| 112 |
+
self._last_update = time.time()
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
@contextlib.contextmanager
|
| 116 |
+
def open_spinner(message: str) -> Generator[SpinnerInterface, None, None]:
|
| 117 |
+
# Interactive spinner goes directly to sys.stdout rather than being routed
|
| 118 |
+
# through the logging system, but it acts like it has level INFO,
|
| 119 |
+
# i.e. it's only displayed if we're at level INFO or better.
|
| 120 |
+
# Non-interactive spinner goes through the logging system, so it is always
|
| 121 |
+
# in sync with logging configuration.
|
| 122 |
+
if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO:
|
| 123 |
+
spinner: SpinnerInterface = InteractiveSpinner(message)
|
| 124 |
+
else:
|
| 125 |
+
spinner = NonInteractiveSpinner(message)
|
| 126 |
+
try:
|
| 127 |
+
with hidden_cursor(sys.stdout):
|
| 128 |
+
yield spinner
|
| 129 |
+
except KeyboardInterrupt:
|
| 130 |
+
spinner.finish("canceled")
|
| 131 |
+
raise
|
| 132 |
+
except Exception:
|
| 133 |
+
spinner.finish("error")
|
| 134 |
+
raise
|
| 135 |
+
else:
|
| 136 |
+
spinner.finish("done")
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
HIDE_CURSOR = "\x1b[?25l"
|
| 140 |
+
SHOW_CURSOR = "\x1b[?25h"
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
@contextlib.contextmanager
|
| 144 |
+
def hidden_cursor(file: IO[str]) -> Generator[None, None, None]:
|
| 145 |
+
# The Windows terminal does not support the hide/show cursor ANSI codes,
|
| 146 |
+
# even via colorama. So don't even try.
|
| 147 |
+
if WINDOWS:
|
| 148 |
+
yield
|
| 149 |
+
# We don't want to clutter the output with control characters if we're
|
| 150 |
+
# writing to a file, or if the user is running with --quiet.
|
| 151 |
+
# See https://github.com/pypa/pip/issues/3418
|
| 152 |
+
elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO:
|
| 153 |
+
yield
|
| 154 |
+
else:
|
| 155 |
+
file.write(HIDE_CURSOR)
|
| 156 |
+
try:
|
| 157 |
+
yield
|
| 158 |
+
finally:
|
| 159 |
+
file.write(SHOW_CURSOR)
|
ACE_plus/flashenv/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
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__init__.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
"lock": CommandInfo(
|
| 27 |
+
"pip._internal.commands.lock",
|
| 28 |
+
"LockCommand",
|
| 29 |
+
"Generate a lock file.",
|
| 30 |
+
),
|
| 31 |
+
"download": CommandInfo(
|
| 32 |
+
"pip._internal.commands.download",
|
| 33 |
+
"DownloadCommand",
|
| 34 |
+
"Download packages.",
|
| 35 |
+
),
|
| 36 |
+
"uninstall": CommandInfo(
|
| 37 |
+
"pip._internal.commands.uninstall",
|
| 38 |
+
"UninstallCommand",
|
| 39 |
+
"Uninstall packages.",
|
| 40 |
+
),
|
| 41 |
+
"freeze": CommandInfo(
|
| 42 |
+
"pip._internal.commands.freeze",
|
| 43 |
+
"FreezeCommand",
|
| 44 |
+
"Output installed packages in requirements format.",
|
| 45 |
+
),
|
| 46 |
+
"inspect": CommandInfo(
|
| 47 |
+
"pip._internal.commands.inspect",
|
| 48 |
+
"InspectCommand",
|
| 49 |
+
"Inspect the python environment.",
|
| 50 |
+
),
|
| 51 |
+
"list": CommandInfo(
|
| 52 |
+
"pip._internal.commands.list",
|
| 53 |
+
"ListCommand",
|
| 54 |
+
"List installed packages.",
|
| 55 |
+
),
|
| 56 |
+
"show": CommandInfo(
|
| 57 |
+
"pip._internal.commands.show",
|
| 58 |
+
"ShowCommand",
|
| 59 |
+
"Show information about installed packages.",
|
| 60 |
+
),
|
| 61 |
+
"check": CommandInfo(
|
| 62 |
+
"pip._internal.commands.check",
|
| 63 |
+
"CheckCommand",
|
| 64 |
+
"Verify installed packages have compatible dependencies.",
|
| 65 |
+
),
|
| 66 |
+
"config": CommandInfo(
|
| 67 |
+
"pip._internal.commands.configuration",
|
| 68 |
+
"ConfigurationCommand",
|
| 69 |
+
"Manage local and global configuration.",
|
| 70 |
+
),
|
| 71 |
+
"search": CommandInfo(
|
| 72 |
+
"pip._internal.commands.search",
|
| 73 |
+
"SearchCommand",
|
| 74 |
+
"Search PyPI for packages.",
|
| 75 |
+
),
|
| 76 |
+
"cache": CommandInfo(
|
| 77 |
+
"pip._internal.commands.cache",
|
| 78 |
+
"CacheCommand",
|
| 79 |
+
"Inspect and manage pip's wheel cache.",
|
| 80 |
+
),
|
| 81 |
+
"index": CommandInfo(
|
| 82 |
+
"pip._internal.commands.index",
|
| 83 |
+
"IndexCommand",
|
| 84 |
+
"Inspect information available from package indexes.",
|
| 85 |
+
),
|
| 86 |
+
"wheel": CommandInfo(
|
| 87 |
+
"pip._internal.commands.wheel",
|
| 88 |
+
"WheelCommand",
|
| 89 |
+
"Build wheels from your requirements.",
|
| 90 |
+
),
|
| 91 |
+
"hash": CommandInfo(
|
| 92 |
+
"pip._internal.commands.hash",
|
| 93 |
+
"HashCommand",
|
| 94 |
+
"Compute hashes of package archives.",
|
| 95 |
+
),
|
| 96 |
+
"completion": CommandInfo(
|
| 97 |
+
"pip._internal.commands.completion",
|
| 98 |
+
"CompletionCommand",
|
| 99 |
+
"A helper command used for command completion.",
|
| 100 |
+
),
|
| 101 |
+
"debug": CommandInfo(
|
| 102 |
+
"pip._internal.commands.debug",
|
| 103 |
+
"DebugCommand",
|
| 104 |
+
"Show information useful for debugging.",
|
| 105 |
+
),
|
| 106 |
+
"help": CommandInfo(
|
| 107 |
+
"pip._internal.commands.help",
|
| 108 |
+
"HelpCommand",
|
| 109 |
+
"Show help for commands.",
|
| 110 |
+
),
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
|
| 114 |
+
def create_command(name: str, **kwargs: Any) -> Command:
|
| 115 |
+
"""
|
| 116 |
+
Create an instance of the Command class with the given name.
|
| 117 |
+
"""
|
| 118 |
+
module_path, class_name, summary = commands_dict[name]
|
| 119 |
+
module = importlib.import_module(module_path)
|
| 120 |
+
command_class = getattr(module, class_name)
|
| 121 |
+
command = command_class(name=name, summary=summary, **kwargs)
|
| 122 |
+
|
| 123 |
+
return command
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
def get_similar_commands(name: str) -> Optional[str]:
|
| 127 |
+
"""Command name auto-correct."""
|
| 128 |
+
from difflib import get_close_matches
|
| 129 |
+
|
| 130 |
+
name = name.lower()
|
| 131 |
+
|
| 132 |
+
close_commands = get_close_matches(name, commands_dict.keys())
|
| 133 |
+
|
| 134 |
+
if close_commands:
|
| 135 |
+
return close_commands[0]
|
| 136 |
+
else:
|
| 137 |
+
return None
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (3.36 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc
ADDED
|
Binary file (6.56 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc
ADDED
|
Binary file (1.98 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc
ADDED
|
Binary file (4.6 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc
ADDED
|
Binary file (8.95 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc
ADDED
|
Binary file (6.9 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc
ADDED
|
Binary file (4.21 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc
ADDED
|
Binary file (2.97 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc
ADDED
|
Binary file (2.16 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc
ADDED
|
Binary file (1.32 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc
ADDED
|
Binary file (4.66 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-310.pyc
ADDED
|
Binary file (2.98 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc
ADDED
|
Binary file (18.1 kB). View file
|
|
|
ACE_plus/flashenv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc
ADDED
|
Binary file (11.3 kB). View file
|
|
|