8000 Support python interpreter target in pip_repository (#39) · rahulmutt/rules_python@ed2f644 · GitHub
[go: up one dir, main page]

Skip to content

Commit ed2f644

Browse files
Support python interpreter target in pip_repository (bazel-contrib#39)
1 parent 3aacabb commit ed2f644

File tree

4 files changed

+98
-6
lines changed

4 files changed

+98
-6
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ load("@rules_python_external//:defs.bzl", "pip_install")
5252
pip_install(
5353
name = "py_deps",
5454
requirements = "//:requirements.txt",
55+
# (Optional) You can provide a python interpreter (by path):
56+
python_interpreter = "/usr/bin/python3.8",
57+
# (Optional) Alternatively you can provide an in-build python interpreter, that is available as a Bazel target.
58+
# This overrides `python_interpreter`.
59+
# Note: You need to set up the interpreter target beforehand (not shown here). Please see the `example` folder for further details.
60+
#python_interpreter_target = "@python_interpreter//:python_bin",
5561
)
5662
```
5763

defs.bzl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ DEFAULT_REPOSITORY_NAME = "pip"
55

66
def _pip_repository_impl(rctx):
77
python_interpreter = rctx.attr.python_interpreter
8-
if '/' not in python_interpreter:
9-
python_interpreter = rctx.which(python_interpreter)
10-
if not python_interpreter:
11-
fail("python interpreter not found")
8+
if rctx.attr.python_interpreter_target != None:
9+
target = rctx.attr.python_interpreter_target
10+
python_interpreter = rctx.path(target)
11+
else:
12+
if '/' not in python_interpreter:
13+
python_interpreter = rctx.which(python_interpreter)
14+
if not python_interpreter:
15+
fail("python interpreter not found")
1216

1317
rctx.file("BUILD", "")
1418

@@ -48,6 +52,12 @@ pip_repository = repository_rule(
4852
"requirements": attr.label(allow_single_file=True, mandatory=True,),
4953
"wheel_env": attr.string_dict(),
5054
"python_interpreter": attr.string(default="python3"),
55+
"python_interpreter_target": attr.label(allow_single_file = True, doc = """
56+
If you are using a custom python interpreter built by another repository rule,
57+
use this attribute to specify its BUILD target. This allows pip_repository to invoke
58+
pip using the same interpreter as your toolchain. If set, takes precedence over
59+
python_interpreter.
60+
"""),
5161
# 600 is documented as default here: https://docs.bazel.build/versions/master/skylark/lib/repository_ctx.html#execute
5262
"timeout": attr.int(default = 600),
5363
},

example/BUILD

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
11
load("@pip//:requirements.bzl", "requirement")
2+
load("@rules_python//python:defs.bzl", "py_runtime_pair")
3+
4+
# Toolchain setup, this is optional.
5+
# Demonstrate that we can use the same python interpreter for the toolchain and executing pip in pip install (see WORKSPACE).
6+
py_runtime(
7+
name = "python3_runtime",
8+
files = ["@python_interpreter//:files"],
9+
interpreter = "@python_interpreter//:python_bin",
10+
python_version = "PY3",
11+
visibility = ["//visibility:public"],
12+
)
13+
14+
py_runtime_pair(
15+
name = "my_py_runtime_pair",
16+
py2_runtime = None,
17+
py3_runtime = ":python3_runtime",
18+
)
19+
20+
toolchain(
21+
name = "my_py_toolchain",
22+
toolchain = ":my_py_runtime_pair",
23+
toolchain_type = "@bazel_tools//tools/python:toolchain_type",
24+
)
25+
# End of toolchain setup.
226

327
py_binary(
428
name = "main",
529
srcs = ["main.py"],
630
deps = [
7-
requirement("boto3")
31+
requirement("boto3"),
832
],
933
)

example/WORKSPACE

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,74 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
44

55
http_archive(
66
name = "rules_python",
7-
url = "https://github.com/bazelbuild/rules_python/releases/download/0.0.1/rules_python-0.0.1.tar.gz",
87
sha256 = "aa96a691d3a8177f3215b14b0edc9641787abaaa30363a080165d06ab65e1161",
8+
url = "https://github.com/bazelbuild/rules_python/releases/download/0.0.1/rules_python-0.0.1.tar.gz",
99
)
10+
1011
load("@rules_python//python:repositories.bzl", "py_repositories")
12+
1113
py_repositories()
1214

15+
# You could optionally use an in-build, compiled python interpreter as a toolchain,
16+
# and also use it to execute pip.
17+
18+
# Special logic for building python interpreter with OpenSSL from homebrew.
19+
# See https://devguide.python.org/setup/#macos-and-os-x
20+
_py_configure = """
21+
if [[ "$OSTYPE" == "darwin"* ]]; then
22+
./configure --prefix=$(pwd)/bazel_install --with-openssl=$(brew --prefix openssl)
23+
else
24+
./configure --prefix=$(pwd)/bazel_install
25+
fi
26+
"""
27+
28+
# NOTE: you need to have the SSL headers installed to build with openssl support (and use HTTPS).
29+
# E.g. on Ubuntu: `sudo apt install libssl-dev`
30+
http_archive(
31+
name = "python_interpreter",
32+
build_file_content = """
33+
exports_files(["python_bin"])
34+
filegroup(
35+
name = "files",
36+
srcs = glob(["bazel_install/**"], exclude = ["**/* *"]),
37+
visibility = ["//visibility:public"],
38+
)
39+
""",
40+
patch_cmds = [
41+
"mkdir $(pwd)/bazel_install",
42+
_py_configure,
43+
"make",
44+
"make install",
45+
"ln -s bazel_install/bin/python3 python_bin",
46+
],
47+
sha256 = "dfab5ec723c218082fe3d5d7ae17ecbdebffa9a1aea4d64aa3a2ecdd2e795864",
48+
strip_prefix = "Python-3.8.3",
49+
urls = ["https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tar.xz"],
50+
)
51+
# End of in-build Python interpreter setup.
52+
1353
local_repository(
1454
name = "rules_python_external",
1555
path = "../",
1656
)
1757

1858
load("@rules_python_external//:repositories.bzl", "rules_python_external_dependencies")
59+
1960
rules_python_external_dependencies()
2061

2162
load("@rules_python_external//:defs.bzl", "pip_install")
63+
2264
pip_install(
65+
# You can optionally provide a python_interpreter (path) or a python_interpreter_target (a Bazel target, that
66+
# acts as an executable). The latter can be anything that could be used as Python interpreter. E.g.:
67+
# 1. Python interpreter that you compile in the build file (as above in @python_interpreter).
68+
# 2. Pre-compiled python interpreter included with http_archive
69+
# 3. Wrapper script, like in the autodetecting python toolchain.
70+
python_interpreter_target = "@python_interpreter//:python_bin",
2371
# Uses the default repository name "pip"
2472
requirements = "//:requirements.txt",
2573
)
74+
75+
# Optional:
76+
# Register the toolchain with the same python interpreter we used for pip in pip_install().
77+
register_toolchains("//:my_py_toolchain")

0 commit comments

Comments
 (0)
0