We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pip-sync broken on Windows
Calling pip-sync on Windows returns:
```
Could not open requirements file: [Errno 13] Permission denied: 'c:\\users\\<username>\\appdata\\local\\temp\\tmpe9jswo'
```

This was introduced in 3.3.1 by the change to using `tempfile.NamedTemporaryFile` in [sync.py](https://github.com/jazzband/pip-tools/blob/3.3.1/piptools/sync.py#L167) to create the requirements file before passing it to `pip install` via `subprocess.check_call`. This is caused by Windows requiring reopened temporary files to be opened with the `O_TEMPORARY`  flag. For context see https://stackoverflow.com/a/15235559. 

##### Environment Versions

1. OS Type: Windows 10
1. Python version: Python 2.7.12
1. pip version: pip 9.0.3
1. pip-tools version: pip-compile, version 3.3.1

##### Steps to replicate

1. `pip-sync -r <requirements_file>`

##### Expected result

Command should complete successfully.

##### Actual result

```
Could not open requirements file: [Errno 13] Permission denied: 'c:\\users\\<username>\\appdata\\local\\temp\\tmpe9jswo'
```


--- 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/sync.py`
Content:
```
1 import collections
2 import os
3 import sys
4 import tempfile
5 from subprocess import check_call
6 
7 from piptools._compat import stdlib_pkgs, DEV_PKGS
8 from . import click
9 from .exceptions import IncompatibleRequirements, UnsupportedConstraint
10 from .utils import flat_map, format_requirement, key_from_ireq, key_from_req, get_hashes_from_ireq
11 
12 PACKAGES_TO_IGNORE = [
13     '-markerlib',
14     'pip',
15     'pip-tools',
16     'pip-review',
17     'pkg-resources',
18 ] + list(stdlib_pkgs) + list(DEV_PKGS)
19 
20 
21 def dependency_tree(installed_keys, root_key):
22     """
23     Calculate the dependency tree for the package `root_key` and return
24     a collection of all its dependencies.  Uses a DFS traversal algorithm.
25 
26     `installed_keys` should be a {key: requirement} mapping, e.g.
27         {'django': from_line('django==1.8')}
28     `root_key` should be the key to return the dependency tree for.
29     """
30     dependencies = set()
31     queue = collections.deque()
32 
33     if root_key in installed_keys:
34         dep = installed_keys[root_key]
35         queue.append(dep)
36 
37     while queue:
38         v = queue.popleft()
39         key = key_from_req(v)
40         if key in dependencies:
41             continue
42 
43         dependencies.add(key)
44 
45         for dep_specifier in v.requires():
46             dep_name = key_from_req(dep_specifier)
47             if dep_name in installed_keys:
48                 dep = installed_keys[dep_name]
49 
50                 if dep_specifier.specifier.contains(dep.version):
51                     queue.append(dep)
52 
53     return dependencies
54 
55 
56 def get_dists_to_ignore(installed):
57     """
58     Returns a collection of package names to ignore when performing pip-sync,
59     based on the currently installed environment.  For example, when pip-tools
60     is installed in the local environment, it should be ignored, including all
61     of its dependencies (e.g. click).  When pip-tools is not installed
62     locally, click should also be installed/uninstalled depending on the given
63     requirements.
64     """
65     installed_keys = {key_from_req(r): r for r in installed}
66     return list(flat_map(lambda req: dependency_tree(installed_keys, req), PACKAGES_TO_IGNORE))
67 
68 
69 def merge(requirements, ignore_conflicts):
70     by_key = {}
71 
72     for ireq in requirements:
73         if ireq.link is not None and not ireq.editable:
74             msg = ('pip-compile does not support URLs as packages, unless they are editable. '
75                    'Perhaps add -e option?')
76             raise UnsupportedConstraint(msg, ireq)
77 
78         key = ireq.link or key_from_req(ireq.req)
79 
80         if not ignore_conflicts:
81             existing_ireq = by_key.get(key)
82             if existing_ireq:
83                 # NOTE: We check equality here since we can assume that the
84                 # requirements are all pinned
85                 if ireq.specifier != existing_ireq.specifier:
86                     raise IncompatibleRequirements(ireq, existing_ireq)
87 
88         # TODO: Always pick the largest specifier in case of a conflict
89         by_key[key] = ireq
90 
91     return by_key.values()
92 
93 
94 def diff(compiled_requirements, installed_dists):
95     """
96     Calculate which packages should be installed or uninstalled, given a set
97     of compiled requirements and a list of currently installed modules.
98     """
99     requirements_lut = {r.link or key_from_req(r.req): r for r in compiled_requirements}
100 
101     satisfied = set()  # holds keys
102     to_install = set()  # holds InstallRequirement objects
103     to_uninstall = set()  # holds keys
104 
105     pkgs_to_ignore = get_dists_to_ignore(installed_dists)
106     for dist in installed_dists:
107         key = key_from_req(dist)
108         if key not in requirements_lut or not requirements_lut[key].match_markers():
109             to_uninstall.add(key)
110         elif requirements_lut[key].specifier.contains(dist.version):
111             satisfied.add(key)
112 
113     for key, requirement in requirements_lut.items():
114         if key not in satisfied and requirement.match_markers():
115             to_install.add(requirement)
116 
117     # Make sure to not uninstall any packages that should be ignored
118     to_uninstall -= set(pkgs_to_ignore)
119 
120     return (to_install, to_uninstall)
121 
122 
123 def sync(to_install, to_uninstall, verbose=False, dry_run=False, pip_flags=None, install_flags=None):
124     """
125     Install and uninstalls the given sets of modules.
126     """
127     if not to_uninstall and not to_install:
128         click.echo("Everything up-to-date")
129 
130     if pip_flags is None:
131         pip_flags = []
132 
133     if not verbose:
134         pip_flags += ['-q']
135 
136     if os.environ.get('VIRTUAL_ENV'):
137         # find pip via PATH
138         pip = 'pip'
139     else:
140         # find pip in same directory as pip-sync entry-point script
141         pip = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), 'pip')
142 
143     if to_uninstall:
144         if dry_run:
145             click.echo("Would uninstall:")
146             for pkg in to_uninstall:
147                 click.echo("  {}".format(pkg))
148         else:
149             check_call([pip, 'uninstall', '-y'] + pip_flags + sorted(to_uninstall))
150 
151     if to_install:
152         if install_flags is None:
153             install_flags = []
154         if dry_run:
155             click.echo("Would install:")
156             for ireq in to_install:
157                 click.echo("  {}".format(format_requirement(ireq)))
158         else:
159             # prepare requirement lines
160             req_lines = []
161             for ireq in sorted(to_install, key=key_from_ireq):
162                 ireq_hashes = get_hashes_from_ireq(ireq)
163                 req_lines.append(format_requirement(ireq, hashes=ireq_hashes))
164 
165             # save requirement lines to a temporary file
166             with tempfile.NamedTemporaryFile(mode='wt') as tmp_req_file:
167                 tmp_req_file.write('\n'.join(req_lines))
168                 tmp_req_file.flush()
169 
170                 check_call([pip, 'install', '-r', tmp_req_file.name] + pip_flags + install_flags)
171     return 0
172
```
--- 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/sync.py b/piptools/sync.py
--- a/piptools/sync.py
+++ b/piptools/sync.py
@@ -163,9 +163,13 @@
                 req_lines.append(format_requirement(ireq, hashes=ireq_hashes))
 
             # save requirement lines to a temporary file
-            with tempfile.NamedTemporaryFile(mode='wt') as tmp_req_file:
-                tmp_req_file.write('\n'.join(req_lines))
-                tmp_req_file.flush()
+            tmp_req_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)
+            tmp_req_file.write('\n'.join(req_lines))
+            tmp_req_file.close()
 
+            try:
                 check_call([pip, 'install', '-r', tmp_req_file.name] + pip_flags + install_flags)
+            finally:
+                os.unlink(tmp_req_file.name)
+
     return 0

{"golden_diff": "diff --git a/piptools/sync.py b/piptools/sync.py\n--- a/piptools/sync.py\n+++ b/piptools/sync.py\n@@ -163,9 +163,13 @@\n                 req_lines.append(format_requirement(ireq, hashes=ireq_hashes))\n \n             # save requirement lines to a temporary file\n-            with tempfile.NamedTemporaryFile(mode='wt') as tmp_req_file:\n-                tmp_req_file.write('\\n'.join(req_lines))\n-                tmp_req_file.flush()\n+            tmp_req_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)\n+            tmp_req_file.write('\\n'.join(req_lines))\n+            tmp_req_file.close()\n \n+            try:\n                 check_call([pip, 'install', '-r', tmp_req_file.name] + pip_flags + install_flags)\n+            finally:\n+                os.unlink(tmp_req_file.name)\n+\n     return 0\n", "issue": "pip-sync broken on Windows\nCalling pip-sync on Windows returns:\r\n```\r\nCould not open requirements file: [Errno 13] Permission denied: 'c:\\\\users\\\\<username>\\\\appdata\\\\local\\\\temp\\\\tmpe9jswo'\r\n```\r\n\r\nThis was introduced in 3.3.1 by the change to using `tempfile.NamedTemporaryFile` in [sync.py](https://github.com/jazzband/pip-tools/blob/3.3.1/piptools/sync.py#L167) to create the requirements file before passing it to `pip install` via `subprocess.check_call`. This is caused by Windows requiring reopened temporary files to be opened with the `O_TEMPORARY`  flag. For context see https://stackoverflow.com/a/15235559. \r\n\r\n##### Environment Versions\r\n\r\n1. OS Type: Windows 10\r\n1. Python version: Python 2.7.12\r\n1. pip version: pip 9.0.3\r\n1. pip-tools version: pip-compile, version 3.3.1\r\n\r\n##### Steps to replicate\r\n\r\n1. `pip-sync -r <requirements_file>`\r\n\r\n##### Expected result\r\n\r\nCommand should complete successfully.\r\n\r\n##### Actual result\r\n\r\n```\r\nCould not open requirements file: [Errno 13] Permission denied: 'c:\\\\users\\\\<username>\\\\appdata\\\\local\\\\temp\\\\tmpe9jswo'\r\n```\r\n\n", "before_files": [{"content": "import collections\nimport os\nimport sys\nimport tempfile\nfrom subprocess import check_call\n\nfrom piptools._compat import stdlib_pkgs, DEV_PKGS\nfrom . import click\nfrom .exceptions import IncompatibleRequirements, UnsupportedConstraint\nfrom .utils import flat_map, format_requirement, key_from_ireq, key_from_req, get_hashes_from_ireq\n\nPACKAGES_TO_IGNORE = [\n    '-markerlib',\n    'pip',\n    'pip-tools',\n    'pip-review',\n    'pkg-resources',\n] + list(stdlib_pkgs) + list(DEV_PKGS)\n\n\ndef dependency_tree(installed_keys, root_key):\n    \"\"\"\n    Calculate the dependency tree for the package `root_key` and return\n    a collection of all its dependencies.  Uses a DFS traversal algorithm.\n\n    `installed_keys` should be a {key: requirement} mapping, e.g.\n        {'django': from_line('django==1.8')}\n    `root_key` should be the key to return the dependency tree for.\n    \"\"\"\n    dependencies = set()\n    queue = collections.deque()\n\n    if root_key in installed_keys:\n        dep = installed_keys[root_key]\n        queue.append(dep)\n\n    while queue:\n        v = queue.popleft()\n        key = key_from_req(v)\n        if key in dependencies:\n            continue\n\n        dependencies.add(key)\n\n        for dep_specifier in v.requires():\n            dep_name = key_from_req(dep_specifier)\n            if dep_name in installed_keys:\n                dep = installed_keys[dep_name]\n\n                if dep_specifier.specifier.contains(dep.version):\n                    queue.append(dep)\n\n    return dependencies\n\n\ndef get_dists_to_ignore(installed):\n    \"\"\"\n    Returns a collection of package names to ignore when performing pip-sync,\n    based on the currently installed environment.  For example, when pip-tools\n    is installed in the local environment, it should be ignored, including all\n    of its dependencies (e.g. click).  When pip-tools is not installed\n    locally, click should also be installed/uninstalled depending on the given\n    requirements.\n    \"\"\"\n    installed_keys = {key_from_req(r): r for r in installed}\n    return list(flat_map(lambda req: dependency_tree(installed_keys, req), PACKAGES_TO_IGNORE))\n\n\ndef merge(requirements, ignore_conflicts):\n    by_key = {}\n\n    for ireq in requirements:\n        if ireq.link is not None and not ireq.editable:\n            msg = ('pip-compile does not support URLs as packages, unless they are editable. '\n                   'Perhaps add -e option?')\n            raise UnsupportedConstraint(msg, ireq)\n\n        key = ireq.link or key_from_req(ireq.req)\n\n        if not ignore_conflicts:\n            existing_ireq = by_key.get(key)\n            if existing_ireq:\n                # NOTE: We check equality here since we can assume that the\n                # requirements are all pinned\n                if ireq.specifier != existing_ireq.specifier:\n                    raise IncompatibleRequirements(ireq, existing_ireq)\n\n        # TODO: Always pick the largest specifier in case of a conflict\n        by_key[key] = ireq\n\n    return by_key.values()\n\n\ndef diff(compiled_requirements, installed_dists):\n    \"\"\"\n    Calculate which packages should be installed or uninstalled, given a set\n    of compiled requirements and a list of currently installed modules.\n    \"\"\"\n    requirements_lut = {r.link or key_from_req(r.req): r for r in compiled_requirements}\n\n    satisfied = set()  # holds keys\n    to_install = set()  # holds InstallRequirement objects\n    to_uninstall = set()  # holds keys\n\n    pkgs_to_ignore = get_dists_to_ignore(installed_dists)\n    for dist in installed_dists:\n        key = key_from_req(dist)\n        if key not in requirements_lut or not requirements_lut[key].match_markers():\n            to_uninstall.add(key)\n        elif requirements_lut[key].specifier.contains(dist.version):\n            satisfied.add(key)\n\n    for key, requirement in requirements_lut.items():\n        if key not in satisfied and requirement.match_markers():\n            to_install.add(requirement)\n\n    # Make sure to not uninstall any packages that should be ignored\n    to_uninstall -= set(pkgs_to_ignore)\n\n    return (to_install, to_uninstall)\n\n\ndef sync(to_install, to_uninstall, verbose=False, dry_run=False, pip_flags=None, install_flags=None):\n    \"\"\"\n    Install and uninstalls the given sets of modules.\n    \"\"\"\n    if not to_uninstall and not to_install:\n        click.echo(\"Everything up-to-date\")\n\n    if pip_flags is None:\n        pip_flags = []\n\n    if not verbose:\n        pip_flags += ['-q']\n\n    if os.environ.get('VIRTUAL_ENV'):\n        # find pip via PATH\n        pip = 'pip'\n    else:\n        # find pip in same directory as pip-sync entry-point script\n        pip = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), 'pip')\n\n    if to_uninstall:\n        if dry_run:\n            click.echo(\"Would uninstall:\")\n            for pkg in to_uninstall:\n                click.echo(\"  {}\".format(pkg))\n        else:\n            check_call([pip, 'uninstall', '-y'] + pip_flags + sorted(to_uninstall))\n\n    if to_install:\n        if install_flags is None:\n            install_flags = []\n        if dry_run:\n            click.echo(\"Would install:\")\n            for ireq in to_install:\n                click.echo(\"  {}\".format(format_requirement(ireq)))\n        else:\n            # prepare requirement lines\n            req_lines = []\n            for ireq in sorted(to_install, key=key_from_ireq):\n                ireq_hashes = get_hashes_from_ireq(ireq)\n                req_lines.append(format_requirement(ireq, hashes=ireq_hashes))\n\n            # save requirement lines to a temporary file\n            with tempfile.NamedTemporaryFile(mode='wt') as tmp_req_file:\n                tmp_req_file.write('\\n'.join(req_lines))\n                tmp_req_file.flush()\n\n                check_call([pip, 'install', '-r', tmp_req_file.name] + pip_flags + install_flags)\n    return 0\n", "path": "piptools/sync.py"}], "after_files": [{"content": "import collections\nimport os\nimport sys\nimport tempfile\nfrom subprocess import check_call\n\nfrom piptools._compat import stdlib_pkgs, DEV_PKGS\nfrom . import click\nfrom .exceptions import IncompatibleRequirements, UnsupportedConstraint\nfrom .utils import flat_map, format_requirement, key_from_ireq, key_from_req, get_hashes_from_ireq\n\nPACKAGES_TO_IGNORE = [\n    '-markerlib',\n    'pip',\n    'pip-tools',\n    'pip-review',\n    'pkg-resources',\n] + list(stdlib_pkgs) + list(DEV_PKGS)\n\n\ndef dependency_tree(installed_keys, root_key):\n    \"\"\"\n    Calculate the dependency tree for the package `root_key` and return\n    a collection of all its dependencies.  Uses a DFS traversal algorithm.\n\n    `installed_keys` should be a {key: requirement} mapping, e.g.\n        {'django': from_line('django==1.8')}\n    `root_key` should be the key to return the dependency tree for.\n    \"\"\"\n    dependencies = set()\n    queue = collections.deque()\n\n    if root_key in installed_keys:\n        dep = installed_keys[root_key]\n        queue.append(dep)\n\n    while queue:\n        v = queue.popleft()\n        key = key_from_req(v)\n        if key in dependencies:\n            continue\n\n        dependencies.add(key)\n\n        for dep_specifier in v.requires():\n            dep_name = key_from_req(dep_specifier)\n            if dep_name in installed_keys:\n                dep = installed_keys[dep_name]\n\n                if dep_specifier.specifier.contains(dep.version):\n                    queue.append(dep)\n\n    return dependencies\n\n\ndef get_dists_to_ignore(installed):\n    \"\"\"\n    Returns a collection of package names to ignore when performing pip-sync,\n    based on the currently installed environment.  For example, when pip-tools\n    is installed in the local environment, it should be ignored, including all\n    of its dependencies (e.g. click).  When pip-tools is not installed\n    locally, click should also be installed/uninstalled depending on the given\n    requirements.\n    \"\"\"\n    installed_keys = {key_from_req(r): r for r in installed}\n    return list(flat_map(lambda req: dependency_tree(installed_keys, req), PACKAGES_TO_IGNORE))\n\n\ndef merge(requirements, ignore_conflicts):\n    by_key = {}\n\n    for ireq in requirements:\n        if ireq.link is not None and not ireq.editable:\n            msg = ('pip-compile does not support URLs as packages, unless they are editable. '\n                   'Perhaps add -e option?')\n            raise UnsupportedConstraint(msg, ireq)\n\n        key = ireq.link or key_from_req(ireq.req)\n\n        if not ignore_conflicts:\n            existing_ireq = by_key.get(key)\n            if existing_ireq:\n                # NOTE: We check equality here since we can assume that the\n                # requirements are all pinned\n                if ireq.specifier != existing_ireq.specifier:\n                    raise IncompatibleRequirements(ireq, existing_ireq)\n\n        # TODO: Always pick the largest specifier in case of a conflict\n        by_key[key] = ireq\n\n    return by_key.values()\n\n\ndef diff(compiled_requirements, installed_dists):\n    \"\"\"\n    Calculate which packages should be installed or uninstalled, given a set\n    of compiled requirements and a list of currently installed modules.\n    \"\"\"\n    requirements_lut = {r.link or key_from_req(r.req): r for r in compiled_requirements}\n\n    satisfied = set()  # holds keys\n    to_install = set()  # holds InstallRequirement objects\n    to_uninstall = set()  # holds keys\n\n    pkgs_to_ignore = get_dists_to_ignore(installed_dists)\n    for dist in installed_dists:\n        key = key_from_req(dist)\n        if key not in requirements_lut or not requirements_lut[key].match_markers():\n            to_uninstall.add(key)\n        elif requirements_lut[key].specifier.contains(dist.version):\n            satisfied.add(key)\n\n    for key, requirement in requirements_lut.items():\n        if key not in satisfied and requirement.match_markers():\n            to_install.add(requirement)\n\n    # Make sure to not uninstall any packages that should be ignored\n    to_uninstall -= set(pkgs_to_ignore)\n\n    return (to_install, to_uninstall)\n\n\ndef sync(to_install, to_uninstall, verbose=False, dry_run=False, pip_flags=None, install_flags=None):\n    \"\"\"\n    Install and uninstalls the given sets of modules.\n    \"\"\"\n    if not to_uninstall and not to_install:\n        click.echo(\"Everything up-to-date\")\n\n    if pip_flags is None:\n        pip_flags = []\n\n    if not verbose:\n        pip_flags += ['-q']\n\n    if os.environ.get('VIRTUAL_ENV'):\n        # find pip via PATH\n        pip = 'pip'\n    else:\n        # find pip in same directory as pip-sync entry-point script\n        pip = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), 'pip')\n\n    if to_uninstall:\n        if dry_run:\n            click.echo(\"Would uninstall:\")\n            for pkg in to_uninstall:\n                click.echo(\"  {}\".format(pkg))\n        else:\n            check_call([pip, 'uninstall', '-y'] + pip_flags + sorted(to_uninstall))\n\n    if to_install:\n        if install_flags is None:\n            install_flags = []\n        if dry_run:\n            click.echo(\"Would install:\")\n            for ireq in to_install:\n                click.echo(\"  {}\".format(format_requirement(ireq)))\n        else:\n            # prepare requirement lines\n            req_lines = []\n            for ireq in sorted(to_install, key=key_from_ireq):\n                ireq_hashes = get_hashes_from_ireq(ireq)\n                req_lines.append(format_requirement(ireq, hashes=ireq_hashes))\n\n            # save requirement lines to a temporary file\n            tmp_req_file = tempfile.NamedTemporaryFile(mode='wt', delete=False)\n            tmp_req_file.write('\\n'.join(req_lines))\n            tmp_req_file.close()\n\n            try:\n                check_call([pip, 'install', '-r', tmp_req_file.name] + pip_flags + install_flags)\n            finally:\n                os.unlink(tmp_req_file.name)\n\n    return 0\n", "path": "piptools/sync.py"}]}