From 3779071bad48b2c4927cfb6365bd022bf101881d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bern=C3=A1t=20G=C3=A1bor?= Date: Thu, 10 Feb 2022 16:56:33 +0000 Subject: [PATCH] Do not perform interpolation for INI files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bernát Gábor --- docs/changelog/2350.bugfix.rst | 1 + src/tox/config/cli/ini.py | 2 +- src/tox/config/source/ini.py | 2 +- tests/config/cli/test_cli_ini.py | 9 +++++++++ tests/config/loader/ini/conftest.py | 2 +- tests/config/source/test_source_ini.py | 10 ++++++++++ tests/session/cmd/test_show_config.py | 8 ++++---- 7 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 docs/changelog/2350.bugfix.rst create mode 100644 tests/config/source/test_source_ini.py diff --git a/docs/changelog/2350.bugfix.rst b/docs/changelog/2350.bugfix.rst new file mode 100644 index 000000000..4d42dee66 --- /dev/null +++ b/docs/changelog/2350.bugfix.rst @@ -0,0 +1 @@ +Do not interpolate values when parsing ``tox.ini`` configuration files - by :user:`gaborbernat`. diff --git a/src/tox/config/cli/ini.py b/src/tox/config/cli/ini.py index f832b1162..8839f4307 100644 --- a/src/tox/config/cli/ini.py +++ b/src/tox/config/cli/ini.py @@ -34,7 +34,7 @@ def __init__(self) -> None: self.config_file = self.config_file.absolute() try: - parser = ConfigParser() + parser = ConfigParser(interpolation=None) with self.config_file.open() as file_handler: parser.read_file(file_handler) self.has_tox_section = parser.has_section(CORE.key) diff --git a/src/tox/config/source/ini.py b/src/tox/config/source/ini.py index c5ea72992..eea006d98 100644 --- a/src/tox/config/source/ini.py +++ b/src/tox/config/source/ini.py @@ -24,7 +24,7 @@ class IniSource(Source, ABC): def __init__(self, path: Path, content: str | None = None) -> None: super().__init__(path) - self._parser = ConfigParser() + self._parser = ConfigParser(interpolation=None) if content is None: if not path.exists(): raise ValueError diff --git a/tests/config/cli/test_cli_ini.py b/tests/config/cli/test_cli_ini.py index f97927d4a..efe3776d1 100644 --- a/tests/config/cli/test_cli_ini.py +++ b/tests/config/cli/test_cli_ini.py @@ -9,6 +9,7 @@ import pytest from pytest_mock import MockerFixture +from tox.config.cli.ini import IniConfig from tox.config.cli.parse import get_options from tox.config.loader.api import Override from tox.pytest import CaptureFixture, LogCaptureFixture, MonkeyPatch @@ -190,3 +191,11 @@ def test_bad_option_cli_ini( ), ] assert vars(parsed) == default_options + + +def test_cli_ini_with_interpolated(tmp_path: Path, monkeypatch: MonkeyPatch) -> None: + to = tmp_path / "tox.ini" + to.write_text("[tox]\na = %(b)s") + monkeypatch.setenv("TOX_CONFIG_FILE", str(to)) + conf = IniConfig() + assert conf.get("a", str) diff --git a/tests/config/loader/ini/conftest.py b/tests/config/loader/ini/conftest.py index 53c6dfd24..52e066e70 100644 --- a/tests/config/loader/ini/conftest.py +++ b/tests/config/loader/ini/conftest.py @@ -12,7 +12,7 @@ def mk_ini_conf(tmp_path: Path) -> Callable[[str], ConfigParser]: def _func(raw: str) -> ConfigParser: filename = tmp_path / "demo.ini" filename.write_bytes(raw.encode("utf-8")) # win32: avoid CR normalization - what you pass is what you get - parser = ConfigParser() + parser = ConfigParser(interpolation=None) with filename.open() as file_handler: parser.read_file(file_handler) return parser diff --git a/tests/config/source/test_source_ini.py b/tests/config/source/test_source_ini.py new file mode 100644 index 000000000..dcf727d7b --- /dev/null +++ b/tests/config/source/test_source_ini.py @@ -0,0 +1,10 @@ +from pathlib import Path + +from tox.config.loader.section import Section +from tox.config.source.ini import IniSource + + +def test_source_ini_with_interpolated(tmp_path: Path) -> None: + loader = IniSource(tmp_path, content="[tox]\na = %(c)s").get_loader(Section(None, "tox"), {}) + assert loader is not None + loader.load_raw("a", None, None) diff --git a/tests/session/cmd/test_show_config.py b/tests/session/cmd/test_show_config.py index 55e4acb4d..4becedb53 100644 --- a/tests/session/cmd/test_show_config.py +++ b/tests/session/cmd/test_show_config.py @@ -24,7 +24,7 @@ def test_show_config_default_run_env(tox_project: ToxProjectCreator, monkeypatch outcome = list(state.envs.iter(only_active=False)) assert outcome == [name] monkeypatch.delenv("TERM", raising=False) # disable conditionally set flag - parser = ConfigParser() + parser = ConfigParser(interpolation=None) parser.read_string(result.out) assert list(parser.sections()) == [f"testenv:{name}", "tox"] @@ -122,7 +122,7 @@ def test_show_config_pkg_env_once( ) result = project.run("c") result.assert_success() - parser = ConfigParser() + parser = ConfigParser(interpolation=None) parser.read_string(result.out) sections = set(parser.sections()) assert sections == {"testenv:.pkg", f"testenv:.pkg-{impl}{prev_ver}", f"testenv:py{prev_ver}", "testenv:py", "tox"} @@ -138,7 +138,7 @@ def test_show_config_pkg_env_skip( ) result = project.run("c") result.assert_success() - parser = ConfigParser() + parser = ConfigParser(interpolation=None) parser.read_string(result.out) sections = set(parser.sections()) assert sections == {"testenv:.pkg", "tox", "testenv:py", f"testenv:py{prev_ver}"} @@ -148,7 +148,7 @@ def test_show_config_select_only(tox_project: ToxProjectCreator) -> None: project = tox_project({"tox.ini": "[tox]\nenv_list=\n a\n b", "pyproject.toml": ""}) result = project.run("c", "-e", ".pkg,b,.pkg") result.assert_success() - parser = ConfigParser() + parser = ConfigParser(interpolation=None) parser.read_string(result.out) sections = list(parser.sections()) assert sections == ["testenv:.pkg", "testenv:b"]