From: Daan De Meyer Date: Thu, 24 Apr 2025 12:31:32 +0000 (+0200) Subject: Don't use default value if optional settings are set to none X-Git-Tag: v26~232 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6f11937dc6660d367ddea7fbe237406f02d612cd;p=thirdparty%2Fmkosi.git Don't use default value if optional settings are set to none Just like it's possible to disable usage of default values for collection based settings, we should also support it for optional settings. This can be used to disable usage of the tools tree even if mkosi.tools.conf exists by setting ToolsTree= in mkosi.local.conf. --- diff --git a/mkosi/config.py b/mkosi/config.py index b1f8d2b14..ec418b4e6 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -1792,8 +1792,8 @@ class Args: @classmethod @functools.lru_cache(maxsize=1) - def fields(cls) -> set[str]: - return {f.name for f in dataclasses.fields(cls)} + def fields(cls) -> dict[str, dataclasses.Field[Any]]: + return {f.name: f for f in dataclasses.fields(cls)} @classmethod def from_namespace(cls, ns: dict[str, Any]) -> "Args": @@ -2190,8 +2190,8 @@ class Config: @classmethod @functools.lru_cache(maxsize=1) - def fields(cls) -> set[str]: - return {f.name for f in dataclasses.fields(cls)} + def fields(cls) -> dict[str, dataclasses.Field[Any]]: + return {f.name: f for f in dataclasses.fields(cls)} @classmethod def from_dict(cls, ns: dict[str, Any]) -> "Config": @@ -4684,8 +4684,18 @@ class ParseContext: ): return v - if (setting.dest in self.cli or setting.dest in self.config) and isinstance( - setting.parse(None, None), (dict, list, set) + # If the type is a collection or optional and the setting was set explicitly, don't use the default + # value. + fieldname = ( + setting.dest.removeprefix("tools_tree_") if setting.scope == SettingScope.tools else setting.dest + ) + field = Config.fields().get(fieldname) + origin = typing.get_origin(field.type) if field else None + args = typing.get_args(field.type) if field else [] + if ( + (setting.dest in self.cli or setting.dest in self.config) + and field + and (origin in (dict, list, str) or (origin is typing.Union and type(None) in args)) ): default = setting.parse(None, None) elif setting.dest in self.defaults: diff --git a/tests/test_config.py b/tests/test_config.py index bc52cd1c7..ff9c2b9fe 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -450,6 +450,20 @@ def test_override_default(tmp_path: Path) -> None: assert config.tools_tree is None assert "MY_KEY" not in config.environment + (d / "mkosi.tools.conf").touch() + + (d / "mkosi.local.conf").write_text( + """\ + [Build] + ToolsTree= + """ + ) + + with chdir(d): + _, _, [config] = parse_config([]) + + assert config.tools_tree is None + def test_local_config(tmp_path: Path) -> None: d = tmp_path