Fix extract_single_wheel for Windows (#498)
On Windows, when using pip_parse, pip would fail with following error:
Could not open requirements file: [Errno 13] Permission denied: ...
This is due to Python holding a handle to the temporary file preventing
pip, which is run as a sub-process, from reading it. For more
information, see: https://bugs.python.org/issue14243
Closing the requirements file before running pip solves the problem.diff --git a/python/pip_install/parse_requirements_to_bzl/extract_single_wheel/__init__.py b/python/pip_install/parse_requirements_to_bzl/extract_single_wheel/__init__.py
index 884b8ad..4ea3758 100644
--- a/python/pip_install/parse_requirements_to_bzl/extract_single_wheel/__init__.py
+++ b/python/pip_install/parse_requirements_to_bzl/extract_single_wheel/__init__.py
@@ -1,3 +1,4 @@
+import os
import argparse
import sys
import glob
@@ -29,15 +30,25 @@
if args.extra_pip_args:
pip_args += json.loads(args.extra_pip_args)["args"]
- with NamedTemporaryFile(mode='wb') as requirement_file:
+ requirement_file = NamedTemporaryFile(mode='wb', delete=False)
+ try:
requirement_file.write(args.requirement.encode("utf-8"))
requirement_file.flush()
+ # Close the file so pip is allowed to read it when running on Windows.
+ # For more information, see: https://bugs.python.org/issue14243
+ requirement_file.close()
# Requirement specific args like --hash can only be passed in a requirements file,
# so write our single requirement into a temp file in case it has any of those flags.
pip_args.extend(["-r", requirement_file.name])
# Assumes any errors are logged by pip so do nothing. This command will fail if pip fails
subprocess.run(pip_args, check=True)
+ finally:
+ try:
+ os.unlink(requirement_file.name)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
name, extras_for_pkg = requirements._parse_requirement_for_extra(args.requirement)
extras = {name: extras_for_pkg} if extras_for_pkg and name else dict()