By default, Pants will simply copy the kwargs (keyword arguments) used in the `provides=setup_py()
` field in the BUILD file when [running the `package
` goal on a `python_distribution
`](🔗).
You can instead write a plugin to add your own logic to what kwargs are used for the `setup()
` function to do any of these things:
Reduce boilerplate by hardcoding common kwargs.
Read from the file system to dynamically determine kwargs, such as the `
long_description
` or `version
`.Run processes like `
git
` to dynamically determine kwargs like `version
`.
Note: regardless of if you wrote a plugin or not, Pants will automatically set some kwargs like `install_requires
` and `namespace_packages
` based on analyzing your code.
Note: there may only be at most one applicable plugin per target customizing the kwargs for the `setup()
` function.
Example
See [here](🔗) for an example that Pants uses internally for its `
python_distribution
` targets. This plugin demonstrates reading from the file system to set the `version
` and `long_description
` kwargs, along with adding hardcoded kwargs.
## 1. Set up a subclass of `SetupKwargsRequest
`
Set the class method `is_applicable()
` to determine whether your implementation should be used for the particular `python_distribution
` target. If `False
`, Pants will use the default implementation which simply uses the explicitly provided `setup_py
` from the BUILD file.
In this example, we will always use our custom implementation:
This example will only use our plugin implementation for `python_distribution
` targets defined in the folder `src/python/project1
`.
Then, register your new `SetupKwargsRequest
` with a [`UnionRule
`](🔗) so that Pants knows your implementation exists:
Consider defining custom `
python_distribution
` target typesIf you don't want to always use a single custom implementation, an effective approach could be to create custom `
python_distribution
` target types so that your users decide which implementation they want to use in their BUILD files.For example, a user could do this:
To support this workflow, [create new target types](🔗).
Then, for each `
SetupKwargsRequest
` subclass, check which target type was used:
## 2. Create a rule with your logic
Your rule should take as a parameter the `SetupKwargsRequest
` from step 1. This type has two fields: `target: Target
` and `explicit_kwargs: dict[str, Any]
`. You can use these fields to get more information on the target you are generating a `setup.py
` for.
Your rule should return `SetupKwargs
`, which takes two arguments: `kwargs: dict[str, Any]
` and `address: Address
`.
For example, this will simply hardcode a kwarg:
Update your plugin's `register.py
` to activate this file's rules.
Then, run `./pants package path/to:python_distribution
` and inspect the generated `setup.py
`to confirm that your plugin worked correctly.
Often, you will want to read from a file in your project to set kwargs like `version
` or `long_description
`. Use `await Get(DigestContents, PathGlobs)
` to do this (see [File system](🔗)):
It can be helpful to allow users to add additional kwargs to their BUILD files for you to consume in your plugin. For example, this plugin adds a custom `long_description_path
` field, which gets popped and replaced by the plugin with a normalized `long_description
` kwarg:
Refer to these guides for additional things you may want to do in your plugin:
[Read from options](🔗). Also see [here](🔗) for an example.
[Read values from the target](🔗) using the Target API.
[Run a `
Process
`](🔗), such as `git
`. Also see [Installing tools](🔗).