Options
A deep dive into how options may be configured.
Option scopes
Options are partitioned into named scopes.
Some systemwide options belong in the global scope. For example, the --level
option, which controls the logging level, is in the global scope.
Other options belong to a subsystem scope. A subsystem is simply a collection of related options, in a scope. For example, the pytest
subsystem contains options related to Python's test framework pytest.
Setting options
Every option can be set in the following ways, in order of precedence:
- Via a command line flag.
- In an environment variable.
- In a config file (
pants.toml
).
If an option isn't set in one of these ways, it will take on a default value.
You can inspect both the current value and the default value by using ./pants help $scope
or ./pants help-advanced $scope
, e.g. ./pants help global
.
Command-line flags
Global options are set using an unqualified flag:
./pants --level=debug ...
Subsystem options are set by providing the flag, with the name prefixed with the lower-case scope name and a dash. So for the option --root-patterns
in the scope source
:
./pants --source-root-patterns="['^ext']"
Environment variables
Global options are set using the environment variable PANTS_{OPTION_NAME}
:
PANTS_LEVEL=debug ./pants ...
Subsystem options are set using the environment variable
PANTS_{SCOPE}_{OPTION_NAME}
:
PANTS_SOURCE_ROOT_PATTERNS="['^ext']" ./pants ...
Note that the scope and option name are upper-cased, and any dashes in the option flag name are converted to underscores: --multiword-name
becomes MULTIWORD_NAME
.
Config file entries
Global options are set in the GLOBAL
section of the config file:
[GLOBAL]
level = "debug"
Subsystem options are set in the section named for their scope:
[source]
root_patterns = ["/src/python"]
Note that any dashes in the option flag name are converted to underscores: --multiword-name
becomes multiword_name
.
Additionally, a few different variables may be interpolated into strings in config files via a %(var)s
syntax. For example, this expands to the absolute path of a file in the root of your repository:
[GLOBAL]
pythonpath = ["%(buildroot)s/examples"]
Option types
Every option has a type, and any values you set must be of that type.
The option types are:
- string
- integer
- bool
- list
- dict
A list-valued option may also declare a specific type for its members (e.g., a list of strings, or a list of integers).
String and integer values
Standalone string and integer values are written without quotes. Any quotes will be considered part of the value, after shell escaping.
Command-line flags:
./pants --scope-intopt=42
./pants --scope-stropt=qux
Environment variables:
PANTS_SCOPE_INTOPT=42
PANTS_SCOPE_STROPT=qux
Config file entries:
[scope]
intopt = 42
stropt = "qux"
Boolean values
Boolean values can be specified using the special strings true
and false
. When specifying them via command-line flags you can also use the --boolopt/--no-boolopt
syntax.
Command-line flags:
./pants --scope-boolopt=true
./pants --scope-boolopt
./pants --no-scope-boolopt
Environment variables:
PANTS_SCOPE_BOOLOPT=true
Config file entries:
[scope]
boolopt = true
List values
List values are parsed as Python list literals, so you must quote string values, and you may need to apply shell-level quoting and/or escaping, as required.
Command-line flags:
./pants --scope-listopt="['foo','bar']"
You can also leave off the []
to append elements. So we can rewrite the above to:
./pants --scope-listopt=foo --scope-listopt=bar
Environment variables:
PANTS_SCOPE_LISTOPT="['foo','bar']"
Like with command-line flags, you can leave off the []
to append elements:
PANTS_SCOPE_LISTOPT=foo
Config file entries:
[scope]
listopt = [
'foo',
'bar'
]
Add/remove semantics
List values have some extra semantics:
- A value can be preceded by
+
, which will append the elements to the value obtained from lower-precedence sources. - A value can be preceded by
-
, which will remove the elements from the value obtained from lower-precedence sources. - Multiple
+
and-
values can be provided, separated by commas. - Otherwise, the value replaces the one obtained from lower-precedence sources.
For example, if the value of --listopt
in scope
is set to [1, 2]
in a config file, then
./pants --scope-listopt="+[3,4]"
will set the value to [1, 2, 3, 4]
.
./pants --scope-listopt="-[1],+[3,4]"
will set the value to [2, 3, 4]
, and
./pants --scope-listopt="[3,4]"
will set the value to [3, 4]
.
The +/- syntax works in .toml files, but the entire value must be quoted:
[scope]
listopt = "+[1,2],-[3,4]"
This means that TOML treats the value as a string, instead of a TOML list.
Alternatively, you can use this syntactic sugar, which allows the values to be regular TOML lists:
[scope]
listopt.add = [1, 2]
listopt.remove = [3, 4]
But note that this only works in Pants's .toml
config files, not in environment variables or command-line flags.
Dict values
Dict values are parsed as Python dict literals on the command-line and environment variables, so you must quote string keys and values, and you may need to apply shell-level quoting and/or escaping, as required.
Command-line flags:
./pants --scope-dictopt="{'foo':1,'bar':2}"
Environment variables:
PANTS_SCOPE_DICTOPT="{'foo':1,'bar':2}"
Config file entries:
You can use TOML's nested table features. These are equivalent:
[scope]
dictopt = { foo = 1, bar = 2}
[scope.dictopt]
foo = 1
bar = 2
You can also use a string literal. Note the quotes:
[scope]
dictopt = """{
'foo': 1,
'bar': 2,
}"""
Add/remove semantics
- A value can be preceded by
+
, which will update the value obtained from lower-precedence sources with the entries. - Otherwise, the value replaces the one obtained from lower-precendence sources.
For example, if the value of --dictopt
in scope
is set to {'foo', 1, 'bar': 2}
in a config file, then
./pants --scope-dictopt="+{'foo':42,'baz':3}"
will set the value to {'foo': 42, 'bar': 2, 'baz': 3}
, and
./pants --scope-dictopt="{'foo':42,'baz':3}"
will set the value to {'foo': 42, 'baz': 3}
.