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

Creating new targets

How to add a custom target type.

When to create a new target type?

Adding new target types is most helpful when you are adding support for a new language.

If you instead want to reduce boilerplate in BUILD files, such as changing default values, use macros .

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.

Step 1: Define the target type

To define a new target:

  1. Subclass pants.engine.target.Target.
  2. Define the class property alias. This is the symbol that people use in BUILD files.
  3. Define the class property core_fields.

For core_fields, we recommend including COMMON_TARGET_FIELDS to add the useful tags and description fields. You also likely want to include Dependencies and Sources.

from pants.engine.target import (
    COMMON_TARGET_FIELDS,
    Dependencies,
    Sources,
    StringField,
    Target,
)


class CustomField(StringField):
    alias = "custom_field"


class CustomTarget(Target):
    """A custom target to demo the Target API.
    
    This docstring will be used in the output of `./pants help $target_type`.
    """

    alias = "custom_target"
    core_fields = (*COMMON_TARGET_FIELDS, Dependencies, Sources, CustomField)

📘

Tip: subclass the Sources field

You will usually want to subclass the Sources field to give custom functionality, such as setting a default value.

You can also set the class property expected_file_extensions to enforce that only certain files are used, such as expected_file_extensions = (".json", ".txt").

📘

Using the fields of a pre-existing target type

Sometimes, you may want to create a new target type that behaves similarly to one that already exists, except for some small changes.

For example, you might like how python_binary() behaves in general, but you have a Django application and keep writing sources=["manage.py"]. Normally, you should write a macro to set this default value; but, here, you also want to add new Django-specific fields, so you decide to create a new target type.

Rather than subclassing the original target type, use this pattern:

from pants.backend.python.target_types import PythonBinary, PythonBinarySources
from pants.engine.target import Target
from pants.util.ordered_set import FrozenOrderedSet

class DjangoManagePySources(PythonBinarySources):
   default = ("manage.py",)


class DjangoManagePy(Target):
   alias = "django_manage_py"
   core_fields = (
       *(FrozenOrderedSet(PythonBinary.core_fields) - {PythonBinarySources}),
       DjangoManagePySources,
   )

In this example, we register all of the fields of PythonBinary, except for the field PythonBinarySources. We instead register our custom field DjangoManagePySources.

Step 2: Register the target type in register.py

Now, in your register.py, add the target type to the def target_types() entry point.

from plugins.target_types import CustomTarget

def target_types():
    return [CustomTarget]

You can confirm this works by running ./pants help custom_target.

Updated about a month ago


Creating new targets


How to add a custom target type.

Suggested Edits are limited on API Reference Pages

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