summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/changelog/2926.bugfix.rst2
-rw-r--r--src/tox/config/source/ini.py9
-rw-r--r--tests/config/source/test_source_ini.py26
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"