diff --git a/docs/changelog/3571.bugfix.rst b/docs/changelog/3571.bugfix.rst new file mode 100644 index 000000000..99dd76bfc --- /dev/null +++ b/docs/changelog/3571.bugfix.rst @@ -0,0 +1,2 @@ +Expand braced range syntax in all internal sections of ``tox.ini`` (e.g. ``deps``, ``testenv``). Syntax like py3{10-14} can be used in those sections now. +- by :user:`marcosboger` diff --git a/docs/config.rst b/docs/config.rst index c3393dfd6..a4e6a274a 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -1663,6 +1663,12 @@ Both enumerations (``{1,2,3}``) and numerical ranges (``{1-3}``) are supported, [tox] env_list = py3{8-10, 11, 13-14} + [testenv] + deps = + py{310,311-314}: urllib3 + setenv = + py{310,311-314}: FOO=bar + will create the following envs: .. code-block:: shell diff --git a/src/tox/config/loader/ini/factor.py b/src/tox/config/loader/ini/factor.py index 9a5bc91d9..8026eace6 100644 --- a/src/tox/config/loader/ini/factor.py +++ b/src/tox/config/loader/ini/factor.py @@ -64,6 +64,7 @@ def expand_factors(value: str) -> Iterator[tuple[list[list[tuple[str, bool]]] | def find_factor_groups(value: str) -> Iterator[list[tuple[str, bool]]]: """Transform '{py,!pi}-{a,b},c' to [{'py', 'a'}, {'py', 'b'}, {'pi', 'a'}, {'pi', 'b'}, {'c'}].""" + value = expand_ranges(value) for env in expand_env_with_negation(value): result = [name_with_negate(f) for f in env.split("-")] yield result diff --git a/src/tox/config/loader/str_convert.py b/src/tox/config/loader/str_convert.py index 7fda1c9ba..ee75e62fe 100644 --- a/src/tox/config/loader/str_convert.py +++ b/src/tox/config/loader/str_convert.py @@ -10,7 +10,6 @@ from typing import TYPE_CHECKING, Any from tox.config.loader.convert import Convert -from tox.config.loader.ini.factor import expand_ranges from tox.config.types import Command, EnvList if TYPE_CHECKING: @@ -115,7 +114,6 @@ def to_command(value: str) -> Command | None: def to_env_list(value: str) -> EnvList: from tox.config.loader.ini.factor import extend_factors # noqa: PLC0415 - value = expand_ranges(value) elements = list(chain.from_iterable(extend_factors(expr) for expr in value.split("\n"))) return EnvList(elements) diff --git a/src/tox/config/source/ini_section.py b/src/tox/config/source/ini_section.py index 7ed3267f7..d7d26720f 100644 --- a/src/tox/config/source/ini_section.py +++ b/src/tox/config/source/ini_section.py @@ -1,6 +1,6 @@ from __future__ import annotations -from tox.config.loader.ini.factor import expand_ranges, extend_factors +from tox.config.loader.ini.factor import extend_factors from tox.config.loader.section import Section @@ -15,7 +15,7 @@ def is_test_env(self) -> bool: @property def names(self) -> list[str]: - return list(extend_factors(expand_ranges(self.name))) + return list(extend_factors(self.name)) TEST_ENV_PREFIX = "testenv" diff --git a/tests/config/loader/ini/test_factor.py b/tests/config/loader/ini/test_factor.py index 049658a82..0d2fc9cea 100644 --- a/tests/config/loader/ini/test_factor.py +++ b/tests/config/loader/ini/test_factor.py @@ -273,6 +273,40 @@ def test_ini_loader_raw_with_factors( assert outcome == result +def test_generative_ranges_in_deps(tox_ini_conf: ToxIniCreator) -> None: + config = tox_ini_conf( + """ + [testenv] + deps-x = + py{310-314}: black + """, + ) + assert list(config) == ["py310", "py311", "py312", "py313", "py314"] + + +def test_generative_ranges_in_deps_with_mixed_approach(tox_ini_conf: ToxIniCreator) -> None: + config = tox_ini_conf( + """ + [testenv] + deps-x = + py3{10-14}: black + """, + ) + assert list(config) == ["py310", "py311", "py312", "py313", "py314"] + + +def test_generative_ranges_in_setenv(tox_ini_conf: ToxIniCreator) -> None: + config = tox_ini_conf( + """ + [testenv] + setenv = + foo{1,2}: FOO=bar + foo{3-5}: FOO=baz + """, + ) + assert list(config) == ["foo1", "foo2", "foo3", "foo4", "foo5"] + + def test_generative_section_name_with_ranges(tox_ini_conf: ToxIniCreator) -> None: config = tox_ini_conf( """