We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pip list outdated
I install Flask version 0.8 with pip in editable mode 

`pip install -e git+https://github.com/mitsuhiko/flask.git@0.8#egg=flask`

Output of pip list 

```
argparse (1.2.1)
Flask (0.8dev-20130506, /home/pratz/VirtualEnv/learnflask/src/flask)
Jinja2 (2.6)
Werkzeug (0.8.3)
wsgiref (0.1.2)
```

Ouput of pip list -o
Nothing ( returns to console without any output )

Should not the output of pip list -o be
`Flask (Current: 0.8dev Latest: 0.9)`

Or is this how pip list -o works for editable mode ?

NOTE: pip version is 1.3.1


--- 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/commands/list.py`
Content:
```
1 from __future__ import absolute_import
2 
3 import logging
4 import warnings
5 
6 from pip.basecommand import Command
7 from pip.exceptions import DistributionNotFound
8 from pip.index import FormatControl, fmt_ctl_formats, PackageFinder, Search
9 from pip.req import InstallRequirement
10 from pip.utils import (
11     get_installed_distributions, dist_is_editable, canonicalize_name)
12 from pip.utils.deprecation import RemovedInPip10Warning
13 from pip.wheel import WheelCache
14 from pip.cmdoptions import make_option_group, index_group
15 
16 
17 logger = logging.getLogger(__name__)
18 
19 
20 class ListCommand(Command):
21     """
22     List installed packages, including editables.
23 
24     Packages are listed in a case-insensitive sorted order.
25     """
26     name = 'list'
27     usage = """
28       %prog [options]"""
29     summary = 'List installed packages.'
30 
31     def __init__(self, *args, **kw):
32         super(ListCommand, self).__init__(*args, **kw)
33 
34         cmd_opts = self.cmd_opts
35 
36         cmd_opts.add_option(
37             '-o', '--outdated',
38             action='store_true',
39             default=False,
40             help='List outdated packages (excluding editables)')
41         cmd_opts.add_option(
42             '-u', '--uptodate',
43             action='store_true',
44             default=False,
45             help='List uptodate packages (excluding editables)')
46         cmd_opts.add_option(
47             '-e', '--editable',
48             action='store_true',
49             default=False,
50             help='List editable projects.')
51         cmd_opts.add_option(
52             '-l', '--local',
53             action='store_true',
54             default=False,
55             help=('If in a virtualenv that has global access, do not list '
56                   'globally-installed packages.'),
57         )
58         self.cmd_opts.add_option(
59             '--user',
60             dest='user',
61             action='store_true',
62             default=False,
63             help='Only output packages installed in user-site.')
64 
65         cmd_opts.add_option(
66             '--pre',
67             action='store_true',
68             default=False,
69             help=("Include pre-release and development versions. By default, "
70                   "pip only finds stable versions."),
71         )
72 
73         index_opts = make_option_group(index_group, self.parser)
74 
75         self.parser.insert_option_group(0, index_opts)
76         self.parser.insert_option_group(0, cmd_opts)
77 
78     def _build_package_finder(self, options, index_urls, session):
79         """
80         Create a package finder appropriate to this list command.
81         """
82         return PackageFinder(
83             find_links=options.find_links,
84             index_urls=index_urls,
85             allow_all_prereleases=options.pre,
86             trusted_hosts=options.trusted_hosts,
87             process_dependency_links=options.process_dependency_links,
88             session=session,
89         )
90 
91     def run(self, options, args):
92         if options.allow_external:
93             warnings.warn(
94                 "--allow-external has been deprecated and will be removed in "
95                 "the future. Due to changes in the repository protocol, it no "
96                 "longer has any effect.",
97                 RemovedInPip10Warning,
98             )
99 
100         if options.allow_all_external:
101             warnings.warn(
102                 "--allow-all-external has been deprecated and will be removed "
103                 "in the future. Due to changes in the repository protocol, it "
104                 "no longer has any effect.",
105                 RemovedInPip10Warning,
106             )
107 
108         if options.allow_unverified:
109             warnings.warn(
110                 "--allow-unverified has been deprecated and will be removed "
111                 "in the future. Due to changes in the repository protocol, it "
112                 "no longer has any effect.",
113                 RemovedInPip10Warning,
114             )
115 
116         if options.outdated:
117             self.run_outdated(options)
118         elif options.uptodate:
119             self.run_uptodate(options)
120         elif options.editable:
121             self.run_editables(options)
122         else:
123             self.run_listing(options)
124 
125     def run_outdated(self, options):
126         for dist, version, typ in self.find_packages_latest_versions(options):
127             if version > dist.parsed_version:
128                 logger.info(
129                     '%s (Current: %s Latest: %s [%s])',
130                     dist.project_name, dist.version, version, typ,
131                 )
132 
133     def find_packages_latest_versions(self, options):
134         index_urls = [options.index_url] + options.extra_index_urls
135         if options.no_index:
136             logger.info('Ignoring indexes: %s', ','.join(index_urls))
137             index_urls = []
138 
139         dependency_links = []
140         for dist in get_installed_distributions(local_only=options.local,
141                                                 user_only=options.user):
142             if dist.has_metadata('dependency_links.txt'):
143                 dependency_links.extend(
144                     dist.get_metadata_lines('dependency_links.txt'),
145                 )
146 
147         with self._build_session(options) as session:
148             finder = self._build_package_finder(options, index_urls, session)
149             finder.add_dependency_links(dependency_links)
150 
151             installed_packages = get_installed_distributions(
152                 local_only=options.local,
153                 user_only=options.user,
154                 include_editables=False,
155             )
156             format_control = FormatControl(set(), set())
157             wheel_cache = WheelCache(options.cache_dir, format_control)
158             for dist in installed_packages:
159                 req = InstallRequirement.from_line(
160                     dist.key, None, isolated=options.isolated_mode,
161                     wheel_cache=wheel_cache
162                 )
163                 typ = 'unknown'
164                 try:
165                     link = finder.find_requirement(req, True)
166 
167                     # If link is None, means installed version is most
168                     # up-to-date
169                     if link is None:
170                         continue
171                 except DistributionNotFound:
172                     continue
173                 else:
174                     canonical_name = canonicalize_name(req.name)
175                     formats = fmt_ctl_formats(format_control, canonical_name)
176                     search = Search(
177                         req.name,
178                         canonical_name,
179                         formats)
180                     remote_version = finder._link_package_versions(
181                         link, search).version
182                     if link.is_wheel:
183                         typ = 'wheel'
184                     else:
185                         typ = 'sdist'
186                 yield dist, remote_version, typ
187 
188     def run_listing(self, options):
189         installed_packages = get_installed_distributions(
190             local_only=options.local,
191             user_only=options.user,
192         )
193         self.output_package_listing(installed_packages)
194 
195     def run_editables(self, options):
196         installed_packages = get_installed_distributions(
197             local_only=options.local,
198             user_only=options.user,
199             editables_only=True,
200         )
201         self.output_package_listing(installed_packages)
202 
203     def output_package_listing(self, installed_packages):
204         installed_packages = sorted(
205             installed_packages,
206             key=lambda dist: dist.project_name.lower(),
207         )
208         for dist in installed_packages:
209             if dist_is_editable(dist):
210                 line = '%s (%s, %s)' % (
211                     dist.project_name,
212                     dist.version,
213                     dist.location,
214                 )
215             else:
216                 line = '%s (%s)' % (dist.project_name, dist.version)
217             logger.info(line)
218 
219     def run_uptodate(self, options):
220         uptodate = []
221         for dist, version, typ in self.find_packages_latest_versions(options):
222             if dist.parsed_version == version:
223                 uptodate.append(dist)
224         self.output_package_listing(uptodate)
225
```
--- 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()

```

diff --git a/pip/commands/list.py b/pip/commands/list.py
--- a/pip/commands/list.py
+++ b/pip/commands/list.py
@@ -4,7 +4,7 @@
 import warnings
 
 from pip.basecommand import Command
-from pip.exceptions import DistributionNotFound
+from pip.exceptions import CommandError, DistributionNotFound
 from pip.index import FormatControl, fmt_ctl_formats, PackageFinder, Search
 from pip.req import InstallRequirement
 from pip.utils import (
@@ -37,12 +37,12 @@
             '-o', '--outdated',
             action='store_true',
             default=False,
-            help='List outdated packages (excluding editables)')
+            help='List outdated packages')
         cmd_opts.add_option(
             '-u', '--uptodate',
             action='store_true',
             default=False,
-            help='List uptodate packages (excluding editables)')
+            help='List uptodate packages')
         cmd_opts.add_option(
             '-e', '--editable',
             action='store_true',
@@ -112,22 +112,25 @@
                 "no longer has any effect.",
                 RemovedInPip10Warning,
             )
+        if options.outdated and options.uptodate:
+            raise CommandError(
+                "Options --outdated and --uptodate cannot be combined.")
 
         if options.outdated:
             self.run_outdated(options)
         elif options.uptodate:
             self.run_uptodate(options)
-        elif options.editable:
-            self.run_editables(options)
         else:
             self.run_listing(options)
 
     def run_outdated(self, options):
-        for dist, version, typ in self.find_packages_latest_versions(options):
-            if version > dist.parsed_version:
+        for dist, latest_version, typ in sorted(
+                self.find_packages_latest_versions(options),
+                key=lambda p: p[0].project_name.lower()):
+            if latest_version > dist.parsed_version:
                 logger.info(
-                    '%s (Current: %s Latest: %s [%s])',
-                    dist.project_name, dist.version, version, typ,
+                    '%s - Latest: %s [%s]',
+                    self.output_package(dist), latest_version, typ,
                 )
 
     def find_packages_latest_versions(self, options):
@@ -137,8 +140,10 @@
             index_urls = []
 
         dependency_links = []
-        for dist in get_installed_distributions(local_only=options.local,
-                                                user_only=options.user):
+        for dist in get_installed_distributions(
+                local_only=options.local,
+                user_only=options.user,
+                editables_only=options.editable):
             if dist.has_metadata('dependency_links.txt'):
                 dependency_links.extend(
                     dist.get_metadata_lines('dependency_links.txt'),
@@ -151,7 +156,7 @@
             installed_packages = get_installed_distributions(
                 local_only=options.local,
                 user_only=options.user,
-                include_editables=False,
+                editables_only=options.editable,
             )
             format_control = FormatControl(set(), set())
             wheel_cache = WheelCache(options.cache_dir, format_control)
@@ -189,16 +194,19 @@
         installed_packages = get_installed_distributions(
             local_only=options.local,
             user_only=options.user,
+            editables_only=options.editable,
         )
         self.output_package_listing(installed_packages)
 
-    def run_editables(self, options):
-        installed_packages = get_installed_distributions(
-            local_only=options.local,
-            user_only=options.user,
-            editables_only=True,
-        )
-        self.output_package_listing(installed_packages)
+    def output_package(self, dist):
+        if dist_is_editable(dist):
+            return '%s (%s, %s)' % (
+                dist.project_name,
+                dist.version,
+                dist.location,
+            )
+        else:
+            return '%s (%s)' % (dist.project_name, dist.version)
 
     def output_package_listing(self, installed_packages):
         installed_packages = sorted(
@@ -206,15 +214,7 @@
             key=lambda dist: dist.project_name.lower(),
         )
         for dist in installed_packages:
-            if dist_is_editable(dist):
-                line = '%s (%s, %s)' % (
-                    dist.project_name,
-                    dist.version,
-                    dist.location,
-                )
-            else:
-                line = '%s (%s)' % (dist.project_name, dist.version)
-            logger.info(line)
+            logger.info(self.output_package(dist))
 
     def run_uptodate(self, options):
         uptodate = []

{"golden_diff": "diff --git a/pip/commands/list.py b/pip/commands/list.py\n--- a/pip/commands/list.py\n+++ b/pip/commands/list.py\n@@ -4,7 +4,7 @@\n import warnings\n \n from pip.basecommand import Command\n-from pip.exceptions import DistributionNotFound\n+from pip.exceptions import CommandError, DistributionNotFound\n from pip.index import FormatControl, fmt_ctl_formats, PackageFinder, Search\n from pip.req import InstallRequirement\n from pip.utils import (\n@@ -37,12 +37,12 @@\n             '-o', '--outdated',\n             action='store_true',\n             default=False,\n-            help='List outdated packages (excluding editables)')\n+            help='List outdated packages')\n         cmd_opts.add_option(\n             '-u', '--uptodate',\n             action='store_true',\n             default=False,\n-            help='List uptodate packages (excluding editables)')\n+            help='List uptodate packages')\n         cmd_opts.add_option(\n             '-e', '--editable',\n             action='store_true',\n@@ -112,22 +112,25 @@\n                 \"no longer has any effect.\",\n                 RemovedInPip10Warning,\n             )\n+        if options.outdated and options.uptodate:\n+            raise CommandError(\n+                \"Options --outdated and --uptodate cannot be combined.\")\n \n         if options.outdated:\n             self.run_outdated(options)\n         elif options.uptodate:\n             self.run_uptodate(options)\n-        elif options.editable:\n-            self.run_editables(options)\n         else:\n             self.run_listing(options)\n \n     def run_outdated(self, options):\n-        for dist, version, typ in self.find_packages_latest_versions(options):\n-            if version > dist.parsed_version:\n+        for dist, latest_version, typ in sorted(\n+                self.find_packages_latest_versions(options),\n+                key=lambda p: p[0].project_name.lower()):\n+            if latest_version > dist.parsed_version:\n                 logger.info(\n-                    '%s (Current: %s Latest: %s [%s])',\n-                    dist.project_name, dist.version, version, typ,\n+                    '%s - Latest: %s [%s]',\n+                    self.output_package(dist), latest_version, typ,\n                 )\n \n     def find_packages_latest_versions(self, options):\n@@ -137,8 +140,10 @@\n             index_urls = []\n \n         dependency_links = []\n-        for dist in get_installed_distributions(local_only=options.local,\n-                                                user_only=options.user):\n+        for dist in get_installed_distributions(\n+                local_only=options.local,\n+                user_only=options.user,\n+                editables_only=options.editable):\n             if dist.has_metadata('dependency_links.txt'):\n                 dependency_links.extend(\n                     dist.get_metadata_lines('dependency_links.txt'),\n@@ -151,7 +156,7 @@\n             installed_packages = get_installed_distributions(\n                 local_only=options.local,\n                 user_only=options.user,\n-                include_editables=False,\n+                editables_only=options.editable,\n             )\n             format_control = FormatControl(set(), set())\n             wheel_cache = WheelCache(options.cache_dir, format_control)\n@@ -189,16 +194,19 @@\n         installed_packages = get_installed_distributions(\n             local_only=options.local,\n             user_only=options.user,\n+            editables_only=options.editable,\n         )\n         self.output_package_listing(installed_packages)\n \n-    def run_editables(self, options):\n-        installed_packages = get_installed_distributions(\n-            local_only=options.local,\n-            user_only=options.user,\n-            editables_only=True,\n-        )\n-        self.output_package_listing(installed_packages)\n+    def output_package(self, dist):\n+        if dist_is_editable(dist):\n+            return '%s (%s, %s)' % (\n+                dist.project_name,\n+                dist.version,\n+                dist.location,\n+            )\n+        else:\n+            return '%s (%s)' % (dist.project_name, dist.version)\n \n     def output_package_listing(self, installed_packages):\n         installed_packages = sorted(\n@@ -206,15 +214,7 @@\n             key=lambda dist: dist.project_name.lower(),\n         )\n         for dist in installed_packages:\n-            if dist_is_editable(dist):\n-                line = '%s (%s, %s)' % (\n-                    dist.project_name,\n-                    dist.version,\n-                    dist.location,\n-                )\n-            else:\n-                line = '%s (%s)' % (dist.project_name, dist.version)\n-            logger.info(line)\n+            logger.info(self.output_package(dist))\n \n     def run_uptodate(self, options):\n         uptodate = []\n", "issue": "pip list outdated\nI install Flask version 0.8 with pip in editable mode \n\n`pip install -e git+https://github.com/mitsuhiko/flask.git@0.8#egg=flask`\n\nOutput of pip list \n\n```\nargparse (1.2.1)\nFlask (0.8dev-20130506, /home/pratz/VirtualEnv/learnflask/src/flask)\nJinja2 (2.6)\nWerkzeug (0.8.3)\nwsgiref (0.1.2)\n```\n\nOuput of pip list -o\nNothing ( returns to console without any output )\n\nShould not the output of pip list -o be\n`Flask (Current: 0.8dev Latest: 0.9)`\n\nOr is this how pip list -o works for editable mode ?\n\nNOTE: pip version is 1.3.1\n\n", "before_files": [{"content": "from __future__ import absolute_import\n\nimport logging\nimport warnings\n\nfrom pip.basecommand import Command\nfrom pip.exceptions import DistributionNotFound\nfrom pip.index import FormatControl, fmt_ctl_formats, PackageFinder, Search\nfrom pip.req import InstallRequirement\nfrom pip.utils import (\n    get_installed_distributions, dist_is_editable, canonicalize_name)\nfrom pip.utils.deprecation import RemovedInPip10Warning\nfrom pip.wheel import WheelCache\nfrom pip.cmdoptions import make_option_group, index_group\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass ListCommand(Command):\n    \"\"\"\n    List installed packages, including editables.\n\n    Packages are listed in a case-insensitive sorted order.\n    \"\"\"\n    name = 'list'\n    usage = \"\"\"\n      %prog [options]\"\"\"\n    summary = 'List installed packages.'\n\n    def __init__(self, *args, **kw):\n        super(ListCommand, self).__init__(*args, **kw)\n\n        cmd_opts = self.cmd_opts\n\n        cmd_opts.add_option(\n            '-o', '--outdated',\n            action='store_true',\n            default=False,\n            help='List outdated packages (excluding editables)')\n        cmd_opts.add_option(\n            '-u', '--uptodate',\n            action='store_true',\n            default=False,\n            help='List uptodate packages (excluding editables)')\n        cmd_opts.add_option(\n            '-e', '--editable',\n            action='store_true',\n            default=False,\n            help='List editable projects.')\n        cmd_opts.add_option(\n            '-l', '--local',\n            action='store_true',\n            default=False,\n            help=('If in a virtualenv that has global access, do not list '\n                  'globally-installed packages.'),\n        )\n        self.cmd_opts.add_option(\n            '--user',\n            dest='user',\n            action='store_true',\n            default=False,\n            help='Only output packages installed in user-site.')\n\n        cmd_opts.add_option(\n            '--pre',\n            action='store_true',\n            default=False,\n            help=(\"Include pre-release and development versions. By default, \"\n                  \"pip only finds stable versions.\"),\n        )\n\n        index_opts = make_option_group(index_group, self.parser)\n\n        self.parser.insert_option_group(0, index_opts)\n        self.parser.insert_option_group(0, cmd_opts)\n\n    def _build_package_finder(self, options, index_urls, session):\n        \"\"\"\n        Create a package finder appropriate to this list command.\n        \"\"\"\n        return PackageFinder(\n            find_links=options.find_links,\n            index_urls=index_urls,\n            allow_all_prereleases=options.pre,\n            trusted_hosts=options.trusted_hosts,\n            process_dependency_links=options.process_dependency_links,\n            session=session,\n        )\n\n    def run(self, options, args):\n        if options.allow_external:\n            warnings.warn(\n                \"--allow-external has been deprecated and will be removed in \"\n                \"the future. Due to changes in the repository protocol, it no \"\n                \"longer has any effect.\",\n                RemovedInPip10Warning,\n            )\n\n        if options.allow_all_external:\n            warnings.warn(\n                \"--allow-all-external has been deprecated and will be removed \"\n                \"in the future. Due to changes in the repository protocol, it \"\n                \"no longer has any effect.\",\n                RemovedInPip10Warning,\n            )\n\n        if options.allow_unverified:\n            warnings.warn(\n                \"--allow-unverified has been deprecated and will be removed \"\n                \"in the future. Due to changes in the repository protocol, it \"\n                \"no longer has any effect.\",\n                RemovedInPip10Warning,\n            )\n\n        if options.outdated:\n            self.run_outdated(options)\n        elif options.uptodate:\n            self.run_uptodate(options)\n        elif options.editable:\n            self.run_editables(options)\n        else:\n            self.run_listing(options)\n\n    def run_outdated(self, options):\n        for dist, version, typ in self.find_packages_latest_versions(options):\n            if version > dist.parsed_version:\n                logger.info(\n                    '%s (Current: %s Latest: %s [%s])',\n                    dist.project_name, dist.version, version, typ,\n                )\n\n    def find_packages_latest_versions(self, options):\n        index_urls = [options.index_url] + options.extra_index_urls\n        if options.no_index:\n            logger.info('Ignoring indexes: %s', ','.join(index_urls))\n            index_urls = []\n\n        dependency_links = []\n        for dist in get_installed_distributions(local_only=options.local,\n                                                user_only=options.user):\n            if dist.has_metadata('dependency_links.txt'):\n                dependency_links.extend(\n                    dist.get_metadata_lines('dependency_links.txt'),\n                )\n\n        with self._build_session(options) as session:\n            finder = self._build_package_finder(options, index_urls, session)\n            finder.add_dependency_links(dependency_links)\n\n            installed_packages = get_installed_distributions(\n                local_only=options.local,\n                user_only=options.user,\n                include_editables=False,\n            )\n            format_control = FormatControl(set(), set())\n            wheel_cache = WheelCache(options.cache_dir, format_control)\n            for dist in installed_packages:\n                req = InstallRequirement.from_line(\n                    dist.key, None, isolated=options.isolated_mode,\n                    wheel_cache=wheel_cache\n                )\n                typ = 'unknown'\n                try:\n                    link = finder.find_requirement(req, True)\n\n                    # If link is None, means installed version is most\n                    # up-to-date\n                    if link is None:\n                        continue\n                except DistributionNotFound:\n                    continue\n                else:\n                    canonical_name = canonicalize_name(req.name)\n                    formats = fmt_ctl_formats(format_control, canonical_name)\n                    search = Search(\n                        req.name,\n                        canonical_name,\n                        formats)\n                    remote_version = finder._link_package_versions(\n                        link, search).version\n                    if link.is_wheel:\n                        typ = 'wheel'\n                    else:\n                        typ = 'sdist'\n                yield dist, remote_version, typ\n\n    def run_listing(self, options):\n        installed_packages = get_installed_distributions(\n            local_only=options.local,\n            user_only=options.user,\n        )\n        self.output_package_listing(installed_packages)\n\n    def run_editables(self, options):\n        installed_packages = get_installed_distributions(\n            local_only=options.local,\n            user_only=options.user,\n            editables_only=True,\n        )\n        self.output_package_listing(installed_packages)\n\n    def output_package_listing(self, installed_packages):\n        installed_packages = sorted(\n            installed_packages,\n            key=lambda dist: dist.project_name.lower(),\n        )\n        for dist in installed_packages:\n            if dist_is_editable(dist):\n                line = '%s (%s, %s)' % (\n                    dist.project_name,\n                    dist.version,\n                    dist.location,\n                )\n            else:\n                line = '%s (%s)' % (dist.project_name, dist.version)\n            logger.info(line)\n\n    def run_uptodate(self, options):\n        uptodate = []\n        for dist, version, typ in self.find_packages_latest_versions(options):\n            if dist.parsed_version == version:\n                uptodate.append(dist)\n        self.output_package_listing(uptodate)\n", "path": "pip/commands/list.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nimport logging\nimport warnings\n\nfrom pip.basecommand import Command\nfrom pip.exceptions import CommandError, DistributionNotFound\nfrom pip.index import FormatControl, fmt_ctl_formats, PackageFinder, Search\nfrom pip.req import InstallRequirement\nfrom pip.utils import (\n    get_installed_distributions, dist_is_editable, canonicalize_name)\nfrom pip.utils.deprecation import RemovedInPip10Warning\nfrom pip.wheel import WheelCache\nfrom pip.cmdoptions import make_option_group, index_group\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass ListCommand(Command):\n    \"\"\"\n    List installed packages, including editables.\n\n    Packages are listed in a case-insensitive sorted order.\n    \"\"\"\n    name = 'list'\n    usage = \"\"\"\n      %prog [options]\"\"\"\n    summary = 'List installed packages.'\n\n    def __init__(self, *args, **kw):\n        super(ListCommand, self).__init__(*args, **kw)\n\n        cmd_opts = self.cmd_opts\n\n        cmd_opts.add_option(\n            '-o', '--outdated',\n            action='store_true',\n            default=False,\n            help='List outdated packages')\n        cmd_opts.add_option(\n            '-u', '--uptodate',\n            action='store_true',\n            default=False,\n            help='List uptodate packages')\n        cmd_opts.add_option(\n            '-e', '--editable',\n            action='store_true',\n            default=False,\n            help='List editable projects.')\n        cmd_opts.add_option(\n            '-l', '--local',\n            action='store_true',\n            default=False,\n            help=('If in a virtualenv that has global access, do not list '\n                  'globally-installed packages.'),\n        )\n        self.cmd_opts.add_option(\n            '--user',\n            dest='user',\n            action='store_true',\n            default=False,\n            help='Only output packages installed in user-site.')\n\n        cmd_opts.add_option(\n            '--pre',\n            action='store_true',\n            default=False,\n            help=(\"Include pre-release and development versions. By default, \"\n                  \"pip only finds stable versions.\"),\n        )\n\n        index_opts = make_option_group(index_group, self.parser)\n\n        self.parser.insert_option_group(0, index_opts)\n        self.parser.insert_option_group(0, cmd_opts)\n\n    def _build_package_finder(self, options, index_urls, session):\n        \"\"\"\n        Create a package finder appropriate to this list command.\n        \"\"\"\n        return PackageFinder(\n            find_links=options.find_links,\n            index_urls=index_urls,\n            allow_all_prereleases=options.pre,\n            trusted_hosts=options.trusted_hosts,\n            process_dependency_links=options.process_dependency_links,\n            session=session,\n        )\n\n    def run(self, options, args):\n        if options.allow_external:\n            warnings.warn(\n                \"--allow-external has been deprecated and will be removed in \"\n                \"the future. Due to changes in the repository protocol, it no \"\n                \"longer has any effect.\",\n                RemovedInPip10Warning,\n            )\n\n        if options.allow_all_external:\n            warnings.warn(\n                \"--allow-all-external has been deprecated and will be removed \"\n                \"in the future. Due to changes in the repository protocol, it \"\n                \"no longer has any effect.\",\n                RemovedInPip10Warning,\n            )\n\n        if options.allow_unverified:\n            warnings.warn(\n                \"--allow-unverified has been deprecated and will be removed \"\n                \"in the future. Due to changes in the repository protocol, it \"\n                \"no longer has any effect.\",\n                RemovedInPip10Warning,\n            )\n        if options.outdated and options.uptodate:\n            raise CommandError(\n                \"Options --outdated and --uptodate cannot be combined.\")\n\n        if options.outdated:\n            self.run_outdated(options)\n        elif options.uptodate:\n            self.run_uptodate(options)\n        else:\n            self.run_listing(options)\n\n    def run_outdated(self, options):\n        for dist, latest_version, typ in sorted(\n                self.find_packages_latest_versions(options),\n                key=lambda p: p[0].project_name.lower()):\n            if latest_version > dist.parsed_version:\n                logger.info(\n                    '%s - Latest: %s [%s]',\n                    self.output_package(dist), latest_version, typ,\n                )\n\n    def find_packages_latest_versions(self, options):\n        index_urls = [options.index_url] + options.extra_index_urls\n        if options.no_index:\n            logger.info('Ignoring indexes: %s', ','.join(index_urls))\n            index_urls = []\n\n        dependency_links = []\n        for dist in get_installed_distributions(\n                local_only=options.local,\n                user_only=options.user,\n                editables_only=options.editable):\n            if dist.has_metadata('dependency_links.txt'):\n                dependency_links.extend(\n                    dist.get_metadata_lines('dependency_links.txt'),\n                )\n\n        with self._build_session(options) as session:\n            finder = self._build_package_finder(options, index_urls, session)\n            finder.add_dependency_links(dependency_links)\n\n            installed_packages = get_installed_distributions(\n                local_only=options.local,\n                user_only=options.user,\n                editables_only=options.editable,\n            )\n            format_control = FormatControl(set(), set())\n            wheel_cache = WheelCache(options.cache_dir, format_control)\n            for dist in installed_packages:\n                req = InstallRequirement.from_line(\n                    dist.key, None, isolated=options.isolated_mode,\n                    wheel_cache=wheel_cache\n                )\n                typ = 'unknown'\n                try:\n                    link = finder.find_requirement(req, True)\n\n                    # If link is None, means installed version is most\n                    # up-to-date\n                    if link is None:\n                        continue\n                except DistributionNotFound:\n                    continue\n                else:\n                    canonical_name = canonicalize_name(req.name)\n                    formats = fmt_ctl_formats(format_control, canonical_name)\n                    search = Search(\n                        req.name,\n                        canonical_name,\n                        formats)\n                    remote_version = finder._link_package_versions(\n                        link, search).version\n                    if link.is_wheel:\n                        typ = 'wheel'\n                    else:\n                        typ = 'sdist'\n                yield dist, remote_version, typ\n\n    def run_listing(self, options):\n        installed_packages = get_installed_distributions(\n            local_only=options.local,\n            user_only=options.user,\n            editables_only=options.editable,\n        )\n        self.output_package_listing(installed_packages)\n\n    def output_package(self, dist):\n        if dist_is_editable(dist):\n            return '%s (%s, %s)' % (\n                dist.project_name,\n                dist.version,\n                dist.location,\n            )\n        else:\n            return '%s (%s)' % (dist.project_name, dist.version)\n\n    def output_package_listing(self, installed_packages):\n        installed_packages = sorted(\n            installed_packages,\n            key=lambda dist: dist.project_name.lower(),\n        )\n        for dist in installed_packages:\n            logger.info(self.output_package(dist))\n\n    def run_uptodate(self, options):\n        uptodate = []\n        for dist, version, typ in self.find_packages_latest_versions(options):\n            if dist.parsed_version == version:\n                uptodate.append(dist)\n        self.output_package_listing(uptodate)\n", "path": "pip/commands/list.py"}]}