(common-deps-with-multiple-pypi-versions)=

How to use a common set of dependencies with multiple PyPI versions

In this guide, we show how to handle a situation common to monorepos that extensively share code: How does a common library refer to the correct @pypi_<name> hub when binaries may have their own requirements (and thus PyPI hub name)? Stated as code, this situation:


py_binary( name = "bin_alpha", deps = ["@pypi_alpha//requests", ":common"], ) py_binary( name = "bin_beta", deps = ["@pypi_beta//requests", ":common"], ) py_library( name = "common", deps = ["@pypi_???//more_itertools"] # <-- Which @pypi repo? )

Using flags to pick a hub

The basic trick to make :common pick the appropriate @pypi_<name> is to use select() to choose one based on build flags. To help this process, py_binary et al allow forcing particular build flags to be used, and custom flags can be registered to allow py_binary et al to set them.

In this example, we create a custom string flag named //:pypi_hub, register it to allow using it with py_binary directly, then use select() to pick different dependencies.

# File: MODULE.bazel

rules_python_config.add_transition_setting(
    setting = "//:pypi_hub",
)

# File: BUILD.bazel

```bzl

load("@bazel_skylib//rules:common_settings.bzl", "string_flag")

string_flag(
    name = "pypi_hub",
)

config_setting(
    name = "is_pypi_alpha",
    flag_values = {"//:pypi_hub": "alpha"},
)

config_setting(
    name = "is_pypi_beta",
    flag_values = {"//:pypi_hub": "beta"}
)

py_binary(
    name = "bin_alpha",
    srcs = ["bin_alpha.py"],
    config_settings = {
        "//:pypi_hub": "alpha",
    },
    deps = ["@pypi_alpha//requests", ":common"],
)
py_binary(
    name = "bin_beta",
    srcs = ["bin_beta.py"],
    config_settings = {
        "//:pypi_hub": "beta",
    },
    deps = ["@pypi_beta//requests", ":common"],
)
py_library(
    name = "common",
    deps = select({
        ":is_pypi_alpha": ["@pypi_alpha//more_itertools"],
        ":is_pypi_beta": ["@pypi_beta//more_itertools"],
    }),
)

When bin_alpha and bin_beta are built, they will have the pypi_hub flag force to their respective value. When :common is evaluated, it sees the flag value of the binary that is consuming it, and the select() resolves appropriately.