Skip to content
Back to top
View this page

# Plugins

Many plugins are available for tox. These include, but are not limited to, the extensions found on the `tox-dev` org on ‘GitHub.

Plugins are automatically discovered once from the Python environment that tox itself is installed in. This means that if tox is installed in an isolated environment (e.g. when installed using pipx or uv), the plugin(s) must be installed in the same environment. To ensure a plugin is always available, you can include the plugin is listed in requires, which will cause tox to auto-provision a new isolated environment with both tox and the plugin(s) installed. For example:

TOML

    requires = ["tox>=4", "tox-uv>=1"]

INI

    [tox]
    requires =
        tox>=4
        tox-uv>=1

For more information, refer to the user guide.

Plugins can be disabled via the `TOX_DISABLED_EXTERNAL_PLUGINS` environment variable. This variable can be set to a comma separated list of plugin names, e.g.:

``bash env TOX_DISABLED_EXTERNAL_PLUGINS=tox-uv,tox-extra tox --version ``

## Developing your own plugin

The below provides some guidance on how to develop your own plugin for tox. A reference guide to the plugin API can be found in API.

### Extensions points

tox uses pluggy to customize the default behavior. It provides an extension mechanism for plugin management by calling hooks.

Pluggy discovers a plugin by looking up for entry-points named `tox`, for example in a pyproject.toml:

    [project.entry-points.tox]
    your_plugin = "your_plugin.hooks"

Therefore, to start using a plugin, you solely need to install it in the same environment tox is running in and it will be discovered via the defined entry-point (in the example above, tox will load `your_plugin.hooks`).

A plugin is created by implementing extension points in the form of hooks. For example the following code snippet would define a new `--magic` command line interface flag the user can specify:

    from tox.config.cli.parser import ToxParser
    from tox.plugin import impl

    @impl
    def tox_add_option(parser: ToxParser) -> None:
        parser.add_argument("--magic", action="store_true", help="magical flag")

You can define such hooks either in a package installed alongside tox or within a `toxfile.py` found alongside your tox configuration file (root of your project).

tox.plugin.NAME = 'tox'

  the name of the tox hook

tox.plugin.impl

  decorator to mark tox plugin hooks

tox.plugin.spec.tox_add_core_config(core_conf, state)

  Called when the core configuration is built for a tox environment.

  Parameters:

    - core_conf (`ConfigSet`) – the core configuration object

    - state (`State`) – the global tox state object

  Return type:

    `None`

tox.plugin.spec.tox_add_env_config(env_conf, state)

  Called when configuration is built for a tox environment.

  Parameters:

    - env_conf (`EnvConfigSet`) – the core configuration object

    - state (`State`) – the global tox state object

  Return type:

    `None`

tox.plugin.spec.tox_add_option(parser)

  Add a command line argument. This is the first hook to be called, right after the logging setup and config source discovery.

  Parameters:

    parser (`ToxParser`) – the command line parser

  Return type:

    `None`

tox.plugin.spec.tox_after_run_commands(tox_env, exit_code, outcomes)

  Called after the commands set is executed.

  Parameters:

    - tox_env (`ToxEnv`) – the tox environment being executed

    - exit_code (`int`) – exit code of the command

    - outcomes (`list`[`Outcome`]) – outcome of each command execution

  Return type:

    `None`

tox.plugin.spec.tox_before_run_commands(tox_env)

  Called before the commands set is executed.

  Parameters:

    tox_env (`ToxEnv`) – the tox environment being executed

  Return type:

    `None`

tox.plugin.spec.tox_env_teardown(tox_env)

  Called after a tox environment has been teared down.

  Parameters:

    tox_env (`ToxEnv`) – the tox environment

  Return type:

    `None`

tox.plugin.spec.tox_extend_envs()

  Declare additional environment names.

  Added in version 4.29.0.

  This hook is called without any arguments early in the lifecycle. It is expected to return an iterable of strings with environment names for tox to consider. It can be used to facilitate dynamic creation of additional environments from within tox plugins.

  This is ideal to pair with `tox_add_core_config` that has access to `state.conf.memory_seed_loaders` allowing to extend it with instances of `tox.config.loader.memory.MemoryLoader` early enough before tox starts caching configuration values sourced elsewhere.

  Return type:

    `Iterable`[`str`]

tox.plugin.spec.tox_on_install(tox_env, arguments, section, of_type)

  Called before executing an installation command.

  Parameters:

    - tox_env (`ToxEnv`) – the tox environment where the command runs in

    - arguments (`Any`) – installation arguments

    - section (`str`) – section of the installation

    - of_type (`str`) – type of the installation

  Return type:

    `None`

tox.plugin.spec.tox_register_tox_env(register)

  Register new tox environment type. You can register:

  - run environment: by default this is a local subprocess backed virtualenv Python

  - packaging environment: by default this is a PEP-517 compliant local subprocess backed virtualenv Python

  Parameters:

    register (`ToxEnvRegister`) – a object that can be used to register new tox environment types

  Return type:

    `None`

A plugin can define its plugin module a:

    def tox_append_version_info() -> str:
        return "magic"

and this message will be appended to the output of the `--version` flag.

### Adoption of a plugin under tox-dev Github organization

You’re free to host your plugin on your favorite platform, however the core tox development is happening on Github, under the `tox-dev` org organization. We are happy to adopt tox plugins under the `tox-dev` organization if:

- we determine it’s trying to solve a valid use case and it’s not malicious (e.g. no plugin that deletes the users home directory),

- it’s released on PyPI with at least 100 downloads per month (to ensure it’s a plugin used by people).

What’s in for you in this:

- you get owner rights on the repository under the tox-dev organization,

- exposure of your plugin under the core umbrella,

- backup maintainers from other tox plugin development.

How to apply:

- create an issue under the `tox-dev/tox` Github repository with the title Adopt plugin <name>,

- wait for the green light by one of our maintainers (see Current maintainers),

- follow the guidance by Github,

- (optionally) add at least one other people as co-maintainer on PyPI.

### Migration from tox 3

This section explains how the plugin interface changed between tox 3 and 4, and provides guidance for plugin developers on how to migrate.

#### `tox_get_python_executable`

With tox 4 the Python discovery is performed `tox.tox_env.python.virtual_env.api._get_python` that delegates the job to `virtualenv`. Therefore first define a new virtualenv discovery mechanism and then set that by setting the `VIRTUALENV_DISCOVERY` environment variable.

#### `tox_package`

Register new packager types via `tox_register_tox_env`.

#### `tox_addoption`

Renamed to `tox_add_option`.