We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Unnamed editable dependency raises AttributeError on second run
An editable dependency without a name raises an AttributeError when pip-compile is run the second time without the --upgrade flag.

##### Environment Versions

1. CentOS 7
1. Python version: Python 3.5.2
1. pip version:  pip 9.0.1
1. pip-tools version: pip-compile, version 1.8.1

##### Steps to replicate
foo.in:

```
-e .
```
run:

```
pip-compile foo.in
pip-compile foo.in
```

##### Expected result

```
#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file foo.txt foo.in
#
-e file:///home/eric/projects/foo
```
(Well, not really the *hoped for* result due to #204.)
##### Actual result

```
Traceback (most recent call last):
  File "/home/eric/projects/foo/.env/bin/pip-compile", line 11, in <module>
    sys.exit(cli())
  File "/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/home/eric/projects/foo/.env/lib64/python3.5/site-packages/piptools/scripts/compile.py", line 139, in cli
    key = key_from_req(ireq.req)
  File "/home/eric/projects/foo/.env/lib64/python3.5/site-packages/piptools/utils.py", line 41, in key_from_req
    key = req.name
AttributeError: 'NoneType' object has no attribute 'name'
```
I think this could be fixed in compile.py (around line 138) by waiting to see if `is_pinned_requirement` returns True before trying to get the key. Something like...

```
        for ireq in ireqs:

            if is_pinned_requirement(ireq):
                key = key_from_req(ireq.req)
                existing_pins[key] = ireq
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `piptools/scripts/compile.py`
Content:
```
1 # coding: utf-8
2 from __future__ import (absolute_import, division, print_function,
3                         unicode_literals)
4 
5 import optparse
6 import os
7 import sys
8 import tempfile
9 from collections import OrderedDict
10 
11 import pip
12 from pip.req import InstallRequirement, parse_requirements
13 
14 from .. import click
15 from ..exceptions import PipToolsError
16 from ..logging import log
17 from ..repositories import LocalRequirementsRepository, PyPIRepository
18 from ..resolver import Resolver
19 from ..utils import (assert_compatible_pip_version, is_pinned_requirement,
20                      key_from_req)
21 from ..writer import OutputWriter
22 
23 # Make sure we're using a compatible version of pip
24 assert_compatible_pip_version()
25 
26 DEFAULT_REQUIREMENTS_FILE = 'requirements.in'
27 
28 
29 class PipCommand(pip.basecommand.Command):
30     name = 'PipCommand'
31 
32 
33 @click.command()
34 @click.version_option()
35 @click.option('-v', '--verbose', is_flag=True, help="Show more output")
36 @click.option('-n', '--dry-run', is_flag=True, help="Only show what would happen, don't change anything")
37 @click.option('-p', '--pre', is_flag=True, default=None, help="Allow resolving to prereleases (default is not)")
38 @click.option('-r', '--rebuild', is_flag=True, help="Clear any caches upfront, rebuild from scratch")
39 @click.option('-f', '--find-links', multiple=True, help="Look for archives in this directory or on this HTML page", envvar='PIP_FIND_LINKS')  # noqa
40 @click.option('-i', '--index-url', help="Change index URL (defaults to PyPI)", envvar='PIP_INDEX_URL')
41 @click.option('--extra-index-url', multiple=True, help="Add additional index URL to search", envvar='PIP_EXTRA_INDEX_URL')  # noqa
42 @click.option('--client-cert', help="Path to SSL client certificate, a single file containing the private key and the certificate in PEM format.")  # noqa
43 @click.option('--trusted-host', multiple=True, envvar='PIP_TRUSTED_HOST',
44               help="Mark this host as trusted, even though it does not have "
45                    "valid or any HTTPS.")
46 @click.option('--header/--no-header', is_flag=True, default=True,
47               help="Add header to generated file")
48 @click.option('--index/--no-index', is_flag=True, default=True,
49               help="Add index URL to generated file")
50 @click.option('--annotate/--no-annotate', is_flag=True, default=True,
51               help="Annotate results, indicating where dependencies come from")
52 @click.option('-U', '--upgrade', is_flag=True, default=False,
53               help='Try to upgrade all dependencies to their latest versions')
54 @click.option('-P', '--upgrade-package', 'upgrade_packages', nargs=1, multiple=True,
55               help="Specify particular packages to upgrade.")
56 @click.option('-o', '--output-file', nargs=1, type=str, default=None,
57               help=('Output file name. Required if more than one input file is given. '
58                     'Will be derived from input file otherwise.'))
59 @click.option('--allow-unsafe', is_flag=True, default=False,
60               help="Pin packages considered unsafe: pip, setuptools & distribute")
61 @click.option('--generate-hashes', is_flag=True, default=False,
62               help="Generate pip 8 style hashes in the resulting requirements file.")
63 @click.option('--max-rounds', default=10,
64               help="Maximum number of rounds before resolving the requirements aborts.")
65 @click.argument('src_files', nargs=-1, type=click.Path(exists=True, allow_dash=True))
66 def cli(verbose, dry_run, pre, rebuild, find_links, index_url, extra_index_url,
67         client_cert, trusted_host, header, index, annotate, upgrade, upgrade_packages,
68         output_file, allow_unsafe, generate_hashes, src_files, max_rounds):
69     """Compiles requirements.txt from requirements.in specs."""
70     log.verbose = verbose
71 
72     if len(src_files) == 0:
73         if os.path.exists(DEFAULT_REQUIREMENTS_FILE):
74             src_files = (DEFAULT_REQUIREMENTS_FILE,)
75         elif os.path.exists('setup.py'):
76             src_files = ('setup.py',)
77             if not output_file:
78                 output_file = 'requirements.txt'
79         else:
80             raise click.BadParameter(("If you do not specify an input file, "
81                                       "the default is {} or setup.py").format(DEFAULT_REQUIREMENTS_FILE))
82 
83     if len(src_files) == 1 and src_files[0] == '-':
84         if not output_file:
85             raise click.BadParameter('--output-file is required if input is from stdin')
86 
87     if len(src_files) > 1 and not output_file:
88         raise click.BadParameter('--output-file is required if two or more input files are given.')
89 
90     if output_file:
91         dst_file = output_file
92     else:
93         base_name, _, _ = src_files[0].rpartition('.')
94         dst_file = base_name + '.txt'
95 
96     if upgrade and upgrade_packages:
97         raise click.BadParameter('Only one of --upgrade or --upgrade-package can be provided as an argument.')
98 
99     ###
100     # Setup
101     ###
102 
103     pip_command = get_pip_command()
104 
105     pip_args = []
106     if find_links:
107         for link in find_links:
108             pip_args.extend(['-f', link])
109     if index_url:
110         pip_args.extend(['-i', index_url])
111     if extra_index_url:
112         for extra_index in extra_index_url:
113             pip_args.extend(['--extra-index-url', extra_index])
114     if client_cert:
115         pip_args.extend(['--client-cert', client_cert])
116     if pre:
117         pip_args.extend(['--pre'])
118     if trusted_host:
119         for host in trusted_host:
120             pip_args.extend(['--trusted-host', host])
121 
122     pip_options, _ = pip_command.parse_args(pip_args)
123 
124     session = pip_command._build_session(pip_options)
125     repository = PyPIRepository(pip_options, session)
126 
127     # Pre-parse the inline package upgrade specs: they should take precedence
128     # over the stuff in the requirements files
129     upgrade_packages = [InstallRequirement.from_line(pkg)
130                         for pkg in upgrade_packages]
131 
132     # Proxy with a LocalRequirementsRepository if --upgrade is not specified
133     # (= default invocation)
134     if not (upgrade or upgrade_packages) and os.path.exists(dst_file):
135         existing_pins = {}
136         ireqs = parse_requirements(dst_file, finder=repository.finder, session=repository.session, options=pip_options)
137         for ireq in ireqs:
138             key = key_from_req(ireq.req)
139 
140             if is_pinned_requirement(ireq):
141                 existing_pins[key] = ireq
142         repository = LocalRequirementsRepository(existing_pins, repository)
143 
144     log.debug('Using indexes:')
145     # remove duplicate index urls before processing
146     repository.finder.index_urls = list(OrderedDict.fromkeys(repository.finder.index_urls))
147     for index_url in repository.finder.index_urls:
148         log.debug('  {}'.format(index_url))
149 
150     if repository.finder.find_links:
151         log.debug('')
152         log.debug('Configuration:')
153         for find_link in repository.finder.find_links:
154             log.debug('  -f {}'.format(find_link))
155 
156     ###
157     # Parsing/collecting initial requirements
158     ###
159 
160     constraints = []
161     for src_file in src_files:
162         is_setup_file = os.path.basename(src_file) == 'setup.py'
163         if is_setup_file or src_file == '-':
164             # pip requires filenames and not files. Since we want to support
165             # piping from stdin, we need to briefly save the input from stdin
166             # to a temporary file and have pip read that.  also used for
167             # reading requirements from install_requires in setup.py.
168             tmpfile = tempfile.NamedTemporaryFile(mode='wt', delete=False)
169             if is_setup_file:
170                 from distutils.core import run_setup
171                 dist = run_setup(src_file)
172                 tmpfile.write('\n'.join(dist.install_requires))
173             else:
174                 tmpfile.write(sys.stdin.read())
175             tmpfile.flush()
176             constraints.extend(parse_requirements(
177                 tmpfile.name, finder=repository.finder, session=repository.session, options=pip_options))
178         else:
179             constraints.extend(parse_requirements(
180                 src_file, finder=repository.finder, session=repository.session, options=pip_options))
181 
182     try:
183         resolver = Resolver(constraints, repository, prereleases=pre,
184                             clear_caches=rebuild, allow_unsafe=allow_unsafe)
185         results = resolver.resolve(max_rounds=max_rounds)
186         if generate_hashes:
187             hashes = resolver.resolve_hashes(results)
188         else:
189             hashes = None
190     except PipToolsError as e:
191         log.error(str(e))
192         sys.exit(2)
193 
194     log.debug('')
195 
196     ##
197     # Output
198     ##
199 
200     # Compute reverse dependency annotations statically, from the
201     # dependency cache that the resolver has populated by now.
202     #
203     # TODO (1a): reverse deps for any editable package are lost
204     #            what SHOULD happen is that they are cached in memory, just
205     #            not persisted to disk!
206     #
207     # TODO (1b): perhaps it's easiest if the dependency cache has an API
208     #            that could take InstallRequirements directly, like:
209     #
210     #                cache.set(ireq, ...)
211     #
212     #            then, when ireq is editable, it would store in
213     #
214     #              editables[egg_name][link_without_fragment] = deps
215     #              editables['pip-tools']['git+...ols.git@future'] = {'click>=3.0', 'six'}
216     #
217     #            otherwise:
218     #
219     #              self[as_name_version_tuple(ireq)] = {'click>=3.0', 'six'}
220     #
221     reverse_dependencies = None
222     if annotate:
223         reverse_dependencies = resolver.reverse_dependencies(results)
224 
225     writer = OutputWriter(src_files, dst_file, dry_run=dry_run,
226                           emit_header=header, emit_index=index,
227                           annotate=annotate,
228                           generate_hashes=generate_hashes,
229                           default_index_url=repository.DEFAULT_INDEX_URL,
230                           index_urls=repository.finder.index_urls,
231                           trusted_hosts=pip_options.trusted_hosts,
232                           format_control=repository.finder.format_control)
233     writer.write(results=results,
234                  reverse_dependencies=reverse_dependencies,
235                  primary_packages={key_from_req(ireq.req) for ireq in constraints},
236                  markers={key_from_req(ireq.req): ireq.markers
237                           for ireq in constraints if ireq.markers},
238                  hashes=hashes)
239 
240     if dry_run:
241         log.warning('Dry-run, so nothing updated.')
242 
243 
244 def get_pip_command():
245     # Use pip's parser for pip.conf management and defaults.
246     # General options (find_links, index_url, extra_index_url, trusted_host,
247     # and pre) are defered to pip.
248     pip_command = PipCommand()
249     index_opts = pip.cmdoptions.make_option_group(
250         pip.cmdoptions.index_group,
251         pip_command.parser,
252     )
253     pip_command.parser.insert_option_group(0, index_opts)
254     pip_command.parser.add_option(optparse.Option('--pre', action='store_true', default=False))
255 
256     return pip_command
257
```
--- 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/piptools/scripts/compile.py b/piptools/scripts/compile.py
--- a/piptools/scripts/compile.py
+++ b/piptools/scripts/compile.py
@@ -132,13 +132,8 @@
     # Proxy with a LocalRequirementsRepository if --upgrade is not specified
     # (= default invocation)
     if not (upgrade or upgrade_packages) and os.path.exists(dst_file):
-        existing_pins = {}
         ireqs = parse_requirements(dst_file, finder=repository.finder, session=repository.session, options=pip_options)
-        for ireq in ireqs:
-            key = key_from_req(ireq.req)
-
-            if is_pinned_requirement(ireq):
-                existing_pins[key] = ireq
+        existing_pins = {key_from_req(ireq.req): ireq for ireq in ireqs if is_pinned_requirement(ireq)}
         repository = LocalRequirementsRepository(existing_pins, repository)
 
     log.debug('Using indexes:')

{"golden_diff": "diff --git a/piptools/scripts/compile.py b/piptools/scripts/compile.py\n--- a/piptools/scripts/compile.py\n+++ b/piptools/scripts/compile.py\n@@ -132,13 +132,8 @@\n     # Proxy with a LocalRequirementsRepository if --upgrade is not specified\n     # (= default invocation)\n     if not (upgrade or upgrade_packages) and os.path.exists(dst_file):\n-        existing_pins = {}\n         ireqs = parse_requirements(dst_file, finder=repository.finder, session=repository.session, options=pip_options)\n-        for ireq in ireqs:\n-            key = key_from_req(ireq.req)\n-\n-            if is_pinned_requirement(ireq):\n-                existing_pins[key] = ireq\n+        existing_pins = {key_from_req(ireq.req): ireq for ireq in ireqs if is_pinned_requirement(ireq)}\n         repository = LocalRequirementsRepository(existing_pins, repository)\n \n     log.debug('Using indexes:')\n", "issue": "Unnamed editable dependency raises AttributeError on second run\nAn editable dependency without a name raises an AttributeError when pip-compile is run the second time without the --upgrade flag.\r\n\r\n##### Environment Versions\r\n\r\n1. CentOS 7\r\n1. Python version: Python 3.5.2\r\n1. pip version:  pip 9.0.1\r\n1. pip-tools version: pip-compile, version 1.8.1\r\n\r\n##### Steps to replicate\r\nfoo.in:\r\n\r\n```\r\n-e .\r\n```\r\nrun:\r\n\r\n```\r\npip-compile foo.in\r\npip-compile foo.in\r\n```\r\n\r\n##### Expected result\r\n\r\n```\r\n#\r\n# This file is autogenerated by pip-compile\r\n# To update, run:\r\n#\r\n#    pip-compile --output-file foo.txt foo.in\r\n#\r\n-e file:///home/eric/projects/foo\r\n```\r\n(Well, not really the *hoped for* result due to #204.)\r\n##### Actual result\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"/home/eric/projects/foo/.env/bin/pip-compile\", line 11, in <module>\r\n    sys.exit(cli())\r\n  File \"/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py\", line 722, in __call__\r\n    return self.main(*args, **kwargs)\r\n  File \"/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py\", line 697, in main\r\n    rv = self.invoke(ctx)\r\n  File \"/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py\", line 895, in invoke\r\n    return ctx.invoke(self.callback, **ctx.params)\r\n  File \"/home/eric/projects/foo/.env/lib64/python3.5/site-packages/click/core.py\", line 535, in invoke\r\n    return callback(*args, **kwargs)\r\n  File \"/home/eric/projects/foo/.env/lib64/python3.5/site-packages/piptools/scripts/compile.py\", line 139, in cli\r\n    key = key_from_req(ireq.req)\r\n  File \"/home/eric/projects/foo/.env/lib64/python3.5/site-packages/piptools/utils.py\", line 41, in key_from_req\r\n    key = req.name\r\nAttributeError: 'NoneType' object has no attribute 'name'\r\n```\r\nI think this could be fixed in compile.py (around line 138) by waiting to see if `is_pinned_requirement` returns True before trying to get the key. Something like...\r\n\r\n```\r\n        for ireq in ireqs:\r\n\r\n            if is_pinned_requirement(ireq):\r\n                key = key_from_req(ireq.req)\r\n                existing_pins[key] = ireq\r\n```\n", "before_files": [{"content": "# coding: utf-8\nfrom __future__ import (absolute_import, division, print_function,\n                        unicode_literals)\n\nimport optparse\nimport os\nimport sys\nimport tempfile\nfrom collections import OrderedDict\n\nimport pip\nfrom pip.req import InstallRequirement, parse_requirements\n\nfrom .. import click\nfrom ..exceptions import PipToolsError\nfrom ..logging import log\nfrom ..repositories import LocalRequirementsRepository, PyPIRepository\nfrom ..resolver import Resolver\nfrom ..utils import (assert_compatible_pip_version, is_pinned_requirement,\n                     key_from_req)\nfrom ..writer import OutputWriter\n\n# Make sure we're using a compatible version of pip\nassert_compatible_pip_version()\n\nDEFAULT_REQUIREMENTS_FILE = 'requirements.in'\n\n\nclass PipCommand(pip.basecommand.Command):\n    name = 'PipCommand'\n\n\n@click.command()\n@click.version_option()\n@click.option('-v', '--verbose', is_flag=True, help=\"Show more output\")\n@click.option('-n', '--dry-run', is_flag=True, help=\"Only show what would happen, don't change anything\")\n@click.option('-p', '--pre', is_flag=True, default=None, help=\"Allow resolving to prereleases (default is not)\")\n@click.option('-r', '--rebuild', is_flag=True, help=\"Clear any caches upfront, rebuild from scratch\")\n@click.option('-f', '--find-links', multiple=True, help=\"Look for archives in this directory or on this HTML page\", envvar='PIP_FIND_LINKS')  # noqa\n@click.option('-i', '--index-url', help=\"Change index URL (defaults to PyPI)\", envvar='PIP_INDEX_URL')\n@click.option('--extra-index-url', multiple=True, help=\"Add additional index URL to search\", envvar='PIP_EXTRA_INDEX_URL')  # noqa\n@click.option('--client-cert', help=\"Path to SSL client certificate, a single file containing the private key and the certificate in PEM format.\")  # noqa\n@click.option('--trusted-host', multiple=True, envvar='PIP_TRUSTED_HOST',\n              help=\"Mark this host as trusted, even though it does not have \"\n                   \"valid or any HTTPS.\")\n@click.option('--header/--no-header', is_flag=True, default=True,\n              help=\"Add header to generated file\")\n@click.option('--index/--no-index', is_flag=True, default=True,\n              help=\"Add index URL to generated file\")\n@click.option('--annotate/--no-annotate', is_flag=True, default=True,\n              help=\"Annotate results, indicating where dependencies come from\")\n@click.option('-U', '--upgrade', is_flag=True, default=False,\n              help='Try to upgrade all dependencies to their latest versions')\n@click.option('-P', '--upgrade-package', 'upgrade_packages', nargs=1, multiple=True,\n              help=\"Specify particular packages to upgrade.\")\n@click.option('-o', '--output-file', nargs=1, type=str, default=None,\n              help=('Output file name. Required if more than one input file is given. '\n                    'Will be derived from input file otherwise.'))\n@click.option('--allow-unsafe', is_flag=True, default=False,\n              help=\"Pin packages considered unsafe: pip, setuptools & distribute\")\n@click.option('--generate-hashes', is_flag=True, default=False,\n              help=\"Generate pip 8 style hashes in the resulting requirements file.\")\n@click.option('--max-rounds', default=10,\n              help=\"Maximum number of rounds before resolving the requirements aborts.\")\n@click.argument('src_files', nargs=-1, type=click.Path(exists=True, allow_dash=True))\ndef cli(verbose, dry_run, pre, rebuild, find_links, index_url, extra_index_url,\n        client_cert, trusted_host, header, index, annotate, upgrade, upgrade_packages,\n        output_file, allow_unsafe, generate_hashes, src_files, max_rounds):\n    \"\"\"Compiles requirements.txt from requirements.in specs.\"\"\"\n    log.verbose = verbose\n\n    if len(src_files) == 0:\n        if os.path.exists(DEFAULT_REQUIREMENTS_FILE):\n            src_files = (DEFAULT_REQUIREMENTS_FILE,)\n        elif os.path.exists('setup.py'):\n            src_files = ('setup.py',)\n            if not output_file:\n                output_file = 'requirements.txt'\n        else:\n            raise click.BadParameter((\"If you do not specify an input file, \"\n                                      \"the default is {} or setup.py\").format(DEFAULT_REQUIREMENTS_FILE))\n\n    if len(src_files) == 1 and src_files[0] == '-':\n        if not output_file:\n            raise click.BadParameter('--output-file is required if input is from stdin')\n\n    if len(src_files) > 1 and not output_file:\n        raise click.BadParameter('--output-file is required if two or more input files are given.')\n\n    if output_file:\n        dst_file = output_file\n    else:\n        base_name, _, _ = src_files[0].rpartition('.')\n        dst_file = base_name + '.txt'\n\n    if upgrade and upgrade_packages:\n        raise click.BadParameter('Only one of --upgrade or --upgrade-package can be provided as an argument.')\n\n    ###\n    # Setup\n    ###\n\n    pip_command = get_pip_command()\n\n    pip_args = []\n    if find_links:\n        for link in find_links:\n            pip_args.extend(['-f', link])\n    if index_url:\n        pip_args.extend(['-i', index_url])\n    if extra_index_url:\n        for extra_index in extra_index_url:\n            pip_args.extend(['--extra-index-url', extra_index])\n    if client_cert:\n        pip_args.extend(['--client-cert', client_cert])\n    if pre:\n        pip_args.extend(['--pre'])\n    if trusted_host:\n        for host in trusted_host:\n            pip_args.extend(['--trusted-host', host])\n\n    pip_options, _ = pip_command.parse_args(pip_args)\n\n    session = pip_command._build_session(pip_options)\n    repository = PyPIRepository(pip_options, session)\n\n    # Pre-parse the inline package upgrade specs: they should take precedence\n    # over the stuff in the requirements files\n    upgrade_packages = [InstallRequirement.from_line(pkg)\n                        for pkg in upgrade_packages]\n\n    # Proxy with a LocalRequirementsRepository if --upgrade is not specified\n    # (= default invocation)\n    if not (upgrade or upgrade_packages) and os.path.exists(dst_file):\n        existing_pins = {}\n        ireqs = parse_requirements(dst_file, finder=repository.finder, session=repository.session, options=pip_options)\n        for ireq in ireqs:\n            key = key_from_req(ireq.req)\n\n            if is_pinned_requirement(ireq):\n                existing_pins[key] = ireq\n        repository = LocalRequirementsRepository(existing_pins, repository)\n\n    log.debug('Using indexes:')\n    # remove duplicate index urls before processing\n    repository.finder.index_urls = list(OrderedDict.fromkeys(repository.finder.index_urls))\n    for index_url in repository.finder.index_urls:\n        log.debug('  {}'.format(index_url))\n\n    if repository.finder.find_links:\n        log.debug('')\n        log.debug('Configuration:')\n        for find_link in repository.finder.find_links:\n            log.debug('  -f {}'.format(find_link))\n\n    ###\n    # Parsing/collecting initial requirements\n    ###\n\n    constraints = []\n    for src_file in src_files:\n        is_setup_file = os.path.basename(src_file) == 'setup.py'\n        if is_setup_file or src_file == '-':\n            # pip requires filenames and not files. Since we want to support\n            # piping from stdin, we need to briefly save the input from stdin\n            # to a temporary file and have pip read that.  also used for\n            # reading requirements from install_requires in setup.py.\n            tmpfile = tempfile.NamedTemporaryFile(mode='wt', delete=False)\n            if is_setup_file:\n                from distutils.core import run_setup\n                dist = run_setup(src_file)\n                tmpfile.write('\\n'.join(dist.install_requires))\n            else:\n                tmpfile.write(sys.stdin.read())\n            tmpfile.flush()\n            constraints.extend(parse_requirements(\n                tmpfile.name, finder=repository.finder, session=repository.session, options=pip_options))\n        else:\n            constraints.extend(parse_requirements(\n                src_file, finder=repository.finder, session=repository.session, options=pip_options))\n\n    try:\n        resolver = Resolver(constraints, repository, prereleases=pre,\n                            clear_caches=rebuild, allow_unsafe=allow_unsafe)\n        results = resolver.resolve(max_rounds=max_rounds)\n        if generate_hashes:\n            hashes = resolver.resolve_hashes(results)\n        else:\n            hashes = None\n    except PipToolsError as e:\n        log.error(str(e))\n        sys.exit(2)\n\n    log.debug('')\n\n    ##\n    # Output\n    ##\n\n    # Compute reverse dependency annotations statically, from the\n    # dependency cache that the resolver has populated by now.\n    #\n    # TODO (1a): reverse deps for any editable package are lost\n    #            what SHOULD happen is that they are cached in memory, just\n    #            not persisted to disk!\n    #\n    # TODO (1b): perhaps it's easiest if the dependency cache has an API\n    #            that could take InstallRequirements directly, like:\n    #\n    #                cache.set(ireq, ...)\n    #\n    #            then, when ireq is editable, it would store in\n    #\n    #              editables[egg_name][link_without_fragment] = deps\n    #              editables['pip-tools']['git+...ols.git@future'] = {'click>=3.0', 'six'}\n    #\n    #            otherwise:\n    #\n    #              self[as_name_version_tuple(ireq)] = {'click>=3.0', 'six'}\n    #\n    reverse_dependencies = None\n    if annotate:\n        reverse_dependencies = resolver.reverse_dependencies(results)\n\n    writer = OutputWriter(src_files, dst_file, dry_run=dry_run,\n                          emit_header=header, emit_index=index,\n                          annotate=annotate,\n                          generate_hashes=generate_hashes,\n                          default_index_url=repository.DEFAULT_INDEX_URL,\n                          index_urls=repository.finder.index_urls,\n                          trusted_hosts=pip_options.trusted_hosts,\n                          format_control=repository.finder.format_control)\n    writer.write(results=results,\n                 reverse_dependencies=reverse_dependencies,\n                 primary_packages={key_from_req(ireq.req) for ireq in constraints},\n                 markers={key_from_req(ireq.req): ireq.markers\n                          for ireq in constraints if ireq.markers},\n                 hashes=hashes)\n\n    if dry_run:\n        log.warning('Dry-run, so nothing updated.')\n\n\ndef get_pip_command():\n    # Use pip's parser for pip.conf management and defaults.\n    # General options (find_links, index_url, extra_index_url, trusted_host,\n    # and pre) are defered to pip.\n    pip_command = PipCommand()\n    index_opts = pip.cmdoptions.make_option_group(\n        pip.cmdoptions.index_group,\n        pip_command.parser,\n    )\n    pip_command.parser.insert_option_group(0, index_opts)\n    pip_command.parser.add_option(optparse.Option('--pre', action='store_true', default=False))\n\n    return pip_command\n", "path": "piptools/scripts/compile.py"}], "after_files": [{"content": "# coding: utf-8\nfrom __future__ import (absolute_import, division, print_function,\n                        unicode_literals)\n\nimport optparse\nimport os\nimport sys\nimport tempfile\nfrom collections import OrderedDict\n\nimport pip\nfrom pip.req import InstallRequirement, parse_requirements\n\nfrom .. import click\nfrom ..exceptions import PipToolsError\nfrom ..logging import log\nfrom ..repositories import LocalRequirementsRepository, PyPIRepository\nfrom ..resolver import Resolver\nfrom ..utils import (assert_compatible_pip_version, is_pinned_requirement,\n                     key_from_req)\nfrom ..writer import OutputWriter\n\n# Make sure we're using a compatible version of pip\nassert_compatible_pip_version()\n\nDEFAULT_REQUIREMENTS_FILE = 'requirements.in'\n\n\nclass PipCommand(pip.basecommand.Command):\n    name = 'PipCommand'\n\n\n@click.command()\n@click.version_option()\n@click.option('-v', '--verbose', is_flag=True, help=\"Show more output\")\n@click.option('-n', '--dry-run', is_flag=True, help=\"Only show what would happen, don't change anything\")\n@click.option('-p', '--pre', is_flag=True, default=None, help=\"Allow resolving to prereleases (default is not)\")\n@click.option('-r', '--rebuild', is_flag=True, help=\"Clear any caches upfront, rebuild from scratch\")\n@click.option('-f', '--find-links', multiple=True, help=\"Look for archives in this directory or on this HTML page\", envvar='PIP_FIND_LINKS')  # noqa\n@click.option('-i', '--index-url', help=\"Change index URL (defaults to PyPI)\", envvar='PIP_INDEX_URL')\n@click.option('--extra-index-url', multiple=True, help=\"Add additional index URL to search\", envvar='PIP_EXTRA_INDEX_URL')  # noqa\n@click.option('--client-cert', help=\"Path to SSL client certificate, a single file containing the private key and the certificate in PEM format.\")  # noqa\n@click.option('--trusted-host', multiple=True, envvar='PIP_TRUSTED_HOST',\n              help=\"Mark this host as trusted, even though it does not have \"\n                   \"valid or any HTTPS.\")\n@click.option('--header/--no-header', is_flag=True, default=True,\n              help=\"Add header to generated file\")\n@click.option('--index/--no-index', is_flag=True, default=True,\n              help=\"Add index URL to generated file\")\n@click.option('--annotate/--no-annotate', is_flag=True, default=True,\n              help=\"Annotate results, indicating where dependencies come from\")\n@click.option('-U', '--upgrade', is_flag=True, default=False,\n              help='Try to upgrade all dependencies to their latest versions')\n@click.option('-P', '--upgrade-package', 'upgrade_packages', nargs=1, multiple=True,\n              help=\"Specify particular packages to upgrade.\")\n@click.option('-o', '--output-file', nargs=1, type=str, default=None,\n              help=('Output file name. Required if more than one input file is given. '\n                    'Will be derived from input file otherwise.'))\n@click.option('--allow-unsafe', is_flag=True, default=False,\n              help=\"Pin packages considered unsafe: pip, setuptools & distribute\")\n@click.option('--generate-hashes', is_flag=True, default=False,\n              help=\"Generate pip 8 style hashes in the resulting requirements file.\")\n@click.option('--max-rounds', default=10,\n              help=\"Maximum number of rounds before resolving the requirements aborts.\")\n@click.argument('src_files', nargs=-1, type=click.Path(exists=True, allow_dash=True))\ndef cli(verbose, dry_run, pre, rebuild, find_links, index_url, extra_index_url,\n        client_cert, trusted_host, header, index, annotate, upgrade, upgrade_packages,\n        output_file, allow_unsafe, generate_hashes, src_files, max_rounds):\n    \"\"\"Compiles requirements.txt from requirements.in specs.\"\"\"\n    log.verbose = verbose\n\n    if len(src_files) == 0:\n        if os.path.exists(DEFAULT_REQUIREMENTS_FILE):\n            src_files = (DEFAULT_REQUIREMENTS_FILE,)\n        elif os.path.exists('setup.py'):\n            src_files = ('setup.py',)\n            if not output_file:\n                output_file = 'requirements.txt'\n        else:\n            raise click.BadParameter((\"If you do not specify an input file, \"\n                                      \"the default is {} or setup.py\").format(DEFAULT_REQUIREMENTS_FILE))\n\n    if len(src_files) == 1 and src_files[0] == '-':\n        if not output_file:\n            raise click.BadParameter('--output-file is required if input is from stdin')\n\n    if len(src_files) > 1 and not output_file:\n        raise click.BadParameter('--output-file is required if two or more input files are given.')\n\n    if output_file:\n        dst_file = output_file\n    else:\n        base_name, _, _ = src_files[0].rpartition('.')\n        dst_file = base_name + '.txt'\n\n    if upgrade and upgrade_packages:\n        raise click.BadParameter('Only one of --upgrade or --upgrade-package can be provided as an argument.')\n\n    ###\n    # Setup\n    ###\n\n    pip_command = get_pip_command()\n\n    pip_args = []\n    if find_links:\n        for link in find_links:\n            pip_args.extend(['-f', link])\n    if index_url:\n        pip_args.extend(['-i', index_url])\n    if extra_index_url:\n        for extra_index in extra_index_url:\n            pip_args.extend(['--extra-index-url', extra_index])\n    if client_cert:\n        pip_args.extend(['--client-cert', client_cert])\n    if pre:\n        pip_args.extend(['--pre'])\n    if trusted_host:\n        for host in trusted_host:\n            pip_args.extend(['--trusted-host', host])\n\n    pip_options, _ = pip_command.parse_args(pip_args)\n\n    session = pip_command._build_session(pip_options)\n    repository = PyPIRepository(pip_options, session)\n\n    # Pre-parse the inline package upgrade specs: they should take precedence\n    # over the stuff in the requirements files\n    upgrade_packages = [InstallRequirement.from_line(pkg)\n                        for pkg in upgrade_packages]\n\n    # Proxy with a LocalRequirementsRepository if --upgrade is not specified\n    # (= default invocation)\n    if not (upgrade or upgrade_packages) and os.path.exists(dst_file):\n        ireqs = parse_requirements(dst_file, finder=repository.finder, session=repository.session, options=pip_options)\n        existing_pins = {key_from_req(ireq.req): ireq for ireq in ireqs if is_pinned_requirement(ireq)}\n        repository = LocalRequirementsRepository(existing_pins, repository)\n\n    log.debug('Using indexes:')\n    # remove duplicate index urls before processing\n    repository.finder.index_urls = list(OrderedDict.fromkeys(repository.finder.index_urls))\n    for index_url in repository.finder.index_urls:\n        log.debug('  {}'.format(index_url))\n\n    if repository.finder.find_links:\n        log.debug('')\n        log.debug('Configuration:')\n        for find_link in repository.finder.find_links:\n            log.debug('  -f {}'.format(find_link))\n\n    ###\n    # Parsing/collecting initial requirements\n    ###\n\n    constraints = []\n    for src_file in src_files:\n        is_setup_file = os.path.basename(src_file) == 'setup.py'\n        if is_setup_file or src_file == '-':\n            # pip requires filenames and not files. Since we want to support\n            # piping from stdin, we need to briefly save the input from stdin\n            # to a temporary file and have pip read that.  also used for\n            # reading requirements from install_requires in setup.py.\n            tmpfile = tempfile.NamedTemporaryFile(mode='wt', delete=False)\n            if is_setup_file:\n                from distutils.core import run_setup\n                dist = run_setup(src_file)\n                tmpfile.write('\\n'.join(dist.install_requires))\n            else:\n                tmpfile.write(sys.stdin.read())\n            tmpfile.flush()\n            constraints.extend(parse_requirements(\n                tmpfile.name, finder=repository.finder, session=repository.session, options=pip_options))\n        else:\n            constraints.extend(parse_requirements(\n                src_file, finder=repository.finder, session=repository.session, options=pip_options))\n\n    try:\n        resolver = Resolver(constraints, repository, prereleases=pre,\n                            clear_caches=rebuild, allow_unsafe=allow_unsafe)\n        results = resolver.resolve(max_rounds=max_rounds)\n        if generate_hashes:\n            hashes = resolver.resolve_hashes(results)\n        else:\n            hashes = None\n    except PipToolsError as e:\n        log.error(str(e))\n        sys.exit(2)\n\n    log.debug('')\n\n    ##\n    # Output\n    ##\n\n    # Compute reverse dependency annotations statically, from the\n    # dependency cache that the resolver has populated by now.\n    #\n    # TODO (1a): reverse deps for any editable package are lost\n    #            what SHOULD happen is that they are cached in memory, just\n    #            not persisted to disk!\n    #\n    # TODO (1b): perhaps it's easiest if the dependency cache has an API\n    #            that could take InstallRequirements directly, like:\n    #\n    #                cache.set(ireq, ...)\n    #\n    #            then, when ireq is editable, it would store in\n    #\n    #              editables[egg_name][link_without_fragment] = deps\n    #              editables['pip-tools']['git+...ols.git@future'] = {'click>=3.0', 'six'}\n    #\n    #            otherwise:\n    #\n    #              self[as_name_version_tuple(ireq)] = {'click>=3.0', 'six'}\n    #\n    reverse_dependencies = None\n    if annotate:\n        reverse_dependencies = resolver.reverse_dependencies(results)\n\n    writer = OutputWriter(src_files, dst_file, dry_run=dry_run,\n                          emit_header=header, emit_index=index,\n                          annotate=annotate,\n                          generate_hashes=generate_hashes,\n                          default_index_url=repository.DEFAULT_INDEX_URL,\n                          index_urls=repository.finder.index_urls,\n                          trusted_hosts=pip_options.trusted_hosts,\n                          format_control=repository.finder.format_control)\n    writer.write(results=results,\n                 reverse_dependencies=reverse_dependencies,\n                 primary_packages={key_from_req(ireq.req) for ireq in constraints},\n                 markers={key_from_req(ireq.req): ireq.markers\n                          for ireq in constraints if ireq.markers},\n                 hashes=hashes)\n\n    if dry_run:\n        log.warning('Dry-run, so nothing updated.')\n\n\ndef get_pip_command():\n    # Use pip's parser for pip.conf management and defaults.\n    # General options (find_links, index_url, extra_index_url, trusted_host,\n    # and pre) are defered to pip.\n    pip_command = PipCommand()\n    index_opts = pip.cmdoptions.make_option_group(\n        pip.cmdoptions.index_group,\n        pip_command.parser,\n    )\n    pip_command.parser.insert_option_group(0, index_opts)\n    pip_command.parser.add_option(optparse.Option('--pre', action='store_true', default=False))\n\n    return pip_command\n", "path": "piptools/scripts/compile.py"}]}