## 2.8
See https://github.com/pantsbuild/pants/blob/main/src/python/pants/notes/2.8.x.md for the changelog.
### Target modeling changes
Pants 2.8 cleaned up the modeling of targets. Now, there are targets that describe the atom of each language, like `python_test
` and `python_source
` which correspond to a single file. There are also target generators which exist solely for less boilerplate, like `python_tests
` and `python_sources
`.
We recommend re-reading [Targets and BUILD files](🔗).
#### `SourcesField
`
The `Sources
` class was replaced with `SourcesField
`, `SingleSourceField
`, and `MultipleSourcesField
`.
When defining new target types with the Target API, you should choose between subclassing `SingleSourceField
` and `MultipleSourcesField
`, depending on if you want the field to be `source: str
` or `sources: list[str]
`.
Wherever you were using `Sources
` in your `@rule
`s, simply replace with `SourcesField
`.
#### Renames of some `Sources
` subclasses
You should update all references to these classes in your `@rule
`s.
`
FilesSources
` -> `FileSourceField
``
ResourcesSources
` -> `ResourceSourceField
``
PythonSources
` -> `PythonSourceField
`
### `OutputPathField.value_or_default()
`
The method `OutputPathField.value_or_default()
` no longer takes `Address
` as an argument.
## 2.7
See https://github.com/pantsbuild/pants/blob/main/src/python/pants/notes/2.7.x.md for the changelog.
### Type hints work properly
Pants was not using PEP 561 properly, which means that MyPy would not enforce type hints when using Pants APIs. Oops! This is now fixed.
### Options scopes should not have `_
`
For example, use `my-subsystem
` instead of `my_subsystem
`. This is to avoid ambiguity with target types.
## 2.6
See https://github.com/pantsbuild/pants/blob/main/src/python/pants/notes/2.6.x.md for the changelog.
### `ProcessCacheScope
`
`ProcessCacheScope.NEVER
` was renamed to `ProcessCacheScope.PER_SESSION
` to better reflect that a rule never runs more than once in a session (i.e. a single Pants run) given the same inputs.
`ProcessCacheScope.PER_RESTART
` was replaced with `ProcessCacheScope.PER_RESTART_ALWAYS
` and `ProcessCacheScope.PER_RESTART_SUCCESSFUL
`.
### `PexInterpreterConstraints
`
Now called `InterpreterConstraints
` and defined in `pants.backend.python.util_rules.interpreter_constraints
`.
## 2.5
See https://github.com/pantsbuild/pants/blob/main/src/python/pants/notes/2.5.x.md for the changelog.
### `TriBoolField
`
`BoolField.value
` is no longer `bool | None
`, but simply `bool
`. This means that you must either set `required = True
` or set the `default
`.
Use `TriBoolField
` if you still want to be able to represent a trinary state: `False
`, `True
`, and `None
`.
### Added `RuleRunner.write_files()
`
This is a more declarative way to set up files than the older API of `RuleRunner.create_file()
`, `.create_files()
`, and `.add_to_build_files()
`. See [Testing plugins](🔗).
## 2.4
See https://github.com/pantsbuild/pants/blob/main/src/python/pants/notes/2.4.x.md for the changelog.
### `PexRequest
` changes how entry point is set
See https://github.com/pantsbuild/pants/pull/11620. Instead of setting `entry_point="pytest"
` in the `PexRequest
` constructor, now you set `main=ConsoleScript("black")
` or `main=EntryPoint("pytest")
`.
### Must use `EnvironmentRequest
` for accessing environment variables
See https://github.com/pantsbuild/pants/pull/11641. Pants now eagerly purges environment variables from the run, so using `os.environ
` in plugins won't work anymore.
Instead, use `await Get(Environment, EnvironmentRequest(["MY_ENV_VAR"])
`.
For `RuleRunner
` tests, you must now either set `env
` or the new `env_inherit
` arguments for environment variables to be set. Tests are now hermetic.
## 2.3
There were no substantial changes to the Plugin API in 2.3. See https://github.com/pantsbuild/pants/blob/main/src/python/pants/notes/2.3.x.md for the changelog.
## 2.2
See https://github.com/pantsbuild/pants/blob/main/src/python/pants/notes/2.2.x.md for the changelog.
### `PrimitiveField
` and `AsyncField
` are removed (2.2.0.dev0)
Rather than subclassing `PrimitiveField
`, subclass `Field
` directly. `Field
` now behaves like `PrimitiveField
` used to, and `PrimitiveField
` was removed for simplicity.
Rather than subclassing `AsyncField
` or `AsyncStringSequenceField
`, subclass `Field
` or a template like `StringField
` and also subclass `AsyncFieldMixin
`:
Async fields now access the raw value with the property `.value
`, rather than `.sanitized_raw_value
`. To override the eager validation, override `compute_value()
`, rather than `sanitize_raw_value()
`. Both these changes bring async fields into alignment with non-async fields.
### Set the property `help
` with Subsystems, Targets, and Fields (2.2.0.dev3)
Previously, you were supposed to set the class's docstring for the `./pants help
` message. Instead, now set a class property `help
`, like this:
Pants will now properly wrap strings and preserve newlines. You may want to run `./pants help ${target/subsystem}
` to verify things render properly.
## 2.1
See https://github.com/pantsbuild/pants/blob/master/src/python/pants/notes/2.1.x.rst for the changelog.
### `SourcesSnapshot
` is now `SpecsSnapshot
` (2.1.0rc0)
The type was renamed for clarity. Still import it from `pants.engine.fs
`.
## 2.0
See https://github.com/pantsbuild/pants/blob/master/src/python/pants/notes/2.0.x.rst for the changelog.
### Use `TransitiveTargetsRequest
` as input for resolving `TransitiveTargets
` (2.0.0rc0)
Rather than `await Get(TransitiveTargets, Addresses([addr1]))
`, use `await Get(TransitiveTargets, TransitiveTargetsRequest([addr1]))
`, from `pants.engine.target
`.
It's no longer possible to include `TransitiveTargets
` in your `@rule
` signature in order to get the transitive closure of what the user specified on the command. Instead, put `Addresses
` in your rule's signature, and use `await Get(TransitiveTargets, TransitiveTargetsRequest(addresses))
`.
### Codegen implementations: use `DependenciesRequestLite
` and `TransitiveTargetsLite
` (2.0.0rc0)
Due to a new cycle in the rule graph, for any codegen implementations, you must use `DependenciesRequestLite
` instead of `DependenciesRequest
`, and `TransitiveTargetsLite
` instead of `TransitiveTargetsRequest
`. Both imports are still from `pants.engine.target
`.
These behave identically, except that they do not include dependency inference in the results. Unless you are generating for `input = PythonSources
`, this should be fine, as dependency inference is currently only used with Python.
This is tracked by https://github.com/pantsbuild/pants/issues/10917.
### Dependencies-like fields have more robust support (2.0.0rc0)
If you have any custom fields that act like the dependencies field, but do not subclass `Dependencies
`, there are two new mechanisms for better support.
Instead of subclassing `
StringSequenceField
`, subclass `SpecialCasedDependencies
` from `pants.engine.target
`. This will ensure that the dependencies show up with `./pants dependencies
` and `./pants dependees
`.You can use `
UnparsedAddressInputs
` from `pants.engine.addresses
` to resolve the addresses:
If you defined a subclass of `SpecialCasedDependencies
`, you can use `await Get(Addresses | Targets, UnparsedAddressInputs, my_tgt[MyField].to_unparsed_address_inputs())
`.
(Why would you ever do this? If you have dependencies that you don't treat like normal—e.g. that you will call the equivalent of `./pants package
` on those deps—it's often helpful to call out this magic through a dedicated field. For example, Pants's [archive](🔗) target type has the fields `files
` and `packages
`, rather than `dependencies
`.)
### `package
` implementations may want to add the field `output_path
` (2.0.0rc0)
All of Pants's target types that can be built via `./pants package
` now have an `output_path
` field, which allows the user to override the path used for the created asset.
You optionally may want to add this `output_path
` field to your custom target type for consistency:
Include `
OutputPathField
` from `pants.core.goals.package
` in your target's `core_fields
` class property.In your `
PackageFieldSet
` subclass, include `output_path: OutputPathField
`.When computing the filename in your rule, use `
my_package_field_set.output_path.value_or_default(field_set.address, file_ending="my_ext")
`.