diff options
-rw-r--r-- | docs/changelog/2926.bugfix.rst | 2 | ||||
-rw-r--r-- | src/tox/config/source/ini.py | 9 | ||||
-rw-r--r-- | tests/config/source/test_source_ini.py | 26 |
3 files changed, 35 insertions, 2 deletions
diff --git a/docs/changelog/2926.bugfix.rst b/docs/changelog/2926.bugfix.rst new file mode 100644 index 00000000..bbecda0f --- /dev/null +++ b/docs/changelog/2926.bugfix.rst @@ -0,0 +1,2 @@ +Plugins are now able to access tox.ini config sections using a custom prefix with the same suffix / name as a tox +``testenv`` - by :user:`masenf` diff --git a/src/tox/config/source/ini.py b/src/tox/config/source/ini.py index df6c2876..fb23c0c3 100644 --- a/src/tox/config/source/ini.py +++ b/src/tox/config/source/ini.py @@ -40,8 +40,13 @@ class IniSource(Source): yield IniSection.from_key(section) def get_loader(self, section: Section, override_map: OverrideMap) -> IniLoader | None: - sections = self._section_mapping.get(section.name) - key = sections[0] if sections else section.key + # look up requested section name in the generative testenv mapping to find the real config source + for key in self._section_mapping.get(section.name) or []: + if section.prefix is None or Section.from_key(key).prefix == section.prefix: + break + else: + # if no matching section/prefix is found, use the requested section key as-is (for custom prefixes) + key = section.key if self._parser.has_section(key): return IniLoader( section=section, diff --git a/tests/config/source/test_source_ini.py b/tests/config/source/test_source_ini.py index 5d61290b..12d4eec2 100644 --- a/tests/config/source/test_source_ini.py +++ b/tests/config/source/test_source_ini.py @@ -2,7 +2,9 @@ from __future__ import annotations from pathlib import Path +from tests.conftest import ToxIniCreator from tox.config.loader.section import Section +from tox.config.sets import ConfigSet from tox.config.source.ini import IniSource @@ -22,3 +24,27 @@ def test_source_ini_ignore_invalid_factor_filters(tmp_path: Path) -> None: loader = IniSource(tmp_path, content="[a]\nb= if c: d") res = list(loader.envs({"env_list": []})) # type: ignore assert not res + + +def test_source_ini_custom_non_testenv_sections(tox_ini_conf: ToxIniCreator) -> None: + """Validate that a plugin can load section with custom prefix overlapping testenv name.""" + + class CustomConfigSet(ConfigSet): + def register_config(self) -> None: + self.add_config( + keys=["a"], + of_type=str, + default="", + desc="d", + ) + + config = tox_ini_conf("[testenv:foo]\n[custom:foo]\na = b") + known_envs = list(config._src.envs(config.core)) + assert known_envs + custom_section = config.get_section_config( + section=Section("custom", "foo"), + base=[], + of_type=CustomConfigSet, + for_env=None, + ) + assert custom_section["a"] == "b" |