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:
requires = ["tox>=4", "tox-uv>=1"]
[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.
- 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 objectstate (
State
) – the global tox state object
- Return type:
- 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.
- tox.plugin.spec.tox_after_run_commands(tox_env, exit_code, outcomes)¶
Called after the commands set is executed.
- tox.plugin.spec.tox_before_run_commands(tox_env)¶
Called before the commands set is executed.
- tox.plugin.spec.tox_env_teardown(tox_env)¶
Called after a tox environment has been teared down.
- 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 tostate.conf.memory_seed_loaders
allowing to extend it with instances oftox.config.loader.memory.MemoryLoader
early enough before tox starts caching configuration values sourced elsewhere.
- tox.plugin.spec.tox_on_install(tox_env, arguments, section, of_type)¶
Called before executing an installation command.
- 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:
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
.