HomeDocs
DocsCommunityTestimonialsUsersGitHubTwitterBlogJobsTermsPrivacyCookies
TermsPrivacyCookies
Hey! These docs are for version 2.12, which is no longer officially supported. Click here for the latest version, 2.18!


Before creating a new target type, the first step is to create all of the target type's fields.

## Defining a Field

To define a new field:

  1. Subclass one of the below field templates, like `IntField` or `BoolField`; or, subclass an existing field, like `SingleSourceField`.

  2. Set the class property `alias`. This is the symbol that people use in BUILD files.

  3. Set the class property `help`. This is used by `./pants help`.

For example:



### `default`

The `default` is used whenever a user does not explicitly specify the field in a BUILD file.



If you don't override this property, `default` will be set to `None`, which signals that the value was undefined.

### `required`

Set `required = True` to require explicitly defining the field.



If you set `required = True`, the `default` will be ignored.

Reminder: subclass existing fields to modify their behavior

If you want to change how an existing field behaves, you should subclass the original field. For example, if you want to change a default value, subclass the original field. When doing this, you only need to override the properties you want to change.

See [Concepts](🔗) for how subclassing plays a key role in the Target API.

## Adding custom validation

The field templates will validate that users are using the correct _types_, like ints or strings. But you may want to add additional validation, such as banning certain values.

To do this, override the classmethod `compute_value`:



Be careful to use the same type hint for the parameter `raw_value` as used in the template. This is used to generate the documentation in `./pants help my_target`.

Cannot use new type hint syntax with `compute_value()` and `default`

You cannot use the [new type hint syntax](🔗) with the Target API, i.e. `list[str] | None` instead of `Optional[List[str]]`. The new syntax breaks `./pants help`.

Otherwise, it's safe to use the new syntax when writing plugins.

## Available templates

All templates are defined in `pants.engine.target`.

### `BoolField`

Use this when the option is a boolean toggle. You must either set `required = True` or set `default` to `False` or `True`.

### `TriBoolField`

This is like `BoolField`, but allows you to use `None` to represent a third state. You do not have to set `required = True` or `default`, as the field template defaults to `None` already.

### `IntField`

Use this when you expect an integer. This will reject floats.

### `FloatField`

Use this when you expect a float. This will reject integers.

### `StringField`

Use this when you expect a single string.

`StringField` can be like an enum

You can set the class property `valid_choices` to limit what strings are acceptable. This class property can either be a tuple of strings or an `enum.Enum`.

For example:



or:



### `StringSequenceField`

Use this when you expect 0-n strings.

The user may use a tuple, set, or list in their BUILD file; Pants will convert the value to an immutable tuple.

### `SequenceField`

Use this when you expect a homogenous sequence of values other than strings, such as a sequence of integers.

The user may use a tuple, set, or list in their BUILD file; Pants will convert the value to an immutable tuple.

You must set the class properties `expected_element_type` and `expected_type_description`. You should also change the type signature of the classmethod `compute_value` so that Pants can show the correct types when running `./pants help $target_type`.



### `DictStringToStringField`

Use this when you expect a dictionary of string keys with strings values, such as `{"k": "v"}`.

The user may use a normal Python dictionary in their BUILD file. Pants will convert this into an instance of `pants.util.frozendict.FrozenDict`, which is a lightweight wrapper around the native `dict` type that simply removes all mechanisms to mutate the dictionary.

### `DictStringToStringSequenceField`

Use this when you expect a dictionary of string keys with a sequence of strings values, such as `{"k": ["v1", "v2"]}`.

The user may use a normal Python dictionary in their BUILD file, and they may use a tuple, set, or list for the dictionary values. Pants will convert this into an instance of `pants.util.frozendict.FrozenDict`, which is a lightweight wrapper around the native `dict` type that simply removes all mechanisms to mutate the dictionary. Pants will also convert the values into immutable tuples, resulting in a type hint of `FrozenDict[str, Tuple[str, ...]]`.

### `Field` - the fallback class

If none of these templates work for you, you can subclass `Field`, which is the superclass of all of these templates.

You must give a type hint for `value`, define the classmethod `compute_value`, and either set `required = True` or define the class property `default`.

For example, we could define a `StringField` explicitly like this:



Asking for help

Have a tricky field you're trying to write? We would love to help! See [Getting Help](🔗).

## Examples