aspect_rules_py
is a layer on top of rules_python
, the standard Python ruleset hosted at
https://github.com/bazelbuild/rules_python.
The lower layer of rules_python
is currently reused, dealing with the toolchain and dependencies.
However, this ruleset introduces a new implementation of py_library
, py_binary
, and py_test
.
Our philosophy is to behave more like idiomatic python ecosystem tools, where rules_python is closely
tied to the way Google does Python development in their internal monorepo, google3.
However we try to maintain compatibility with rules_python's rules for most use cases.
Layer | Legacy | Recommended |
---|---|---|
toolchain: fetch hermetic interpreter | rules_python | rules_python |
pip.parse: fetch and install deps from pypi | rules_python | rules_python |
gazelle: generate BUILD files | rules_python | aspect configure |
rules: user-facing implementations | rules_python | rules_py |
Watch our video series for a quick tutorial on how rules_py makes it easy to do Python with Bazel:
Need help? This ruleset has support provided by https://aspect.dev.
We think you'll love rules_py because it fixes many issues with rules_python's rule implementations:
- The launcher uses the Bash toolchain rather than Python, so we have no dependency on a system interpreter. Fixes:
- We don't mess with the Python
sys.path
/$PYTHONPATH
. Instead we use the standardsite-packages
folder layout produced bypip_install
. This avoids problems like package naming collisions with built-ins (e.g.collections
) or whereargparse
comes from a transitive dependency instead. Fixes: - We run python in isolated mode so we don't accidentally break out of Bazel's action sandbox. Fixes:
- We create a python-idiomatic virtualenv to run actions, which means better compatibility with userland implementations of importlib.
- Thanks to the virtualenv, you can open the project in an editor like PyCharm or VSCode and have working auto-complete, jump-to-definition, etc.
Note
What about the "starlarkification" effort in rules_python?
We think this is only useful within Google, because the semantics of the rules will remain identical. Even though the code will live in bazelbuild/rules_python rather than bazelbuild/bazel, it still cannot change without breaking Google-internal usage, and has all the ergonomic bugs above due to the way the runtime is stubbed.
Follow instructions from the release you wish to use: https://github.com/aspect-build/rules_py/releases
In any ancestor BUILD
file of the Python code, add these lines to instruct Gazelle to create rules_py
variants of the py_*
rules:
# gazelle:map_kind py_library py_library @aspect_rules_py//py:defs.bzl
# gazelle:map_kind py_binary py_binary @aspect_rules_py//py:defs.bzl
# gazelle:map_kind py_test py_test @aspect_rules_py//py:defs.bzl
- py_binary an executable Python program, used with
bazel run
or as a tool. - py_test a Python program that executes a test runner such as
unittest
orpytest
, to be used withbazel test
. - py_venv create a virtualenv for a
py_binary
orpy_test
target for use outside Bazel, such as in an editor/IDE.
- py_pex_binary Create a zip file containing a full Python application.
- py_library a unit of Python code, used as a dependency of other rules.