Skip to content

Commit f4fcb7b

Browse files
Custom prefix in .ini source (#2927)
* test_source_ini: custom config can overlap testenv regression test for plugin behavior in #2926 * IniSource.get_loader: check section.prefix ensure that loaders returned from .ini source are bound to the correct section prefix, if specified. add comment explaining why the code must look up the name in the _section_mapping fix #2926 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 23ebd04 commit f4fcb7b

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

docs/changelog/2926.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Plugins are now able to access tox.ini config sections using a custom prefix with the same suffix / name as a tox
2+
``testenv`` - by :user:`masenf`

src/tox/config/source/ini.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,13 @@ def sections(self) -> Iterator[IniSection]:
4040
yield IniSection.from_key(section)
4141

4242
def get_loader(self, section: Section, override_map: OverrideMap) -> IniLoader | None:
43-
sections = self._section_mapping.get(section.name)
44-
key = sections[0] if sections else section.key
43+
# look up requested section name in the generative testenv mapping to find the real config source
44+
for key in self._section_mapping.get(section.name) or []:
45+
if section.prefix is None or Section.from_key(key).prefix == section.prefix:
46+
break
47+
else:
48+
# if no matching section/prefix is found, use the requested section key as-is (for custom prefixes)
49+
key = section.key
4550
if self._parser.has_section(key):
4651
return IniLoader(
4752
section=section,

tests/config/source/test_source_ini.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
from pathlib import Path
44

5+
from tests.conftest import ToxIniCreator
56
from tox.config.loader.section import Section
7+
from tox.config.sets import ConfigSet
68
from tox.config.source.ini import IniSource
79

810

@@ -22,3 +24,27 @@ def test_source_ini_ignore_invalid_factor_filters(tmp_path: Path) -> None:
2224
loader = IniSource(tmp_path, content="[a]\nb= if c: d")
2325
res = list(loader.envs({"env_list": []})) # type: ignore
2426
assert not res
27+
28+
29+
def test_source_ini_custom_non_testenv_sections(tox_ini_conf: ToxIniCreator) -> None:
30+
"""Validate that a plugin can load section with custom prefix overlapping testenv name."""
31+
32+
class CustomConfigSet(ConfigSet):
33+
def register_config(self) -> None:
34+
self.add_config(
35+
keys=["a"],
36+
of_type=str,
37+
default="",
38+
desc="d",
39+
)
40+
41+
config = tox_ini_conf("[testenv:foo]\n[custom:foo]\na = b")
42+
known_envs = list(config._src.envs(config.core))
43+
assert known_envs
44+
custom_section = config.get_section_config(
45+
section=Section("custom", "foo"),
46+
base=[],
47+
of_type=CustomConfigSet,
48+
for_env=None,
49+
)
50+
assert custom_section["a"] == "b"

0 commit comments

Comments
 (0)