Mercurial > repos > bcclaywell > argo_navis
comparison venv/lib/python2.7/site-packages/pip/basecommand.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
| author | bcclaywell |
|---|---|
| date | Mon, 12 Oct 2015 17:43:33 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d67268158946 |
|---|---|
| 1 """Base Command class, and related routines""" | |
| 2 from __future__ import absolute_import | |
| 3 | |
| 4 import logging | |
| 5 import os | |
| 6 import sys | |
| 7 import traceback | |
| 8 import optparse | |
| 9 import warnings | |
| 10 | |
| 11 from pip._vendor.six import StringIO | |
| 12 | |
| 13 from pip import cmdoptions | |
| 14 from pip.locations import running_under_virtualenv | |
| 15 from pip.download import PipSession | |
| 16 from pip.exceptions import (BadCommand, InstallationError, UninstallationError, | |
| 17 CommandError, PreviousBuildDirError) | |
| 18 from pip.compat import logging_dictConfig | |
| 19 from pip.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter | |
| 20 from pip.status_codes import ( | |
| 21 SUCCESS, ERROR, UNKNOWN_ERROR, VIRTUALENV_NOT_FOUND, | |
| 22 PREVIOUS_BUILD_DIR_ERROR, | |
| 23 ) | |
| 24 from pip.utils import appdirs, get_prog, normalize_path | |
| 25 from pip.utils.deprecation import RemovedInPip8Warning | |
| 26 from pip.utils.filesystem import check_path_owner | |
| 27 from pip.utils.logging import IndentingFormatter | |
| 28 from pip.utils.outdated import pip_version_check | |
| 29 | |
| 30 | |
| 31 __all__ = ['Command'] | |
| 32 | |
| 33 | |
| 34 logger = logging.getLogger(__name__) | |
| 35 | |
| 36 | |
| 37 class Command(object): | |
| 38 name = None | |
| 39 usage = None | |
| 40 hidden = False | |
| 41 log_streams = ("ext://sys.stdout", "ext://sys.stderr") | |
| 42 | |
| 43 def __init__(self, isolated=False): | |
| 44 parser_kw = { | |
| 45 'usage': self.usage, | |
| 46 'prog': '%s %s' % (get_prog(), self.name), | |
| 47 'formatter': UpdatingDefaultsHelpFormatter(), | |
| 48 'add_help_option': False, | |
| 49 'name': self.name, | |
| 50 'description': self.__doc__, | |
| 51 'isolated': isolated, | |
| 52 } | |
| 53 | |
| 54 self.parser = ConfigOptionParser(**parser_kw) | |
| 55 | |
| 56 # Commands should add options to this option group | |
| 57 optgroup_name = '%s Options' % self.name.capitalize() | |
| 58 self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) | |
| 59 | |
| 60 # Add the general options | |
| 61 gen_opts = cmdoptions.make_option_group( | |
| 62 cmdoptions.general_group, | |
| 63 self.parser, | |
| 64 ) | |
| 65 self.parser.add_option_group(gen_opts) | |
| 66 | |
| 67 def _build_session(self, options, retries=None, timeout=None): | |
| 68 session = PipSession( | |
| 69 cache=( | |
| 70 normalize_path(os.path.join(options.cache_dir, "http")) | |
| 71 if options.cache_dir else None | |
| 72 ), | |
| 73 retries=retries if retries is not None else options.retries, | |
| 74 insecure_hosts=options.trusted_hosts, | |
| 75 ) | |
| 76 | |
| 77 # Handle custom ca-bundles from the user | |
| 78 if options.cert: | |
| 79 session.verify = options.cert | |
| 80 | |
| 81 # Handle SSL client certificate | |
| 82 if options.client_cert: | |
| 83 session.cert = options.client_cert | |
| 84 | |
| 85 # Handle timeouts | |
| 86 if options.timeout or timeout: | |
| 87 session.timeout = ( | |
| 88 timeout if timeout is not None else options.timeout | |
| 89 ) | |
| 90 | |
| 91 # Handle configured proxies | |
| 92 if options.proxy: | |
| 93 session.proxies = { | |
| 94 "http": options.proxy, | |
| 95 "https": options.proxy, | |
| 96 } | |
| 97 | |
| 98 # Determine if we can prompt the user for authentication or not | |
| 99 session.auth.prompting = not options.no_input | |
| 100 | |
| 101 return session | |
| 102 | |
| 103 def parse_args(self, args): | |
| 104 # factored out for testability | |
| 105 return self.parser.parse_args(args) | |
| 106 | |
| 107 def main(self, args): | |
| 108 options, args = self.parse_args(args) | |
| 109 | |
| 110 if options.quiet: | |
| 111 level = "WARNING" | |
| 112 elif options.verbose: | |
| 113 level = "DEBUG" | |
| 114 else: | |
| 115 level = "INFO" | |
| 116 | |
| 117 # Compute the path for our debug log. | |
| 118 debug_log_path = os.path.join(appdirs.user_log_dir("pip"), "debug.log") | |
| 119 | |
| 120 # Ensure that the path for our debug log is owned by the current user | |
| 121 # and if it is not, disable the debug log. | |
| 122 write_debug_log = check_path_owner(debug_log_path) | |
| 123 | |
| 124 logging_dictConfig({ | |
| 125 "version": 1, | |
| 126 "disable_existing_loggers": False, | |
| 127 "filters": { | |
| 128 "exclude_warnings": { | |
| 129 "()": "pip.utils.logging.MaxLevelFilter", | |
| 130 "level": logging.WARNING, | |
| 131 }, | |
| 132 }, | |
| 133 "formatters": { | |
| 134 "indent": { | |
| 135 "()": IndentingFormatter, | |
| 136 "format": ( | |
| 137 "%(message)s" | |
| 138 if not options.log_explicit_levels | |
| 139 else "[%(levelname)s] %(message)s" | |
| 140 ), | |
| 141 }, | |
| 142 }, | |
| 143 "handlers": { | |
| 144 "console": { | |
| 145 "level": level, | |
| 146 "class": "pip.utils.logging.ColorizedStreamHandler", | |
| 147 "stream": self.log_streams[0], | |
| 148 "filters": ["exclude_warnings"], | |
| 149 "formatter": "indent", | |
| 150 }, | |
| 151 "console_errors": { | |
| 152 "level": "WARNING", | |
| 153 "class": "pip.utils.logging.ColorizedStreamHandler", | |
| 154 "stream": self.log_streams[1], | |
| 155 "formatter": "indent", | |
| 156 }, | |
| 157 "debug_log": { | |
| 158 "level": "DEBUG", | |
| 159 "class": "pip.utils.logging.BetterRotatingFileHandler", | |
| 160 "filename": debug_log_path, | |
| 161 "maxBytes": 10 * 1000 * 1000, # 10 MB | |
| 162 "backupCount": 1, | |
| 163 "delay": True, | |
| 164 "formatter": "indent", | |
| 165 }, | |
| 166 "user_log": { | |
| 167 "level": "DEBUG", | |
| 168 "class": "pip.utils.logging.BetterRotatingFileHandler", | |
| 169 "filename": options.log or "/dev/null", | |
| 170 "delay": True, | |
| 171 "formatter": "indent", | |
| 172 }, | |
| 173 }, | |
| 174 "root": { | |
| 175 "level": level, | |
| 176 "handlers": list(filter(None, [ | |
| 177 "console", | |
| 178 "console_errors", | |
| 179 "debug_log" if write_debug_log else None, | |
| 180 "user_log" if options.log else None, | |
| 181 ])), | |
| 182 }, | |
| 183 # Disable any logging besides WARNING unless we have DEBUG level | |
| 184 # logging enabled. These use both pip._vendor and the bare names | |
| 185 # for the case where someone unbundles our libraries. | |
| 186 "loggers": dict( | |
| 187 ( | |
| 188 name, | |
| 189 { | |
| 190 "level": ( | |
| 191 "WARNING" | |
| 192 if level in ["INFO", "ERROR"] | |
| 193 else "DEBUG" | |
| 194 ), | |
| 195 }, | |
| 196 ) | |
| 197 for name in ["pip._vendor", "distlib", "requests", "urllib3"] | |
| 198 ), | |
| 199 }) | |
| 200 | |
| 201 # We add this warning here instead of up above, because the logger | |
| 202 # hasn't been configured until just now. | |
| 203 if not write_debug_log: | |
| 204 logger.warning( | |
| 205 "The directory '%s' or its parent directory is not owned by " | |
| 206 "the current user and the debug log has been disabled. Please " | |
| 207 "check the permissions and owner of that directory. If " | |
| 208 "executing pip with sudo, you may want sudo's -H flag.", | |
| 209 os.path.dirname(debug_log_path), | |
| 210 ) | |
| 211 | |
| 212 if options.log_explicit_levels: | |
| 213 warnings.warn( | |
| 214 "--log-explicit-levels has been deprecated and will be removed" | |
| 215 " in a future version.", | |
| 216 RemovedInPip8Warning, | |
| 217 ) | |
| 218 | |
| 219 # TODO: try to get these passing down from the command? | |
| 220 # without resorting to os.environ to hold these. | |
| 221 | |
| 222 if options.no_input: | |
| 223 os.environ['PIP_NO_INPUT'] = '1' | |
| 224 | |
| 225 if options.exists_action: | |
| 226 os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) | |
| 227 | |
| 228 if options.require_venv: | |
| 229 # If a venv is required check if it can really be found | |
| 230 if not running_under_virtualenv(): | |
| 231 logger.critical( | |
| 232 'Could not find an activated virtualenv (required).' | |
| 233 ) | |
| 234 sys.exit(VIRTUALENV_NOT_FOUND) | |
| 235 | |
| 236 # Check if we're using the latest version of pip available | |
| 237 if (not options.disable_pip_version_check and not | |
| 238 getattr(options, "no_index", False)): | |
| 239 with self._build_session( | |
| 240 options, | |
| 241 retries=0, | |
| 242 timeout=min(5, options.timeout)) as session: | |
| 243 pip_version_check(session) | |
| 244 | |
| 245 try: | |
| 246 status = self.run(options, args) | |
| 247 # FIXME: all commands should return an exit status | |
| 248 # and when it is done, isinstance is not needed anymore | |
| 249 if isinstance(status, int): | |
| 250 return status | |
| 251 except PreviousBuildDirError as exc: | |
| 252 logger.critical(str(exc)) | |
| 253 logger.debug('Exception information:\n%s', format_exc()) | |
| 254 | |
| 255 return PREVIOUS_BUILD_DIR_ERROR | |
| 256 except (InstallationError, UninstallationError, BadCommand) as exc: | |
| 257 logger.critical(str(exc)) | |
| 258 logger.debug('Exception information:\n%s', format_exc()) | |
| 259 | |
| 260 return ERROR | |
| 261 except CommandError as exc: | |
| 262 logger.critical('ERROR: %s', exc) | |
| 263 logger.debug('Exception information:\n%s', format_exc()) | |
| 264 | |
| 265 return ERROR | |
| 266 except KeyboardInterrupt: | |
| 267 logger.critical('Operation cancelled by user') | |
| 268 logger.debug('Exception information:\n%s', format_exc()) | |
| 269 | |
| 270 return ERROR | |
| 271 except: | |
| 272 logger.critical('Exception:\n%s', format_exc()) | |
| 273 | |
| 274 return UNKNOWN_ERROR | |
| 275 | |
| 276 return SUCCESS | |
| 277 | |
| 278 | |
| 279 def format_exc(exc_info=None): | |
| 280 if exc_info is None: | |
| 281 exc_info = sys.exc_info() | |
| 282 out = StringIO() | |
| 283 traceback.print_exception(*exc_info, **dict(file=out)) | |
| 284 return out.getvalue() |
