rules_venv
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:
-
Use of
PYTHONPATHto construct the python environment leads to operating system limitations.Some details on
MAX_ARG_STRLENandARG_MAXcan be found here: https://unix.stackexchange.com/a/120842 -
Slow startup on windows systems that do not support symlinks.
rules_pythoncreates 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
bazel_dep(name = "rules_venv", version = "{version}")
Venv
Core Bazel rules for defining Python targets.
Rules
Functions
- py_venv_common.create_dep_info
- py_venv_common.create_py_info
- py_venv_common.create_runfiles_collection
- py_venv_common.create_venv_attrs
- py_venv_common.create_venv_config_info
- py_venv_common.create_venv_entrypoint
- py_venv_common.get_toolchain
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| deps | Other python targets to link to the current target. | List of labels | optional | [] |
| srcs | The list of source (.py) files that are processed to create the target. | List of labels | optional | [] |
| data | Files needed by this rule at runtime. May list file or rule targets. Generally allows any target. | List of labels | optional | [] |
| env | Dictionary of strings; values are subject to $(location) and "Make variable" substitution. | Dictionary: String -> String | optional | {} |
| imports | List of import directories to be added to the PYTHONPATH. | List of strings | optional | [] |
| main | The 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. | Label | optional | None |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| deps | Other python targets to link to the current target. | List of labels | optional | [] |
| srcs | The list of source (.py) files that are processed to create the target. | List of labels | optional | [] |
| data | Files needed by this rule at runtime. May list file or rule targets. Generally allows any target. | List of labels | optional | [] |
| imports | List of import directories to be added to the PYTHONPATH. | List of strings | optional | [] |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| deps | Other python targets to link to the current target. | List of labels | optional | [] |
| srcs | The list of source (.py) files that are processed to create the target. | List of labels | optional | [] |
| data | Files needed by this rule at runtime. May list file or rule targets. Generally allows any target. | List of labels | optional | [] |
| env | Dictionary of strings; values are subject to $(location) and "Make variable" substitution. | Dictionary: String -> String | optional | {} |
| env_inherit | Specifies additional environment variables to inherit from the external environment when the test is executed by bazel test. | List of strings | optional | [] |
| imports | List of import directories to be added to the PYTHONPATH. | List of strings | optional | [] |
| main | The 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. | Label | optional | None |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| zipapp_shebang | The shebang to use when creating zipapps (OutputGroupInfo.python_zip_file). | String | optional | "" |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| args | Arguments to add to the beginning of all invocations of the zipapp. | List of strings | optional | [] |
| binary | The binary to package as a zipapp. | Label | optional | None |
| env | Environment variables to inject into all invocations of the zipapp. | Dictionary: String -> String | optional | {} |
| inherit_args | Inherit template variable expanded arguments from binary. | Boolean | optional | False |
| inherit_env | Inherit template variable expanded environment variables from binary. | Boolean | optional | False |
| shebang | Optional shebang line to prepend to the zip (provided as content after #!). | String | optional | "" |
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
| Name | Description | Default Value |
|---|---|---|
| ctx | The rule's context object. | none |
| deps | A list of python dependency targets | none |
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
| Name | Description | Default Value |
|---|---|---|
| ctx | The rule's context object. | none |
| imports | The raw imports attribute. | none |
| srcs | A list of python (.py) source files. | none |
| dep_info | Dependency 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
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()
Create attributes for consumers of py_venv_common.
RETURNS
dict: Attributes unique to rules_venv rules.
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
| Name | Description | Default Value |
|---|---|---|
| label | The label of the target that owns the venv. | none |
| name | The name for the venv. | none |
| imports | A 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
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)
Access the py_venv_toolchain from the current configuration.
Note that for cfg = "exec" toolchains, the rule must have the attributes from
py_venv_common.create_venv_attrs.
PARAMETERS
| Name | Description | Default Value |
|---|---|---|
| ctx | The rule's context object. | none |
| cfg | What configuration to access the toolchain from (exec or target). | "target" |
RETURNS
py_venv_toolchain: The accessed toolchain.
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:py_black_aspect.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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| config | The config file (pyproject.toml) containing black settings. | Label | optional | "@rules_venv//python/black:config" |
| target | The target to run black on. | Label | required |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| black | The black py_library to use with the rules. | Label | required |
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:py_isort_aspect.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
srcsattribute. - Repository relative packages.
Third party
- Other
py_*targets (thedepsattribute). Note thatdepswhich 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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| config | The config file (isort.cfg) containing isort settings. | Label | optional | "@rules_venv//python/isort:config" |
| target | The target to run isort on. | Label | required |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| isort | The isort py_library to use with the rules. | Label | required |
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
| Name | Description | Default Value |
|---|---|---|
| name | The name of the target. | none |
| srcs | he 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.srcs | none |
| conlyopts | Add these options to the C compilation command. For more details see cc_binary.conlyopts | [] |
| copts | Add these options to the C/C++ compilation command. For more details see cc_binary.copts | [] |
| cxxopts | Add these options to the C++ compilation command. For more details see cc_binary.cxxopts | [] |
| data | List of files used by this rule at compile time and runtime. For more details see cc_binary.data | [] |
| defines | List of defines to add to the compile line of this and all dependent targets For more details see cc_binary.defines | [] |
| deps | The list of other libraries to be linked in to the binary target. For more details see cc_binary.deps | [] |
| dynamic_deps | These are other cc_shared_library dependencies the current target depends on. For more details see cc_binary.dynamic_deps | [] |
| imports | List of import directories to be added to the PYTHONPATH. For more details see py_library.imports. | [] |
| includes | List of include dirs to be added to the compile line. For more details see cc_binary.includes | [] |
| linkopts | Add these flags to the C++ linker command. For more details see cc_binary.linkopts | [] |
| local_defines | List of defines to add to the compile line. For more details see cc_binary.local_defines | None |
| malloc | Override the default dependency on malloc. For more details see cc_binary.malloc | None |
| compilation_mode | The compilation_mode value to build the extension for. If set to "current", the current configuration will be used. | "opt" |
| abi | The ABI value to use for the output library name. | select({"@platforms//os:linux": "gnu", "//conditions:default": ""}) |
| stripped | Use the stripped output of the c extension for the library. | None |
| kwargs | Additional 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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| config | The config file (mypy.ini) containing mypy settings. | Label | optional | "@rules_venv//python/mypy:config" |
| target | The target to run mypy on. | Label | required |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| mypy | The mypy py_library to use with the rules. | Label | required |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| config | The config file (pylintrc) containing pylint settings. | Label | optional | "@rules_venv//python/pylint:config" |
| target | The target to run pylint on. | Label | required |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| pylint | The pylint py_library to use with the rules. | Label | required |
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:py_pylint_aspect.bzl%py_pylint_aspect
build --output_groups=+py_pylint_checks
ASPECT ATTRIBUTES
ATTRIBUTES
Pytest
Bazel rules for the python test framework Pytest.
Rules
Functions
current_py_pytest_toolchain
load("@rules_venv//python/pytest:defs.bzl", "current_py_pytest_toolchain")
current_py_pytest_toolchain(name)
A rule for exposing the current registered py_pytest_toolchain.
ATTRIBUTES
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required |
py_pytest_test
load("@rules_venv//python/pytest:defs.bzl", "py_pytest_test")
py_pytest_test(name, deps, srcs, data, config, coverage_rc, env, env_inherit, numprocesses)
A rule which runs python tests using pytest as the py_test test runner.
This rule also supports a build setting for globally applying extra flags to test invocations.
Users can add something similar to the following to their .bazelrc files:
build --@rules_venv//python/pytest:extra_args=--color=yes,-vv
The example above will add --colors=yes and -vv arguments to the end of the pytest invocation.
Tips:
- It's common for tests to have some utility code that does not live in a test source file.
To account for this. A
py_librarycan be created that contains only these sources which are then passed topy_pytest_testviadeps.
load("@rules_venv//python:defs.bzl", "py_library")
load("@rules_venv//python/pytest:defs.bzl", "py_pytest_test")
py_library(
name = "test_utils",
srcs = [
"tests/__init__.py",
"tests/conftest.py",
],
deps = ["@rules_venv//python/pytest:current_py_pytest_toolchain"],
testonly = True,
)
py_pytest_test(
name = "test",
srcs = ["tests/example_test.py"],
deps = [":test_utils"],
)
ATTRIBUTES
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| deps | The list of other libraries to be linked in to the binary target. | List of labels | optional | [] |
| srcs | An explicit list of source files to test. | List of labels | optional | [] |
| data | Files needed by this rule at runtime. May list file or rule targets. Generally allows any target. | List of labels | optional | [] |
| config | The pytest configuration file to use. | Label | optional | "@rules_venv//python/pytest:config" |
| coverage_rc | The pytest-cov configuration file to use. | Label | optional | "@rules_venv//python/pytest:coverage_rc" |
| env | Dictionary of strings; values are subject to $(location) and "Make variable" substitution | Dictionary: String -> String | optional | {} |
| env_inherit | Specifies additional environment variables to inherit from the external environment when the test is executed by bazel test. | List of strings | optional | [] |
| numprocesses | If set the pytest-xdist argument --numprocesses (-n) will be passed to the test. Note that the a value 0 or less indicates this flag should not be passed. | Integer | optional | 0 |
py_pytest_toolchain
load("@rules_venv//python/pytest:defs.bzl", "py_pytest_toolchain")
py_pytest_toolchain(name, pytest)
A toolchain for the pytest rules.
ATTRIBUTES
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| pytest | The pytest py_library to use with the rules. | Label | required |
py_pytest_test_suite
load("@rules_venv//python/pytest:defs.bzl", "py_pytest_test_suite")
py_pytest_test_suite(name, tests, args, data, **kwargs)
Generates a test_suite which groups various test targets for a set of python sources.
Given an idiomatic python project structure:
BUILD.bazel
my_lib/
__init__.py
mod_a.py
mod_b.py
mod_c.py
requirements.in
requirements.txt
tests/
__init__.py
fixtures.py
test_mod_a.py
test_mod_b.py
test_mod_c.py
This rule can be used to easily define test targets:
load("@rules_venv//python:defs.bzl", "py_library")
load("@rules_venv//python/pytest:defs.bzl", "py_pytest_test_suite")
py_library(
name = "my_lib",
srcs = glob(["my_lib/**/*.py"])
imports = ["."],
)
py_pytest_test_suite(
name = "my_lib_test_suite",
# Source files containing test helpers should go here.
# Note that the test sources are excluded. This avoids
# a test to be updated without invalidating all other
# targets.
srcs = glob(
include = ["tests/**/*.py"],
exclude = ["tests/**/*_test.py"],
),
# Any data files the tests may need would be passed here
data = glob(["tests/**/*.json"]),
# This field is used for dedicated test files.
tests = glob(["tests/**/*_test.py"]),
deps = [
":my_lib",
],
)
For each file passed to tests, a py_pytest_test target will be created. From the example above,
the user should expect to see the following test targets:
//:my_lib_test_suite
//:tests/test_mod_a
//:tests/test_mod_b
//:tests/test_mod_c
Additional Notes:
- No file passed to
testsshould be passed found in thesrcsordataattributes or tests will not be able to be individually cached.
PARAMETERS
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:
- Requirements are collected from transitive dependencies and added as
Require-Distto the wheel. - 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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| repository_url | The repository (package index) URL to upload the wheel to. If passed the twine arg --repository-url will be set to this value. | String | optional | "" |
| wheel | The wheel to extract. | Label | required |
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
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| twine | A py_library for twine. | Label | required |
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
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:
| name | details |
|---|---|
{name} | The py_library target for the wheel. |
{name}.whl | The py_wheel target created from the {name} target. |
{name}.publish | A py_wheel_publisher target for publishing the wheel to a remote index. Defined only with repository_url. |
PARAMETERS