Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Jul 21, 2021. It is now read-only.

Commit 1c1f5cd

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

File tree

1 file changed

+51
-20
lines changed
Filter options

1 file changed

+51
-20
lines changed

‎rules_python/piptool.py

Copy file name to clipboardExpand all lines: rules_python/piptool.py
+51-20Lines 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)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.