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

As explained in [Options](🔗), options are partitioned into named scopes, like `[test]` and `[isort]`. Each of these scopes corresponds to a _subsystem_.

To add new options:

  1. Define a subclass of `Subsystem` from `pants.subsystem.subsystem`.

    1. Set the class property `options_scope` with the name of the subsystem.

      • This value will be prepended to all options in the subsystem, e.g. `--skip` will become `--shellcheck-skip`.

    2. Set the class property `help`, which is used by `./pants help`.

  2. Add new options through the class method `register_options()`.

  3. Register the `Subsystem` with `SubsystemRule` and `register.py`.

    • You don't need this if the `Subsystem` is used in an `@rule` because `collect_rules()` will recognize it. It doesn't hurt to keep this around, though.

The subsystem should now show up when you run `./pants help shellcheck`.


As explained in [Goal rules](🔗), goals use a subclass of `Subsystem`: `GoalSubsystem` from `pants.engine.goal`.

`GoalSubsystem` behaves the same way as a normal subsystem, except that you set the class property `name` rather than `options_scope`. The `name` will auto-populate the `options_scope`.

## `register()` parameters

### Flag name

The first argument to `register()` should be a string with the option name, like, `--example-option`.

When users use a command-line flag, the option will get prefixed with the `options_scope`, e.g. `--shellcheck-skip`. With config files, every `-` will be replaced by `_`, e.g. `example_option`.

You may also specify a short flag, like `-e`. You may pass multiple values, so you may pass `-e, --example-option`.

### `metavar`

`metavar` changes what users see in `./pants help` as possible values for the flag. If unspecified, Pants will use a `metavar` based on the `type` you specify.

### `default`

`default` will be used if the user does not specify the value.

If you leave this off, the `default` will depend on the `type` you specify.

### `type`

Refer to [Options](🔗) for how a user specifies these different types.

`type`Default (if not overridden)Other notes
`int``None`Will error if a user passes a `float`.
`float``None`Will convert an `int` into a `float`.
`bool``False` Set `default=UnsetBool` from `pants.option.custom_types` to represent a trinary state. If the user does not specify a value, the option will return `None`.
Enums`None`Create an `enum.Enum`, with the value for each member as a string. See below for an example.
`list``[]` (empty list)You must also set `member_type` to one of `str`, `int`, `float`, `dict`, `dir_option`, `file_option`, `target_option`, `shell_str`, or an `Enum`.
`dict``{}` (empty dictionary)
`shell_str``[]` (empty list)You must set `type=list` and `member_type=shell_str`. Pants will ["shlex"](🔗) the string passed by the user, i.e. to split on each space. For example, `./pants --docformatter-args='--wrap-summaries 100 --wrap-descriptions 100'` will get converted into `["--wrap_summaries", "100", "--wrap-descriptions", "100"]`. The type is from `pants.option.custom_types`.
`target_option``None`This behaves like `str`, but changes the `metavar` so that `./pants help` is more useful. The type is from `pants.option.custom_types`.
`file_option``None`This behaves like `str`, but changes the `metavar` so that `./pants help` is more useful. It will also validate that the file exists. The type is from `pants.option.custom_types`.
`dir_option``None`This behaves like `str`, but changes the `metavar` so that `./pants help` is more useful. It will also validate that the directory exists. The type is from `pants.option.custom_types`.

An example of an `Enum`:

### `passthrough`

Set `passthrough=True` if the option should work with the `-- <args>` syntax, e.g. `./pants test app.py -- -v -k demo`.

### `advanced`

If you set `advanced=True`, the option will only show up in `help-advanced`, and not `help`.

You should generally set this value if the option will primarily be used by codebase administrators, such as setting up a config file.

### `help`

This help message will show up when running `./pants help` and `./pants help-advanced`.

## Using options in rules

To use a `Subsystem` or `GoalSubsystem` in your rule, request it as a parameter. Then, use the property `.options`, followed by the name of the option. Replace any `-` with `_`, e.g. `--my-option` becomes `my_option`.

Tip: teach MyPy about your subsystem

MyPy does not understand the property `.options`.

Instead, you can create a `@property` for each option and use `typing.cast()` to teach MyPy what each value is.

This is optional. It can make your call sites simpler and safer thanks to MyPy, but it requires some boilerplate.