prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  pip search picks older version if returned list of versions are not ordered
  * Pip version: 9.0.1
  * Python version: 2.7
  * Operating System: Ubuntu/CentOS
  
  ### Description:
  
  For a list of versions returned by local pypi server that was ill-ordered like
  ```[{...'versions': ['1.0.249', '1.0.251', '1.0.250'], 'name':...}...]```
  
  search picks the top element among all the versions returned to it.
  ```version = hit.get('versions', ['-'])[-1]```
   at https://github.com/pypa/pip/blob/9.0.1/pip/commands/search.py#L107 and https://github.com/pypa/pip/blob/9.0.1/pip/commands/search.py#L99
  
  Rather it should do something like
  ```version = highest_version(hit.get('versions', ['-']))```
  
  
  
  </issue>
  <code>
  [start of pip/commands/search.py]
  1 from __future__ import absolute_import
  2 
  3 import logging
  4 import sys
  5 import textwrap
  6 
  7 from pip.basecommand import Command, SUCCESS
  8 from pip.compat import OrderedDict
  9 from pip.download import PipXmlrpcTransport
  10 from pip.models import PyPI
  11 from pip.utils import get_terminal_size
  12 from pip.utils.logging import indent_log
  13 from pip.exceptions import CommandError
  14 from pip.status_codes import NO_MATCHES_FOUND
  15 from pip._vendor.packaging.version import parse as parse_version
  16 from pip._vendor import pkg_resources
  17 from pip._vendor.six.moves import xmlrpc_client
  18 
  19 
  20 logger = logging.getLogger(__name__)
  21 
  22 
  23 class SearchCommand(Command):
  24     """Search for PyPI packages whose name or summary contains <query>."""
  25     name = 'search'
  26     usage = """
  27       %prog [options] <query>"""
  28     summary = 'Search PyPI for packages.'
  29 
  30     def __init__(self, *args, **kw):
  31         super(SearchCommand, self).__init__(*args, **kw)
  32         self.cmd_opts.add_option(
  33             '-i', '--index',
  34             dest='index',
  35             metavar='URL',
  36             default=PyPI.pypi_url,
  37             help='Base URL of Python Package Index (default %default)')
  38 
  39         self.parser.insert_option_group(0, self.cmd_opts)
  40 
  41     def run(self, options, args):
  42         if not args:
  43             raise CommandError('Missing required argument (search query).')
  44         query = args
  45         pypi_hits = self.search(query, options)
  46         hits = transform_hits(pypi_hits)
  47 
  48         terminal_width = None
  49         if sys.stdout.isatty():
  50             terminal_width = get_terminal_size()[0]
  51 
  52         print_results(hits, terminal_width=terminal_width)
  53         if pypi_hits:
  54             return SUCCESS
  55         return NO_MATCHES_FOUND
  56 
  57     def search(self, query, options):
  58         index_url = options.index
  59         with self._build_session(options) as session:
  60             transport = PipXmlrpcTransport(index_url, session)
  61             pypi = xmlrpc_client.ServerProxy(index_url, transport)
  62             hits = pypi.search({'name': query, 'summary': query}, 'or')
  63             return hits
  64 
  65 
  66 def transform_hits(hits):
  67     """
  68     The list from pypi is really a list of versions. We want a list of
  69     packages with the list of versions stored inline. This converts the
  70     list from pypi into one we can use.
  71     """
  72     packages = OrderedDict()
  73     for hit in hits:
  74         name = hit['name']
  75         summary = hit['summary']
  76         version = hit['version']
  77 
  78         if name not in packages.keys():
  79             packages[name] = {
  80                 'name': name,
  81                 'summary': summary,
  82                 'versions': [version],
  83             }
  84         else:
  85             packages[name]['versions'].append(version)
  86 
  87             # if this is the highest version, replace summary and score
  88             if version == highest_version(packages[name]['versions']):
  89                 packages[name]['summary'] = summary
  90 
  91     return list(packages.values())
  92 
  93 
  94 def print_results(hits, name_column_width=None, terminal_width=None):
  95     if not hits:
  96         return
  97     if name_column_width is None:
  98         name_column_width = max([
  99             len(hit['name']) + len(hit.get('versions', ['-'])[-1])
  100             for hit in hits
  101         ]) + 4
  102 
  103     installed_packages = [p.project_name for p in pkg_resources.working_set]
  104     for hit in hits:
  105         name = hit['name']
  106         summary = hit['summary'] or ''
  107         version = hit.get('versions', ['-'])[-1]
  108         if terminal_width is not None:
  109             target_width = terminal_width - name_column_width - 5
  110             if target_width > 10:
  111                 # wrap and indent summary to fit terminal
  112                 summary = textwrap.wrap(summary, target_width)
  113                 summary = ('\n' + ' ' * (name_column_width + 3)).join(summary)
  114 
  115         line = '%-*s - %s' % (name_column_width,
  116                               '%s (%s)' % (name, version), summary)
  117         try:
  118             logger.info(line)
  119             if name in installed_packages:
  120                 dist = pkg_resources.get_distribution(name)
  121                 with indent_log():
  122                     latest = highest_version(hit['versions'])
  123                     if dist.version == latest:
  124                         logger.info('INSTALLED: %s (latest)', dist.version)
  125                     else:
  126                         logger.info('INSTALLED: %s', dist.version)
  127                         logger.info('LATEST:    %s', latest)
  128         except UnicodeEncodeError:
  129             pass
  130 
  131 
  132 def highest_version(versions):
  133     return max(versions, key=parse_version)
  134
  [end of pip/commands/search.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/pip/commands/search.py b/pip/commands/search.py
  --- a/pip/commands/search.py
  +++ b/pip/commands/search.py
  @@ -96,7 +96,7 @@
           return
       if name_column_width is None:
           name_column_width = max([
  -            len(hit['name']) + len(hit.get('versions', ['-'])[-1])
  +            len(hit['name']) + len(highest_version(hit.get('versions', ['-'])))
               for hit in hits
           ]) + 4
   
  @@ -104,7 +104,7 @@
       for hit in hits:
           name = hit['name']
           summary = hit['summary'] or ''
  -        version = hit.get('versions', ['-'])[-1]
  +        latest = highest_version(hit.get('versions', ['-']))
           if terminal_width is not None:
               target_width = terminal_width - name_column_width - 5
               if target_width > 10:
  @@ -113,13 +113,12 @@
                   summary = ('\n' + ' ' * (name_column_width + 3)).join(summary)
   
           line = '%-*s - %s' % (name_column_width,
  -                              '%s (%s)' % (name, version), summary)
  +                              '%s (%s)' % (name, latest), summary)
           try:
               logger.info(line)
               if name in installed_packages:
                   dist = pkg_resources.get_distribution(name)
                   with indent_log():
  -                    latest = highest_version(hit['versions'])
                       if dist.version == latest:
                           logger.info('INSTALLED: %s (latest)', dist.version)
                       else:
  
verification_info: {"golden_diff": "diff --git a/pip/commands/search.py b/pip/commands/search.py\n--- a/pip/commands/search.py\n+++ b/pip/commands/search.py\n@@ -96,7 +96,7 @@\n         return\n     if name_column_width is None:\n         name_column_width = max([\n-            len(hit['name']) + len(hit.get('versions', ['-'])[-1])\n+            len(hit['name']) + len(highest_version(hit.get('versions', ['-'])))\n             for hit in hits\n         ]) + 4\n \n@@ -104,7 +104,7 @@\n     for hit in hits:\n         name = hit['name']\n         summary = hit['summary'] or ''\n-        version = hit.get('versions', ['-'])[-1]\n+        latest = highest_version(hit.get('versions', ['-']))\n         if terminal_width is not None:\n             target_width = terminal_width - name_column_width - 5\n             if target_width > 10:\n@@ -113,13 +113,12 @@\n                 summary = ('\\n' + ' ' * (name_column_width + 3)).join(summary)\n \n         line = '%-*s - %s' % (name_column_width,\n-                              '%s (%s)' % (name, version), summary)\n+                              '%s (%s)' % (name, latest), summary)\n         try:\n             logger.info(line)\n             if name in installed_packages:\n                 dist = pkg_resources.get_distribution(name)\n                 with indent_log():\n-                    latest = highest_version(hit['versions'])\n                     if dist.version == latest:\n                         logger.info('INSTALLED: %s (latest)', dist.version)\n                     else:\n", "issue": "pip search picks older version if returned list of versions are not ordered\n* Pip version: 9.0.1\r\n* Python version: 2.7\r\n* Operating System: Ubuntu/CentOS\r\n\r\n### Description:\r\n\r\nFor a list of versions returned by local pypi server that was ill-ordered like\r\n```[{...'versions': ['1.0.249', '1.0.251', '1.0.250'], 'name':...}...]```\r\n\r\nsearch picks the top element among all the versions returned to it.\r\n```version = hit.get('versions', ['-'])[-1]```\r\n at https://github.com/pypa/pip/blob/9.0.1/pip/commands/search.py#L107 and https://github.com/pypa/pip/blob/9.0.1/pip/commands/search.py#L99\r\n\r\nRather it should do something like\r\n```version = highest_version(hit.get('versions', ['-']))```\r\n\r\n\n", "before_files": [{"content": "from __future__ import absolute_import\n\nimport logging\nimport sys\nimport textwrap\n\nfrom pip.basecommand import Command, SUCCESS\nfrom pip.compat import OrderedDict\nfrom pip.download import PipXmlrpcTransport\nfrom pip.models import PyPI\nfrom pip.utils import get_terminal_size\nfrom pip.utils.logging import indent_log\nfrom pip.exceptions import CommandError\nfrom pip.status_codes import NO_MATCHES_FOUND\nfrom pip._vendor.packaging.version import parse as parse_version\nfrom pip._vendor import pkg_resources\nfrom pip._vendor.six.moves import xmlrpc_client\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass SearchCommand(Command):\n    \"\"\"Search for PyPI packages whose name or summary contains <query>.\"\"\"\n    name = 'search'\n    usage = \"\"\"\n      %prog [options] <query>\"\"\"\n    summary = 'Search PyPI for packages.'\n\n    def __init__(self, *args, **kw):\n        super(SearchCommand, self).__init__(*args, **kw)\n        self.cmd_opts.add_option(\n            '-i', '--index',\n            dest='index',\n            metavar='URL',\n            default=PyPI.pypi_url,\n            help='Base URL of Python Package Index (default %default)')\n\n        self.parser.insert_option_group(0, self.cmd_opts)\n\n    def run(self, options, args):\n        if not args:\n            raise CommandError('Missing required argument (search query).')\n        query = args\n        pypi_hits = self.search(query, options)\n        hits = transform_hits(pypi_hits)\n\n        terminal_width = None\n        if sys.stdout.isatty():\n            terminal_width = get_terminal_size()[0]\n\n        print_results(hits, terminal_width=terminal_width)\n        if pypi_hits:\n            return SUCCESS\n        return NO_MATCHES_FOUND\n\n    def search(self, query, options):\n        index_url = options.index\n        with self._build_session(options) as session:\n            transport = PipXmlrpcTransport(index_url, session)\n            pypi = xmlrpc_client.ServerProxy(index_url, transport)\n            hits = pypi.search({'name': query, 'summary': query}, 'or')\n            return hits\n\n\ndef transform_hits(hits):\n    \"\"\"\n    The list from pypi is really a list of versions. We want a list of\n    packages with the list of versions stored inline. This converts the\n    list from pypi into one we can use.\n    \"\"\"\n    packages = OrderedDict()\n    for hit in hits:\n        name = hit['name']\n        summary = hit['summary']\n        version = hit['version']\n\n        if name not in packages.keys():\n            packages[name] = {\n                'name': name,\n                'summary': summary,\n                'versions': [version],\n            }\n        else:\n            packages[name]['versions'].append(version)\n\n            # if this is the highest version, replace summary and score\n            if version == highest_version(packages[name]['versions']):\n                packages[name]['summary'] = summary\n\n    return list(packages.values())\n\n\ndef print_results(hits, name_column_width=None, terminal_width=None):\n    if not hits:\n        return\n    if name_column_width is None:\n        name_column_width = max([\n            len(hit['name']) + len(hit.get('versions', ['-'])[-1])\n            for hit in hits\n        ]) + 4\n\n    installed_packages = [p.project_name for p in pkg_resources.working_set]\n    for hit in hits:\n        name = hit['name']\n        summary = hit['summary'] or ''\n        version = hit.get('versions', ['-'])[-1]\n        if terminal_width is not None:\n            target_width = terminal_width - name_column_width - 5\n            if target_width > 10:\n                # wrap and indent summary to fit terminal\n                summary = textwrap.wrap(summary, target_width)\n                summary = ('\\n' + ' ' * (name_column_width + 3)).join(summary)\n\n        line = '%-*s - %s' % (name_column_width,\n                              '%s (%s)' % (name, version), summary)\n        try:\n            logger.info(line)\n            if name in installed_packages:\n                dist = pkg_resources.get_distribution(name)\n                with indent_log():\n                    latest = highest_version(hit['versions'])\n                    if dist.version == latest:\n                        logger.info('INSTALLED: %s (latest)', dist.version)\n                    else:\n                        logger.info('INSTALLED: %s', dist.version)\n                        logger.info('LATEST:    %s', latest)\n        except UnicodeEncodeError:\n            pass\n\n\ndef highest_version(versions):\n    return max(versions, key=parse_version)\n", "path": "pip/commands/search.py"}]}