Skip to content

Commit 6b8e83a

Browse files
Replace undefined settings with overrides when appending (#3101)
Co-authored-by: Bernát Gábor <[email protected]>
1 parent 0ac7121 commit 6b8e83a

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

docs/changelog/3100.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
``--override foo+=bar`` appending syntax will now work correctly when ``foo`` wasn't defined in ``tox.ini``.

src/tox/config/loader/api.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class Loader(Convert[T]):
8080

8181
def __init__(self, section: Section, overrides: list[Override]) -> None:
8282
self._section = section
83-
self.overrides = {o.key: o for o in overrides}
83+
self.overrides: dict[str, Override] = {o.key: o for o in overrides}
8484
self.parent: Loader[Any] | None = None
8585

8686
@property
@@ -130,18 +130,24 @@ def load( # noqa: PLR0913
130130
from tox.config.set_env import SetEnv
131131

132132
override = self.overrides.get(key)
133-
if override and not override.append:
134-
return _STR_CONVERT.to(override.value, of_type, factory)
135-
raw = self.load_raw(key, conf, args.env_name)
133+
if override:
134+
converted_override = _STR_CONVERT.to(override.value, of_type, factory)
135+
if not override.append:
136+
return converted_override
137+
try:
138+
raw = self.load_raw(key, conf, args.env_name)
139+
except KeyError:
140+
if override:
141+
return converted_override
142+
raise
136143
converted = self.build(key, of_type, factory, conf, raw, args)
137144
if override and override.append:
138-
appends = _STR_CONVERT.to(override.value, of_type, factory)
139-
if isinstance(converted, list) and isinstance(appends, list):
140-
converted += appends
141-
elif isinstance(converted, dict) and isinstance(appends, dict):
142-
converted.update(appends)
143-
elif isinstance(converted, SetEnv) and isinstance(appends, SetEnv):
144-
converted.update(appends, override=True)
145+
if isinstance(converted, list) and isinstance(converted_override, list):
146+
converted += converted_override
147+
elif isinstance(converted, dict) and isinstance(converted_override, dict):
148+
converted.update(converted_override)
149+
elif isinstance(converted, SetEnv) and isinstance(converted_override, SetEnv):
150+
converted.update(converted_override, override=True)
145151
else:
146152
msg = "Only able to append to lists and dicts"
147153
raise ValueError(msg)

tests/config/test_main.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ def test_config_override_appends_to_list(tox_ini_conf: ToxIniCreator) -> None:
7676
assert conf["passenv"] == ["foo", "bar"]
7777

7878

79+
def test_config_override_appends_to_empty_list(tox_ini_conf: ToxIniCreator) -> None:
80+
conf = tox_ini_conf("[testenv]", override=[Override("testenv.passenv+=bar")]).get_env("testenv")
81+
conf.add_config("passenv", of_type=List[str], default=[], desc="desc")
82+
assert conf["passenv"] == ["bar"]
83+
84+
7985
def test_config_override_appends_to_setenv(tox_ini_conf: ToxIniCreator) -> None:
8086
example = """
8187
[testenv]
@@ -87,6 +93,11 @@ def test_config_override_appends_to_setenv(tox_ini_conf: ToxIniCreator) -> None:
8793
assert conf["setenv"].load("baz") == "quux"
8894

8995

96+
def test_config_override_appends_to_empty_setenv(tox_ini_conf: ToxIniCreator) -> None:
97+
conf = tox_ini_conf("[testenv]", override=[Override("testenv.setenv+=foo=bar")]).get_env("testenv")
98+
assert conf["setenv"].load("foo") == "bar"
99+
100+
90101
def test_config_override_cannot_append(tox_ini_conf: ToxIniCreator) -> None:
91102
example = """
92103
[testenv]

0 commit comments

Comments
 (0)