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

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.


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 types

If 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](🔗).