8000 Allow piptool to build wheels. · raaaar/rules_python@1c1f5cd · GitHub
[go: up one dir, main page]

Skip to content

Commit 1c1f5cd

Browse files
author
Doug Greiman
committed
Allow piptool to build wheels.
Depends on google/subpar#52
1 parent 8f3daa1 commit 1c1f5cd

File tree

1 file changed

+51
-20
lines changed

1 file changed

+51
-20
lines changed

rules_python/piptool.py

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,67 @@
1414
"""The piptool module imports pip requirements into Bazel rules."""
1515

1616
import argparse
17+
import atexit
1718
import json
1819
import os
1920
import pkgutil
2021
import re
22+
import shutil
2123
import sys
2224
import tempfile
2325
import zipfile
2426

25-
# PIP erroneously emits an error when bundled as a PAR file. We
26-
# disable the version check to silence it.
27-
try:
28-
# Make sure we're using a suitable version of pip as a library.
29-
# Fallback on using it as a CLI.
30-
from pip._vendor import requests
31-
32-
from pip import main as _pip_main
33-
def pip_main(argv):
34-
# Extract the certificates from the PAR following the example of get-pip.py
35-
# https://github.com/pypa/get-pip/blob/430ba37776ae2ad89/template.py#L164-L168
36-
cert_path = os.path.join(tempfile.mkdtemp(), "cacert.pem")
37-
with open(cert_path, "wb") as cert:
38-
cert.write(pkgutil.get_data("pip._vendor.requests", "cacert.pem"))
39-
argv = ["--disable-pip-version-check", "--cert", cert_path] + argv
40-
return _pip_main(argv)
27+
# Note: We carefully import the following modules in a particular
28+
# order, since these modules modify the import path and machinery.
29+
import pkg_resources
4130

42-
except:
43-
import subprocess
4431

45-
def pip_main(argv):
46-
return subprocess.call(['pip'] + argv)
32+
def extract_packages(package_names):
33+
"""Extract zipfile contents to disk and add to import path"""
34+
35+
# Set a safe extraction dir
36+
extraction_tmpdir = tempfile.mkdtemp()
37+
atexit.register(lambda: shutil.rmtree(
38+
extraction_tmpdir, ignore_errors=True))
39+
pkg_resources.set_extraction_path(extraction_tmpdir)
40+
41+
# Extract each package to disk
42+
dirs_to_add = []
43+
for package_name in package_names:
44+
req = pkg_resources.Requirement.parse(package_name)
45+
extraction_dir = pkg_resources.resource_filename(req, '')
46+
dirs_to_add.append(extraction_dir)
47+
48+
# Add extracted directories to import path ahead of their zip file
49+
# counterparts.
50+
sys.path[0:0] = dirs_to_add
51+
existing_pythonpath = os.environ['PYTHONPATH'].split(':')
52+
os.environ['PYTHONPATH'] = ':'.join(dirs_to_add + existing_pythonpath)
53+
54+
55+
# Wheel, pip, and setuptools are much happier running from actual
56+
# files on disk, rather than entries in a zipfile. Extract zipfile
57+
# contents, add those contents to the path, then import them.
58+
extract_packages(['pip', 'setuptools', 'wheel'])
59+
60+
# Defeat pip's attempt to mangle sys.path
61+
saved_sys_path = sys.path
62+
sys.path = sys.path[:]
63+
import pip
64+
sys.path = saved_sys_path
65+
66+
import setuptools
67+
import wheel
68+
69+
# Make sure we're using a suitable version of pip as a library.
70+
# Fallback on using it as a CLI.
71+
from pip._vendor import requests
72+
73+
from pip import main as _pip_main
74+
def pip_main(argv):
75+
argv = ["--disable-pip-version-check"] + argv
76+
return _pip_main(argv)
77+
4778

4879
# TODO(mattmoor): We can't easily depend on other libraries when
4980
# being invoked as a raw .py file. Once bundled, we should be able

0 commit comments

Comments
 (0)
0