Pants v2: Fast, consistent builds for Python and more

Welcome to the Pants v2 documentation hub!

Pants v2 is a fast, scalable build system for growing codebases. It's currently focused on Python, with support for other languages coming soon.

Here you'll find guides to help you get started with Pants v2, comprehensive documentation on how to configure, run and customize Pants v2, and information on how to get help from the Pants community.

Get Started

Macros

Reducing boilerplate in BUILD files.

When to use a macro

Macros are useful to reduce boilerplate in BUILD files. For example, if you keep using the same value for a field, you can use a macro.

If you instead want to add support for a new language, or do something more complex than a macro allows, create a new target type.

If you are already using a target type, but need to store additional metadata for your plugin, add a new field to the target type.

How to add a macro

Macros are defined in Python files that act like a normal BUILD file. They have access to all the symbols you normally have registered in a BUILD file, such as all of your target types.

Macros cannot import other modules, just like BUILD files cannot have import statements.

To define a new macro, add a function with def and the name of the new symbol. Usually, the last line of the macro will create a new target, like this:

def python2_library(**kwargs):
    kwargs["interpreter_constraints"] = ["==2.7.*"]
    python_library(**kwargs)

def python3_library(**kwargs):
    kwargs["interpreter_constraints"] = [">=3.5"]
    python_library(**kwargs)

Then, add this file to the option build_file_prelude_globs in the [GLOBAL] scope:

[GLOBAL]
build_file_prelude_globs = [
  "pants-plugins/macros.py",
]

Now, in BUILD files, you can use the new macros:

python2_library(
    name="app_py2",
    sources=["app_py2.py"],
)

python3_library(
    name="app_py3",
    sources=["app_py3.py"],
)

A macro can create multiple targets:

def python23_tests(name, **kwargs):
    kwargs.pop("interpreter_constraints", None)

    python_tests(
        name=f"{name}_py2",
        interpreter_constraints=["==2.7.*"],
        **kwargs,
    )
 
    python_tests(
        name=f"{name}_py3",
        interpreter_constraints=[">=3.5"],
        **kwargs,
    )

A macro can perform validation:

def custom_python_library(**kwargs):
    if "2.7" in kwargs.get("interpreter_constraints", ""):
        raise ValueError("Python 2.7 is banned!")
    python_library(**kwargs)

A macro can take new parameters to generate the target dynamically. For example:

def custom_python_library(has_type_hints: bool = True, **kwargs):
    if has_type_hints:
        kwargs["tags"] = kwargs.get("tags", []) + ["type_checked"]
    python_library(**kwargs)
custom_python_library(
    has_type_hints=False,
)

Updated 18 days ago


Macros


Reducing boilerplate in BUILD files.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.