Fix progress bar since Windows doesn't support ANSI escape codes

* Use the colorama module to enable the "clear the line" ANSI escape
  code on Windows.
* Disable cursor hiding on Windows since Windows terminal doesn't
  support it nor does colorama.
This commit is contained in:
Donald Stufft 2014-12-28 18:19:14 -05:00
parent 1927dfce6a
commit fada9e66d8
1 changed files with 36 additions and 2 deletions

View File

@ -4,12 +4,20 @@ from __future__ import division
import itertools
import sys
from pip.compat import WINDOWS
from pip.utils import format_size
from pip.utils.logging import get_indentation
from pip._vendor.progress.bar import Bar
from pip._vendor.progress.helpers import WritelnMixin
from pip._vendor.progress.spinner import Spinner
try:
from pip._vendor import colorama
# Lots of different errors can come from this, including SystemError and
# ImportError.
except Exception:
colorama = None
class DownloadProgressMixin(object):
@ -41,14 +49,40 @@ class DownloadProgressMixin(object):
self.finish()
class DownloadProgressBar(DownloadProgressMixin, Bar):
class WindowsMixin(object):
def __init__(self, *args, **kwargs):
super(WindowsMixin, self).__init__(*args, **kwargs)
# Check if we are running on Windows and we have the colorama module,
# if we do then wrap our file with it.
if WINDOWS and colorama:
self.file = colorama.AnsiToWin32(self.file)
# The progress code expects to be able to call self.file.isatty()
# but the colorama.AnsiToWin32() object doesn't have that, so we'll
# add it.
self.file.isatty = lambda: self.file.wrapped.isatty()
# The progress code expects to be able to call self.file.flush()
# but the colorama.AnsiToWin32() object doesn't have that, so we'll
# add it.
self.file.flush = lambda: self.file.wrapped.flush()
# The Windows terminal does not support the hide/show cursor ANSI codes
# even with colorama. So we'll ensure that hide_cursor is False on
# Windows.
if WINDOWS and self.hide_cursor:
self.hide_cursor = False
class DownloadProgressBar(WindowsMixin, DownloadProgressMixin, Bar):
file = sys.stdout
message = "%(percent)d%%"
suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s"
class DownloadProgressSpinner(DownloadProgressMixin, WritelnMixin, Spinner):
class DownloadProgressSpinner(WindowsMixin, DownloadProgressMixin,
WritelnMixin, Spinner):
file = sys.stdout
suffix = "%(downloaded)s %(download_speed)s"