How to clean a tox environment after running?

Question:

I have the following tox.ini file:

[tox]
envlist = flake8,py{35,36,37,38}{,-keyring}

[testenv]
usedevelop = True
install_command = pip install -U {opts} {packages}
deps =
    .[test]
    keyring: .[keyring]
setenv =
    COVERAGE_FILE = .coverage.{envname}
commands=
    pytest {toxinidir}/tests -n 4 {posargs}

[testenv:flake8]
basepython = python3
deps = flake8
commands=
    flake8 src tests

[flake8]
ignore: F401,E402,E501,W605,W503

When I run the tox command, it creates a .tox folder containing a folder for every environment specified in the [tox] section of the tox.ini.

I would like to automatically get rid of these particular folders after the test have succeeded when running tox without having to manually run rm -rf .tox/NAME_OF_THE_ENV. I have searched through the tox documentation but I have found nothing.

Is it possible to do so? If yes, how?

Asked By: vinzee

||

Answers:

There is no way in tox. The reason is that tox preserves these environments as a cache: next time you run tox the environments will be reused thus saving time.

You can remove them at once after running tox with rm -rf .tox.

Answered By: phd

I found a way by creating a tox hook. This hook runs the shutil.rmtree command after the tests have been run inside the env.

In a tox_clean_env.py file:

import shutil
from tox import hookimpl

@hookimpl
def tox_runtest_post(venv):
    try:
        shutil.rmtree(venv.path)
    except Exception as e:
        print("An exception occurred while removing '{}':".format(venv.path))
        print(e)

I created a package around this code and I just need to install it using pip.

In my setup.py, in the setup function:

    entry_points={"tox": ["clean_env = tox_clean_env"]},
Answered By: vinzee

I know it’s not exactly what you were asking for but it’s worth mentioning that the -r / --recreate flag to tox will force recreation of virtual environments

Answered By: Matthew Hegarty

The new version tox 3.18 (July 23, 2020) has a setting allowlist_externals=(MULTI-LINE-LIST) that allows to specify command names which can be used in the commands section without triggering a “not installed in virtualenv” warning. That allows to use rm command directly.

[testenv]
...
allowlist_externals = rm
commands=
    pytest ...
    rm -rf {envdir}

The line with rm command is not executed after errors. (unless you add a setting ignore_errors = True that allows to continue)

Answered By: hynekcer
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.