Skip to content

Commit c97e0b8

Browse files
Migrate tox 3 documentation (#2408)
Co-authored-by: Jürgen Gmach <[email protected]>
1 parent 0ee8853 commit c97e0b8

File tree

6 files changed

+489
-73
lines changed

6 files changed

+489
-73
lines changed

docs/changelog/2408.doc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add new documentation for tox 4 - by :user:`gaborbernat`.

docs/conf.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,13 @@
6666
nitpicky = True
6767
nitpick_ignore = []
6868
linkcheck_workers = 10
69-
linkcheck_ignore = [re.escape(r"https://github.com/tox-dev/tox/issues/new?title=Trouble+with+development+environment")]
69+
linkcheck_ignore = [
70+
re.escape(i)
71+
for i in (
72+
r"https://github.com/tox-dev/tox/issues/new?title=Trouble+with+development+environment",
73+
r"https://www.unix.org/version2/sample/abort.html",
74+
)
75+
]
7076
extlinks_detect_hardcoded_links = True
7177

7278

docs/config.rst

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. _configuration:
2+
13
Configuration
24
+++++++++++++
35

@@ -102,10 +104,10 @@ Core
102104
:default: <empty list>
103105
:version_added: 3.2.0
104106

105-
Specify a list of `PEP-508 <https://www.python.org/dev/peps/pep-0508/>`_ compliant dependencies that must be
106-
satisfied in the Python environment hosting tox when running the tox command. If any of these dependencies are not
107-
satisfied will automatically create a provisioned tox environment that does not have this issue, and run the tox
108-
command within that environment. See :ref:`provision_tox_env` for more details.
107+
Specify a list of :pep:`508` compliant dependencies that must be satisfied in the Python environment hosting tox when
108+
running the tox command. If any of these dependencies are not satisfied will automatically create a provisioned tox
109+
environment that does not have this issue, and run the tox command within that environment. See
110+
:ref:`provision_tox_env` for more details.
109111

110112
.. code-block:: ini
111113
@@ -313,9 +315,9 @@ Base options
313315
:default: <empty list>
314316

315317
Each line specifies a command name (in glob-style pattern format) which can be used in the commands section even if
316-
it's located outside of the tox environment. For example: if you use the unix make command for running tests you can list
317-
``allowlist_externals=make`` or ``allowlist_externals=/usr/bin/make``. If you want to allow all external commands
318-
you can use ``allowlist_externals=*`` which will match all commands (not recommended).
318+
it's located outside of the tox environment. For example: if you use the unix *rm* command for running tests you can
319+
list ``allowlist_externals=rm`` or ``allowlist_externals=/usr/bin/rm``. If you want to allow all external
320+
commands you can use ``allowlist_externals=*`` which will match all commands (not recommended).
319321

320322
.. conf::
321323
:keys: labels
@@ -527,8 +529,8 @@ Python options
527529

528530
Leaving this unset will cause an error if the package under test has a different Python requires than tox itself
529531
and tox is installed into a Python that's not supported by the package. For example, if your package requires
530-
Python 3.9 or later, and you install tox in Python 3.8, when you run a tox environment that has left this
531-
unspecified tox will use Python 3.8 to build and install your package which will fail given it requires 3.9.
532+
Python 3.10 or later, and you install tox in Python 3.9, when you run a tox environment that has left this
533+
unspecified tox will use Python 3.9 to build and install your package which will fail given it requires 3.10.
532534

533535
.. conf::
534536
:keys: env_site_packages_dir, envsitepackagesdir
@@ -554,9 +556,25 @@ Python run
554556
:keys: deps
555557
:default: <empty list>
556558

557-
Name of the Python dependencies as specified by `PEP-440`_. Installed into the environment prior to project after
558-
environment creation, but before package installation. All installer commands are executed using the :ref:`tox_root`
559-
as the current working directory.
559+
Name of the Python dependencies. Installed into the environment prior to project after environment creation, but
560+
before package installation. All installer commands are executed using the :ref:`tox_root` as the current working
561+
directory. Each value must be one of:
562+
563+
- a Python dependency as specified by :pep:`440`,
564+
- a `requirement file <https://pip.pypa.io/en/stable/user_guide/#requirements-files>`_ when the value starts with
565+
``-r`` (followed by a file path),
566+
- a `constraint file <https://pip.pypa.io/en/stable/user_guide/#constraints-files>`_ when the value starts with
567+
``-c`` (followed by a file path).
568+
569+
For example:
570+
571+
.. code-block:: ini
572+
573+
[testenv]
574+
deps =
575+
pytest>=7,<8
576+
-r requirements.txt
577+
-c constraints.txt
560578
561579
.. conf::
562580
:keys: use_develop, usedevelop
@@ -610,7 +628,7 @@ tox supports operating with externally built packages. External packages might b
610628
:default: <empty list>
611629
:ref_suffix: external
612630

613-
Name of the Python dependencies as specified by `PEP-440`_. Installed into the environment prior running the build
631+
Name of the Python dependencies as specified by :pep:`440`. Installed into the environment prior running the build
614632
commands. All installer commands are executed using the :ref:`tox_root` as the current working directory.
615633

616634
.. conf::
@@ -731,6 +749,3 @@ Pip installer
731749
If ``true``, adds ``--pre`` to the ``opts`` passed to :ref:`install_command`. This will cause it to install the
732750
latest available pre-release of any dependencies without a specified version. If ``false``, pip will only install
733751
final releases of unpinned dependencies.
734-
735-
.. _`PEP-508`: https://www.python.org/dev/peps/pep-0508/
736-
.. _`PEP-440`: https://www.python.org/dev/peps/pep-0440/

docs/faq.rst

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,50 @@ FAQ
33

44
Here you'll find answers to some frequently asked questions.
55

6+
Using a custom PyPI server
7+
--------------------------
8+
9+
By default tox uses pip to install Python dependencies. Therefore to change the index server you should configure pip
10+
directly. pip accepts environment variables as configuration flags, therefore the easiest way to do this is to set the
11+
``PIP_INDEX_URL`` environment variable:
12+
13+
.. code-block:: ini
14+
15+
set_env =
16+
PIP_INDEX_URL = https://tox.wiki/pypi/simple
17+
18+
It's considered a best practice to allow the user to change the index server rather than hard code it, allowing them
19+
to use for example a local cache when they are offline. Therefore, a better form of this would be:
20+
21+
.. code-block:: ini
22+
23+
set_env =
24+
PIP_INDEX_URL = {env:PIP_INDEX_URL:https://tox.wiki/pypi/simple}
25+
26+
Here we use an environment substitution to set the index URL if not set by the user, but otherwise default to our target
27+
URI.
28+
29+
Using two PyPI servers
30+
----------------------
31+
32+
When you want to use two PyPI index servers because not all dependencies are found in either of them use the
33+
``PIP_EXTRA_INDEX_URL`` environment variable:
34+
35+
.. code-block:: ini
36+
37+
set_env =
38+
PIP_INDEX_URL = {env:PIP_INDEX_URL:https://tox.wiki/pypi/simple-first}
39+
PIP_EXTRA_INDEX_URL = {env:PIP_EXTRA_INDEX_URL:https://tox.wiki/pypi/simple-second}
40+
41+
If the index server defined under ``PIP_INDEX_URL`` does not contain a package, pip will attempt to resolve it also from
42+
the URI from ``PIP_EXTRA_INDEX_URL``.
43+
44+
.. warning::
45+
46+
Using an extra PyPI index for installing private packages may cause security issues. For example, if ``package1`` is
47+
registered with the default PyPI index, pip will install ``package1`` from the default PyPI index, not from the extra
48+
one.
49+
650
Using constraint files
751
----------------------
852
`Constraint files <https://pip.pypa.io/en/stable/user_guide/#constraints-files>`_ are a type of artifact, supported by
@@ -75,3 +119,126 @@ and the following ``tox.ini`` content:
75119
You can invoke ``tox`` in the directory where your ``tox.ini`` resides. ``tox`` creates two virtualenv environments
76120
with the ``python3.10`` and ``python3.9`` interpreters, respectively, and will then run the specified command according
77121
to platform you invoke ``tox`` at.
122+
123+
Ignoring the exit code of a given command
124+
-----------------------------------------
125+
126+
When multiple commands are defined within the :ref:`commands` configuration field tox will run them sequentially until
127+
one of them fails (by exiting with non zero exit code) or all of them are run. If you want to ignore the status code of
128+
a given command add a ``-`` prefix to that line (similar syntax to how the GNU ``make`` handles this):
129+
130+
.. code-block:: ini
131+
132+
133+
[testenv]
134+
commands =
135+
- python -c 'import sys; sys.exit(1)'
136+
python --version
137+
138+
Customizing virtual environment creation
139+
----------------------------------------
140+
141+
By default tox uses the :pypi:`virtualenv` to create Python virtual environments to run your tools in. To change how tox
142+
creates virtual environments you can set environment variables to customize virtualenv. For example, to provision a given
143+
pip version in the virtual environment you can set ``VIRTUALENV_PIP`` or to enable system site packages use the
144+
``VIRTUALENV_SYSTEM_SITE_PACKAGES``:
145+
146+
147+
.. code-block:: ini
148+
149+
150+
[testenv]
151+
setenv =
152+
VIRTUALENV_PIP==22.1
153+
VIRTUALENV_SYSTEM_SITE_PACKAGES=true
154+
155+
Consult the :pypi:`virtualenv` project for supported values (any CLI flag for virtualenv, in all upper case, prefixed
156+
by the ``VIRTUALENV_`` key).
157+
158+
Building documentation with Sphinx
159+
----------------------------------
160+
161+
It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the
162+
documentation can be part of the CI, and whenever any validations/checks/operations fail while generating the
163+
documentation you'll catch it within tox.
164+
165+
We don't recommend using the Make and Batch file generated by Sphinx, as this makes your documentation generation
166+
platform specific. A better solution is to use tox to setup a documentation build environment and invoke sphinx inside
167+
it. This solution is cross platform.
168+
169+
For example if the sphinx file structure is under the ``docs`` folder the following configuration will generate
170+
the documentation under ``.tox/docs_out/index.html`` and print out a link to the generated documentation:
171+
172+
.. code-block:: ini
173+
174+
[testenv:docs]
175+
description = build documentation
176+
basepython = python3.10
177+
deps =
178+
sphinx>=4
179+
commands =
180+
sphinx-build -d "{envtmpdir}{/}doctree" docs "{toxworkdir}{/}docs_out" --color -b html
181+
python -c 'print(r"documentation available under file://{toxworkdir}{/}docs_out{/}index.html")'
182+
183+
Note here we also require Python 3.10, allowing us to use f-strings within the sphinx ``conf.py``.
184+
185+
Building documentation with mkdocs
186+
----------------------------------
187+
188+
It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the
189+
documentation can be part of the CI, and whenever any validations/checks/operations fail while generating the
190+
documentation you'll catch it within tox.
191+
192+
It's best to define one environment to write/generate the documentation, and another to deploy it. Use the config
193+
substitution logic to avoid duplication:
194+
195+
.. code-block:: ini
196+
197+
[testenv:docs]
198+
description = Run a development server for working on documentation
199+
deps =
200+
mkdocs>=1.3
201+
mkdocs-material
202+
commands =
203+
mkdocs build --clean
204+
python -c 'print("###### Starting local server. Press Control+C to stop server ######")'
205+
mkdocs serve -a localhost:8080
206+
207+
[testenv:docs-deploy]
208+
description = built fresh docs and deploy them
209+
deps = {[testenv:docs]deps}
210+
commands = mkdocs gh-deploy --clean
211+
212+
Understanding ``InvocationError`` exit codes
213+
--------------------------------------------
214+
215+
When a command executed by tox fails, it always has a non-zero exit code and an ``InvocationError`` exception is
216+
raised:
217+
218+
.. code-block:: shell
219+
220+
ERROR: InvocationError for command
221+
'<command defined in tox.ini>' (exited with code 1)
222+
223+
Generally always check the documentation for the command executed to understand what the code means. For example for
224+
:pypi:`pytest` you'd read `here <https://docs.pytest.org/en/latest/reference/exit-codes.html#exit-codes>`_. On unix
225+
systems, there are some rather `common exit codes <http://www.faqs.org/docs/abs/HTML/exitcodes.html>`_. This is why for
226+
exit codes larger than 128, if a signal with number equal to ``<exit code> - 128`` is found in the :py:mod:`signal`
227+
module, an additional hint is given:
228+
229+
.. code-block:: shell
230+
231+
ERROR: InvocationError for command
232+
'<command>' (exited with code 139)
233+
Note: this might indicate a fatal error signal (139 - 128 = 11: SIGSEGV)
234+
235+
236+
The signal numbers (e.g. 11 for a segmentation fault) can be found in the "Standard signals" section of the
237+
`signal man page <https://man7.org/linux/man-pages/man7/signal.7.html>`_.
238+
Their meaning is described in `POSIX signals <https://en.wikipedia.org/wiki/Signal_(IPC)#POSIX_signals>`_. Beware
239+
that programs may issue custom exit codes with any value, so their documentation should be consulted.
240+
241+
242+
Sometimes, no exit code is given at all. An example may be found in
243+
:gh:`pytest-qt issue #170 <pytest-dev/pytest-qt/issues/170>`, where Qt was calling
244+
`abort() <https://www.unix.org/version2/sample/abort.html>`_ instead of ``exit()``.

docs/installation.rst

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Installation
44
via pipx
55
--------
66

7-
:pypi:`tox` is a CLI tool that needs a Python interpreter (version 3.6 or higher) to run. We recommend :pypi:`pipx` to
7+
:pypi:`tox` is a CLI tool that needs a Python interpreter (version 3.7 or higher) to run. We recommend :pypi:`pipx` to
88
install tox into an isolated environment. This has the added benefit that later you'll be able to upgrade tox without
99
affecting other parts of the system.
1010

@@ -30,27 +30,24 @@ state. Note, if you go down this path you need to ensure pip is new enough per t
3030
wheel
3131
~~~~~
3232
Installing tox via a wheel (default with pip) requires an installer that can understand the ``python-requires`` tag (see
33-
`PEP-503 <https://www.python.org/dev/peps/pep-0503/>`_), with pip this is version ``9.0.0`` (released in November 2016).
34-
Furthermore, in case you're not installing it via PyPI you need to use a mirror that correctly forwards the
35-
``python-requires`` tag (notably the OpenStack mirrors don't do this, or older :gh_repo:`devpi/devpi` versions -
36-
added with version ``4.7.0``).
33+
:pep:`503`), with pip this is version ``9.0.0`` (released in November 2016). Furthermore, in case you're not installing
34+
it via PyPI you need to use a mirror that correctly forwards the ``python-requires`` tag (notably the OpenStack mirrors
35+
don't do this, or older :gh_repo:`devpi/devpi` versions - added with version ``4.7.0``).
3736

3837
.. _sdist:
3938

4039
sdist
4140
~~~~~
42-
When installing via a source distribution you need an installer that handles the
43-
`PEP-517 <https://www.python.org/dev/peps/pep-0517/>`_ specification. In case of ``pip`` this is version ``18.0.0`` or
44-
later (released in July 2018). If you cannot upgrade your pip to support this you need to ensure that the build
45-
requirements from :gh:`pyproject.toml <tox-dev/tox/blob/rewrite/pyproject.toml#L2>` are satisfied before triggering the
46-
installation.
41+
When installing via a source distribution you need an installer that handles the :pep:`517` specification. In case of
42+
``pip`` this is version ``18.0.0`` or later (released in July 2018). If you cannot upgrade your pip to support this you
43+
need to ensure that the build requirements from :gh:`pyproject.toml <tox-dev/tox/blob/rewrite/pyproject.toml#L2>` are
44+
satisfied before triggering the installation.
4745

4846
via ``setup.py``
4947
----------------
50-
We don't recommend and officially support this method. You should prefer using an installer that supports
51-
`PEP-517 <https://www.python.org/dev/peps/pep-0517/>`_ interface, such as pip ``19.0.0`` or later. That being said you
52-
might be able to still install a package via this method if you satisfy build dependencies before calling the
53-
installation command (as described under :ref:`sdist`).
48+
We don't recommend and officially support this method. You should prefer using an installer that supports :pep:`517`
49+
interface, such as pip ``19.0.0`` or later. That being said you might be able to still install a package via this method
50+
if you satisfy build dependencies before calling the installation command (as described under :ref:`sdist`).
5451

5552
latest unreleased
5653
-----------------

0 commit comments

Comments
 (0)