Question
Normally when I change the deps
in my tox.ini
file tox
will notice the change and recreate the virtualenv with the new dependencies. But if I use deps = -r requirements.txt
to read my dependencies from a requirements.txt
file then tox
doesn't update the virtualenv when requirements.txt
changes. How can I automatically keep my tox virtualenvs in sync with my requirements.txt
files?
Details
tox detects changes to deps
in tox.ini
When using the deps
setting in tox.ini
to list your dependencies if you change the deps
then the next time you run a tox
command it'll notice the change and will create the virtualenv and install the new deps
into the new virtualenv. Here's a minimal tox.ini
file to demonstrate what I'm talking about:
# tox.ini
[tox]
skipsdist = true
[testenv]
deps = pytest
commands = pytest --version
If you run tox
in a directory containing this tox.ini
file then tox
will create a virtualenv in the .tox
directory, install pytest
into that virtualenv, and run pytest --version
in the virtualenv. If you run tox
again it'll reuse the existing virtualenv and just run pytest --version
without unnecessarily reinstalling pytest
again. If you make a change to the deps
in tox.ini
, for example like this:
diff --git a/tox.ini b/tox.ini
index 7d92601..e45a612 100644
--- a/tox.ini
+++ b/tox.ini
@@ -2,5 +2,5 @@
skipsdist = true
[testenv]
-deps = pytest
-commands = pytest --version
+deps = pylint
+commands = pylint --version
Then the next time I run tox
it'll recreate the virtualenv and reinstall the dependencies before running the commands:
$ tox
python recreate: /tmp/tox/.tox/python
python installdeps: pylint
python installed: astroid==2.12.4,dill==0.3.5.1,isort==5.10.1,lazy-object-proxy==1.7.1,mccabe==0.7.0,platformdirs==2.5.2,pylint==2.15.0,tomli==2.0.1,tomlkit==0.11.4,wrapt==1.14.1
python run-test-pre: PYTHONHASHSEED='4045882343'
python run-test: commands[0] | pylint --version
pylint 2.15.0
astroid 2.12.4
Python 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0]
___________________________________ summary ____________________________________
python: commands succeeded
congratulations :)
You can put requirements files in deps
You can reference pip requirements files from tox.ini
with -r
, for example:
# tox.ini
[tox]
skipsdist = true
[testenv]
deps = -r requirements.txt
commands = pylint --version
Now when you run tox
it'll install the dependencies from requirements.txt
into the virtualenv.
The problem: tox doesn't detect changes to requirements.txt
But there's a problem: tox
won't notice if the requirements.txt
file changes. Your virtualenv will still contain the dependencies from the old version of the requirements.txt
file. tox
only notices direct changes to the deps
setting in tox.ini
itself.
Ideally you wouldn't want tox
to recreate the virtualenv from scratch when requirements.txt
changes like it does when tox.ini
changes: requirements.txt
files are often quite large and reinstalling them from scratch can take a long time. Ideally tox
would update the virtualenv in place: installing, removing, updating and downgrading packages as necessary to synchronize the virtualenv with the requirements.txt
file.