From 3d12d933f945cc48331580a45296d23bc5abc088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Thu, 28 Apr 2022 09:55:07 -0600 Subject: [PATCH 1/6] Migrate tox 3 documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the first pass. Signed-off-by: Bernát Gábor --- docs/config.rst | 34 +++-- docs/faq.rst | 167 ++++++++++++++++++++++ docs/installation.rst | 2 +- docs/user_guide.rst | 320 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 469 insertions(+), 54 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index 9e2945b12..87fe75cb4 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -1,3 +1,5 @@ +.. _configuration: + Configuration +++++++++++++ @@ -313,9 +315,9 @@ Base options :default: Each line specifies a command name (in glob-style pattern format) which can be used in the commands section even if - it's located outside of the tox environment. For example: if you use the unix make command for running tests you can list - ``allowlist_externals=make`` or ``allowlist_externals=/usr/bin/make``. If you want to allow all external commands - you can use ``allowlist_externals=*`` which will match all commands (not recommended). + it's located outside of the tox environment. For example: if you use the unix *rm* command for running tests you can + list ``allowlist_externals=rm`` or ``allowlist_externals=/usr/bin/rm``. If you want to allow all external + commands you can use ``allowlist_externals=*`` which will match all commands (not recommended). .. conf:: :keys: labels @@ -527,8 +529,8 @@ Python options Leaving this unset will cause an error if the package under test has a different Python requires than tox itself and tox is installed into a Python that's not supported by the package. For example, if your package requires - Python 3.9 or later, and you install tox in Python 3.8, when you run a tox environment that has left this - unspecified tox will use Python 3.8 to build and install your package which will fail given it requires 3.9. + Python 3.10 or later, and you install tox in Python 3.9, when you run a tox environment that has left this + unspecified tox will use Python 3.9 to build and install your package which will fail given it requires 3.10. .. conf:: :keys: env_site_packages_dir, envsitepackagesdir @@ -554,9 +556,25 @@ Python run :keys: deps :default: - Name of the Python dependencies as specified by `PEP-440`_. Installed into the environment prior to project after - environment creation, but before package installation. All installer commands are executed using the :ref:`tox_root` - as the current working directory. + Name of the Python dependencies. Installed into the environment prior to project after environment creation, but + before package installation. All installer commands are executed using the :ref:`tox_root` as the current working + directory. Each value must be one of: + + - a python dependency as specified by `PEP-440`_, + - a `requirement file `_ when the value starts with + ``-r`` (followed by a file path), + - a `constraint file `_ when the value starts with + ``-c`` (followed by a file path). + + For example: + + .. code-block:: ini + + [testenv] + deps = + pytest>=7,<8 + -r requirements.txt + -c constraints.txt .. conf:: :keys: use_develop, usedevelop diff --git a/docs/faq.rst b/docs/faq.rst index ffb798c01..487aa4c06 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -3,6 +3,50 @@ FAQ Here you'll find answers to some frequently asked questions. +Using a custom PyPI server +-------------------------- + +By default tox uses pip to install Python dependencies. Therefore to change the index server you should configure pip +directly. pip accepts environment variables as configuration flags, therefore the easiest way to do this is to set the +``PIP_INDEX_URL`` environment variable: + +.. code-block:: ini + + set_env = + PIP_INDEX_URL = https://tox.wiki/pypi/simple + +It's considered a best practice to allow the user to change the index server rather than hard code it, allowing them +to use for example a local cache of that when they are offline. Therefore, a better form of this would be: + +.. code-block:: ini + + set_env = + PIP_INDEX_URL = {env:PIP_INDEX_URL:https://tox.wiki/pypi/simple} + +Here we use an environment substitution to set the index URL if not set by the user, but otherwise default to our target +URI. + +Using two PyPI servers +---------------------- + +When you want to use two PyPI index servers because not all dependencies are found in either of them use the +``PIP_EXTRA_INDEX_URL`` environment variable: + +.. code-block:: ini + + set_env = + PIP_INDEX_URL = {env:PIP_INDEX_URL:https://tox.wiki/pypi/simple-first} + PIP_EXTRA_INDEX_URL = {env:PIP_EXTRA_INDEX_URL:https://tox.wiki/pypi/simple-second} + +If the index server defined under ``PIP_INDEX_URL`` does not contain a package pip will attempt to resolve it also from +the URI from ``PIP_EXTRA_INDEX_URL``. + +.. warning:: + + Using an extra PyPI index for installing private packages may cause security issues. For example, if ``package1`` is + registered with the default PyPI index, pip will install ``package1`` from the default PyPI index, not from the extra + one. + Using constraint files ---------------------- `Constraint files `_ are a type of artifact, supported by @@ -75,3 +119,126 @@ and the following ``tox.ini`` content: You can invoke ``tox`` in the directory where your ``tox.ini`` resides. ``tox`` creates two virtualenv environments with the ``python3.10`` and ``python3.9`` interpreters, respectively, and will then run the specified command according to platform you invoke ``tox`` at. + +Ignoring the exit code of a given command +----------------------------------------- + +When multiple commands are defined within the :ref:`commands` configuration field tox will run them sequentially until +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 +a given command add a ``-`` prefix to that line (similar syntax to how the GNU ``make`` handles this): + +.. code-block:: ini + + + [testenv:py310] + commands = + - python -c 'import sys; sys.exit(1)' + python --version + +Customize virtual environment creation +-------------------------------------- + +By default tox uses the :pypi:`project` to create Python virtual environments to run your tools in. To change how tox +creates virtual environments set environment variables to customize virtualenv. For example, to provision a given +pip version in the virtual environment set ``VIRTUALENV_PIP`` or to enable system site packages use the +``VIRTUALENV_SYSTEM_SITE_PACKAGES``: + + +.. code-block:: ini + + + [testenv] + setenv = + VIRTUALENV_PIP==22.1 + VIRTUALENV_SYSTEM_SITE_PACKAGES=true + +Consult the :pypi:`virtualenv` project for supported values (any CLI flag for virtualenv, in all upper case, prefixed +by the ``VIRTUALENV_`` key). + +Build documentation with Sphinx +------------------------------- + +It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the +documentation can be part of the CI, and whenever any validations/checks/operations fail while generating the +documentation you'll catch it within tox. + +We don't recommend using the Make and Batch file generated by Sphinx, as this makes your documentation generation +platform specific. A better solution is to use tox to setup a documentation build environment and invoke sphinx inside +it. This solution is cross platform. + +For example if the sphinx file structure is under the ``docs`` folder the following configuration will generate +the documentation under ``.tox/docs_out/index.html`` and print out a link to the generated documentation: + +.. code-block:: ini + + [testenv:docs] + description = build documentation + basepython = python3.10 + deps = + sphinx>=4 + commands = + sphinx-build -d "{envtmpdir}{/}doctree" docs "{toxworkdir}{/}docs_out" --color -b html + python -c 'print(r"documentation available under file://{toxworkdir}{/}docs_out{/}index.html")' + +Note here we also require python 3.10, allowing us to use f-strings within the sphinx ``conf.py``. + +Build documentation with mkdocs +------------------------------- + +It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the +documentation can be part of the CI, and whenever any validations/checks/operations fail while generating the +documentation you'll catch it within tox. + +It's best to define one environment to write/generate the documentation, and another to deploy it. Use the config +substitution logic to avoid defining dependencies multiple time: + +.. code-block:: ini + + [testenv:docs] + description = Run a development server for working on documentation + deps = + mkdocs>=1.3 + mkdocs-material + commands = + mkdocs build --clean + python -c 'print("###### Starting local server. Press Control+C to stop server ######")' + mkdocs serve -a localhost:8080 + + [testenv:docs-deploy] + description = built fresh docs and deploy them + deps = {[testenv:docs]deps} + commands = mkdocs gh-deploy --clean + +Understanding ``InvocationError`` exit codes +-------------------------------------------- + +When a command executed by tox fails, it always has a non-zero exit code and an ``InvocationError`` exception is +raised: + +.. code-block:: shell + + ERROR: InvocationError for command + '' (exited with code 1) + +Generally always check the documentation for the command executed to understand what the code means. For example for +:pypi:`pytest` you'd read `here `_. On unix systems, +there are some rather `common exit codes `_. This is why for exit +codes larger than 128, if a signal with number equal to `` - 128`` is found in the :py:mod:`signal` module, +an additional hint is given: + +.. code-block:: shell + + ERROR: InvocationError for command + '' (exited with code 139) + Note: this might indicate a fatal error signal (139 - 128 = 11: SIGSEGV) + + +The signal numbers (e.g. 11 for a segmentation fault) can be found in the "Standard signals" section of the +`signal man page `_. +Their meaning is described in `POSIX signals `_. Beware +that programs may issue custom exit codes with any value, so their documentation should be consulted. + + +Sometimes, no exit code is given at all. An example may be found in +:gh:`pytest-qt issue #170 `, where Qt was calling +`abort() `_ instead of ``exit()``. diff --git a/docs/installation.rst b/docs/installation.rst index c751a5d80..23deb1736 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -4,7 +4,7 @@ Installation via pipx -------- -:pypi:`tox` is a CLI tool that needs a Python interpreter (version 3.6 or higher) to run. We recommend :pypi:`pipx` to +:pypi:`tox` is a CLI tool that needs a Python interpreter (version 3.7 or higher) to run. We recommend :pypi:`pipx` to install tox into an isolated environment. This has the added benefit that later you'll be able to upgrade tox without affecting other parts of the system. diff --git a/docs/user_guide.rst b/docs/user_guide.rst index a62ea9259..e24b6ab7f 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -4,8 +4,24 @@ User Guide Basic example ------------- -Put basic information about your project and the test environments you want your project to run in into a ``tox.ini`` -file residing at the root of your project: +tox is a environment orchestrator. Use it to define the how to setup and execute various tools on your projects. The +tool can be: + +- a test runner (such as :pypi:`pytest`), +- a linter (e.g., :pypi:`flake8`), +- a formatter (for example :pypi:`black` or :pypi:`isort`), +- a documentation generator (e.g., :pypi:`sphinx`), +- library build and publisher (e.g., :pypi:`build` with :pypi:`twine`), +- or anything else you may need to execute. + +First, you need to define in a configuration file what tools you need to run and how to provision a test environment for +these. The canonical file for this is the ``tox.ini`` file, let's take a look at an example of this (this needs to live +at the root of your project): + +.. note:: + + You can also try generating a ``tox.ini`` file automatically by running ``tox quickstart`` and then answering a few + questions. .. code-block:: ini @@ -13,44 +29,63 @@ file residing at the root of your project: envlist = format py310 - py39 - [testenv] - # install pytest in a virtual environment and invoke it on the test folder + [testenv:format] + description = install black in a virtual environment and invoke it on the current folder + deps = black==22.3.0 + skip_install = true + commands = black . + + [testenv:py310] + description = install pytest in a virtual environment and invoke it on the tests folder deps = - pytest>=6 + pytest>=7 pytest-sugar commands = pytest tests {posargs} - [testenv:format] - # install black in a virtual environment and invoke it on the current folder - deps = black - skip_install = true - commands = black . -You can also try generating a ``tox.ini`` file automatically by running ``tox quickstart`` and then answering a few -simple questions. The configuration above will run three separate tox environments ``format``, ``py310`` and ``py39`` -when you type in ``tox`` onto the command line within the projects folder (as defined by ``envlist``). The ``format`` -environment will create a Python virtual environment, install the ``black`` tool in it and the invoke it on the project -root folder. +The configuration is split to two type of configuration: core settings are hosted under the ``tox`` section and per run +environment settings hosted under ``testenv:``. Under the core section we define that this project has two +run environments named ``format`` and ``py310`` respectively (we use the ``envlist`` configuration key to do so). + +Then we define separately what should the formatting environment (``testenv:format`` section) and the test environment +(``testenv:py310`` section). For example to format the project we: + +- add a description (visible when you type ``tox list`` into the command line), +- we define that requires the ``black`` PyPI dependency with version ``22.3.0``, +- the black tool does not need the project we are testing to be installed into the test environment so we disable this + default behaviour via the ``skip_install`` configuration, +- and we defined that the tool should be invoked as we'd type ``black .`` into the command line. + +For testing the project we use the ``py310`` environment, for which we: + +- define a text description of the environment, +- specify that requires ``pytest`` ``7`` ot later together with the :pypi:`pytest-sugar` project, +- and that the tool should be invoked via the ``pytest tests`` CLI command. -The ``py310`` and ``py39`` do not have their own dedicated configuration section as ```format`` had (via -``[testenv:format]``) so they'll pull their configuration entirely from the ``[testenv]`` section. A Python virtual -environment is created, the dependencies from the ``deps`` config installed, the project package built and installed, -and then the ``pytest`` tool invoked. +The ``{posargs}`` is a place holder part for the CLI command that allows us to pass additional flags to the pytest +invocation, for example if we'd want to run ``pytest tests -v`` as a one off, instead of ``tox run -e py310`` we'd type +``tox run -e py310 -- -v``. The ``--`` delimits flags for the tox tool and what should be forwarded to the tool within. -The ``{posargs}`` argument is replaced with whatever you pass in after the ``--`` on the CI, so if you'd run -``tox -- -k test_something`` the command tox would run would be ``pytest tests -k test_something``. Note for this to -work you must have Python 3.10 and 3.9 installed on the machine as virtualenv can only create virtual environments if -the given python version is globally available on the machine. +tox, by default, always creates a fresh virtual environment for every run environment. The python version to use for a +given environment can be controlled via the :ref:`base_python` configuration, however if not set will try to use the +environment name to determine something sensible: if the name is in the format of ``pyxy`` then will create a CPython +with version ``x.y`` (for example ``py310`` means CPython ``3.10``). If the name does not matches this pattern it will +use a virtual environment with the same python version as the one tox is installed into (this is the case for +``format``). -When you run ``tox`` a second time you'll notice that it runs much faster because it keeps track of virtualenv -details and will not recreate or re-install dependencies. +tox environments are reused between runs, so while the first ``tox run -e py310`` will take a while as tox needs to +create a virtual environment and install ``pytest`` and ``pytest-sugar`` in it, subsequent runs only need to reinstall +your project (as long as the environments dependency list does not changes). + +Almost every step and aspect of virtual environments and command execution can be customized. You'll find +an exhaustive list of configuration flags (together with what it does and detailed explanation of what values are +accepted) at our :ref:`configuration page `. System overview --------------- -Here you can see a graphical representation of its run states: +Below is a graphical representation of the tox states and transition pathways between them: .. image:: img/overview_light.svg :align: center @@ -61,14 +96,14 @@ Here you can see a graphical representation of its run states: :class: only-dark -tox roughly follows the following states: +The primary tox states are: -#. **configuration:** load tox configuration files (such as ``tox.ini``, ``pyproject.toml``, and ``toxfile.py``) and - merge it with options from the command line and the operating system environment variables +#. **Configuration:** load tox configuration files (such as ``tox.ini``, ``pyproject.toml`` and ``toxfile.py``) and + merge it with options from the command line plus the operating system environment variables. -#. **environment**: for each selected tox environment (e.g. ``py310``, ``py39``) do: +#. **Environment**: for each selected tox environment (e.g. ``py310``, ``format``) do: - #. **creation**: create a fresh environment; by default :pypi:`virtualenv` is used, but configurable via + #. **Creation**: create a fresh environment; by default :pypi:`virtualenv` is used, but configurable via :ref:`runner`. For `virtualenv` tox will use the `virtualenv discovery logic `_ where the python specification is defined by the tox environments :ref:`base_python` (if not set will default to the environments name). This is @@ -76,14 +111,14 @@ tox roughly follows the following states: version, dependencies removed, etc.), a re-creation of the environment is automatically triggered. To force the recreation tox can be invoked with the :ref:`recreate` flag (``-r``). - #. **install dependencies** (optional): install the environment dependencies specified inside the ``deps`` + #. **Install dependencies** (optional): install the environment dependencies specified inside the ``deps`` configuration section, and then the earlier packaged source distribution. By default ``pip`` is used to install packages, however one can customize this via ``install_command``. Note ``pip`` will not update project dependencies (specified either in the ``install_requires`` or the ``extras`` section of the ``setup.py``) if any version already exists in the virtual environment; therefore we recommend to recreate your environments whenever your project dependencies change. - #. **packaging** (optional): create a distribution of the current project + #. **Packaging** (optional): create a distribution of the current project. #. **Build**: If the tox environment has a package configured tox will build a package from the current source tree. If multiple tox environments are run and the package built are compatible in between them then it will be @@ -94,11 +129,11 @@ tox roughly follows the following states: #. **Install the package**. This operation will force reinstall the package without its dependencies. - #. **commands**: run the specified commands in the specified order. Whenever the exit code of any of them is not + #. **Commands**: run the specified commands in the specified order. Whenever the exit code of any of them is not zero, stop and mark the environment failed. When you start a command with a dash character, the exit code will be ignored. -#. **report** print out a report of outcomes for each tox environment: +#. **Report** print out a report of outcomes for each tox environment: .. code:: bash @@ -109,10 +144,10 @@ tox roughly follows the following states: Only if all environments ran successfully tox will return exit code ``0`` (success). In this case you'll also see the message ``congratulations :)``. -tox will take care of environment isolation for you: it will strip away all operating system environment variables not -specified via ``passenv``. Furthermore, it will also alter the ``PATH`` variable so that your commands resolve -within the current active tox environment. In general, all executables in the path are available in ``commands``, but -tox will error if it was not explicitly allowed via :ref:`allowlist_externals`. +tox will take care of environment variable isolation for you (will remove system environment variables not specified via +``passenv``). Furthermore, it will also alter the ``PATH`` variable so that your commands resolve within the current +active tox environment. In general, all executables outside of hte tox environment are available in ``commands``, but +external commands need to be explicitly allowed via the :ref:`allowlist_externals` configuration. Main features ------------- @@ -126,12 +161,207 @@ Main features * ``plugin system`` to modify tox execution with simple hooks. * uses :pypi:`pip` and :pypi:`virtualenv` by default. Support for plugins replacing it with their own. -* **cross-Python compatible**: CPython 3.6 and higher. -* **cross-platform**: Windows, macOS and Unix style environments +* **cross-Python compatible**: tox requires CPython 3.7 and higher (but can create environments 2.7 or later). +* **cross-platform**: Windows, macOS and Unix style environments, * **full interoperability with devpi**: is integrated with and is used for testing in the :pypi:`devpi` system, a - versatile PyPI index server and release managing tool + versatile PyPI index server and release managing tool. * **driven by a simple (but flexible to allow expressing more complicated variants) ini-style config file** * **documented** examples and configuration * **concise reporting** about tool invocations and configuration errors -* **professionally** supported -* supports using different / multiple PyPI index servers +* supports using different / multiple PyPI index servers. + +Related projects +---------------- + +tox has influenced several other projects in the Python test automation space. If tox doesn't quite fit your needs or +you want to do more research, we recommend taking a look at these projects: + +- `nox `__ is a project similar in spirit to tox but different in approach. The primary key + difference is that it uses Python scripts instead of a configuration file. It might be useful if you find tox + configuration too limiting but aren't looking to move to something as general-purpose as ``Invoke`` or ``make``. + Note tox will also soon support defining the configuration in a python file. +- `Invoke `__ is a general-purpose task execution library, similar to Make. Invoke is far + more general-purpose than tox but it does not contain the Python testing-specific features that tox specializes in. + + +Auto-provisioning +----------------- +In case the host tox does not satisfy either the :ref:`min_version` or the :ref:`requires`, tox will automatically +create a virtual environment under :ref:`provision_tox_env` name that satisfies those constraints and delegate all +calls to this meta environment. This should allow automatically satisfying constraints on your tox environment, +given you have at least version ``3.8.0`` of tox. + +For example given: + +.. code-block:: ini + + [tox] + min_version = 4 + requires = tox-docker>=1 + +if the user runs it with tox ``3.8`` or later installed tox will automatically ensured that both the minimum version and +requires constraints are satisfied, by creating a virtual environment under ``.tox`` folder, and then installing into it +``tox>=4`` and ``tox-docker>=1``. Afterwards all tox invocations are forwarded to the tox installed inside ``.tox\.tox`` +folder (referred to as meta-tox or auto-provisioned tox). + +This allows tox to automatically setup itself with all its plugins for the current project. If the host tox satisfies +the constraints expressed with the :ref:`requires` and :ref:`min_version` no such provisioning is done (to avoid +setup cost and indirection when it's not explicitly needed). + +Cheat sheet +------------ + +This section details information that you'll use most often in short form. + +CLI +~~~ +- Each tox subcommand has a 1 (or 2) letter shortcut form too, e.g. ``tox run`` can also be written as ``tox r`` or + ``tox config`` can be shorten to ``tox c``. +- To run all tox environments defined in the :ref:`env_list` run tox without any flags: ``tox``. +- To run a single tox environment use the ``-e`` flag for the ``run`` sub-command as in ``tox run -e py310``. +- To run two or more tox environment pass comma separated values, e.g. ``tox run -e format,py310``. The run command will + run the tox environments sequentially, one at a time, in the specified order. +- To run two or more tox environment in parallel use the ``parallel`` sub-command , e.g. ``tox parallel -e py39,py310``. + The ``--parallel`` flag for this sub-command controls the degree of parallelism. +- To view the configuration value for a given environment and a given configuration key use the config sub-command with + the ``-k`` flag to filter for targeted configuration values: ``tox config -e py310 -k pass_env``. +- tox tries to automatically detect changes to your project dependencies and force a recreation when needed. + Unfortunately the detection is not always accurate, and will also not detect changes on the PyPI index server. You can + force a fresh start for the tox environments by passing the ``-r`` flag to your run command. Whenever you see + something that should work but fails with some esoteric error it's recommended to use this flag to make sure you don't + have a stale Python environment; e.g. ``tox run -e py310 -r`` would clean the run environment and recreate it from + scratch. + +Configuration +~~~~~~~~~~~~~ + +- Every tox environment has its own configuration section (e.g. in case of ``tox.ini`` configuration method the + ``py310`` tox environments configuration is read from ``testenv:py310`` section). If the section is missing or does + not contain that configuration value it will fallback to section defined by the :ref:`base` configuration (for + ``tox.ini`` this is the ``testenv`` section). For example: + + .. code-block:: ini + + [testenv] + commands = pytest tests + + [testenv:test] + description = run the test suite with pytest + + Here the ``test`` tox environments description is taken from ``testenv:test``. The ``commands`` is not specified, + so will instead use the value defined under the ``testenv`` section. If the base environment is also missing a + configuration value then the configuration default will be used (e.g. in case of the ``pass_env`` configuration here). + +- To change the current working directory for the commands run use :ref:`change_dir` (note this will make the change for + all install commands too - watch out if you have relative paths in your project dependencies). +- Environment variables: + + - To view environment variables set and passed down use ``tox4 c -e py310 -k set_env pass_env``. + - To pass through additional environment variables use :ref:`pass_env`. + - To set environment variables use :ref:`set_env`. +- Setup operation can be configured via the :ref:`commands_pre`, while teardown commands via the :ref:`commands_post`. +- Configurations may be set conditionally within the ``tox.ini`` file. If a line starts with an environment name + (optionally can be more than one when separated by ``,``) followed by ``:`` the configuration will only be used if the + environment name(s) matches the executed tox environment. For example: + + .. code-block:: ini + + [testenv] + deps = + pip + format: black + py310,py39: pytest + + Here pip will be always installed as the configuration value is not conditional. black is only used for the ``format`` + environment, while ``pytest`` is only installed for the ``py310`` and ``py39`` environments. + +.. _`parallel_mode`: + +Parallel mode +------------- +``tox`` allows running environments in parallel mode via the ``parallel`` sub-command: + +- After the packaging phase completes tox will run in parallel processes tox environments (multi-thread based). +- ``--parallel`` flags takes an argument specifying the degree of parallelization, defaulting to ``auto``: + + - ``all`` to run all invoked environments in parallel, + - ``auto`` to limit it to CPU count, + - or pass an integer to set that limit. +- Parallel mode displays a progress spinner while running tox environments in parallel, and reports outcome of these as + soon as completed with a human readable duration timing attached. This spinner can be disabled via the + ``--parallel-no-spinner`` flag. +- Parallel mode by default shows output only of failed environments and ones marked as :ref:`parallel_show_output` + ``=True``. +- There's now a concept of dependency between environments (specified via :ref:`depends`), tox will re-order the + environment list to be run to satisfy these dependencies (in sequential run too). Furthermore, in parallel mode, + will only schedule a tox environment to run once all of its dependencies finished (independent of their outcome). + + .. warning:: + + ``depends`` does not pull in dependencies into the run target, for example if you select ``py310,py39,coverage`` + via the ``-e`` tox will only run those three (even if ``coverage`` may specify as ``depends`` other targets too - + such as ``py310, py39, py38, py37``). + +- ``--parallel-live``/``-o`` allows showing the live output of the standard output and error, also turns off reporting + described above. +- Note: parallel evaluation disables standard input. Use non parallel invocation if you need standard input. + +Example final output: + +.. code-block:: bash + + $ tox -e py310,py39,coverage -p all + ✔ OK py39 in 9.533 seconds + ✔ OK py310 in 9.96 seconds + ✔ OK coverage in 2.0 seconds + ___________________________ summary ______________________________________________________ + py310: commands succeeded + py39: commands succeeded + coverage: commands succeeded + congratulations :) + + +Example progress bar, showing a rotating spinner, the number of environments running and their list (limited up to \ +120 characters): + +.. code-block:: bash + + ⠹ [2] py310 | py39 + +Packaging +--------- + +tox always builds projects in a PEP-518 compatible virtual environment and communicates with the build backend according +to the interface defined in PEP-517 and PEP-660. To define package build dependencies and specify the build backend to +use create a ``pyproject.toml`` at the root of the project, for example to use hatch: + +.. code-block:: toml + + [build-system] + build-backend = "hatchling.build" + requires = ["hatchling>=0.22", "hatch-vcs>=0.2"] + +By default tox will create and install a source distribution. You can configure to build a wheel instead by setting +the :ref:`package` configuration to ``wheel``. Wheels are much faster to install than source distributions. + +To query the projects dependencies tox will use a virtual environment whose name is defined under the :ref:`package_env` +configuration (by default ``.pkg``). The virtual environment to use for building the package depends on the artifact +built: + +- for source distribution the :ref:`package_env`, +- for wheels the name defined under :ref:`wheel_build_env` (this depends on the Python version defined by the target tox + environment under :ref:`base_python`, if the environment targets CPython 3.10 it will be ``.pkg-cpython310`` or + for PyPy 3.9 it will be ``.pkg-pypy39``). + +For pure python projects (non C-Extension ones) it's recommended to set :ref:`wheel_build_env` to the same as the +:ref:`package_env`. This way you'll build the wheel once and install the same wheel for all tox environments. + +Advanced features +----------------- + +tox supports these features that 90 percent of the time you'll not need, but are very useful the other ten percent. + +Generative environments +~~~~~~~~~~~~~~~~~~~~~~~ + +Django. From 5c925d73f2a3a24ed86be2f9376a4a8a2462e71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sun, 21 Aug 2022 11:47:29 -0700 Subject: [PATCH 2/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jürgen Gmach --- docs/config.rst | 2 +- docs/faq.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/config.rst b/docs/config.rst index 87fe75cb4..f3190612c 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -560,7 +560,7 @@ Python run before package installation. All installer commands are executed using the :ref:`tox_root` as the current working directory. Each value must be one of: - - a python dependency as specified by `PEP-440`_, + - a Python dependency as specified by `PEP-440`_, - a `requirement file `_ when the value starts with ``-r`` (followed by a file path), - a `constraint file `_ when the value starts with diff --git a/docs/faq.rst b/docs/faq.rst index 487aa4c06..e1b84ab45 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -16,7 +16,7 @@ directly. pip accepts environment variables as configuration flags, therefore th PIP_INDEX_URL = https://tox.wiki/pypi/simple It's considered a best practice to allow the user to change the index server rather than hard code it, allowing them -to use for example a local cache of that when they are offline. Therefore, a better form of this would be: +to use for example a local cache when they are offline. Therefore, a better form of this would be: .. code-block:: ini @@ -38,7 +38,7 @@ When you want to use two PyPI index servers because not all dependencies are fou PIP_INDEX_URL = {env:PIP_INDEX_URL:https://tox.wiki/pypi/simple-first} PIP_EXTRA_INDEX_URL = {env:PIP_EXTRA_INDEX_URL:https://tox.wiki/pypi/simple-second} -If the index server defined under ``PIP_INDEX_URL`` does not contain a package pip will attempt to resolve it also from +If the index server defined under ``PIP_INDEX_URL`` does not contain a package, pip will attempt to resolve it also from the URI from ``PIP_EXTRA_INDEX_URL``. .. warning:: @@ -130,7 +130,7 @@ a given command add a ``-`` prefix to that line (similar syntax to how the GNU ` .. code-block:: ini - [testenv:py310] + [testenv] commands = - python -c 'import sys; sys.exit(1)' python --version From 4e9ef50643cf30d133be9258c2e3f11232ff6c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sun, 21 Aug 2022 11:48:10 -0700 Subject: [PATCH 3/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jürgen Gmach --- docs/faq.rst | 14 +++++++------- docs/user_guide.rst | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/faq.rst b/docs/faq.rst index e1b84ab45..b3b2ca030 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -135,12 +135,12 @@ a given command add a ``-`` prefix to that line (similar syntax to how the GNU ` - python -c 'import sys; sys.exit(1)' python --version -Customize virtual environment creation +Customizing virtual environment creation -------------------------------------- By default tox uses the :pypi:`project` to create Python virtual environments to run your tools in. To change how tox -creates virtual environments set environment variables to customize virtualenv. For example, to provision a given -pip version in the virtual environment set ``VIRTUALENV_PIP`` or to enable system site packages use the +creates virtual environments you can set environment variables to customize virtualenv. For example, to provision a given +pip version in the virtual environment you can set ``VIRTUALENV_PIP`` or to enable system site packages use the ``VIRTUALENV_SYSTEM_SITE_PACKAGES``: @@ -155,7 +155,7 @@ pip version in the virtual environment set ``VIRTUALENV_PIP`` or to enable syste Consult the :pypi:`virtualenv` project for supported values (any CLI flag for virtualenv, in all upper case, prefixed by the ``VIRTUALENV_`` key). -Build documentation with Sphinx +Building documentation with Sphinx ------------------------------- It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the @@ -180,9 +180,9 @@ the documentation under ``.tox/docs_out/index.html`` and print out a link to the sphinx-build -d "{envtmpdir}{/}doctree" docs "{toxworkdir}{/}docs_out" --color -b html python -c 'print(r"documentation available under file://{toxworkdir}{/}docs_out{/}index.html")' -Note here we also require python 3.10, allowing us to use f-strings within the sphinx ``conf.py``. +Note here we also require Python 3.10, allowing us to use f-strings within the sphinx ``conf.py``. -Build documentation with mkdocs +Building documentation with mkdocs ------------------------------- It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the @@ -190,7 +190,7 @@ documentation can be part of the CI, and whenever any validations/checks/operati documentation you'll catch it within tox. It's best to define one environment to write/generate the documentation, and another to deploy it. Use the config -substitution logic to avoid defining dependencies multiple time: +substitution logic to avoid duplication: .. code-block:: ini diff --git a/docs/user_guide.rst b/docs/user_guide.rst index e24b6ab7f..acaf0a1b5 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -4,23 +4,23 @@ User Guide Basic example ------------- -tox is a environment orchestrator. Use it to define the how to setup and execute various tools on your projects. The +tox is an environment orchestrator. Use it to define how to setup and execute various tools on your projects. The tool can be: - a test runner (such as :pypi:`pytest`), - a linter (e.g., :pypi:`flake8`), - a formatter (for example :pypi:`black` or :pypi:`isort`), - a documentation generator (e.g., :pypi:`sphinx`), -- library build and publisher (e.g., :pypi:`build` with :pypi:`twine`), +- library builder and publisher (e.g., :pypi:`build` with :pypi:`twine`), - or anything else you may need to execute. -First, you need to define in a configuration file what tools you need to run and how to provision a test environment for +First, in a configuration file you need to define what tools you need to run and how to provision a test environment for these. The canonical file for this is the ``tox.ini`` file, let's take a look at an example of this (this needs to live at the root of your project): .. note:: - You can also try generating a ``tox.ini`` file automatically by running ``tox quickstart`` and then answering a few + You can also generate a ``tox.ini`` file automatically by running ``tox quickstart`` and then answering a few questions. .. code-block:: ini @@ -44,7 +44,7 @@ at the root of your project): commands = pytest tests {posargs} -The configuration is split to two type of configuration: core settings are hosted under the ``tox`` section and per run +The configuration is split into two type of configuration: core settings are hosted under the ``tox`` section and per run environment settings hosted under ``testenv:``. Under the core section we define that this project has two run environments named ``format`` and ``py310`` respectively (we use the ``envlist`` configuration key to do so). @@ -52,10 +52,10 @@ Then we define separately what should the formatting environment (``testenv:form (``testenv:py310`` section). For example to format the project we: - add a description (visible when you type ``tox list`` into the command line), -- we define that requires the ``black`` PyPI dependency with version ``22.3.0``, +- we define that it requires the ``black`` PyPI dependency with version ``22.3.0``, - the black tool does not need the project we are testing to be installed into the test environment so we disable this default behaviour via the ``skip_install`` configuration, -- and we defined that the tool should be invoked as we'd type ``black .`` into the command line. +- and we define that the tool should be invoked as we'd type ``black .`` into the command line. For testing the project we use the ``py310`` environment, for which we: From dd08e16c0a9051ddac86aa6aa1158371b8457dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sun, 21 Aug 2022 11:48:43 -0700 Subject: [PATCH 4/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jürgen Gmach --- docs/user_guide.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/user_guide.rst b/docs/user_guide.rst index acaf0a1b5..70eef7e77 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -63,20 +63,20 @@ For testing the project we use the ``py310`` environment, for which we: - specify that requires ``pytest`` ``7`` ot later together with the :pypi:`pytest-sugar` project, - and that the tool should be invoked via the ``pytest tests`` CLI command. -The ``{posargs}`` is a place holder part for the CLI command that allows us to pass additional flags to the pytest +``{posargs}`` is a place holder part for the CLI command that allows us to pass additional flags to the pytest invocation, for example if we'd want to run ``pytest tests -v`` as a one off, instead of ``tox run -e py310`` we'd type ``tox run -e py310 -- -v``. The ``--`` delimits flags for the tox tool and what should be forwarded to the tool within. -tox, by default, always creates a fresh virtual environment for every run environment. The python version to use for a +tox, by default, always creates a fresh virtual environment for every run environment. The Python version to use for a given environment can be controlled via the :ref:`base_python` configuration, however if not set will try to use the -environment name to determine something sensible: if the name is in the format of ``pyxy`` then will create a CPython -with version ``x.y`` (for example ``py310`` means CPython ``3.10``). If the name does not matches this pattern it will -use a virtual environment with the same python version as the one tox is installed into (this is the case for +environment name to determine something sensible: if the name is in the format of ``pyxy`` then tox will create an environment with CPython +with version ``x.y`` (for example ``py310`` means CPython ``3.10``). If the name does not match this pattern it will +use a virtual environment with the same Python version as the one tox is installed into (this is the case for ``format``). tox environments are reused between runs, so while the first ``tox run -e py310`` will take a while as tox needs to create a virtual environment and install ``pytest`` and ``pytest-sugar`` in it, subsequent runs only need to reinstall -your project (as long as the environments dependency list does not changes). +your project, as long as the environments dependency list does not change. Almost every step and aspect of virtual environments and command execution can be customized. You'll find an exhaustive list of configuration flags (together with what it does and detailed explanation of what values are @@ -144,9 +144,9 @@ The primary tox states are: Only if all environments ran successfully tox will return exit code ``0`` (success). In this case you'll also see the message ``congratulations :)``. -tox will take care of environment variable isolation for you (will remove system environment variables not specified via -``passenv``). Furthermore, it will also alter the ``PATH`` variable so that your commands resolve within the current -active tox environment. In general, all executables outside of hte tox environment are available in ``commands``, but +tox will take care of environment variable isolation for you. That means it will remove system environment variables not specified via +``passenv``. Furthermore, it will also alter the ``PATH`` variable so that your commands resolve within the current +active tox environment. In general, all executables outside of the tox environment are available in ``commands``, but external commands need to be explicitly allowed via the :ref:`allowlist_externals` configuration. Main features @@ -161,7 +161,7 @@ Main features * ``plugin system`` to modify tox execution with simple hooks. * uses :pypi:`pip` and :pypi:`virtualenv` by default. Support for plugins replacing it with their own. -* **cross-Python compatible**: tox requires CPython 3.7 and higher (but can create environments 2.7 or later). +* **cross-Python compatible**: tox requires CPython 3.7 and higher, but it can create environments 2.7 or later * **cross-platform**: Windows, macOS and Unix style environments, * **full interoperability with devpi**: is integrated with and is used for testing in the :pypi:`devpi` system, a versatile PyPI index server and release managing tool. From 0df671aa3daa21e09058994ddf5ae7f5031d4153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sun, 21 Aug 2022 11:49:37 -0700 Subject: [PATCH 5/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jürgen Gmach --- docs/user_guide.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/user_guide.rst b/docs/user_guide.rst index 70eef7e77..18667d432 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -162,13 +162,13 @@ Main features * ``plugin system`` to modify tox execution with simple hooks. * uses :pypi:`pip` and :pypi:`virtualenv` by default. Support for plugins replacing it with their own. * **cross-Python compatible**: tox requires CPython 3.7 and higher, but it can create environments 2.7 or later -* **cross-platform**: Windows, macOS and Unix style environments, +* **cross-platform**: Windows, macOS and Unix style environments * **full interoperability with devpi**: is integrated with and is used for testing in the :pypi:`devpi` system, a - versatile PyPI index server and release managing tool. + versatile PyPI index server and release managing tool * **driven by a simple (but flexible to allow expressing more complicated variants) ini-style config file** * **documented** examples and configuration * **concise reporting** about tool invocations and configuration errors -* supports using different / multiple PyPI index servers. +* supports using different / multiple PyPI index servers Related projects ---------------- @@ -179,16 +179,16 @@ you want to do more research, we recommend taking a look at these projects: - `nox `__ is a project similar in spirit to tox but different in approach. The primary key difference is that it uses Python scripts instead of a configuration file. It might be useful if you find tox configuration too limiting but aren't looking to move to something as general-purpose as ``Invoke`` or ``make``. - Note tox will also soon support defining the configuration in a python file. + Please note that tox will support defining configuration in a Python file soon, too. - `Invoke `__ is a general-purpose task execution library, similar to Make. Invoke is far more general-purpose than tox but it does not contain the Python testing-specific features that tox specializes in. Auto-provisioning ----------------- -In case the host tox does not satisfy either the :ref:`min_version` or the :ref:`requires`, tox will automatically +In case the installed tox version does not satisfy either the :ref:`min_version` or the :ref:`requires`, tox will automatically create a virtual environment under :ref:`provision_tox_env` name that satisfies those constraints and delegate all -calls to this meta environment. This should allow automatically satisfying constraints on your tox environment, +calls to this meta environment. This should allow satisfying constraints on your tox environment automatically, given you have at least version ``3.8.0`` of tox. For example given: @@ -199,7 +199,7 @@ For example given: min_version = 4 requires = tox-docker>=1 -if the user runs it with tox ``3.8`` or later installed tox will automatically ensured that both the minimum version and +if the user runs it with tox ``3.8`` or later the installed tox application will automatically ensure that both the minimum version and requires constraints are satisfied, by creating a virtual environment under ``.tox`` folder, and then installing into it ``tox>=4`` and ``tox-docker>=1``. Afterwards all tox invocations are forwarded to the tox installed inside ``.tox\.tox`` folder (referred to as meta-tox or auto-provisioned tox). @@ -216,7 +216,7 @@ This section details information that you'll use most often in short form. CLI ~~~ - Each tox subcommand has a 1 (or 2) letter shortcut form too, e.g. ``tox run`` can also be written as ``tox r`` or - ``tox config`` can be shorten to ``tox c``. + ``tox config`` can be shortened to ``tox c``. - To run all tox environments defined in the :ref:`env_list` run tox without any flags: ``tox``. - To run a single tox environment use the ``-e`` flag for the ``run`` sub-command as in ``tox run -e py310``. - To run two or more tox environment pass comma separated values, e.g. ``tox run -e format,py310``. The run command will @@ -226,7 +226,7 @@ CLI - To view the configuration value for a given environment and a given configuration key use the config sub-command with the ``-k`` flag to filter for targeted configuration values: ``tox config -e py310 -k pass_env``. - tox tries to automatically detect changes to your project dependencies and force a recreation when needed. - Unfortunately the detection is not always accurate, and will also not detect changes on the PyPI index server. You can + Unfortunately the detection is not always accurate, and it also won't detect changes on the PyPI index server. You can force a fresh start for the tox environments by passing the ``-r`` flag to your run command. Whenever you see something that should work but fails with some esoteric error it's recommended to use this flag to make sure you don't have a stale Python environment; e.g. ``tox run -e py310 -r`` would clean the run environment and recreate it from @@ -236,8 +236,8 @@ Configuration ~~~~~~~~~~~~~ - Every tox environment has its own configuration section (e.g. in case of ``tox.ini`` configuration method the - ``py310`` tox environments configuration is read from ``testenv:py310`` section). If the section is missing or does - not contain that configuration value it will fallback to section defined by the :ref:`base` configuration (for + ``py310`` tox environments configuration is read from the ``testenv:py310`` section). If the section is missing or does + not contain that configuration value, it will fall back to the section defined by the :ref:`base` configuration (for ``tox.ini`` this is the ``testenv`` section). For example: .. code-block:: ini @@ -248,8 +248,8 @@ Configuration [testenv:test] description = run the test suite with pytest - Here the ``test`` tox environments description is taken from ``testenv:test``. The ``commands`` is not specified, - so will instead use the value defined under the ``testenv`` section. If the base environment is also missing a + Here the environment description for ``test`` is taken from ``testenv:test``. As ``commands`` is not specified, + the value defined under the ``testenv`` section will be used. If the base environment is also missing a configuration value then the configuration default will be used (e.g. in case of the ``pass_env`` configuration here). - To change the current working directory for the commands run use :ref:`change_dir` (note this will make the change for From 0a492fa0a7ddac8a59c9323e7f158dd76192761d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Sun, 21 Aug 2022 11:50:15 -0700 Subject: [PATCH 6/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jürgen Gmach Signed-off-by: Bernát Gábor --- docs/changelog/2408.doc.rst | 1 + docs/conf.py | 8 +++++++- docs/config.rst | 15 ++++++--------- docs/faq.rst | 20 ++++++++++---------- docs/installation.rst | 23 ++++++++++------------- docs/user_guide.rst | 26 +++++++++++++------------- 6 files changed, 47 insertions(+), 46 deletions(-) create mode 100644 docs/changelog/2408.doc.rst diff --git a/docs/changelog/2408.doc.rst b/docs/changelog/2408.doc.rst new file mode 100644 index 000000000..c97175aa8 --- /dev/null +++ b/docs/changelog/2408.doc.rst @@ -0,0 +1 @@ +Add new documentation for tox 4 - by :user:`gaborbernat`. diff --git a/docs/conf.py b/docs/conf.py index 3759508f7..5822ec85f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -66,7 +66,13 @@ nitpicky = True nitpick_ignore = [] linkcheck_workers = 10 -linkcheck_ignore = [re.escape(r"https://github.com/tox-dev/tox/issues/new?title=Trouble+with+development+environment")] +linkcheck_ignore = [ + re.escape(i) + for i in ( + r"https://github.com/tox-dev/tox/issues/new?title=Trouble+with+development+environment", + r"https://www.unix.org/version2/sample/abort.html", + ) +] extlinks_detect_hardcoded_links = True diff --git a/docs/config.rst b/docs/config.rst index f3190612c..804896c4d 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -104,10 +104,10 @@ Core :default: :version_added: 3.2.0 - Specify a list of `PEP-508 `_ compliant dependencies that must be - satisfied in the Python environment hosting tox when running the tox command. If any of these dependencies are not - satisfied will automatically create a provisioned tox environment that does not have this issue, and run the tox - command within that environment. See :ref:`provision_tox_env` for more details. + Specify a list of :pep:`508` compliant dependencies that must be satisfied in the Python environment hosting tox when + running the tox command. If any of these dependencies are not satisfied will automatically create a provisioned tox + environment that does not have this issue, and run the tox command within that environment. See + :ref:`provision_tox_env` for more details. .. code-block:: ini @@ -560,7 +560,7 @@ Python run before package installation. All installer commands are executed using the :ref:`tox_root` as the current working directory. Each value must be one of: - - a Python dependency as specified by `PEP-440`_, + - a Python dependency as specified by :pep:`440`, - a `requirement file `_ when the value starts with ``-r`` (followed by a file path), - a `constraint file `_ when the value starts with @@ -628,7 +628,7 @@ tox supports operating with externally built packages. External packages might b :default: :ref_suffix: external - Name of the Python dependencies as specified by `PEP-440`_. Installed into the environment prior running the build + Name of the Python dependencies as specified by :pep:`440`. Installed into the environment prior running the build commands. All installer commands are executed using the :ref:`tox_root` as the current working directory. .. conf:: @@ -749,6 +749,3 @@ Pip installer If ``true``, adds ``--pre`` to the ``opts`` passed to :ref:`install_command`. This will cause it to install the latest available pre-release of any dependencies without a specified version. If ``false``, pip will only install final releases of unpinned dependencies. - -.. _`PEP-508`: https://www.python.org/dev/peps/pep-0508/ -.. _`PEP-440`: https://www.python.org/dev/peps/pep-0440/ diff --git a/docs/faq.rst b/docs/faq.rst index b3b2ca030..0d232f56f 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -136,9 +136,9 @@ a given command add a ``-`` prefix to that line (similar syntax to how the GNU ` python --version Customizing virtual environment creation --------------------------------------- +---------------------------------------- -By default tox uses the :pypi:`project` to create Python virtual environments to run your tools in. To change how tox +By default tox uses the :pypi:`virtualenv` to create Python virtual environments to run your tools in. To change how tox creates virtual environments you can set environment variables to customize virtualenv. For example, to provision a given pip version in the virtual environment you can set ``VIRTUALENV_PIP`` or to enable system site packages use the ``VIRTUALENV_SYSTEM_SITE_PACKAGES``: @@ -156,7 +156,7 @@ Consult the :pypi:`virtualenv` project for supported values (any CLI flag for vi by the ``VIRTUALENV_`` key). Building documentation with Sphinx -------------------------------- +---------------------------------- It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the documentation can be part of the CI, and whenever any validations/checks/operations fail while generating the @@ -183,7 +183,7 @@ the documentation under ``.tox/docs_out/index.html`` and print out a link to the Note here we also require Python 3.10, allowing us to use f-strings within the sphinx ``conf.py``. Building documentation with mkdocs -------------------------------- +---------------------------------- It's possible to orchestrate the projects documentation with tox. The advantage of this is that now generating the documentation can be part of the CI, and whenever any validations/checks/operations fail while generating the @@ -221,10 +221,10 @@ raised: '' (exited with code 1) Generally always check the documentation for the command executed to understand what the code means. For example for -:pypi:`pytest` you'd read `here `_. On unix systems, -there are some rather `common exit codes `_. This is why for exit -codes larger than 128, if a signal with number equal to `` - 128`` is found in the :py:mod:`signal` module, -an additional hint is given: +:pypi:`pytest` you'd read `here `_. On unix +systems, there are some rather `common exit codes `_. This is why for +exit codes larger than 128, if a signal with number equal to `` - 128`` is found in the :py:mod:`signal` +module, an additional hint is given: .. code-block:: shell @@ -234,11 +234,11 @@ an additional hint is given: The signal numbers (e.g. 11 for a segmentation fault) can be found in the "Standard signals" section of the -`signal man page `_. +`signal man page `_. Their meaning is described in `POSIX signals `_. Beware that programs may issue custom exit codes with any value, so their documentation should be consulted. Sometimes, no exit code is given at all. An example may be found in :gh:`pytest-qt issue #170 `, where Qt was calling -`abort() `_ instead of ``exit()``. +`abort() `_ instead of ``exit()``. diff --git a/docs/installation.rst b/docs/installation.rst index 23deb1736..9a6aaade4 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -30,27 +30,24 @@ state. Note, if you go down this path you need to ensure pip is new enough per t wheel ~~~~~ Installing tox via a wheel (default with pip) requires an installer that can understand the ``python-requires`` tag (see -`PEP-503 `_), with pip this is version ``9.0.0`` (released in November 2016). -Furthermore, in case you're not installing it via PyPI you need to use a mirror that correctly forwards the -``python-requires`` tag (notably the OpenStack mirrors don't do this, or older :gh_repo:`devpi/devpi` versions - -added with version ``4.7.0``). +:pep:`503`), with pip this is version ``9.0.0`` (released in November 2016). Furthermore, in case you're not installing +it via PyPI you need to use a mirror that correctly forwards the ``python-requires`` tag (notably the OpenStack mirrors +don't do this, or older :gh_repo:`devpi/devpi` versions - added with version ``4.7.0``). .. _sdist: sdist ~~~~~ -When installing via a source distribution you need an installer that handles the -`PEP-517 `_ specification. In case of ``pip`` this is version ``18.0.0`` or -later (released in July 2018). If you cannot upgrade your pip to support this you need to ensure that the build -requirements from :gh:`pyproject.toml ` are satisfied before triggering the -installation. +When installing via a source distribution you need an installer that handles the :pep:`517` specification. In case of +``pip`` this is version ``18.0.0`` or later (released in July 2018). If you cannot upgrade your pip to support this you +need to ensure that the build requirements from :gh:`pyproject.toml ` are +satisfied before triggering the installation. via ``setup.py`` ---------------- -We don't recommend and officially support this method. You should prefer using an installer that supports -`PEP-517 `_ interface, such as pip ``19.0.0`` or later. That being said you -might be able to still install a package via this method if you satisfy build dependencies before calling the -installation command (as described under :ref:`sdist`). +We don't recommend and officially support this method. You should prefer using an installer that supports :pep:`517` +interface, such as pip ``19.0.0`` or later. That being said you might be able to still install a package via this method +if you satisfy build dependencies before calling the installation command (as described under :ref:`sdist`). latest unreleased ----------------- diff --git a/docs/user_guide.rst b/docs/user_guide.rst index 18667d432..45daf7ed3 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -254,14 +254,14 @@ Configuration - To change the current working directory for the commands run use :ref:`change_dir` (note this will make the change for all install commands too - watch out if you have relative paths in your project dependencies). -- Environment variables: - - To view environment variables set and passed down use ``tox4 c -e py310 -k set_env pass_env``. +- Environment variables: + - To view environment variables set and passed down use ``tox c -e py310 -k set_env pass_env``. - To pass through additional environment variables use :ref:`pass_env`. - To set environment variables use :ref:`set_env`. - Setup operation can be configured via the :ref:`commands_pre`, while teardown commands via the :ref:`commands_post`. - Configurations may be set conditionally within the ``tox.ini`` file. If a line starts with an environment name - (optionally can be more than one when separated by ``,``) followed by ``:`` the configuration will only be used if the + or names, separated by a comma, followed by ``:`` the configuration will only be used if the environment name(s) matches the executed tox environment. For example: .. code-block:: ini @@ -281,20 +281,20 @@ Parallel mode ------------- ``tox`` allows running environments in parallel mode via the ``parallel`` sub-command: -- After the packaging phase completes tox will run in parallel processes tox environments (multi-thread based). -- ``--parallel`` flags takes an argument specifying the degree of parallelization, defaulting to ``auto``: +- After the packaging phase completes tox will run the tox environments in parallel processes (multi-thread based). +- the ``--parallel`` flag takes an argument specifying the degree of parallelization, defaulting to ``auto``: - ``all`` to run all invoked environments in parallel, - ``auto`` to limit it to CPU count, - or pass an integer to set that limit. - Parallel mode displays a progress spinner while running tox environments in parallel, and reports outcome of these as - soon as completed with a human readable duration timing attached. This spinner can be disabled via the + soon as they have been completed with a human readable duration timing attached. This spinner can be disabled via the ``--parallel-no-spinner`` flag. - Parallel mode by default shows output only of failed environments and ones marked as :ref:`parallel_show_output` ``=True``. - There's now a concept of dependency between environments (specified via :ref:`depends`), tox will re-order the - environment list to be run to satisfy these dependencies (in sequential run too). Furthermore, in parallel mode, - will only schedule a tox environment to run once all of its dependencies finished (independent of their outcome). + environment list to be run to satisfy these dependencies, also for sequential runs. Furthermore, in parallel mode, + tox will only schedule a tox environment to run once all of its dependencies have finished (independent of their outcome). .. warning:: @@ -303,7 +303,7 @@ Parallel mode such as ``py310, py39, py38, py37``). - ``--parallel-live``/``-o`` allows showing the live output of the standard output and error, also turns off reporting - described above. + as described above. - Note: parallel evaluation disables standard input. Use non parallel invocation if you need standard input. Example final output: @@ -321,7 +321,7 @@ Example final output: congratulations :) -Example progress bar, showing a rotating spinner, the number of environments running and their list (limited up to \ +Example progress bar, showing a rotating spinner, the number of environments running and their list (limited up to 120 characters): .. code-block:: bash @@ -333,7 +333,7 @@ Packaging tox always builds projects in a PEP-518 compatible virtual environment and communicates with the build backend according to the interface defined in PEP-517 and PEP-660. To define package build dependencies and specify the build backend to -use create a ``pyproject.toml`` at the root of the project, for example to use hatch: +use create a ``pyproject.toml`` at the root of the project. For example to use hatch: .. code-block:: toml @@ -345,7 +345,7 @@ By default tox will create and install a source distribution. You can configure the :ref:`package` configuration to ``wheel``. Wheels are much faster to install than source distributions. To query the projects dependencies tox will use a virtual environment whose name is defined under the :ref:`package_env` -configuration (by default ``.pkg``). The virtual environment to use for building the package depends on the artifact +configuration (by default ``.pkg``). The virtual environment used for building the package depends on the artifact built: - for source distribution the :ref:`package_env`, @@ -353,7 +353,7 @@ built: environment under :ref:`base_python`, if the environment targets CPython 3.10 it will be ``.pkg-cpython310`` or for PyPy 3.9 it will be ``.pkg-pypy39``). -For pure python projects (non C-Extension ones) it's recommended to set :ref:`wheel_build_env` to the same as the +For pure Python projects (non C-Extension ones) it's recommended to set :ref:`wheel_build_env` to the same as the :ref:`package_env`. This way you'll build the wheel once and install the same wheel for all tox environments. Advanced features