Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keewenaw
GitHub Repository: keewenaw/ethereum-wallet-cracker
Path: blob/main/test/lib/python3.9/site-packages/pip/_internal/commands/configuration.py
4804 views
1
import logging
2
import os
3
import subprocess
4
from optparse import Values
5
from typing import Any, List, Optional
6
7
from pip._internal.cli.base_command import Command
8
from pip._internal.cli.status_codes import ERROR, SUCCESS
9
from pip._internal.configuration import (
10
Configuration,
11
Kind,
12
get_configuration_files,
13
kinds,
14
)
15
from pip._internal.exceptions import PipError
16
from pip._internal.utils.logging import indent_log
17
from pip._internal.utils.misc import get_prog, write_output
18
19
logger = logging.getLogger(__name__)
20
21
22
class ConfigurationCommand(Command):
23
"""
24
Manage local and global configuration.
25
26
Subcommands:
27
28
- list: List the active configuration (or from the file specified)
29
- edit: Edit the configuration file in an editor
30
- get: Get the value associated with command.option
31
- set: Set the command.option=value
32
- unset: Unset the value associated with command.option
33
- debug: List the configuration files and values defined under them
34
35
Configuration keys should be dot separated command and option name,
36
with the special prefix "global" affecting any command. For example,
37
"pip config set global.index-url https://example.org/" would configure
38
the index url for all commands, but "pip config set download.timeout 10"
39
would configure a 10 second timeout only for "pip download" commands.
40
41
If none of --user, --global and --site are passed, a virtual
42
environment configuration file is used if one is active and the file
43
exists. Otherwise, all modifications happen to the user file by
44
default.
45
"""
46
47
ignore_require_venv = True
48
usage = """
49
%prog [<file-option>] list
50
%prog [<file-option>] [--editor <editor-path>] edit
51
52
%prog [<file-option>] get command.option
53
%prog [<file-option>] set command.option value
54
%prog [<file-option>] unset command.option
55
%prog [<file-option>] debug
56
"""
57
58
def add_options(self) -> None:
59
self.cmd_opts.add_option(
60
"--editor",
61
dest="editor",
62
action="store",
63
default=None,
64
help=(
65
"Editor to use to edit the file. Uses VISUAL or EDITOR "
66
"environment variables if not provided."
67
),
68
)
69
70
self.cmd_opts.add_option(
71
"--global",
72
dest="global_file",
73
action="store_true",
74
default=False,
75
help="Use the system-wide configuration file only",
76
)
77
78
self.cmd_opts.add_option(
79
"--user",
80
dest="user_file",
81
action="store_true",
82
default=False,
83
help="Use the user configuration file only",
84
)
85
86
self.cmd_opts.add_option(
87
"--site",
88
dest="site_file",
89
action="store_true",
90
default=False,
91
help="Use the current environment configuration file only",
92
)
93
94
self.parser.insert_option_group(0, self.cmd_opts)
95
96
def run(self, options: Values, args: List[str]) -> int:
97
handlers = {
98
"list": self.list_values,
99
"edit": self.open_in_editor,
100
"get": self.get_name,
101
"set": self.set_name_value,
102
"unset": self.unset_name,
103
"debug": self.list_config_values,
104
}
105
106
# Determine action
107
if not args or args[0] not in handlers:
108
logger.error(
109
"Need an action (%s) to perform.",
110
", ".join(sorted(handlers)),
111
)
112
return ERROR
113
114
action = args[0]
115
116
# Determine which configuration files are to be loaded
117
# Depends on whether the command is modifying.
118
try:
119
load_only = self._determine_file(
120
options, need_value=(action in ["get", "set", "unset", "edit"])
121
)
122
except PipError as e:
123
logger.error(e.args[0])
124
return ERROR
125
126
# Load a new configuration
127
self.configuration = Configuration(
128
isolated=options.isolated_mode, load_only=load_only
129
)
130
self.configuration.load()
131
132
# Error handling happens here, not in the action-handlers.
133
try:
134
handlers[action](options, args[1:])
135
except PipError as e:
136
logger.error(e.args[0])
137
return ERROR
138
139
return SUCCESS
140
141
def _determine_file(self, options: Values, need_value: bool) -> Optional[Kind]:
142
file_options = [
143
key
144
for key, value in (
145
(kinds.USER, options.user_file),
146
(kinds.GLOBAL, options.global_file),
147
(kinds.SITE, options.site_file),
148
)
149
if value
150
]
151
152
if not file_options:
153
if not need_value:
154
return None
155
# Default to user, unless there's a site file.
156
elif any(
157
os.path.exists(site_config_file)
158
for site_config_file in get_configuration_files()[kinds.SITE]
159
):
160
return kinds.SITE
161
else:
162
return kinds.USER
163
elif len(file_options) == 1:
164
return file_options[0]
165
166
raise PipError(
167
"Need exactly one file to operate upon "
168
"(--user, --site, --global) to perform."
169
)
170
171
def list_values(self, options: Values, args: List[str]) -> None:
172
self._get_n_args(args, "list", n=0)
173
174
for key, value in sorted(self.configuration.items()):
175
write_output("%s=%r", key, value)
176
177
def get_name(self, options: Values, args: List[str]) -> None:
178
key = self._get_n_args(args, "get [name]", n=1)
179
value = self.configuration.get_value(key)
180
181
write_output("%s", value)
182
183
def set_name_value(self, options: Values, args: List[str]) -> None:
184
key, value = self._get_n_args(args, "set [name] [value]", n=2)
185
self.configuration.set_value(key, value)
186
187
self._save_configuration()
188
189
def unset_name(self, options: Values, args: List[str]) -> None:
190
key = self._get_n_args(args, "unset [name]", n=1)
191
self.configuration.unset_value(key)
192
193
self._save_configuration()
194
195
def list_config_values(self, options: Values, args: List[str]) -> None:
196
"""List config key-value pairs across different config files"""
197
self._get_n_args(args, "debug", n=0)
198
199
self.print_env_var_values()
200
# Iterate over config files and print if they exist, and the
201
# key-value pairs present in them if they do
202
for variant, files in sorted(self.configuration.iter_config_files()):
203
write_output("%s:", variant)
204
for fname in files:
205
with indent_log():
206
file_exists = os.path.exists(fname)
207
write_output("%s, exists: %r", fname, file_exists)
208
if file_exists:
209
self.print_config_file_values(variant)
210
211
def print_config_file_values(self, variant: Kind) -> None:
212
"""Get key-value pairs from the file of a variant"""
213
for name, value in self.configuration.get_values_in_config(variant).items():
214
with indent_log():
215
write_output("%s: %s", name, value)
216
217
def print_env_var_values(self) -> None:
218
"""Get key-values pairs present as environment variables"""
219
write_output("%s:", "env_var")
220
with indent_log():
221
for key, value in sorted(self.configuration.get_environ_vars()):
222
env_var = f"PIP_{key.upper()}"
223
write_output("%s=%r", env_var, value)
224
225
def open_in_editor(self, options: Values, args: List[str]) -> None:
226
editor = self._determine_editor(options)
227
228
fname = self.configuration.get_file_to_edit()
229
if fname is None:
230
raise PipError("Could not determine appropriate file.")
231
232
try:
233
subprocess.check_call([editor, fname])
234
except FileNotFoundError as e:
235
if not e.filename:
236
e.filename = editor
237
raise
238
except subprocess.CalledProcessError as e:
239
raise PipError(
240
"Editor Subprocess exited with exit code {}".format(e.returncode)
241
)
242
243
def _get_n_args(self, args: List[str], example: str, n: int) -> Any:
244
"""Helper to make sure the command got the right number of arguments"""
245
if len(args) != n:
246
msg = (
247
"Got unexpected number of arguments, expected {}. "
248
'(example: "{} config {}")'
249
).format(n, get_prog(), example)
250
raise PipError(msg)
251
252
if n == 1:
253
return args[0]
254
else:
255
return args
256
257
def _save_configuration(self) -> None:
258
# We successfully ran a modifying command. Need to save the
259
# configuration.
260
try:
261
self.configuration.save()
262
except Exception:
263
logger.exception(
264
"Unable to save configuration. Please report this as a bug."
265
)
266
raise PipError("Internal Error.")
267
268
def _determine_editor(self, options: Values) -> str:
269
if options.editor is not None:
270
return options.editor
271
elif "VISUAL" in os.environ:
272
return os.environ["VISUAL"]
273
elif "EDITOR" in os.environ:
274
return os.environ["EDITOR"]
275
else:
276
raise PipError("Could not determine editor to use.")
277
278