Search code examples
pythonbazel

Bazel: install python using bazel


I am working on an Bazel build MVP, and one of the steps in this process is to run our build in CI. However, CI builds are run in docker containers that do not contain much. Previously I had to add gcc to the container to build python that is used by Bazel itself, but now when I try to build a python library with py_wheel, I get the error /usr/bin/env: 'python3': No such file or directory. On the one hand, I do realise that I can just add the required python to the container, but that does not seem to be hermetic, and then the python version will have to be configured in the repo where the Docker images for our containers are kept, not within the project itself, which adds another layer of complexity.

Is there a way to install the required python from Bazel iteslf? Or do I have to install it in docker?

UPD My initial approach was as per the documentation and what Brian Silverman described below. I also tried other approaches (https://www.anthonyvardaro.com/blog/hermetic-python-toolchain-with-bazel, https://thundergolfer.com/bazel/python/2021/06/25/a-basic-python-bazel-toolchain/), but to no avail. Each of these approaches does download python, but when I run my python binaries or the py_wheel rule, the scripts look for /usr/bin/env python, which cannot be found.


Solution

  • For most of the build, you can register a hermetic Python toolchain:

    load("@rules_python//python:repositories.bzl", "python_register_toolchains")
    
    python_register_toolchains(
        name = "python3_9",
        # Available versions are listed in @rules_python//python:versions.bzl.
        python_version = "3.9",
    )
    
    load("@python3_9//:defs.bzl", "interpreter")
    
    load("@rules_python//python:pip.bzl", "pip_parse")
    
    pip_parse(
        ...
        python_interpreter_target = interpreter,
        ...
    )
    

    Most other targets (py_binary etc) will just use the toolchain without needing any changes.

    However, rules_python#691 says you'll need a system-installed python for bootstrapping. There's some potential workarounds in there, I've never tried them.