prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  pip 6.0.3 weird symbols shown with download progress bar
  with pip 6.0.3 on Windows with cmd.exe
  
  ```
  py -mpip install --upgrade setuptools
  
  Collecting setuptools from https://pypi.python.org/packages/3.4/s/setuptools/set
  uptools-8.3-py2.py3-none-any.whl#md5=a6c2914e2ae62227a5dfb6e908475b02
    Downloading setuptools-8.3-py2.py3-none-any.whl (552kB)
  ←[K    100% |################################| 552kB 835kB/s ta 0:00:01
  ←[?25hInstalling collected packages: setuptools
    Found existing installation: setuptools 7.0
      Uninstalling setuptools-7.0:
        Successfully uninstalled setuptools-7.0
  
  Successfully installed setuptools-8.3
  ```
  
  There's weird stuff with the progress bar, possibly control characers that cmd.exe terminal can't handle
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pip/utils/ui.py`
  Content:
  ```
  1 from __future__ import absolute_import
  2 from __future__ import division
  3 
  4 import itertools
  5 import sys
  6 
  7 from pip.utils import format_size
  8 from pip.utils.logging import get_indentation
  9 from pip._vendor.progress.bar import Bar
  10 from pip._vendor.progress.helpers import WritelnMixin
  11 from pip._vendor.progress.spinner import Spinner
  12 
  13 
  14 class DownloadProgressMixin(object):
  15 
  16     def __init__(self, *args, **kwargs):
  17         super(DownloadProgressMixin, self).__init__(*args, **kwargs)
  18         self.message = (" " * (get_indentation() + 2)) + self.message
  19 
  20     @property
  21     def downloaded(self):
  22         return format_size(self.index)
  23 
  24     @property
  25     def download_speed(self):
  26         # Avoid zero division errors...
  27         if self.avg == 0.0:
  28             return "..."
  29         return format_size(1 / self.avg) + "/s"
  30 
  31     @property
  32     def pretty_eta(self):
  33         if self.eta:
  34             return "eta %s" % self.eta_td
  35         return ""
  36 
  37     def iter(self, it, n=1):
  38         for x in it:
  39             yield x
  40             self.next(n)
  41         self.finish()
  42 
  43 
  44 class DownloadProgressBar(DownloadProgressMixin, Bar):
  45 
  46     file = sys.stdout
  47     message = "%(percent)d%%"
  48     suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s"
  49 
  50 
  51 class DownloadProgressSpinner(DownloadProgressMixin, WritelnMixin, Spinner):
  52 
  53     file = sys.stdout
  54     suffix = "%(downloaded)s %(download_speed)s"
  55 
  56     def next_phase(self):
  57         if not hasattr(self, "_phaser"):
  58             self._phaser = itertools.cycle(self.phases)
  59         return next(self._phaser)
  60 
  61     def update(self):
  62         message = self.message % self
  63         phase = self.next_phase()
  64         suffix = self.suffix % self
  65         line = ''.join([
  66             message,
  67             " " if message else "",
  68             phase,
  69             " " if suffix else "",
  70             suffix,
  71         ])
  72 
  73         self.writeln(line)
  74
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pip/utils/ui.py b/pip/utils/ui.py
  --- a/pip/utils/ui.py
  +++ b/pip/utils/ui.py
  @@ -4,12 +4,20 @@
   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 @@
           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"
  
verification_info: {"golden_diff": "diff --git a/pip/utils/ui.py b/pip/utils/ui.py\n--- a/pip/utils/ui.py\n+++ b/pip/utils/ui.py\n@@ -4,12 +4,20 @@\n import itertools\n import sys\n \n+from pip.compat import WINDOWS\n from pip.utils import format_size\n from pip.utils.logging import get_indentation\n from pip._vendor.progress.bar import Bar\n from pip._vendor.progress.helpers import WritelnMixin\n from pip._vendor.progress.spinner import Spinner\n \n+try:\n+    from pip._vendor import colorama\n+# Lots of different errors can come from this, including SystemError and\n+# ImportError.\n+except Exception:\n+    colorama = None\n+\n \n class DownloadProgressMixin(object):\n \n@@ -41,14 +49,40 @@\n         self.finish()\n \n \n-class DownloadProgressBar(DownloadProgressMixin, Bar):\n+class WindowsMixin(object):\n+\n+    def __init__(self, *args, **kwargs):\n+        super(WindowsMixin, self).__init__(*args, **kwargs)\n+\n+        # Check if we are running on Windows and we have the colorama module,\n+        # if we do then wrap our file with it.\n+        if WINDOWS and colorama:\n+            self.file = colorama.AnsiToWin32(self.file)\n+            # The progress code expects to be able to call self.file.isatty()\n+            # but the colorama.AnsiToWin32() object doesn't have that, so we'll\n+            # add it.\n+            self.file.isatty = lambda: self.file.wrapped.isatty()\n+            # The progress code expects to be able to call self.file.flush()\n+            # but the colorama.AnsiToWin32() object doesn't have that, so we'll\n+            # add it.\n+            self.file.flush = lambda: self.file.wrapped.flush()\n+\n+        # The Windows terminal does not support the hide/show cursor ANSI codes\n+        # even with colorama. So we'll ensure that hide_cursor is False on\n+        # Windows.\n+        if WINDOWS and self.hide_cursor:\n+            self.hide_cursor = False\n+\n+\n+class DownloadProgressBar(WindowsMixin, DownloadProgressMixin, Bar):\n \n     file = sys.stdout\n     message = \"%(percent)d%%\"\n     suffix = \"%(downloaded)s %(download_speed)s %(pretty_eta)s\"\n \n \n-class DownloadProgressSpinner(DownloadProgressMixin, WritelnMixin, Spinner):\n+class DownloadProgressSpinner(WindowsMixin, DownloadProgressMixin,\n+                              WritelnMixin, Spinner):\n \n     file = sys.stdout\n     suffix = \"%(downloaded)s %(download_speed)s\"\n", "issue": "pip 6.0.3 weird symbols shown with download progress bar\nwith pip 6.0.3 on Windows with cmd.exe\n\n```\npy -mpip install --upgrade setuptools\n\nCollecting setuptools from https://pypi.python.org/packages/3.4/s/setuptools/set\nuptools-8.3-py2.py3-none-any.whl#md5=a6c2914e2ae62227a5dfb6e908475b02\n  Downloading setuptools-8.3-py2.py3-none-any.whl (552kB)\n\u2190[K    100% |################################| 552kB 835kB/s ta 0:00:01\n\u2190[?25hInstalling collected packages: setuptools\n  Found existing installation: setuptools 7.0\n    Uninstalling setuptools-7.0:\n      Successfully uninstalled setuptools-7.0\n\nSuccessfully installed setuptools-8.3\n```\n\nThere's weird stuff with the progress bar, possibly control characers that cmd.exe terminal can't handle\n\n", "before_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import division\n\nimport itertools\nimport sys\n\nfrom pip.utils import format_size\nfrom pip.utils.logging import get_indentation\nfrom pip._vendor.progress.bar import Bar\nfrom pip._vendor.progress.helpers import WritelnMixin\nfrom pip._vendor.progress.spinner import Spinner\n\n\nclass DownloadProgressMixin(object):\n\n    def __init__(self, *args, **kwargs):\n        super(DownloadProgressMixin, self).__init__(*args, **kwargs)\n        self.message = (\" \" * (get_indentation() + 2)) + self.message\n\n    @property\n    def downloaded(self):\n        return format_size(self.index)\n\n    @property\n    def download_speed(self):\n        # Avoid zero division errors...\n        if self.avg == 0.0:\n            return \"...\"\n        return format_size(1 / self.avg) + \"/s\"\n\n    @property\n    def pretty_eta(self):\n        if self.eta:\n            return \"eta %s\" % self.eta_td\n        return \"\"\n\n    def iter(self, it, n=1):\n        for x in it:\n            yield x\n            self.next(n)\n        self.finish()\n\n\nclass DownloadProgressBar(DownloadProgressMixin, Bar):\n\n    file = sys.stdout\n    message = \"%(percent)d%%\"\n    suffix = \"%(downloaded)s %(download_speed)s %(pretty_eta)s\"\n\n\nclass DownloadProgressSpinner(DownloadProgressMixin, WritelnMixin, Spinner):\n\n    file = sys.stdout\n    suffix = \"%(downloaded)s %(download_speed)s\"\n\n    def next_phase(self):\n        if not hasattr(self, \"_phaser\"):\n            self._phaser = itertools.cycle(self.phases)\n        return next(self._phaser)\n\n    def update(self):\n        message = self.message % self\n        phase = self.next_phase()\n        suffix = self.suffix % self\n        line = ''.join([\n            message,\n            \" \" if message else \"\",\n            phase,\n            \" \" if suffix else \"\",\n            suffix,\n        ])\n\n        self.writeln(line)\n", "path": "pip/utils/ui.py"}], "after_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import division\n\nimport itertools\nimport sys\n\nfrom pip.compat import WINDOWS\nfrom pip.utils import format_size\nfrom pip.utils.logging import get_indentation\nfrom pip._vendor.progress.bar import Bar\nfrom pip._vendor.progress.helpers import WritelnMixin\nfrom pip._vendor.progress.spinner import Spinner\n\ntry:\n    from pip._vendor import colorama\n# Lots of different errors can come from this, including SystemError and\n# ImportError.\nexcept Exception:\n    colorama = None\n\n\nclass DownloadProgressMixin(object):\n\n    def __init__(self, *args, **kwargs):\n        super(DownloadProgressMixin, self).__init__(*args, **kwargs)\n        self.message = (\" \" * (get_indentation() + 2)) + self.message\n\n    @property\n    def downloaded(self):\n        return format_size(self.index)\n\n    @property\n    def download_speed(self):\n        # Avoid zero division errors...\n        if self.avg == 0.0:\n            return \"...\"\n        return format_size(1 / self.avg) + \"/s\"\n\n    @property\n    def pretty_eta(self):\n        if self.eta:\n            return \"eta %s\" % self.eta_td\n        return \"\"\n\n    def iter(self, it, n=1):\n        for x in it:\n            yield x\n            self.next(n)\n        self.finish()\n\n\nclass WindowsMixin(object):\n\n    def __init__(self, *args, **kwargs):\n        super(WindowsMixin, self).__init__(*args, **kwargs)\n\n        # Check if we are running on Windows and we have the colorama module,\n        # if we do then wrap our file with it.\n        if WINDOWS and colorama:\n            self.file = colorama.AnsiToWin32(self.file)\n            # The progress code expects to be able to call self.file.isatty()\n            # but the colorama.AnsiToWin32() object doesn't have that, so we'll\n            # add it.\n            self.file.isatty = lambda: self.file.wrapped.isatty()\n            # The progress code expects to be able to call self.file.flush()\n            # but the colorama.AnsiToWin32() object doesn't have that, so we'll\n            # add it.\n            self.file.flush = lambda: self.file.wrapped.flush()\n\n        # The Windows terminal does not support the hide/show cursor ANSI codes\n        # even with colorama. So we'll ensure that hide_cursor is False on\n        # Windows.\n        if WINDOWS and self.hide_cursor:\n            self.hide_cursor = False\n\n\nclass DownloadProgressBar(WindowsMixin, DownloadProgressMixin, Bar):\n\n    file = sys.stdout\n    message = \"%(percent)d%%\"\n    suffix = \"%(downloaded)s %(download_speed)s %(pretty_eta)s\"\n\n\nclass DownloadProgressSpinner(WindowsMixin, DownloadProgressMixin,\n                              WritelnMixin, Spinner):\n\n    file = sys.stdout\n    suffix = \"%(downloaded)s %(download_speed)s\"\n\n    def next_phase(self):\n        if not hasattr(self, \"_phaser\"):\n            self._phaser = itertools.cycle(self.phases)\n        return next(self._phaser)\n\n    def update(self):\n        message = self.message % self\n        phase = self.next_phase()\n        suffix = self.suffix % self\n        line = ''.join([\n            message,\n            \" \" if message else \"\",\n            phase,\n            \" \" if suffix else \"\",\n            suffix,\n        ])\n\n        self.writeln(line)\n", "path": "pip/utils/ui.py"}]}