We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
via lines often result in git conflict
#### What's the problem this feature will solve?
currently when adding and removing packages in multiple github PRs the `# via` line will conflict

#### Describe the solution you'd like
put each `# via` on a new line:
```
six==1.12.0 \
    --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
    --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 \
    # via automat, bcrypt, cryptography, ecdsa, format-cef, grpcio, patchy, pathlib, prompt-toolkit, protobuf, pyhamcrest
```
instead use:
```
six==1.12.0 \
    --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
    --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 \
    # via automat
    #   , bcrypt
    #   , cryptography
    #   , ecdsa
    #   , format-cef
    #   , grpcio
    #   , patchy
    #   , pathlib
    #   , prompt-toolkit
    #   , protobuf
    #   , pyhamcrest
```
<!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. -->

#### Alternative Solutions
<!-- Have you tried to workaround the problem using pip-tools or other tools? Or a different approach to solving this issue? Please elaborate here. -->

#### Additional context
<!-- Add any other context, links, etc. about the feature here. -->


--- 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/writer.py`
Content:
```
1 from __future__ import unicode_literals
2 
3 import os
4 import re
5 from itertools import chain
6 
7 from pip._vendor import six
8 
9 from .click import unstyle
10 from .logging import log
11 from .utils import (
12     UNSAFE_PACKAGES,
13     comment,
14     dedup,
15     format_requirement,
16     get_compile_command,
17     key_from_ireq,
18 )
19 
20 MESSAGE_UNHASHED_PACKAGE = comment(
21     "# WARNING: pip install will require the following package to be hashed."
22     "\n# Consider using a hashable URL like "
23     "https://github.com/jazzband/pip-tools/archive/SOMECOMMIT.zip"
24 )
25 
26 MESSAGE_UNSAFE_PACKAGES_UNPINNED = comment(
27     "# WARNING: The following packages were not pinned, but pip requires them to be"
28     "\n# pinned when the requirements file includes hashes. "
29     "Consider using the --allow-unsafe flag."
30 )
31 
32 MESSAGE_UNSAFE_PACKAGES = comment(
33     "# The following packages are considered to be unsafe in a requirements file:"
34 )
35 
36 MESSAGE_UNINSTALLABLE = (
37     "The generated requirements file may be rejected by pip install. "
38     "See # WARNING lines for details."
39 )
40 
41 
42 strip_comes_from_line_re = re.compile(r" \(line \d+\)$")
43 
44 
45 def _comes_from_as_string(ireq):
46     if isinstance(ireq.comes_from, six.string_types):
47         return strip_comes_from_line_re.sub("", ireq.comes_from)
48     return key_from_ireq(ireq.comes_from)
49 
50 
51 class OutputWriter(object):
52     def __init__(
53         self,
54         src_files,
55         dst_file,
56         click_ctx,
57         dry_run,
58         emit_header,
59         emit_index_url,
60         emit_trusted_host,
61         annotate,
62         generate_hashes,
63         default_index_url,
64         index_urls,
65         trusted_hosts,
66         format_control,
67         allow_unsafe,
68         find_links,
69         emit_find_links,
70     ):
71         self.src_files = src_files
72         self.dst_file = dst_file
73         self.click_ctx = click_ctx
74         self.dry_run = dry_run
75         self.emit_header = emit_header
76         self.emit_index_url = emit_index_url
77         self.emit_trusted_host = emit_trusted_host
78         self.annotate = annotate
79         self.generate_hashes = generate_hashes
80         self.default_index_url = default_index_url
81         self.index_urls = index_urls
82         self.trusted_hosts = trusted_hosts
83         self.format_control = format_control
84         self.allow_unsafe = allow_unsafe
85         self.find_links = find_links
86         self.emit_find_links = emit_find_links
87 
88     def _sort_key(self, ireq):
89         return (not ireq.editable, str(ireq.req).lower())
90 
91     def write_header(self):
92         if self.emit_header:
93             yield comment("#")
94             yield comment("# This file is autogenerated by pip-compile")
95             yield comment("# To update, run:")
96             yield comment("#")
97             compile_command = os.environ.get(
98                 "CUSTOM_COMPILE_COMMAND"
99             ) or get_compile_command(self.click_ctx)
100             yield comment("#    {}".format(compile_command))
101             yield comment("#")
102 
103     def write_index_options(self):
104         if self.emit_index_url:
105             for index, index_url in enumerate(dedup(self.index_urls)):
106                 if index_url.rstrip("/") == self.default_index_url:
107                     continue
108                 flag = "--index-url" if index == 0 else "--extra-index-url"
109                 yield "{} {}".format(flag, index_url)
110 
111     def write_trusted_hosts(self):
112         if self.emit_trusted_host:
113             for trusted_host in dedup(self.trusted_hosts):
114                 yield "--trusted-host {}".format(trusted_host)
115 
116     def write_format_controls(self):
117         for nb in dedup(sorted(self.format_control.no_binary)):
118             yield "--no-binary {}".format(nb)
119         for ob in dedup(sorted(self.format_control.only_binary)):
120             yield "--only-binary {}".format(ob)
121 
122     def write_find_links(self):
123         if self.emit_find_links:
124             for find_link in dedup(self.find_links):
125                 yield "--find-links {}".format(find_link)
126 
127     def write_flags(self):
128         emitted = False
129         for line in chain(
130             self.write_index_options(),
131             self.write_find_links(),
132             self.write_trusted_hosts(),
133             self.write_format_controls(),
134         ):
135             emitted = True
136             yield line
137         if emitted:
138             yield ""
139 
140     def _iter_lines(self, results, unsafe_requirements=None, markers=None, hashes=None):
141         # default values
142         unsafe_requirements = unsafe_requirements or []
143         markers = markers or {}
144         hashes = hashes or {}
145 
146         # Check for unhashed or unpinned packages if at least one package does have
147         # hashes, which will trigger pip install's --require-hashes mode.
148         warn_uninstallable = False
149         has_hashes = hashes and any(hash for hash in hashes.values())
150 
151         yielded = False
152 
153         for line in self.write_header():
154             yield line
155             yielded = True
156         for line in self.write_flags():
157             yield line
158             yielded = True
159 
160         unsafe_requirements = (
161             {r for r in results if r.name in UNSAFE_PACKAGES}
162             if not unsafe_requirements
163             else unsafe_requirements
164         )
165         packages = {r for r in results if r.name not in UNSAFE_PACKAGES}
166 
167         if packages:
168             packages = sorted(packages, key=self._sort_key)
169             for ireq in packages:
170                 if has_hashes and not hashes.get(ireq):
171                     yield MESSAGE_UNHASHED_PACKAGE
172                     warn_uninstallable = True
173                 line = self._format_requirement(
174                     ireq, markers.get(key_from_ireq(ireq)), hashes=hashes
175                 )
176                 yield line
177             yielded = True
178 
179         if unsafe_requirements:
180             unsafe_requirements = sorted(unsafe_requirements, key=self._sort_key)
181             yield ""
182             yielded = True
183             if has_hashes and not self.allow_unsafe:
184                 yield MESSAGE_UNSAFE_PACKAGES_UNPINNED
185                 warn_uninstallable = True
186             else:
187                 yield MESSAGE_UNSAFE_PACKAGES
188 
189             for ireq in unsafe_requirements:
190                 ireq_key = key_from_ireq(ireq)
191                 if not self.allow_unsafe:
192                     yield comment("# {}".format(ireq_key))
193                 else:
194                     line = self._format_requirement(
195                         ireq, marker=markers.get(ireq_key), hashes=hashes
196                     )
197                     yield line
198 
199         # Yield even when there's no real content, so that blank files are written
200         if not yielded:
201             yield ""
202 
203         if warn_uninstallable:
204             log.warning(MESSAGE_UNINSTALLABLE)
205 
206     def write(self, results, unsafe_requirements, markers, hashes):
207 
208         for line in self._iter_lines(results, unsafe_requirements, markers, hashes):
209             log.info(line)
210             if not self.dry_run:
211                 self.dst_file.write(unstyle(line).encode("utf-8"))
212                 self.dst_file.write(os.linesep.encode("utf-8"))
213 
214     def _format_requirement(self, ireq, marker=None, hashes=None):
215         ireq_hashes = (hashes if hashes is not None else {}).get(ireq)
216 
217         line = format_requirement(ireq, marker=marker, hashes=ireq_hashes)
218 
219         if not self.annotate:
220             return line
221 
222         # Annotate what packages or reqs-ins this package is required by
223         required_by = set()
224         if hasattr(ireq, "_source_ireqs"):
225             required_by |= {
226                 _comes_from_as_string(src_ireq)
227                 for src_ireq in ireq._source_ireqs
228                 if src_ireq.comes_from
229             }
230         elif ireq.comes_from:
231             required_by.add(_comes_from_as_string(ireq))
232         if required_by:
233             annotation = ", ".join(sorted(required_by))
234             line = "{:24}{}{}".format(
235                 line,
236                 " \\\n    " if ireq_hashes else "  ",
237                 comment("# via " + annotation),
238             )
239         return line
240
```
--- 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/writer.py b/piptools/writer.py
--- a/piptools/writer.py
+++ b/piptools/writer.py
@@ -230,10 +230,14 @@
         elif ireq.comes_from:
             required_by.add(_comes_from_as_string(ireq))
         if required_by:
-            annotation = ", ".join(sorted(required_by))
-            line = "{:24}{}{}".format(
-                line,
-                " \\\n    " if ireq_hashes else "  ",
-                comment("# via " + annotation),
-            )
+            required_by = sorted(required_by)
+            if len(required_by) == 1:
+                source = required_by[0]
+                annotation = "    # via " + source
+            else:
+                annotation_lines = ["    # via"]
+                for source in required_by:
+                    annotation_lines.append("    #   " + source)
+                annotation = "\n".join(annotation_lines)
+            line = "{}\n{}".format(line, comment(annotation))
         return line

{"golden_diff": "diff --git a/piptools/writer.py b/piptools/writer.py\n--- a/piptools/writer.py\n+++ b/piptools/writer.py\n@@ -230,10 +230,14 @@\n         elif ireq.comes_from:\n             required_by.add(_comes_from_as_string(ireq))\n         if required_by:\n-            annotation = \", \".join(sorted(required_by))\n-            line = \"{:24}{}{}\".format(\n-                line,\n-                \" \\\\\\n    \" if ireq_hashes else \"  \",\n-                comment(\"# via \" + annotation),\n-            )\n+            required_by = sorted(required_by)\n+            if len(required_by) == 1:\n+                source = required_by[0]\n+                annotation = \"    # via \" + source\n+            else:\n+                annotation_lines = [\"    # via\"]\n+                for source in required_by:\n+                    annotation_lines.append(\"    #   \" + source)\n+                annotation = \"\\n\".join(annotation_lines)\n+            line = \"{}\\n{}\".format(line, comment(annotation))\n         return line\n", "issue": "via lines often result in git conflict\n#### What's the problem this feature will solve?\r\ncurrently when adding and removing packages in multiple github PRs the `# via` line will conflict\r\n\r\n#### Describe the solution you'd like\r\nput each `# via` on a new line:\r\n```\r\nsix==1.12.0 \\\r\n    --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \\\r\n    --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 \\\r\n    # via automat, bcrypt, cryptography, ecdsa, format-cef, grpcio, patchy, pathlib, prompt-toolkit, protobuf, pyhamcrest\r\n```\r\ninstead use:\r\n```\r\nsix==1.12.0 \\\r\n    --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \\\r\n    --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 \\\r\n    # via automat\r\n    #   , bcrypt\r\n    #   , cryptography\r\n    #   , ecdsa\r\n    #   , format-cef\r\n    #   , grpcio\r\n    #   , patchy\r\n    #   , pathlib\r\n    #   , prompt-toolkit\r\n    #   , protobuf\r\n    #   , pyhamcrest\r\n```\r\n<!-- Provide examples of real-world use cases that this would enable and how it solves the problem described above. -->\r\n\r\n#### Alternative Solutions\r\n<!-- Have you tried to workaround the problem using pip-tools or other tools? Or a different approach to solving this issue? Please elaborate here. -->\r\n\r\n#### Additional context\r\n<!-- Add any other context, links, etc. about the feature here. -->\r\n\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nimport os\nimport re\nfrom itertools import chain\n\nfrom pip._vendor import six\n\nfrom .click import unstyle\nfrom .logging import log\nfrom .utils import (\n    UNSAFE_PACKAGES,\n    comment,\n    dedup,\n    format_requirement,\n    get_compile_command,\n    key_from_ireq,\n)\n\nMESSAGE_UNHASHED_PACKAGE = comment(\n    \"# WARNING: pip install will require the following package to be hashed.\"\n    \"\\n# Consider using a hashable URL like \"\n    \"https://github.com/jazzband/pip-tools/archive/SOMECOMMIT.zip\"\n)\n\nMESSAGE_UNSAFE_PACKAGES_UNPINNED = comment(\n    \"# WARNING: The following packages were not pinned, but pip requires them to be\"\n    \"\\n# pinned when the requirements file includes hashes. \"\n    \"Consider using the --allow-unsafe flag.\"\n)\n\nMESSAGE_UNSAFE_PACKAGES = comment(\n    \"# The following packages are considered to be unsafe in a requirements file:\"\n)\n\nMESSAGE_UNINSTALLABLE = (\n    \"The generated requirements file may be rejected by pip install. \"\n    \"See # WARNING lines for details.\"\n)\n\n\nstrip_comes_from_line_re = re.compile(r\" \\(line \\d+\\)$\")\n\n\ndef _comes_from_as_string(ireq):\n    if isinstance(ireq.comes_from, six.string_types):\n        return strip_comes_from_line_re.sub(\"\", ireq.comes_from)\n    return key_from_ireq(ireq.comes_from)\n\n\nclass OutputWriter(object):\n    def __init__(\n        self,\n        src_files,\n        dst_file,\n        click_ctx,\n        dry_run,\n        emit_header,\n        emit_index_url,\n        emit_trusted_host,\n        annotate,\n        generate_hashes,\n        default_index_url,\n        index_urls,\n        trusted_hosts,\n        format_control,\n        allow_unsafe,\n        find_links,\n        emit_find_links,\n    ):\n        self.src_files = src_files\n        self.dst_file = dst_file\n        self.click_ctx = click_ctx\n        self.dry_run = dry_run\n        self.emit_header = emit_header\n        self.emit_index_url = emit_index_url\n        self.emit_trusted_host = emit_trusted_host\n        self.annotate = annotate\n        self.generate_hashes = generate_hashes\n        self.default_index_url = default_index_url\n        self.index_urls = index_urls\n        self.trusted_hosts = trusted_hosts\n        self.format_control = format_control\n        self.allow_unsafe = allow_unsafe\n        self.find_links = find_links\n        self.emit_find_links = emit_find_links\n\n    def _sort_key(self, ireq):\n        return (not ireq.editable, str(ireq.req).lower())\n\n    def write_header(self):\n        if self.emit_header:\n            yield comment(\"#\")\n            yield comment(\"# This file is autogenerated by pip-compile\")\n            yield comment(\"# To update, run:\")\n            yield comment(\"#\")\n            compile_command = os.environ.get(\n                \"CUSTOM_COMPILE_COMMAND\"\n            ) or get_compile_command(self.click_ctx)\n            yield comment(\"#    {}\".format(compile_command))\n            yield comment(\"#\")\n\n    def write_index_options(self):\n        if self.emit_index_url:\n            for index, index_url in enumerate(dedup(self.index_urls)):\n                if index_url.rstrip(\"/\") == self.default_index_url:\n                    continue\n                flag = \"--index-url\" if index == 0 else \"--extra-index-url\"\n                yield \"{} {}\".format(flag, index_url)\n\n    def write_trusted_hosts(self):\n        if self.emit_trusted_host:\n            for trusted_host in dedup(self.trusted_hosts):\n                yield \"--trusted-host {}\".format(trusted_host)\n\n    def write_format_controls(self):\n        for nb in dedup(sorted(self.format_control.no_binary)):\n            yield \"--no-binary {}\".format(nb)\n        for ob in dedup(sorted(self.format_control.only_binary)):\n            yield \"--only-binary {}\".format(ob)\n\n    def write_find_links(self):\n        if self.emit_find_links:\n            for find_link in dedup(self.find_links):\n                yield \"--find-links {}\".format(find_link)\n\n    def write_flags(self):\n        emitted = False\n        for line in chain(\n            self.write_index_options(),\n            self.write_find_links(),\n            self.write_trusted_hosts(),\n            self.write_format_controls(),\n        ):\n            emitted = True\n            yield line\n        if emitted:\n            yield \"\"\n\n    def _iter_lines(self, results, unsafe_requirements=None, markers=None, hashes=None):\n        # default values\n        unsafe_requirements = unsafe_requirements or []\n        markers = markers or {}\n        hashes = hashes or {}\n\n        # Check for unhashed or unpinned packages if at least one package does have\n        # hashes, which will trigger pip install's --require-hashes mode.\n        warn_uninstallable = False\n        has_hashes = hashes and any(hash for hash in hashes.values())\n\n        yielded = False\n\n        for line in self.write_header():\n            yield line\n            yielded = True\n        for line in self.write_flags():\n            yield line\n            yielded = True\n\n        unsafe_requirements = (\n            {r for r in results if r.name in UNSAFE_PACKAGES}\n            if not unsafe_requirements\n            else unsafe_requirements\n        )\n        packages = {r for r in results if r.name not in UNSAFE_PACKAGES}\n\n        if packages:\n            packages = sorted(packages, key=self._sort_key)\n            for ireq in packages:\n                if has_hashes and not hashes.get(ireq):\n                    yield MESSAGE_UNHASHED_PACKAGE\n                    warn_uninstallable = True\n                line = self._format_requirement(\n                    ireq, markers.get(key_from_ireq(ireq)), hashes=hashes\n                )\n                yield line\n            yielded = True\n\n        if unsafe_requirements:\n            unsafe_requirements = sorted(unsafe_requirements, key=self._sort_key)\n            yield \"\"\n            yielded = True\n            if has_hashes and not self.allow_unsafe:\n                yield MESSAGE_UNSAFE_PACKAGES_UNPINNED\n                warn_uninstallable = True\n            else:\n                yield MESSAGE_UNSAFE_PACKAGES\n\n            for ireq in unsafe_requirements:\n                ireq_key = key_from_ireq(ireq)\n                if not self.allow_unsafe:\n                    yield comment(\"# {}\".format(ireq_key))\n                else:\n                    line = self._format_requirement(\n                        ireq, marker=markers.get(ireq_key), hashes=hashes\n                    )\n                    yield line\n\n        # Yield even when there's no real content, so that blank files are written\n        if not yielded:\n            yield \"\"\n\n        if warn_uninstallable:\n            log.warning(MESSAGE_UNINSTALLABLE)\n\n    def write(self, results, unsafe_requirements, markers, hashes):\n\n        for line in self._iter_lines(results, unsafe_requirements, markers, hashes):\n            log.info(line)\n            if not self.dry_run:\n                self.dst_file.write(unstyle(line).encode(\"utf-8\"))\n                self.dst_file.write(os.linesep.encode(\"utf-8\"))\n\n    def _format_requirement(self, ireq, marker=None, hashes=None):\n        ireq_hashes = (hashes if hashes is not None else {}).get(ireq)\n\n        line = format_requirement(ireq, marker=marker, hashes=ireq_hashes)\n\n        if not self.annotate:\n            return line\n\n        # Annotate what packages or reqs-ins this package is required by\n        required_by = set()\n        if hasattr(ireq, \"_source_ireqs\"):\n            required_by |= {\n                _comes_from_as_string(src_ireq)\n                for src_ireq in ireq._source_ireqs\n                if src_ireq.comes_from\n            }\n        elif ireq.comes_from:\n            required_by.add(_comes_from_as_string(ireq))\n        if required_by:\n            annotation = \", \".join(sorted(required_by))\n            line = \"{:24}{}{}\".format(\n                line,\n                \" \\\\\\n    \" if ireq_hashes else \"  \",\n                comment(\"# via \" + annotation),\n            )\n        return line\n", "path": "piptools/writer.py"}], "after_files": [{"content": "from __future__ import unicode_literals\n\nimport os\nimport re\nfrom itertools import chain\n\nfrom pip._vendor import six\n\nfrom .click import unstyle\nfrom .logging import log\nfrom .utils import (\n    UNSAFE_PACKAGES,\n    comment,\n    dedup,\n    format_requirement,\n    get_compile_command,\n    key_from_ireq,\n)\n\nMESSAGE_UNHASHED_PACKAGE = comment(\n    \"# WARNING: pip install will require the following package to be hashed.\"\n    \"\\n# Consider using a hashable URL like \"\n    \"https://github.com/jazzband/pip-tools/archive/SOMECOMMIT.zip\"\n)\n\nMESSAGE_UNSAFE_PACKAGES_UNPINNED = comment(\n    \"# WARNING: The following packages were not pinned, but pip requires them to be\"\n    \"\\n# pinned when the requirements file includes hashes. \"\n    \"Consider using the --allow-unsafe flag.\"\n)\n\nMESSAGE_UNSAFE_PACKAGES = comment(\n    \"# The following packages are considered to be unsafe in a requirements file:\"\n)\n\nMESSAGE_UNINSTALLABLE = (\n    \"The generated requirements file may be rejected by pip install. \"\n    \"See # WARNING lines for details.\"\n)\n\n\nstrip_comes_from_line_re = re.compile(r\" \\(line \\d+\\)$\")\n\n\ndef _comes_from_as_string(ireq):\n    if isinstance(ireq.comes_from, six.string_types):\n        return strip_comes_from_line_re.sub(\"\", ireq.comes_from)\n    return key_from_ireq(ireq.comes_from)\n\n\nclass OutputWriter(object):\n    def __init__(\n        self,\n        src_files,\n        dst_file,\n        click_ctx,\n        dry_run,\n        emit_header,\n        emit_index_url,\n        emit_trusted_host,\n        annotate,\n        generate_hashes,\n        default_index_url,\n        index_urls,\n        trusted_hosts,\n        format_control,\n        allow_unsafe,\n        find_links,\n        emit_find_links,\n    ):\n        self.src_files = src_files\n        self.dst_file = dst_file\n        self.click_ctx = click_ctx\n        self.dry_run = dry_run\n        self.emit_header = emit_header\n        self.emit_index_url = emit_index_url\n        self.emit_trusted_host = emit_trusted_host\n        self.annotate = annotate\n        self.generate_hashes = generate_hashes\n        self.default_index_url = default_index_url\n        self.index_urls = index_urls\n        self.trusted_hosts = trusted_hosts\n        self.format_control = format_control\n        self.allow_unsafe = allow_unsafe\n        self.find_links = find_links\n        self.emit_find_links = emit_find_links\n\n    def _sort_key(self, ireq):\n        return (not ireq.editable, str(ireq.req).lower())\n\n    def write_header(self):\n        if self.emit_header:\n            yield comment(\"#\")\n            yield comment(\"# This file is autogenerated by pip-compile\")\n            yield comment(\"# To update, run:\")\n            yield comment(\"#\")\n            compile_command = os.environ.get(\n                \"CUSTOM_COMPILE_COMMAND\"\n            ) or get_compile_command(self.click_ctx)\n            yield comment(\"#    {}\".format(compile_command))\n            yield comment(\"#\")\n\n    def write_index_options(self):\n        if self.emit_index_url:\n            for index, index_url in enumerate(dedup(self.index_urls)):\n                if index_url.rstrip(\"/\") == self.default_index_url:\n                    continue\n                flag = \"--index-url\" if index == 0 else \"--extra-index-url\"\n                yield \"{} {}\".format(flag, index_url)\n\n    def write_trusted_hosts(self):\n        if self.emit_trusted_host:\n            for trusted_host in dedup(self.trusted_hosts):\n                yield \"--trusted-host {}\".format(trusted_host)\n\n    def write_format_controls(self):\n        for nb in dedup(sorted(self.format_control.no_binary)):\n            yield \"--no-binary {}\".format(nb)\n        for ob in dedup(sorted(self.format_control.only_binary)):\n            yield \"--only-binary {}\".format(ob)\n\n    def write_find_links(self):\n        if self.emit_find_links:\n            for find_link in dedup(self.find_links):\n                yield \"--find-links {}\".format(find_link)\n\n    def write_flags(self):\n        emitted = False\n        for line in chain(\n            self.write_index_options(),\n            self.write_find_links(),\n            self.write_trusted_hosts(),\n            self.write_format_controls(),\n        ):\n            emitted = True\n            yield line\n        if emitted:\n            yield \"\"\n\n    def _iter_lines(self, results, unsafe_requirements=None, markers=None, hashes=None):\n        # default values\n        unsafe_requirements = unsafe_requirements or []\n        markers = markers or {}\n        hashes = hashes or {}\n\n        # Check for unhashed or unpinned packages if at least one package does have\n        # hashes, which will trigger pip install's --require-hashes mode.\n        warn_uninstallable = False\n        has_hashes = hashes and any(hash for hash in hashes.values())\n\n        yielded = False\n\n        for line in self.write_header():\n            yield line\n            yielded = True\n        for line in self.write_flags():\n            yield line\n            yielded = True\n\n        unsafe_requirements = (\n            {r for r in results if r.name in UNSAFE_PACKAGES}\n            if not unsafe_requirements\n            else unsafe_requirements\n        )\n        packages = {r for r in results if r.name not in UNSAFE_PACKAGES}\n\n        if packages:\n            packages = sorted(packages, key=self._sort_key)\n            for ireq in packages:\n                if has_hashes and not hashes.get(ireq):\n                    yield MESSAGE_UNHASHED_PACKAGE\n                    warn_uninstallable = True\n                line = self._format_requirement(\n                    ireq, markers.get(key_from_ireq(ireq)), hashes=hashes\n                )\n                yield line\n            yielded = True\n\n        if unsafe_requirements:\n            unsafe_requirements = sorted(unsafe_requirements, key=self._sort_key)\n            yield \"\"\n            yielded = True\n            if has_hashes and not self.allow_unsafe:\n                yield MESSAGE_UNSAFE_PACKAGES_UNPINNED\n                warn_uninstallable = True\n            else:\n                yield MESSAGE_UNSAFE_PACKAGES\n\n            for ireq in unsafe_requirements:\n                ireq_key = key_from_ireq(ireq)\n                if not self.allow_unsafe:\n                    yield comment(\"# {}\".format(ireq_key))\n                else:\n                    line = self._format_requirement(\n                        ireq, marker=markers.get(ireq_key), hashes=hashes\n                    )\n                    yield line\n\n        # Yield even when there's no real content, so that blank files are written\n        if not yielded:\n            yield \"\"\n\n        if warn_uninstallable:\n            log.warning(MESSAGE_UNINSTALLABLE)\n\n    def write(self, results, unsafe_requirements, markers, hashes):\n\n        for line in self._iter_lines(results, unsafe_requirements, markers, hashes):\n            log.info(line)\n            if not self.dry_run:\n                self.dst_file.write(unstyle(line).encode(\"utf-8\"))\n                self.dst_file.write(os.linesep.encode(\"utf-8\"))\n\n    def _format_requirement(self, ireq, marker=None, hashes=None):\n        ireq_hashes = (hashes if hashes is not None else {}).get(ireq)\n\n        line = format_requirement(ireq, marker=marker, hashes=ireq_hashes)\n\n        if not self.annotate:\n            return line\n\n        # Annotate what packages or reqs-ins this package is required by\n        required_by = set()\n        if hasattr(ireq, \"_source_ireqs\"):\n            required_by |= {\n                _comes_from_as_string(src_ireq)\n                for src_ireq in ireq._source_ireqs\n                if src_ireq.comes_from\n            }\n        elif ireq.comes_from:\n            required_by.add(_comes_from_as_string(ireq))\n        if required_by:\n            required_by = sorted(required_by)\n            if len(required_by) == 1:\n                source = required_by[0]\n                annotation = \"    # via \" + source\n            else:\n                annotation_lines = [\"    # via\"]\n                for source in required_by:\n                    annotation_lines.append(\"    #   \" + source)\n                annotation = \"\\n\".join(annotation_lines)\n            line = \"{}\\n{}\".format(line, comment(annotation))\n        return line\n", "path": "piptools/writer.py"}]}