Skip to content

Commit a5198d6

Browse files
committed
📝 Simplify tox’s version range syntax
1 parent e25d599 commit a5198d6

File tree

1 file changed

+123
-76
lines changed

1 file changed

+123
-76
lines changed

docs/test/tox.rst

Lines changed: 123 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,20 @@ To run tox, simply start tox:
112112
.. code-block:: pytest
113113
114114
$ uv run tox
115-
py313: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/57/items-0.1.0.tar.gz
115+
.pkg: _optional_hooks> python /Users/veit/cusy/prj/items/.venv/lib/python3.13/site-packages/pyproject_api/_backend.py True hatchling.build
116+
.pkg: get_requires_for_build_sdist> python /Users/veit/cusy/prj/items/.venv/lib/python3.13/site-packages/pyproject_api/_backend.py True hatchling.build
117+
.pkg: build_sdist> python /Users/veit/cusy/prj/items/.venv/lib/python3.13/site-packages/pyproject_api/_backend.py True hatchling.build
118+
py313: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/18/items-0.1.0.tar.gz
116119
py313: commands[0]> python --version --version
120+
Python 3.13.0 (main, Oct 7 2024, 23:47:22) [Clang 18.1.8 ]
121+
py313: commands[1]> coverage run -m pytest
117122
============================= test session starts ==============================
118-
platform darwin -- Python 3.13.0, pytest-8.4.1, pluggy-1.6.0
123+
platform darwin -- Python 3.13.0, pytest-9.0.2, pluggy-1.6.0
119124
cachedir: .tox/py313/.pytest_cache
120125
rootdir: /Users/veit/cusy/prj/items
121126
configfile: pyproject.toml
122127
testpaths: tests
123-
plugins: anyio-4.9.0, Faker-37.4.0, cov-6.2.1
128+
plugins: Faker-40.1.0, cov-7.0.0
124129
collected 83 items
125130
126131
tests/api/test_add.py ...... [ 7%]
@@ -149,8 +154,10 @@ To run tox, simply start tox:
149154
tests/cli/test_update.py . [ 98%]
150155
tests/cli/test_version.py . [100%]
151156
152-
============================== 83 passed in 0.27s ==============================
153-
py313: OK ✔ in 1.17 seconds
157+
============================== 83 passed in 0.35s ==============================
158+
.pkg: _exit> python /Users/veit/cusy/prj/items/.venv/lib/python3.13/site-packages/pyproject_api/_backend.py True hatchling.build
159+
py313: OK (1.19=setup[0.45]+cmd[0.01,0.72] seconds)
160+
congratulations :) (1.23 seconds)
154161
155162
Testing multiple Python versions
156163
--------------------------------
@@ -162,55 +169,95 @@ Python versions:
162169
:emphasize-lines: 2, 4
163170
164171
[tox]
165-
envlist = py3{9,10,11,12,13,13t,14,14t}
172+
envlist = py3{10,11,12,13,14,13t,14t}
166173
isolated_build = True
167174
skip_missing_interpreters = True
168175
169-
We will now test Python versions from 3.8 to 3.11. In addition, we have also
176+
We will now test Python versions from 3.10 to 3.14. In addition, we have also
170177
added the setting ``skip_missing_interpreters = True`` so that tox does not fail
171178
if one of the listed Python versions is missing on your system. If the value is
172179
set to ``True``, tox will run the tests with every available Python version, but
173180
will skip versions it doesn’t find without failing. The output is very similar,
174181
although I will only highlight the differences in the following illustration:
175182

176183
.. code-block:: pytest
177-
:emphasize-lines: 3-4, 8-12, 16-20, 24-28, 32-
178-
179-
$ uv run tox
180-
...
181-
py39: install_package> python -I -m pip install --force-reinstall --no-deps /Users/veit/cusy/prj/items/.tox/.tmp/package/17/items-0.1.0.tar.gz
182-
py39: commands[0]> coverage run -m pytest
183-
============================= test session starts ==============================
184-
...
185-
============================== 49 passed in 0.16s ==============================
186-
py39: OK ✔ in 2.17 seconds
187-
py310: skipped because could not find python interpreter with spec(s): py310
188-
py310: SKIP ⚠ in 0.01 seconds
189-
py311: install_package> python -I -m pip install --force-reinstall --no-deps /Users/veit/cusy/prj/items/.tox/.tmp/package/18/items-0.1.0.tar.gz
190-
py311: commands[0]> coverage run -m pytest
191-
============================= test session starts ==============================
192-
...
193-
============================== 49 passed in 0.15s ==============================
194-
py311: OK ✔ in 1.41 seconds
195-
py312: install_package> python -I -m pip install --force-reinstall --no-deps /Users/veit/cusy/prj/items/.tox/.tmp/package/19/items-0.1.0.tar.gz
196-
py312: commands[0]> coverage run -m pytest
197-
============================= test session starts ==============================
198-
...
199-
============================== 49 passed in 0.15s ==============================
200-
py312: OK ✔ in 1.43 seconds
201-
py313: install_package> python -I -m pip install --force-reinstall --no-deps /Users/veit/cusy/prj/items/.tox/.tmp/package/20/items-0.1.0.tar.gz
202-
py313: commands[0]> coverage run -m pytest
203-
============================= test session starts ==============================
204-
...
205-
============================== 49 passed in 0.16s ==============================
206-
.pkg: _exit> python /Users/veit/cusy/prj/items/.venv/lib/python3.13/site-packages/pyproject_api/_backend.py True hatchling.build
207-
py313: OK ✔ in 1.48 seconds
208-
py39: OK (2.17=setup[1.54]+cmd[0.63] seconds)
209-
py310: SKIP (0.01 seconds)
210-
py311: OK (1.41=setup[0.81]+cmd[0.60] seconds)
211-
py312: OK (1.43=setup[0.82]+cmd[0.61] seconds)
212-
py313: OK (1.48=setup[0.82]+cmd[0.66] seconds)
213-
congratulations :) (10.46 seconds)
184+
:emphasize-lines: 3-6, 10-14, 18-22, 26-30, 34-38, 42-46, 50-54, 59-
185+
186+
$ uv run tox
187+
...
188+
py310: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/19/items-0.1.0.tar.gz
189+
py310: commands[0]> python --version --version
190+
Python 3.10.17 (main, Apr 9 2025, 03:47:39) [Clang 20.1.0 ]
191+
py310: commands[1]> coverage run -m pytest
192+
============================= test session starts ==============================
193+
...
194+
============================== 83 passed in 0.35s ==============================
195+
py310: OK ✔ in 1.3 seconds
196+
py311: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/20/items-0.1.0.tar.gz
197+
py311: commands[0]> python --version --version
198+
Python 3.11.11 (main, Feb 5 2025, 18:58:27) [Clang 19.1.6 ]
199+
py311: commands[1]> coverage run -m pytest
200+
============================= test session starts ==============================
201+
...
202+
============================== 83 passed in 0.36s ==============================
203+
py311: OK ✔ in 1.16 seconds
204+
py312: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/21/items-0.1.0.tar.gz
205+
py312: commands[0]> python --version --version
206+
Python 3.12.12 (main, Oct 14 2025, 21:38:21) [Clang 20.1.4 ]
207+
py312: commands[1]> coverage run -m pytest
208+
============================= test session starts ==============================
209+
...
210+
============================== 83 passed in 0.55s ==============================
211+
py312: OK ✔ in 1.79 seconds
212+
py313: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/22/items-0.1.0.tar.gz
213+
py313: commands[0]> python --version --version
214+
Python 3.13.0 (main, Oct 7 2024, 23:47:22) [Clang 18.1.8 ]
215+
py313: commands[1]> coverage run -m pytest
216+
============================= test session starts ==============================
217+
...
218+
============================== 83 passed in 0.35s ==============================
219+
py313: OK ✔ in 1.07 seconds
220+
py314: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/23/items-0.1.0.tar.gz
221+
py314: commands[0]> python --version --version
222+
Python 3.14.0 (main, Oct 14 2025, 21:10:22) [Clang 20.1.4 ]
223+
py314: commands[1]> coverage run -m pytest
224+
============================= test session starts ==============================
225+
...
226+
============================== 83 passed in 0.36s ==============================
227+
py314: OK ✔ in 1.28 seconds
228+
py313t: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/24/items-0.1.0.tar.gz
229+
py313t: commands[0]> python --version --version
230+
Python 3.13.0 experimental free-threading build (main, Oct 16 2024, 08:24:33) [Clang 18.1.8 ]
231+
py313t: commands[1]> coverage run -m pytest
232+
============================= test session starts ==============================
233+
...
234+
============================== 83 passed in 0.49s ==============================
235+
py313t: OK ✔ in 1.51 seconds
236+
py314t: install_package> .venv/bin/uv pip install --reinstall --no-deps items@/Users/veit/cusy/prj/items/.tox/.tmp/package/25/items-0.1.0.tar.gz
237+
py314t: commands[0]> python --version --version
238+
Python 3.14.0b4 free-threading build (main, Jul 8 2025, 21:06:49) [Clang 20.1.4 ]
239+
py314t: commands[1]> coverage run -m pytest
240+
============================= test session starts ==============================
241+
...
242+
============================== 83 passed in 0.39s ==============================
243+
.pkg: _exit> python /Users/veit/cusy/prj/items/.venv/lib/python3.13/site-packages/pyproject_api/_backend.py True hatchling.build
244+
py310: OK (1.30=setup[0.54]+cmd[0.01,0.75] seconds)
245+
py311: OK (1.16=setup[0.38]+cmd[0.01,0.76] seconds)
246+
py312: OK (1.79=setup[0.42]+cmd[0.01,1.36] seconds)
247+
py313: OK (1.07=setup[0.34]+cmd[0.01,0.71] seconds)
248+
py314: OK (1.28=setup[0.42]+cmd[0.01,0.85] seconds)
249+
py313t: OK (1.51=setup[0.44]+cmd[0.01,1.05] seconds)
250+
py314t: OK (1.34=setup[0.44]+cmd[0.01,0.89] seconds)
251+
congratulations :) (9.48 seconds)
252+
253+
.. versionadded:: tox 4.25.0
254+
From tox 4.25.0 dated 27 March 2025, the various Python versions can also be
255+
specified as follows:
256+
257+
.. code-block:: ini
258+
259+
[tox]
260+
envlist = py3{9-14,13t,14t}
214261
215262
Running Tox environments in parallel
216263
------------------------------------
@@ -221,17 +268,20 @@ other. It is also possible to run them in parallel with the ``-p`` option:
221268
.. code-block:: pytest
222269
223270
$ uv run tox -p
224-
py310: SKIP ⚠ in 0.09 seconds
225-
py312: OK ✔ in 2.08 seconds
226-
py313: OK ✔ in 2.18 seconds
227-
py311: OK ✔ in 2.23 seconds
228-
py39: OK ✔ in 2.91 seconds
229-
py39: OK (2.91=setup[2.17]+cmd[0.74] seconds)
230-
py310: SKIP (0.09 seconds)
231-
py311: OK (2.23=setup[1.27]+cmd[0.96] seconds)
232-
py312: OK (2.08=setup[1.22]+cmd[0.86] seconds)
233-
py313: OK (2.18=setup[1.23]+cmd[0.95] seconds)
234-
congratulations :) (3.05 seconds)
271+
py311: OK ✔ in 1.7 seconds
272+
py310: OK ✔ in 1.8 seconds
273+
py313: OK ✔ in 1.8 seconds
274+
py314t: OK ✔ in 1.89 seconds
275+
py314: OK ✔ in 1.91 seconds
276+
py313t: OK ✔ in 2.24 seconds
277+
py310: OK (1.80=setup[0.62]+cmd[0.02,1.16] seconds)
278+
py311: OK (1.70=setup[0.54]+cmd[0.02,1.15] seconds)
279+
py312: OK (2.28=setup[0.58]+cmd[0.01,1.69] seconds)
280+
py313: OK (1.80=setup[0.60]+cmd[0.02,1.18] seconds)
281+
py314: OK (1.91=setup[0.62]+cmd[0.02,1.28] seconds)
282+
py313t: OK (2.24=setup[0.72]+cmd[0.02,1.51] seconds)
283+
py314t: OK (1.89=setup[0.61]+cmd[0.02,1.26] seconds)
284+
congratulations :) (2.33 seconds)
235285
236286
.. note::
237287
The output is not abbreviated; this is the full output you will see if
@@ -250,7 +300,7 @@ extend commands to ``pytest --cov=items``:
250300
:emphasize-lines: 12-
251301
252302
[tox]
253-
envlist = py3{9,10,11,12,13,13t,14,14t}
303+
envlist = py3{10-14,13t,14t}
254304
isolated_build = True
255305
skip_missing_interpreters = True
256306
@@ -273,7 +323,7 @@ When using Coverage with ``tox``, it can sometimes be useful to add a section in
273323
the :file:`pyproject.toml` file to tell Coverage which source code paths should
274324
be considered identical:
275325

276-
.. code-block:: ini
326+
.. code-block:: toml
277327
278328
[tool.coverage.paths]
279329
source = ["src", ".tox/py*/**/site-packages"]
@@ -288,23 +338,20 @@ example.
288338
289339
$ uv run tox
290340
...
291-
coverage-report: commands[0]> coverage combine
292-
Combined data file .coverage.fay.local.19539.XpQXpsGx
293-
coverage-report: commands[1]> coverage report
294-
Name Stmts Miss Branch BrPart Cover Missing
295-
--------------------------------------------------------------
296-
src/items/api.py 68 1 12 1 98% 88
297-
--------------------------------------------------------------
298-
TOTAL 428 1 32 1 99%
299-
300-
26 files skipped due to complete coverage.
301-
py39: OK (2.12=setup[1.49]+cmd[0.63] seconds)
302-
py310: SKIP (0.01 seconds)
303-
py311: OK (1.41=setup[0.80]+cmd[0.62] seconds)
304-
py312: OK (1.43=setup[0.81]+cmd[0.62] seconds)
305-
py313: OK (1.46=setup[0.83]+cmd[0.62] seconds)
306-
coverage-report: OK (0.16=setup[0.00]+cmd[0.07,0.09] seconds)
307-
congratulations :) (10.26 seconds)
341+
Name Stmts Miss Branch BrPart Cover Missing
342+
---------------------------------------------------
343+
TOTAL 540 0 32 0 100%
344+
345+
33 files skipped due to complete coverage.
346+
py310: OK (1.10=setup[0.44]+cmd[0.01,0.64] seconds)
347+
py311: OK (0.98=setup[0.31]+cmd[0.01,0.66] seconds)
348+
py312: OK (1.59=setup[0.34]+cmd[0.01,1.24] seconds)
349+
py313: OK (1.06=setup[0.34]+cmd[0.01,0.71] seconds)
350+
py314: OK (1.10=setup[0.35]+cmd[0.01,0.74] seconds)
351+
py313t: OK (1.36=setup[0.40]+cmd[0.01,0.95] seconds)
352+
py314t: OK (1.31=setup[0.44]+cmd[0.01,0.86] seconds)
353+
coverage-report: OK (1.55=setup[0.37]+cmd[1.08,0.10] seconds)
354+
congratulations :) (10.09 seconds)
308355
309356
Set minimum coverage
310357
--------------------
@@ -336,13 +383,13 @@ We can also call individual tests with tox by making another change so that
336383
:term:`parameters <Parameter>` can be passed to pytest:
337384

338385
.. code-block:: ini
339-
:emphasize-lines: 17
386+
:emphasize-lines: 16
340387
341388
[tox]
342389
envlist =
343390
pre-commit
344391
docs
345-
py3{9,10,11,12,13,13t,14,14t}
392+
py3{10-14,13t,14t}
346393
coverage-report
347394
isolated_build = True
348395
skip_missing_interpreters = True

0 commit comments

Comments
 (0)