@@ -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{9-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
170177added the setting ``skip_missing_interpreters = True `` so that tox does not fail
171178if one of the listed Python versions is missing on your system. If the value is
172179set to ``True ``, tox will run the tests with every available Python version, but
173180will skip versions it doesn’t find without failing. The output is very similar,
174181although 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+ .. versionchanged :: tox 4 25.0
254+ Before tox 4.25.0 dated 27 March 2025, the versions had to be specified one
255+ by one:
256+
257+ .. code-block :: ini
258+
259+ [tox]
260+ envlist = py3{10,11,12,13,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
273323the :file: `pyproject.toml ` file to tell Coverage which source code paths should
274324be 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