rules_venv

Overview

This repository implements Bazel rules for Python and is designed to be a drop-in replacement for the existing rules_python where uses of @rules_python//python:defs.bzl can be replaced with @rules_venv//python:defs.bzl.

Improvements over rules_python

While rules_python has fantastic toolchain infrastructure which this repo relies on, rules_python ultimately suffers from a few issues which this repo aims to solve:

  1. Use of PYTHONPATH to construct the python environment leads to operating system limitations.

    Some details on MAX_ARG_STRLEN and ARG_MAX can be found here: https://unix.stackexchange.com/a/120842

  2. Slow startup on windows systems that do not support symlinks.

    rules_python creates zipapps on systems that do not support runfiles. For large projects, this can lead to large (~500MB+) zip files being constantly compressed and uncompressed to run simple actions which is a lot more expensive than systems which support runfiles.

Setup

bzlmod

bazel_dep(name = "rules_venv", version = "{version}")

WORKSPACE.bazel

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# See releases for urls and checksums
http_archive(
    name = "rules_venv",
    sha256 = "{sha256}",
    urls = ["https://github.com/periareon/rules_venv/releases/download/{version}/rules_venv-v{version}.tar.gz"],
)

load("@rules_venv//venv:repositories.bzl", "venv_register_toolchains", "rules_venv_dependencies")

rules_venv_dependencies()

venv_register_toolchains()

load("@rules_venv//python/venv:repositories_transitive.bzl", "rules_venv_transitive_deps")

rules_venv_transitive_deps()

Venv

Core Bazel rules for defining Python targets.

Rules

Functions

py_venv_binary

load("@rules_venv//python/venv:defs.bzl", "py_venv_binary")

py_venv_binary(name, deps, srcs, data, env, imports, main)

A py_venv_binary is an executable Python program consisting of a collection of .py source files (possibly belonging to other py_library rules), a *.runfiles directory tree containing all the code and data needed by the program at run-time, and a stub script that starts up the program with the correct initial environment and data.

load("@rules_venv//python/venv:defs.bzl", "py_venv_binary")

py_venv_binary(
    name = "foo",
    srcs = ["foo.py"],
    data = [":transform"],  # a cc_binary which we invoke at run time
    deps = [
        ":bar",  # a py_library
    ],
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsOther python targets to link to the current target.List of labelsoptional[]
srcsThe list of source (.py) files that are processed to create the target.List of labelsoptional[]
dataFiles needed by this rule at runtime. May list file or rule targets. Generally allows any target.List of labelsoptional[]
envDictionary of strings; values are subject to $(location) and "Make variable" substitution.Dictionary: String -> Stringoptional{}
importsList of import directories to be added to the PYTHONPATH.List of stringsoptional[]
mainThe name of the source file that is the main entry point of the application. This file must also be listed in srcs. If left unspecified, name is used instead. If name does not match any filename in srcs, main must be specified.LabeloptionalNone

py_venv_library

load("@rules_venv//python/venv:defs.bzl", "py_venv_library")

py_venv_library(name, deps, srcs, data, imports)

A library of Python code that can be depended upon.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsOther python targets to link to the current target.List of labelsoptional[]
srcsThe list of source (.py) files that are processed to create the target.List of labelsoptional[]
dataFiles needed by this rule at runtime. May list file or rule targets. Generally allows any target.List of labelsoptional[]
importsList of import directories to be added to the PYTHONPATH.List of stringsoptional[]

py_venv_test

load("@rules_venv//python/venv:defs.bzl", "py_venv_test")

py_venv_test(name, deps, srcs, data, env, env_inherit, imports, main)

A py_venv_test rule compiles a test. A test is a binary wrapper around some test code.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
depsOther python targets to link to the current target.List of labelsoptional[]
srcsThe list of source (.py) files that are processed to create the target.List of labelsoptional[]
dataFiles needed by this rule at runtime. May list file or rule targets. Generally allows any target.List of labelsoptional[]
envDictionary of strings; values are subject to $(location) and "Make variable" substitution.Dictionary: String -> Stringoptional{}
env_inheritSpecifies additional environment variables to inherit from the external environment when the test is executed by bazel test.List of stringsoptional[]
importsList of import directories to be added to the PYTHONPATH.List of stringsoptional[]
mainThe name of the source file that is the main entry point of the application. This file must also be listed in srcs. If left unspecified, name is used instead. If name does not match any filename in srcs, main must be specified.LabeloptionalNone

py_venv_toolchain

load("@rules_venv//python/venv:defs.bzl", "py_venv_toolchain")

py_venv_toolchain(name, zipapp_shebang)

Declare a toolchain for rules_venv rules.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
zipapp_shebangThe shebang to use when creating zipapps (OutputGroupInfo.python_zip_file).Stringoptional""

py_venv_zipapp

load("@rules_venv//python/venv:defs.bzl", "py_venv_zipapp")

py_venv_zipapp(name, args, binary, env, inherit_args, inherit_env, shebang)

A py_venv_zipapp is an executable Python zipapp which contains all of the dependencies and runfiles for a given executable.

load("@rules_venv//python/venv:defs.bzl", "py_venv_binary", "py_venv_zipapp")

py_venv_binary(
    name = "foo",
    srcs = ["foo.py"],
)

py_venv_zipapp(
    name = "foo_pyz",
    binary = ":foo",
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
argsArguments to add to the beginning of all invocations of the zipapp.List of stringsoptional[]
binaryThe binary to package as a zipapp.LabeloptionalNone
envEnvironment variables to inject into all invocations of the zipapp.Dictionary: String -> Stringoptional{}
inherit_argsInherit template variable expanded arguments from binary.BooleanoptionalFalse
inherit_envInherit template variable expanded environment variables from binary.BooleanoptionalFalse
shebangOptional shebang line to prepend to the zip (provided as content after #!).Stringoptional""

py_venv_common.create_dep_info

load("@rules_venv//python/venv:defs.bzl", "py_venv_common")

py_venv_common.create_dep_info(*, ctx, deps)

Construct dependency info required for building PyInfo

PARAMETERS

NameDescriptionDefault Value
ctxThe rule's context object.none
depsA list of python dependency targetsnone

RETURNS

struct: Dependency info.

py_venv_common.create_py_info

load("@rules_venv//python/venv:defs.bzl", "py_venv_common")

py_venv_common.create_py_info(*, ctx, imports, srcs, dep_info)

Construct a PyInfo provider

PARAMETERS

NameDescriptionDefault Value
ctxThe rule's context object.none
importsThe raw imports attribute.none
srcsA list of python (.py) source files.none
dep_infoDependency info from the current target.None

RETURNS

PyInfo: A PyInfo provider.

py_venv_common.create_runfiles_collection

load("@rules_venv//python/venv:defs.bzl", "py_venv_common")

py_venv_common.create_runfiles_collection(*, ctx, venv_toolchain, py_toolchain, runfiles,
                                          exclude_files, name, use_zip)

Generate a runfiles directory

This functionality exists due to the lack of native support for generating runfiles in an action. For details see: https://github.com/bazelbuild/bazel/issues/15486

PARAMETERS

NameDescriptionDefault Value
ctxThe rule's context object.none
venv_toolchainA py_venv_toolchain toolchain.none
py_toolchainA py_toolchain toolchain.none
runfilesThe runfiles to render into a directorynone
exclude_filesA collection of files to exclude from the collection despite them appearing in runfiles.depset([])
nameAn alternate name to use in the output instead of ctx.label.name.None
use_zipIf True, a zip file will be generated instead of a json manifest.False

RETURNS

Tuple[File, Runfiles]: The generated runfiles collection and associated runfiles.

py_venv_common.create_venv_attrs

load("@rules_venv//python/venv:defs.bzl", "py_venv_common")

py_venv_common.create_venv_attrs()

py_venv_common.create_venv_config_info

load("@rules_venv//python/venv:defs.bzl", "py_venv_common")

py_venv_common.create_venv_config_info(*, label, name, imports)

Construct info used to create venvs.

PARAMETERS

NameDescriptionDefault Value
labelThe label of the target that owns the venv.none
nameThe name for the venv.none
importsA list of import paths to write to .pth files.none

RETURNS

struct: the data.

py_venv_common.create_venv_entrypoint

load("@rules_venv//python/venv:defs.bzl", "py_venv_common")

py_venv_common.create_venv_entrypoint(*, ctx, venv_toolchain, py_info, main, runfiles, py_toolchain,
                                      name, use_runfiles_in_entrypoint, force_runfiles)

Create an executable which constructs a python venv and subprocesses a given entrypoint.

PARAMETERS

NameDescriptionDefault Value
ctxThe rule's context object.none
venv_toolchainA py_venv_toolchain toolchain.none
py_infoThe PyInfo provider for the current target.none
mainThe main python entrypoint.none
runfilesRunfiles associated with the executable.none
py_toolchainA py_toolchain toolchain. If one is not provided one will be acquired via py_venv_toolchain.None
nameAn alternate name to use in the output instead of ctx.label.name.None
use_runfiles_in_entrypointIf true, an entrypoint will be created that relies on runfiles.True
force_runfilesIf True, a rendered runfiles directory will be used over builtin runfiles where RUNFILES_DIR would be provided.False

RETURNS

Tuple[File, Runfiles]: The generated entrypoint and associated runfiles.

py_venv_common.get_toolchain

load("@rules_venv//python/venv:defs.bzl", "py_venv_common")

py_venv_common.get_toolchain(ctx, *, cfg)

PARAMETERS

NameDescriptionDefault Value
ctx

-

none
cfg

-

"target"

Extensions

Additional rules which are built from core rules_venv to provide Bazel rules for popular python tools.

Black

Bazel rules for the Python formatter black.

Setup

First ensure rules_venv is setup by referring to rules_venv setup.

Next, the black rules work mostly off of toolchains which are used to provide the necessary python targets (aka black) for the process wrappers. Users will want to make sure they have a way to get the necessary python dependencies. Tools such as req-compile can provide these.

With the appropriate dependencies available, a py_black_toolchain will need to be configured:

load("@rules_venv//python/black:defs.bzl", "py_black_toolchain")

py_black_toolchain(
    name = "toolchain_impl",
    black = "@pip_deps//:black",
    visibility = ["//visibility:public"]
)

toolchain(
    name = "toolchain",
    toolchain = ":toolchain_impl",
    toolchain_type = "@rules_venv//python/black:toolchain_type",
    visibility = ["//visibility:public"]
)

This toolchain then needs to be registered in the MODULE.bazel file.

register_toolchains("//tools/python/black:toolchain")

Usage

Python code can be formatted using the following command:

bazel run @rules_venv//python/black

In addition to this formatter, a check can be added to bazel build invocations using the py_black_aspect aspect. Simply add the following to a .bazelrc file to enable this check.

build --aspects=@rules_venv//python/black:defs.bzl%py_black_aspect
build --output_groups=+py_black_checks

Rules

Aspects

py_black_test

load("@rules_venv//python/black:defs.bzl", "py_black_test")

py_black_test(name, config, target)

A rule for running black on a Python target.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
configThe config file (pyproject.toml) containing black settings.Labeloptional"@rules_venv//python/black:config"
targetThe target to run black on.Labelrequired

py_black_toolchain

load("@rules_venv//python/black:defs.bzl", "py_black_toolchain")

py_black_toolchain(name, black)

A toolchain for the black formatter rules.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
blackThe black py_library to use with the rules.Labelrequired

py_black_aspect

load("@rules_venv//python/black:defs.bzl", "py_black_aspect")

py_black_aspect()

An aspect for running black on targets with Python sources.

ASPECT ATTRIBUTES

ATTRIBUTES

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.

Aspects

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

isort

Bazel rules for the Python formatter isort.

Setup

First ensure rules_venv is setup by referring to rules_venv setup.

Next, the rules_venv rules work mostly off of toolchains which are used to provide the necessary python targets (aka isort) for the process wrappers. Users will want to make sure they have a way to get the necessary python dependencies. Tools such as req-compile can provide these.

With the appropriate dependencies available, a py_isort_toolchain will need to be configured:

load("@rules_venv//python/isort:defs.bzl", "py_isort_toolchain")

py_isort_toolchain(
    name = "toolchain_impl",
    isort = "@pip_deps//:isort",
    visibility = ["//visibility:public"]
)

toolchain(
    name = "toolchain",
    toolchain = ":toolchain_impl",
    toolchain_type = "@rules_venv//python/isort:toolchain_type",
    visibility = ["//visibility:public"]
)

This toolchain then needs to be registered in the MODULE.bazel file.

register_toolchains("//tools/python/isort:toolchain")

Usage

Python code can be formatted using the following command:

bazel run @rules_venv//python/isort

In addition to this formatter, a check can be added to bazel build invocations using the py_isort_aspect aspect. Simply add the following to a .bazelrc file to enable this check.

build --aspects=@rules_venv//python/isort:defs.bzl%py_isort_aspect
build --output_groups=+py_isort_checks

Sections and Ordering

Of all isort sections, FIRSTPARTY and THIRDPARTY follow unique rules to ensure ordering makes sense on a per-target basis.

First party

  • Direct source dependencies passed to the srcs attribute.
  • Repository relative packages.

Third party

  • Other py_* targets (the deps attribute). Note that deps which use repo absolute import paths will be considered first party.

Tips

Isort is sensitive to the legacy_create_init attribute on python rules. For more correct and consistent behavior, this value should always be 0 or if the default of -1 is set, the --incompatible_default_to_explicit_init_py flag should be added to the workspace's .bazelrc file to ensure the behavior is disabled.

Rules

Aspects

py_isort_test

load("@rules_venv//python/isort:defs.bzl", "py_isort_test")

py_isort_test(name, config, target)

A rule for running isort on a Python target.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
configThe config file (isort.cfg) containing isort settings.Labeloptional"@rules_venv//python/isort:config"
targetThe target to run isort on.Labelrequired

py_isort_toolchain

load("@rules_venv//python/isort:defs.bzl", "py_isort_toolchain")

py_isort_toolchain(name, isort)

A toolchain for the isort formatter rules.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
isortThe isort py_library to use with the rules.Labelrequired

py_isort_aspect

load("@rules_venv//python/isort:defs.bzl", "py_isort_aspect")

py_isort_aspect()

An aspect for running isort on targets with Python sources.

ASPECT ATTRIBUTES

ATTRIBUTES

Module Extensions

Rules for building Module Extensions

Functions

py_cc_extension

load("@rules_venv//python/module_extension:defs.bzl", "py_cc_extension")

py_cc_extension(*, name, srcs, conlyopts, copts, cxxopts, data, defines, deps, dynamic_deps,
                imports, includes, linkopts, local_defines, malloc, compilation_mode, abi, stripped,
                **kwargs)

Define a Python C extension module.

This target is consumed just as a py_library would be.

PARAMETERS

NameDescriptionDefault Value
nameThe name of the target.none
srcshe list of C and C++ files that are processed to create the library target. These are C/C++ source and header files, either non-generated (normal source code) or generated. For more details see cc_binary.srcsnone
conlyoptsAdd these options to the C compilation command. For more details see cc_binary.conlyopts[]
coptsAdd these options to the C/C++ compilation command. For more details see cc_binary.copts[]
cxxoptsAdd these options to the C++ compilation command. For more details see cc_binary.cxxopts[]
dataList of files used by this rule at compile time and runtime. For more details see cc_binary.data[]
definesList of defines to add to the compile line of this and all dependent targets For more details see cc_binary.defines[]
depsThe list of other libraries to be linked in to the binary target. For more details see cc_binary.deps[]
dynamic_depsThese are other cc_shared_library dependencies the current target depends on. For more details see cc_binary.dynamic_deps[]
importsList of import directories to be added to the PYTHONPATH. For more details see py_library.imports.[]
includesList of include dirs to be added to the compile line. For more details see cc_binary.includes[]
linkoptsAdd these flags to the C++ linker command. For more details see cc_binary.linkopts[]
local_definesList of defines to add to the compile line. For more details see cc_binary.local_definesNone
mallocOverride the default dependency on malloc. For more details see cc_binary.mallocNone
compilation_modeThe compilation_mode value to build the extension for. If set to "current", the current configuration will be used."opt"
abiThe ABI value to use for the output library name.select({"@platforms//os:linux": "gnu", "//conditions:default": ""})
strippedUse the stripped output of the c extension for the library.None
kwargsAdditional keyword arguments for common definition attributes.none

rules_mypy

Bazel rules for the Python linter mypy.

Setup

First ensure rules_venv is setup by referring to rules_venv setup.

Next, the mypy rules work mostly off of toolchains which are used to provide the necessary python targets (aka mypy) for the process wrappers. Users will want to make sure they have a way to get the necessary python dependencies. Tools such as req-compile can provide these.

With the appropriate dependencies available, a py_mypy_toolchain will need to be configured:

load("@rules_venv//python:defs.bzl", "py_library")
load("@rules_venv//python/mypy:defs.bzl", "py_mypy_toolchain")

py_library(
    name = "mypy_deps",
    deps = [
        "@pip_deps//:mypy",

        # Types libraries can also be added here.
    ],
)

py_mypy_toolchain(
    name = "toolchain_impl",
    mypy = ":mypy_deps",
    visibility = ["//visibility:public"]
)

toolchain(
    name = "toolchain",
    toolchain = ":toolchain_impl",
    toolchain_type = "@rules_venv//python/mypy:toolchain_type",
    visibility = ["//visibility:public"]
)

This toolchain then needs to be registered in the MODULE.bazel file.

register_toolchains("//tools/python/mypy:toolchain")

From here, py_mypy_test and the py_mypy_aspect should now be usable. Both of these rules use a global flag to determine which mypy configuration file to use with in actions. The following snippet can be added to the .bazelrc file to chose the desired configuration file

build --@rules_mypy//python/mypy:config=//:.mypyrc.toml

Note that these files will need to be available via exports_files

Rules

Aspects

py_mypy_test

load("@rules_venv//python/mypy:defs.bzl", "py_mypy_test")

py_mypy_test(name, config, target)

A rule for running mypy on a Python target.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
configThe config file (mypy.ini) containing mypy settings.Labeloptional"@rules_venv//python/mypy:config"
targetThe target to run mypy on.Labelrequired

py_mypy_toolchain

load("@rules_venv//python/mypy:defs.bzl", "py_mypy_toolchain")

py_mypy_toolchain(name, mypy)

A toolchain for the mypy formatter rules.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
mypyThe mypy py_library to use with the rules.Labelrequired

py_mypy_aspect

load("@rules_venv//python/mypy:defs.bzl", "py_mypy_aspect")

py_mypy_aspect()

An aspect for running mypy on targets with Python sources.

ASPECT ATTRIBUTES

ATTRIBUTES

Pylint

Bazel rules for the Python linter Pylint.

Setup

First ensure rules_venv is setup by referring to rules_venv setup.

Next, the pylint rules work mostly off of toolchains which are used to provide the necessary python targets (aka pylint) for the process wrappers. Users will want to make sure they have a way to get the necessary python dependencies. Tools such as req-compile can provide these.

With the appropriate dependencies available, a py_pylint_toolchain will need to be configured:

load("@rules_venv//python/pylint:defs.bzl", "py_pylint_toolchain")

py_pylint_toolchain(
    name = "toolchain_impl",
    pylint = "@pip_deps//:pylint",
    visibility = ["//visibility:public"]
)

toolchain(
    name = "toolchain",
    toolchain = ":toolchain_impl",
    toolchain_type = "@rules_venv//python/pylint:toolchain_type",
    visibility = ["//visibility:public"]
)

This toolchain then needs to be registered in the MODULE.bazel file.

register_toolchains("//tools/python/pylint:toolchain")

From here, py_pylint_test and the py_pylint_aspect should now be usable. Both of these rules use a global flag to determine which pylint configuration file to use with in actions. The following snippet can be added to the .bazelrc file to chose the desired configuration file

build --@rules_pylint//python/pylint:config=//:.pylintrc.toml

Note that these files will need to be available via exports_files

Rules

Aspects

py_pylint_test

load("@rules_venv//python/pylint:defs.bzl", "py_pylint_test")

py_pylint_test(name, config, target)

A rule for running pylint on a Python target.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
configThe config file (pylintrc) containing pylint settings.Labeloptional"@rules_venv//python/pylint:config"
targetThe target to run pylint on.Labelrequired

py_pylint_toolchain

load("@rules_venv//python/pylint:defs.bzl", "py_pylint_toolchain")

py_pylint_toolchain(name, pylint)

A toolchain for the pylint formatter rules.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
pylintThe pylint py_library to use with the rules.Labelrequired

py_pylint_aspect

load("@rules_venv//python/pylint:defs.bzl", "py_pylint_aspect")

py_pylint_aspect()

An aspect for running pylint on targets with Python sources.

This aspect can be configured by adding the following snippet to a workspace's .bazelrc file:

build --aspects=@rules_venv//python/pylint:defs.bzl%py_pylint_aspect
build --output_groups=+py_pylint_checks

ASPECT ATTRIBUTES

ATTRIBUTES

Wheel

A framework for defining wheels from a tree of Bazel targets.

Why use this over what rules_python provides?

The rules here primarily wrap what rules_python provides but offers some improvements:

  1. Requirements are collected from transitive dependencies and added as Require-Dist to the wheel.
  2. Sources and data are automatically collected.

Setup

Building wheels requires no setup, however, to activate all features of the wheel rules, a toolchain must be registered.

First some external python requirements will be required. There is guidance on how to configure this in projects like rules_req_compile. Once there is a means to fetch external dependencies within your repository, a toolchain can be defined in a BUILD.bazel file.

Example //:BUILD.bazel:

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_toolchain")

py_wheel_toolchain(
    name = "py_wheel_toolchain_impl",
    # Definable using bzlmod modules like: https://github.com/periareon/req-compile
    twine = "@pip_deps//:twine",
    visibility = ["//visibility:public"],
)

toolchain(
    name = "py_wheel_toolchain",
    toolchain = ":py_wheel_toolchain_impl",
    toolchain_type = "@rules_venv//python/wheel:toolchain_type",
    visibility = ["//visibility:public"],
)

Once the toolchain is defined, it should be registered in the MODULE.bazel file

Example //:MODULE.bazel:

register_toolchains(
    "//:py_wheel_toolchain",
)

This will ensure all features of the wheel rules are available and usable.

Rules

Functions

py_wheel_publisher

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_publisher")

py_wheel_publisher(name, repository_url, wheel)

A rule for publishing wheels to pypi registries.

The rule uses twine to python registries. Users should refer to the documentation there for any configuration flags (such as auth) needed to deploy to the desired location.

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
repository_urlThe repository (package index) URL to upload the wheel to. If passed the twine arg --repository-url will be set to this value.Stringoptional""
wheelThe wheel to extract.Labelrequired

py_wheel_toolchain

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_toolchain")

py_wheel_toolchain(name, twine)

A toolchain for powering the py_wheel rules.

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_toolchain")

py_wheel_toolchain(
    name = "py_wheel_toolchain_impl",
    # Definable using bzlmod modules like: https://github.com/periareon/req-compile
    twine = "@pip_deps//:twine",
    visibility = ["//visibility:public"],
)

toolchain(
    name = "py_wheel_toolchain",
    toolchain = ":py_wheel_toolchain_impl",
    toolchain_type = "@rules_venv//python/wheel:toolchain_type",
    visibility = ["//visibility:public"],
)

ATTRIBUTES

NameDescriptionTypeMandatoryDefault
nameA unique name for this target.Namerequired
twineA py_library for twine.Labelrequired

package_tag

load("@rules_venv//python/wheel:defs.bzl", "package_tag")

package_tag(name)

Generate a tag used to associate the target with a python package.

This tag should only be applied to other py_* targets.

Example:

load("@rules_venv//python:defs.bzl", "py_library")
load("@rules_venv//python/wheel:defs.bzl", "package_tag")

py_library(
    name = "my_target",
    tags = [package_tag("my_python_package")],
    # ...
    # ...
    # ...
)

PARAMETERS

NameDescriptionDefault Value
nameThe name of the packagenone

RETURNS

str: The tag.

py_wheel_library

load("@rules_venv//python/wheel:defs.bzl", "py_wheel_library")

py_wheel_library(name, srcs, deps, data, abi, author, author_email, classifiers, constraints_file,
                 data_files, description_content_type, description_file, extra_distinfo_files,
                 homepage, license, platform, project_urls, python_requires, python_tag,
                 strip_path_prefixes, summary, version, distribution, repository_url, **kwargs)

Define a py_library with an associated wheel.

This rule will traverse dependencies (deps) to collect all data and dependencies that belong to the current package. Any dependency tagged with the package_tag whose name matches this targets name will be considered a submodule and included in the package.

Example:

load("@rules_venv//python:defs.bzl", "py_library")
load("@rules_venv//python/wheel:defs.bzl", "package_tag", "py_wheel_library")

py_library(
    name = "submodule",
    srcs = ["submodule.py"],
    tags = [
        # Note this name matches the name of the `py_wheel_library` target
        # and as a result will be included as a submodule within the wheel.
        package_tag("my_py_package")
    ],
)

py_wheel_library(
    name = "my_py_package",
    deps = [":submodule"],
)

Targets created by this library:

namedetails
{name}The py_library target for the wheel.
{name}.whlThe py_wheel target created from the {name} target.
{name}.publishA py_wheel_publisher target for publishing the wheel to a remote index. Defined only with repository_url.

PARAMETERS

NameDescriptionDefault Value
nameThe name of the target.none
srcsPython source files which make up the lirary.[]
depsA list of Python dependencies.[]
dataData required at runtime.[]
abiPython ABI tag. 'none' for pure-Python wheels.None
authorA string specifying the author of the package.None
author_emailA string specifying the email address of the package author.None
classifiersA list of strings describing the categories for the package. For valid classifiers see https://pypi.org/classifiersNone
constraints_fileA constraints (requirements.in) file which contains package constraints.None
data_files"Any file that is not normally installed inside site-packages goes into the .data directory, named as the .dist-info directory but with the .data/ extension. Allowed paths: ("purelib", "platlib", "headers", "scripts", "data")None
description_content_typeThe type of contents in description_file. If not provided, the type will be inferred from the extension of description_file. Also see https://packaging.python.org/en/latest/specifications/core-metadata/#description-content-typeNone
description_fileA file containing text describing the package.None
extra_distinfo_filesExtra files to add to distinfo directory in the archive.None
homepageA string specifying the URL for the package homepage.None
licenseA string specifying the license of the package.None
platformSupported platform. Use 'any' for pure-Python wheel.None
project_urlsA string dict specifying additional browsable URLs for the project and corresponding labels, where label is the key and url is the value. e.g {{"Bug Tracker": "http://bitbucket.org/tarek/distribute/issues/"}}None
python_requiresPython versions required by this distribution, e.g. '>=3.9,<3.13'None
python_tagSupported Python version(s), eg py3, cp39.cp310, etcNone
strip_path_prefixespath prefixes to strip from files added to the generated packageNone
summaryA one-line summary of what the distribution doesNone
versionThe version of the package."0.0.0"
distributionName of the distribution. If unset, name will be used.None
repository_urlThe repository (package index) URL to upload the wheel to.None
kwargsAdditional keyword arguments.none