Mercurial > repos > guerler > hhblits
comparison lib/python3.8/site-packages/pip/_internal/cli/base_command.py @ 0:9e54283cc701 draft
"planemo upload commit d12c32a45bcd441307e632fca6d9af7d60289d44"
author | guerler |
---|---|
date | Mon, 27 Jul 2020 03:47:31 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:9e54283cc701 |
---|---|
1 """Base Command class, and related routines""" | |
2 | |
3 from __future__ import absolute_import, print_function | |
4 | |
5 import logging | |
6 import logging.config | |
7 import optparse | |
8 import os | |
9 import platform | |
10 import sys | |
11 import traceback | |
12 | |
13 from pip._internal.cli import cmdoptions | |
14 from pip._internal.cli.command_context import CommandContextMixIn | |
15 from pip._internal.cli.parser import ( | |
16 ConfigOptionParser, | |
17 UpdatingDefaultsHelpFormatter, | |
18 ) | |
19 from pip._internal.cli.status_codes import ( | |
20 ERROR, | |
21 PREVIOUS_BUILD_DIR_ERROR, | |
22 SUCCESS, | |
23 UNKNOWN_ERROR, | |
24 VIRTUALENV_NOT_FOUND, | |
25 ) | |
26 from pip._internal.exceptions import ( | |
27 BadCommand, | |
28 CommandError, | |
29 InstallationError, | |
30 PreviousBuildDirError, | |
31 UninstallationError, | |
32 ) | |
33 from pip._internal.utils.deprecation import deprecated | |
34 from pip._internal.utils.filesystem import check_path_owner | |
35 from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging | |
36 from pip._internal.utils.misc import get_prog, normalize_path | |
37 from pip._internal.utils.temp_dir import global_tempdir_manager | |
38 from pip._internal.utils.typing import MYPY_CHECK_RUNNING | |
39 from pip._internal.utils.virtualenv import running_under_virtualenv | |
40 | |
41 if MYPY_CHECK_RUNNING: | |
42 from typing import List, Tuple, Any | |
43 from optparse import Values | |
44 | |
45 __all__ = ['Command'] | |
46 | |
47 logger = logging.getLogger(__name__) | |
48 | |
49 | |
50 class Command(CommandContextMixIn): | |
51 usage = None # type: str | |
52 ignore_require_venv = False # type: bool | |
53 | |
54 def __init__(self, name, summary, isolated=False): | |
55 # type: (str, str, bool) -> None | |
56 super(Command, self).__init__() | |
57 parser_kw = { | |
58 'usage': self.usage, | |
59 'prog': '%s %s' % (get_prog(), name), | |
60 'formatter': UpdatingDefaultsHelpFormatter(), | |
61 'add_help_option': False, | |
62 'name': name, | |
63 'description': self.__doc__, | |
64 'isolated': isolated, | |
65 } | |
66 | |
67 self.name = name | |
68 self.summary = summary | |
69 self.parser = ConfigOptionParser(**parser_kw) | |
70 | |
71 # Commands should add options to this option group | |
72 optgroup_name = '%s Options' % self.name.capitalize() | |
73 self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) | |
74 | |
75 # Add the general options | |
76 gen_opts = cmdoptions.make_option_group( | |
77 cmdoptions.general_group, | |
78 self.parser, | |
79 ) | |
80 self.parser.add_option_group(gen_opts) | |
81 | |
82 def handle_pip_version_check(self, options): | |
83 # type: (Values) -> None | |
84 """ | |
85 This is a no-op so that commands by default do not do the pip version | |
86 check. | |
87 """ | |
88 # Make sure we do the pip version check if the index_group options | |
89 # are present. | |
90 assert not hasattr(options, 'no_index') | |
91 | |
92 def run(self, options, args): | |
93 # type: (Values, List[Any]) -> Any | |
94 raise NotImplementedError | |
95 | |
96 def parse_args(self, args): | |
97 # type: (List[str]) -> Tuple[Any, Any] | |
98 # factored out for testability | |
99 return self.parser.parse_args(args) | |
100 | |
101 def main(self, args): | |
102 # type: (List[str]) -> int | |
103 try: | |
104 with self.main_context(): | |
105 return self._main(args) | |
106 finally: | |
107 logging.shutdown() | |
108 | |
109 def _main(self, args): | |
110 # type: (List[str]) -> int | |
111 # Intentionally set as early as possible so globally-managed temporary | |
112 # directories are available to the rest of the code. | |
113 self.enter_context(global_tempdir_manager()) | |
114 | |
115 options, args = self.parse_args(args) | |
116 | |
117 # Set verbosity so that it can be used elsewhere. | |
118 self.verbosity = options.verbose - options.quiet | |
119 | |
120 level_number = setup_logging( | |
121 verbosity=self.verbosity, | |
122 no_color=options.no_color, | |
123 user_log_file=options.log, | |
124 ) | |
125 | |
126 if ( | |
127 sys.version_info[:2] == (2, 7) and | |
128 not options.no_python_version_warning | |
129 ): | |
130 message = ( | |
131 "A future version of pip will drop support for Python 2.7. " | |
132 "More details about Python 2 support in pip, can be found at " | |
133 "https://pip.pypa.io/en/latest/development/release-process/#python-2-support" # noqa | |
134 ) | |
135 if platform.python_implementation() == "CPython": | |
136 message = ( | |
137 "Python 2.7 reached the end of its life on January " | |
138 "1st, 2020. Please upgrade your Python as Python 2.7 " | |
139 "is no longer maintained. " | |
140 ) + message | |
141 deprecated(message, replacement=None, gone_in=None) | |
142 | |
143 if options.skip_requirements_regex: | |
144 deprecated( | |
145 "--skip-requirements-regex is unsupported and will be removed", | |
146 replacement=( | |
147 "manage requirements/constraints files explicitly, " | |
148 "possibly generating them from metadata" | |
149 ), | |
150 gone_in="20.1", | |
151 issue=7297, | |
152 ) | |
153 | |
154 # TODO: Try to get these passing down from the command? | |
155 # without resorting to os.environ to hold these. | |
156 # This also affects isolated builds and it should. | |
157 | |
158 if options.no_input: | |
159 os.environ['PIP_NO_INPUT'] = '1' | |
160 | |
161 if options.exists_action: | |
162 os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) | |
163 | |
164 if options.require_venv and not self.ignore_require_venv: | |
165 # If a venv is required check if it can really be found | |
166 if not running_under_virtualenv(): | |
167 logger.critical( | |
168 'Could not find an activated virtualenv (required).' | |
169 ) | |
170 sys.exit(VIRTUALENV_NOT_FOUND) | |
171 | |
172 if options.cache_dir: | |
173 options.cache_dir = normalize_path(options.cache_dir) | |
174 if not check_path_owner(options.cache_dir): | |
175 logger.warning( | |
176 "The directory '%s' or its parent directory is not owned " | |
177 "or is not writable by the current user. The cache " | |
178 "has been disabled. Check the permissions and owner of " | |
179 "that directory. If executing pip with sudo, you may want " | |
180 "sudo's -H flag.", | |
181 options.cache_dir, | |
182 ) | |
183 options.cache_dir = None | |
184 | |
185 try: | |
186 status = self.run(options, args) | |
187 # FIXME: all commands should return an exit status | |
188 # and when it is done, isinstance is not needed anymore | |
189 if isinstance(status, int): | |
190 return status | |
191 except PreviousBuildDirError as exc: | |
192 logger.critical(str(exc)) | |
193 logger.debug('Exception information:', exc_info=True) | |
194 | |
195 return PREVIOUS_BUILD_DIR_ERROR | |
196 except (InstallationError, UninstallationError, BadCommand) as exc: | |
197 logger.critical(str(exc)) | |
198 logger.debug('Exception information:', exc_info=True) | |
199 | |
200 return ERROR | |
201 except CommandError as exc: | |
202 logger.critical('%s', exc) | |
203 logger.debug('Exception information:', exc_info=True) | |
204 | |
205 return ERROR | |
206 except BrokenStdoutLoggingError: | |
207 # Bypass our logger and write any remaining messages to stderr | |
208 # because stdout no longer works. | |
209 print('ERROR: Pipe to stdout was broken', file=sys.stderr) | |
210 if level_number <= logging.DEBUG: | |
211 traceback.print_exc(file=sys.stderr) | |
212 | |
213 return ERROR | |
214 except KeyboardInterrupt: | |
215 logger.critical('Operation cancelled by user') | |
216 logger.debug('Exception information:', exc_info=True) | |
217 | |
218 return ERROR | |
219 except BaseException: | |
220 logger.critical('Exception:', exc_info=True) | |
221 | |
222 return UNKNOWN_ERROR | |
223 finally: | |
224 self.handle_pip_version_check(options) | |
225 | |
226 return SUCCESS |