diff options
| author | Shubham Saini <shubham6405@gmail.com> | 2019-08-05 08:32:33 +0000 |
|---|---|---|
| committer | Shubham Saini <shubham6405@gmail.com> | 2019-08-05 08:32:33 +0000 |
| commit | 227b2d30a8675b44918f9d9ca89b24144a938215 (patch) | |
| tree | 9f8e6a28724514b6fdf463a9ab2067a7ef309b72 /venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py | |
| parent | 842a8cfbbbdb1f92889d892e4859dbd5d40c5be8 (diff) | |
removing venv files
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py')
| -rw-r--r-- | venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py | 421 |
1 files changed, 0 insertions, 421 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py deleted file mode 100644 index d97ea36..0000000 --- a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_internal/utils/ui.py +++ /dev/null | |||
| @@ -1,421 +0,0 @@ | |||
| 1 | from __future__ import absolute_import, division | ||
| 2 | |||
| 3 | import contextlib | ||
| 4 | import itertools | ||
| 5 | import logging | ||
| 6 | import sys | ||
| 7 | import time | ||
| 8 | from signal import SIGINT, default_int_handler, signal | ||
| 9 | |||
| 10 | from pip._vendor import six | ||
| 11 | from pip._vendor.progress.bar import ( | ||
| 12 | Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, | ||
| 13 | ShadyBar, | ||
| 14 | ) | ||
| 15 | from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin | ||
| 16 | from pip._vendor.progress.spinner import Spinner | ||
| 17 | |||
| 18 | from pip._internal.compat import WINDOWS | ||
| 19 | from pip._internal.utils.logging import get_indentation | ||
| 20 | from pip._internal.utils.misc import format_size | ||
| 21 | from pip._internal.utils.typing import MYPY_CHECK_RUNNING | ||
| 22 | |||
| 23 | if MYPY_CHECK_RUNNING: | ||
| 24 | from typing import Any | ||
| 25 | |||
| 26 | try: | ||
| 27 | from pip._vendor import colorama | ||
| 28 | # Lots of different errors can come from this, including SystemError and | ||
| 29 | # ImportError. | ||
| 30 | except Exception: | ||
| 31 | colorama = None | ||
| 32 | |||
| 33 | logger = logging.getLogger(__name__) | ||
| 34 | |||
| 35 | |||
| 36 | def _select_progress_class(preferred, fallback): | ||
| 37 | encoding = getattr(preferred.file, "encoding", None) | ||
| 38 | |||
| 39 | # If we don't know what encoding this file is in, then we'll just assume | ||
| 40 | # that it doesn't support unicode and use the ASCII bar. | ||
| 41 | if not encoding: | ||
| 42 | return fallback | ||
| 43 | |||
| 44 | # Collect all of the possible characters we want to use with the preferred | ||
| 45 | # bar. | ||
| 46 | characters = [ | ||
| 47 | getattr(preferred, "empty_fill", six.text_type()), | ||
| 48 | getattr(preferred, "fill", six.text_type()), | ||
| 49 | ] | ||
| 50 | characters += list(getattr(preferred, "phases", [])) | ||
| 51 | |||
| 52 | # Try to decode the characters we're using for the bar using the encoding | ||
| 53 | # of the given file, if this works then we'll assume that we can use the | ||
| 54 | # fancier bar and if not we'll fall back to the plaintext bar. | ||
| 55 | try: | ||
| 56 | six.text_type().join(characters).encode(encoding) | ||
| 57 | except UnicodeEncodeError: | ||
| 58 | return fallback | ||
| 59 | else: | ||
| 60 | return preferred | ||
| 61 | |||
| 62 | |||
| 63 | _BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any | ||
| 64 | |||
| 65 | |||
| 66 | class InterruptibleMixin(object): | ||
| 67 | """ | ||
| 68 | Helper to ensure that self.finish() gets called on keyboard interrupt. | ||
| 69 | |||
| 70 | This allows downloads to be interrupted without leaving temporary state | ||
| 71 | (like hidden cursors) behind. | ||
| 72 | |||
| 73 | This class is similar to the progress library's existing SigIntMixin | ||
| 74 | helper, but as of version 1.2, that helper has the following problems: | ||
| 75 | |||
| 76 | 1. It calls sys.exit(). | ||
| 77 | 2. It discards the existing SIGINT handler completely. | ||
| 78 | 3. It leaves its own handler in place even after an uninterrupted finish, | ||
| 79 | which will have unexpected delayed effects if the user triggers an | ||
| 80 | unrelated keyboard interrupt some time after a progress-displaying | ||
| 81 | download has already completed, for example. | ||
| 82 | """ | ||
| 83 | |||
| 84 | def __init__(self, *args, **kwargs): | ||
| 85 | """ | ||
| 86 | Save the original SIGINT handler for later. | ||
| 87 | """ | ||
| 88 | super(InterruptibleMixin, self).__init__(*args, **kwargs) | ||
| 89 | |||
| 90 | self.original_handler = signal(SIGINT, self.handle_sigint) | ||
| 91 | |||
| 92 | # If signal() returns None, the previous handler was not installed from | ||
| 93 | # Python, and we cannot restore it. This probably should not happen, | ||
| 94 | # but if it does, we must restore something sensible instead, at least. | ||
| 95 | # The least bad option should be Python's default SIGINT handler, which | ||
| 96 | # just raises KeyboardInterrupt. | ||
| 97 | if self.original_handler is None: | ||
| 98 | self.original_handler = default_int_handler | ||
| 99 | |||
| 100 | def finish(self): | ||
| 101 | """ | ||
| 102 | Restore the original SIGINT handler after finishing. | ||
| 103 | |||
| 104 | This should happen regardless of whether the progress display finishes | ||
| 105 | normally, or gets interrupted. | ||
| 106 | """ | ||
| 107 | super(InterruptibleMixin, self).finish() | ||
| 108 | signal(SIGINT, self.original_handler) | ||
| 109 | |||
| 110 | def handle_sigint(self, signum, frame): | ||
| 111 | """ | ||
| 112 | Call self.finish() before delegating to the original SIGINT handler. | ||
| 113 | |||
| 114 | This handler should only be in place while the progress display is | ||
| 115 | active. | ||
| 116 | """ | ||
| 117 | self.finish() | ||
| 118 | self.original_handler(signum, frame) | ||
| 119 | |||
| 120 | |||
| 121 | class SilentBar(Bar): | ||
| 122 | |||
| 123 | def update(self): | ||
| 124 | pass | ||
| 125 | |||
| 126 | |||
| 127 | class BlueEmojiBar(IncrementalBar): | ||
| 128 | |||
| 129 | suffix = "%(percent)d%%" | ||
| 130 | bar_prefix = " " | ||
| 131 | bar_suffix = " " | ||
| 132 | phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any | ||
| 133 | |||
| 134 | |||
| 135 | class DownloadProgressMixin(object): | ||
| 136 | |||
| 137 | def __init__(self, *args, **kwargs): | ||
| 138 | super(DownloadProgressMixin, self).__init__(*args, **kwargs) | ||
| 139 | self.message = (" " * (get_indentation() + 2)) + self.message | ||
| 140 | |||
| 141 | @property | ||
| 142 | def downloaded(self): | ||
| 143 | return format_size(self.index) | ||
| 144 | |||
| 145 | @property | ||
| 146 | def download_speed(self): | ||
| 147 | # Avoid zero division errors... | ||
| 148 | if self.avg == 0.0: | ||
| 149 | return "..." | ||
| 150 | return format_size(1 / self.avg) + "/s" | ||
| 151 | |||
| 152 | @property | ||
| 153 | def pretty_eta(self): | ||
| 154 | if self.eta: | ||
| 155 | return "eta %s" % self.eta_td | ||
| 156 | return "" | ||
| 157 | |||
| 158 | def iter(self, it, n=1): | ||
| 159 | for x in it: | ||
| 160 | yield x | ||
| 161 | self.next(n) | ||
| 162 | self.finish() | ||
| 163 | |||
| 164 | |||
| 165 | class WindowsMixin(object): | ||
| 166 | |||
| 167 | def __init__(self, *args, **kwargs): | ||
| 168 | # The Windows terminal does not support the hide/show cursor ANSI codes | ||
| 169 | # even with colorama. So we'll ensure that hide_cursor is False on | ||
| 170 | # Windows. | ||
| 171 | # This call neds to go before the super() call, so that hide_cursor | ||
| 172 | # is set in time. The base progress bar class writes the "hide cursor" | ||
| 173 | # code to the terminal in its init, so if we don't set this soon | ||
| 174 | # enough, we get a "hide" with no corresponding "show"... | ||
| 175 | if WINDOWS and self.hide_cursor: | ||
| 176 | self.hide_cursor = False | ||
| 177 | |||
| 178 | super(WindowsMixin, self).__init__(*args, **kwargs) | ||
| 179 | |||
| 180 | # Check if we are running on Windows and we have the colorama module, | ||
| 181 | # if we do then wrap our file with it. | ||
| 182 | if WINDOWS and colorama: | ||
| 183 | self.file = colorama.AnsiToWin32(self.file) | ||
| 184 | # The progress code expects to be able to call self.file.isatty() | ||
| 185 | # but the colorama.AnsiToWin32() object doesn't have that, so we'll | ||
| 186 | # add it. | ||
| 187 | self.file.isatty = lambda: self.file.wrapped.isatty() | ||
| 188 | # The progress code expects to be able to call self.file.flush() | ||
| 189 | # but the colorama.AnsiToWin32() object doesn't have that, so we'll | ||
| 190 | # add it. | ||
| 191 | self.file.flush = lambda: self.file.wrapped.flush() | ||
| 192 | |||
| 193 | |||
| 194 | class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, | ||
| 195 | DownloadProgressMixin): | ||
| 196 | |||
| 197 | file = sys.stdout | ||
| 198 | message = "%(percent)d%%" | ||
| 199 | suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" | ||
| 200 | |||
| 201 | # NOTE: The "type: ignore" comments on the following classes are there to | ||
| 202 | # work around https://github.com/python/typing/issues/241 | ||
| 203 | |||
| 204 | |||
| 205 | class DefaultDownloadProgressBar(BaseDownloadProgressBar, | ||
| 206 | _BaseBar): # type: ignore | ||
| 207 | pass | ||
| 208 | |||
| 209 | |||
| 210 | class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore | ||
| 211 | pass | ||
| 212 | |||
| 213 | |||
| 214 | class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore | ||
| 215 | IncrementalBar): | ||
| 216 | pass | ||
| 217 | |||
| 218 | |||
| 219 | class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore | ||
| 220 | ChargingBar): | ||
| 221 | pass | ||
| 222 | |||
| 223 | |||
| 224 | class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore | ||
| 225 | pass | ||
| 226 | |||
| 227 | |||
| 228 | class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore | ||
| 229 | FillingSquaresBar): | ||
| 230 | pass | ||
| 231 | |||
| 232 | |||
| 233 | class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore | ||
| 234 | FillingCirclesBar): | ||
| 235 | pass | ||
| 236 | |||
| 237 | |||
| 238 | class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore | ||
| 239 | BlueEmojiBar): | ||
| 240 | pass | ||
| 241 | |||
| 242 | |||
| 243 | class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, | ||
| 244 | DownloadProgressMixin, WritelnMixin, Spinner): | ||
| 245 | |||
| 246 | file = sys.stdout | ||
| 247 | suffix = "%(downloaded)s %(download_speed)s" | ||
| 248 | |||
| 249 | def next_phase(self): | ||
| 250 | if not hasattr(self, "_phaser"): | ||
| 251 | self._phaser = itertools.cycle(self.phases) | ||
| 252 | return next(self._phaser) | ||
| 253 | |||
| 254 | def update(self): | ||
| 255 | message = self.message % self | ||
| 256 | phase = self.next_phase() | ||
| 257 | suffix = self.suffix % self | ||
| 258 | line = ''.join([ | ||
| 259 | message, | ||
| 260 | " " if message else "", | ||
| 261 | phase, | ||
| 262 | " " if suffix else "", | ||
| 263 | suffix, | ||
| 264 | ]) | ||
| 265 | |||
| 266 | self.writeln(line) | ||
| 267 | |||
| 268 | |||
| 269 | BAR_TYPES = { | ||
| 270 | "off": (DownloadSilentBar, DownloadSilentBar), | ||
| 271 | "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), | ||
| 272 | "ascii": (DownloadIncrementalBar, DownloadProgressSpinner), | ||
| 273 | "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), | ||
| 274 | "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) | ||
| 275 | } | ||
| 276 | |||
| 277 | |||
| 278 | def DownloadProgressProvider(progress_bar, max=None): | ||
| 279 | if max is None or max == 0: | ||
| 280 | return BAR_TYPES[progress_bar][1]().iter | ||
| 281 | else: | ||
| 282 | return BAR_TYPES[progress_bar][0](max=max).iter | ||
| 283 | |||
| 284 | |||
| 285 | ################################################################ | ||
| 286 | # Generic "something is happening" spinners | ||
| 287 | # | ||
| 288 | # We don't even try using progress.spinner.Spinner here because it's actually | ||
| 289 | # simpler to reimplement from scratch than to coerce their code into doing | ||
| 290 | # what we need. | ||
| 291 | ################################################################ | ||
| 292 | |||
| 293 | @contextlib.contextmanager | ||
| 294 | def hidden_cursor(file): | ||
| 295 | # The Windows terminal does not support the hide/show cursor ANSI codes, | ||
| 296 | # even via colorama. So don't even try. | ||
| 297 | if WINDOWS: | ||
| 298 | yield | ||
| 299 | # We don't want to clutter the output with control characters if we're | ||
| 300 | # writing to a file, or if the user is running with --quiet. | ||
| 301 | # See https://github.com/pypa/pip/issues/3418 | ||
| 302 | elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: | ||
| 303 | yield | ||
| 304 | else: | ||
| 305 | file.write(HIDE_CURSOR) | ||
| 306 | try: | ||
| 307 | yield | ||
| 308 | finally: | ||
| 309 | file.write(SHOW_CURSOR) | ||
| 310 | |||
| 311 | |||
| 312 | class RateLimiter(object): | ||
| 313 | def __init__(self, min_update_interval_seconds): | ||
| 314 | self._min_update_interval_seconds = min_update_interval_seconds | ||
| 315 | self._last_update = 0 | ||
| 316 | |||
| 317 | def ready(self): | ||
| 318 | now = time.time() | ||
| 319 | delta = now - self._last_update | ||
| 320 | return delta >= self._min_update_interval_seconds | ||
| 321 | |||
| 322 | def reset(self): | ||
| 323 | self._last_update = time.time() | ||
| 324 | |||
| 325 | |||
| 326 | class InteractiveSpinner(object): | ||
| 327 | def __init__(self, message, file=None, spin_chars="-\\|/", | ||
| 328 | # Empirically, 8 updates/second looks nice | ||
| 329 | min_update_interval_seconds=0.125): | ||
| 330 | self._message = message | ||
| 331 | if file is None: | ||
| 332 | file = sys.stdout | ||
| 333 | self._file = file | ||
| 334 | self._rate_limiter = RateLimiter(min_update_interval_seconds) | ||
| 335 | self._finished = False | ||
| 336 | |||
| 337 | self._spin_cycle = itertools.cycle(spin_chars) | ||
| 338 | |||
| 339 | self._file.write(" " * get_indentation() + self._message + " ... ") | ||
| 340 | self._width = 0 | ||
| 341 | |||
| 342 | def _write(self, status): | ||
| 343 | assert not self._finished | ||
| 344 | # Erase what we wrote before by backspacing to the beginning, writing | ||
| 345 | # spaces to overwrite the old text, and then backspacing again | ||
| 346 | backup = "\b" * self._width | ||
| 347 | self._file.write(backup + " " * self._width + backup) | ||
| 348 | # Now we have a blank slate to add our status | ||
| 349 | self._file.write(status) | ||
| 350 | self._width = len(status) | ||
| 351 | self._file.flush() | ||
| 352 | self._rate_limiter.reset() | ||
| 353 | |||
| 354 | def spin(self): | ||
| 355 | if self._finished: | ||
| 356 | return | ||
| 357 | if not self._rate_limiter.ready(): | ||
| 358 | return | ||
| 359 | self._write(next(self._spin_cycle)) | ||
| 360 | |||
| 361 | def finish(self, final_status): | ||
| 362 | if self._finished: | ||
| 363 | return | ||
| 364 | self._write(final_status) | ||
| 365 | self._file.write("\n") | ||
| 366 | self._file.flush() | ||
| 367 | self._finished = True | ||
| 368 | |||
| 369 | |||
| 370 | # Used for dumb terminals, non-interactive installs (no tty), etc. | ||
| 371 | # We still print updates occasionally (once every 60 seconds by default) to | ||
| 372 | # act as a keep-alive for systems like Travis-CI that take lack-of-output as | ||
| 373 | # an indication that a task has frozen. | ||
| 374 | class NonInteractiveSpinner(object): | ||
| 375 | def __init__(self, message, min_update_interval_seconds=60): | ||
| 376 | self._message = message | ||
| 377 | self._finished = False | ||
| 378 | self._rate_limiter = RateLimiter(min_update_interval_seconds) | ||
| 379 | self._update("started") | ||
| 380 | |||
| 381 | def _update(self, status): | ||
| 382 | assert not self._finished | ||
| 383 | self._rate_limiter.reset() | ||
| 384 | logger.info("%s: %s", self._message, status) | ||
| 385 | |||
| 386 | def spin(self): | ||
| 387 | if self._finished: | ||
| 388 | return | ||
| 389 | if not self._rate_limiter.ready(): | ||
| 390 | return | ||
| 391 | self._update("still running...") | ||
| 392 | |||
| 393 | def finish(self, final_status): | ||
| 394 | if self._finished: | ||
| 395 | return | ||
| 396 | self._update("finished with status '%s'" % (final_status,)) | ||
| 397 | self._finished = True | ||
| 398 | |||
| 399 | |||
| 400 | @contextlib.contextmanager | ||
| 401 | def open_spinner(message): | ||
| 402 | # Interactive spinner goes directly to sys.stdout rather than being routed | ||
| 403 | # through the logging system, but it acts like it has level INFO, | ||
| 404 | # i.e. it's only displayed if we're at level INFO or better. | ||
| 405 | # Non-interactive spinner goes through the logging system, so it is always | ||
| 406 | # in sync with logging configuration. | ||
| 407 | if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: | ||
| 408 | spinner = InteractiveSpinner(message) | ||
| 409 | else: | ||
| 410 | spinner = NonInteractiveSpinner(message) | ||
| 411 | try: | ||
| 412 | with hidden_cursor(sys.stdout): | ||
| 413 | yield spinner | ||
| 414 | except KeyboardInterrupt: | ||
| 415 | spinner.finish("canceled") | ||
| 416 | raise | ||
| 417 | except Exception: | ||
| 418 | spinner.finish("error") | ||
| 419 | raise | ||
| 420 | else: | ||
| 421 | spinner.finish("done") | ||
