Search code examples
pythonbazelbazel-rules

What's the difference between Bazel's py_library and py_binary rules


Bazel's documentation explains how to use each, but I don't understand the difference in their nature. Aren't all python files executables anyway? What difference does it make to specify it is a binary?


Solution

  • Executable or not?

    Aren't all python files executables anyway?

    If we don't take file permissions into account, the answer to that question, if we are observing the behavior, is not necessarily. In the real world, it depends on what is written in the python file.

    What do I mean by "observing the behavior"?

    Python files can be executable in the sense that they perform "actual work" like calling methods, performing calculations, file handling, logging, etc.

    Have in mind that python files may also have a different purpose like simply defining the functions, enums, or classes that are to be used from separate python files.

    To understand the upper sentences, my recommendation is to read more about __main__ in python.


    Providing a functionality

    Now imagine a use case in which it is needed to provide a set of functions, enums, or classes for someone else to use, but not to use them in the file in which they are written. Most of the time when there is a such requirement, it is needed to develop a library that provides all the necessary functionality.


    py_library

    To create an artifact that is "passive" and is to be used by other executables you can use py_library Bazel python rule. py_library should not be an executable, it creates an artifact that can be used by other artifacts such as py_test or py_binary.

    Creating a py_library allows you to use that library in multiple Bazel targets and provides a clear message to the developers that the current target has a dependency on the specified py_library.


    py_binary

    Is the executable that is intended to be run and to perform a certain set of tasks.


    TL;DR

    What difference does it make to specify it is a binary?

    1. Use py_binary when you need to actually execute the code written in the python source files
    2. Use py_binary if it is needed to execute defined functionality from a separate file (e.g. perform setup/cleanup) like it is described in the second example of py_binary
    3. Use py_library when you need to provide passive functionalities that will be utilized from a separate python (or even a different programming language) file/artifact
    4. My recommendation is that you also watch this Youtube video that gives good insight on when/how to use, and how to "connect" py_binary, py_library and py_test