Global Venv

Bazel rules for generating usable virtualenv from Bazel targets.

Usage

A venv can be created by invoking the following command

bazel run @rules_venv//python/global_venv

From here a venv will likely be available at .venv within your workspace that can be activated for improved IDE support.

Pyright / Pylance

By default, a bazel-pyrightconfig.json is generated with extraPaths pointing to each Bazel output directory that contains generated Python sources. To use it, add an extends field to your pyrightconfig.json:

{
    "extends": "bazel-pyrightconfig.json"
}

Important: Do not define extraPaths in your own pyrightconfig.json. Pyright's extends replaces array fields rather than merging them, so any extraPaths in the child config will override the generated values.

Ruff / isort

Ruff classifies imports as first-party by checking whether the imported module can be resolved under its src directories. Generated sources (.pyi stubs, .so extensions) only exist under bazel-out, so ruff needs those directories in src:

# .ruff.toml
src = [".", "bazel-out/k8-*/bin"]

For standalone isort:

# .isort.cfg
[isort]
src_paths = .,bazel-out/k8-*/bin

The glob k8-* covers all Bazel configurations (k8-fastbuild, k8-opt, k8-dbg).

Entrypoints

By default, py_global_venv auto-discovers console_scripts entrypoints from pip packages (via importlib.metadata) and generates executable scripts in the venv's bin/ directory. Pre-built binaries shipped via wheel data scripts (e.g. ruff) are also symlinked into the venv. This allows IDEs to find tools like black, ruff, or mypy inside the venv.

Additional entrypoints can be specified manually:

py_global_venv(
    name = "global_venv",
    entrypoints = {
        "my_tool": "my.module:cli",
    },
)

Auto-discovery can be disabled with gen_entrypoints = False.

Functions

Aspects

py_global_venv

load("@rules_venv//python/global_venv:defs.bzl", "py_global_venv")

py_global_venv(*, name, gen_pyrightconfig, gen_entrypoints, entrypoints, build_srcs, **kwargs)

Define a "global venv" executable.

When gen_pyrightconfig is enabled (the default), running this target writes a bazel-pyrightconfig.json at the workspace root containing extraPaths that point into bazel-bin. This lets Pyright/Pylance resolve generated Python sources that live outside the source tree.

To use it, add an extends field to your pyrightconfig.json::

{
    "extends": "bazel-pyrightconfig.json",
    ...
}

Important: Do not define extraPaths in your own pyrightconfig.json when using extends. Pyright's extends replaces array fields rather than merging them, so any extraPaths in the child config will override the generated values from bazel-pyrightconfig.json.

When targets use configuration transitions (e.g. py_cc_extension building with compilation_mode = "opt"), generated files may live in directories like bazel-out/k8-opt/bin instead of bazel-out/k8-fastbuild/bin. The generated bazel-pyrightconfig.json includes all observed output directories automatically.

For ruff or isort to correctly classify first-party imports that include generated sources, add the Bazel output directories to the src setting::

# .ruff.toml
src = [".", "bazel-out/k8-*/bin"]

For standalone isort::

# .isort.cfg
[isort]
src_paths = .,bazel-out/k8-*/bin

This allows ruff/isort to find generated .pyi stubs and .so extensions when determining whether an import is first-party or third-party.

When gen_entrypoints is enabled (the default), running this target will auto-discover console_scripts entrypoints from pip packages via importlib.metadata and generate executable scripts in the venv's bin/ directory. Pre-built binaries shipped via wheel data scripts (e.g. ruff) are also symlinked into the venv. This allows IDEs to find tools like black, ruff, or mypy inside the venv. Additional entrypoints can be specified manually via entrypoints.

PARAMETERS

NameDescriptionDefault Value
nameThe name of the targetnone
gen_pyrightconfigGenerate a bazel-pyrightconfig.json to support indexing Bazel generated files.True
gen_entrypointsAuto-discover console_scripts entrypoints from pip packages and generate executable scripts in the venv bin/ directory.True
entrypointsA mapping of script names to module specs (e.g. {"black": "black:patched_main"}). These are always rendered regardless of gen_entrypoints. When gen_entrypoints is also enabled, manual entries take precedence over auto-discovered ones.{}
build_srcsBuild all python sources to ensure they're available for loading.False
kwargsAdditional keyword arguments for the py_venv_binary.none

py_global_venv_aspect

load("@rules_venv//python/global_venv:defs.bzl", "py_global_venv_aspect")

py_global_venv_aspect()

An aspect for generating metadata required to include Python targets in a global venv.

ASPECT ATTRIBUTES

ATTRIBUTES