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


Union rules solve the same problem that polymorphism solves in general: how to write generic code that operates on types not known about at the time of writing.

For example, Pants has many generic goals like `lint` and `test`. Those `@goal_rule` definitions cannot know about every concrete linter or test implementation ahead-of-time.

Unions allow a specific linter to be registered with `UnionRule(LintRequest, ShellcheckRequest)`, and then for `lint.py` to access its type:



This example will find all registered linter implementations by looking up `union_membership[LintRequest]`, which returns a tuple of all `LintRequest` types that were registered with a `UnionRule`, such as `ShellcheckRequest` and `Flake8Request`.

## How to create a new Union

To set up a new union, create a class for the union "base". Typically, this should be an [abstract class](🔗) that is subclassed by the union members, but it does not need to be. Mark the class with `@union`.



Then, register every implementation of your union with `UnionRule`:



Now, your rules can request `UnionMembership` as a parameter in the `@rule`, and then look up `union_membership[Vehicle]` to get a tuple of all relevant types that are registered via `UnionRule`.