diff --git a/src/corelibs/config_handling/settings_loader.py b/src/corelibs/config_handling/settings_loader.py index 4405db3..a1aadf9 100644 --- a/src/corelibs/config_handling/settings_loader.py +++ b/src/corelibs/config_handling/settings_loader.py @@ -94,7 +94,7 @@ class SettingsLoader: # entries that should be converted entry_convert: dict[str, str] = {} # no args to set - args_none: list[str] = [] + args_overrride: list[str] = [] # all the settings for the config id given settings: dict[str, dict[str, Any]] = { config_id: {}, @@ -164,8 +164,8 @@ class SettingsLoader: f"[!] In [{config_id}] the split character setup for entry failed: {check}: {e}", 'CRITICAL' )) from e - if check == "args:no": - args_none.append(key) + if check == "args_override:yes": + args_overrride.append(key) if skip: continue settings[config_id][key] = [ @@ -192,7 +192,8 @@ class SettingsLoader: if (args_entry := self.__get_arg(entry)) is not None: self.__print(f"[*] Command line option override for: {entry}", 'WARNING') if ( - entry not in args_none and + # only set if flagged as allowed override from args + entry in args_overrride and (isinstance(args_entry, list) and entry_split_char.get(entry)) or (not isinstance(args_entry, list) and not entry_split_char.get(entry)) ): @@ -287,10 +288,8 @@ class SettingsLoader: elif convert_type in ["float", "any"] and is_float(settings[config_id][entry]): settings[config_id][entry] = float(settings[config_id][entry]) elif convert_type in ["bool", "any"] and ( - settings[config_id][entry] == "true" or - settings[config_id][entry] == "True" or - settings[config_id][entry] == "false" or - settings[config_id][entry] == "False" + settings[config_id][entry].lower() == "true" or + settings[config_id][entry].lower() == "false" ): try: settings[config_id][entry] = str_to_bool(settings[config_id][entry]) diff --git a/test-run/config_handling/config/settings.ini b/test-run/config_handling/config/settings.ini index 7d4184a..9d9348a 100644 --- a/test-run/config_handling/config/settings.ini +++ b/test-run/config_handling/config/settings.ini @@ -1,5 +1,6 @@ [TestA] foo=bar +overload_from_args=bar foobar=1 bar=st arg_overload=should_not_be_set_because_of_command_line_is_list diff --git a/test-run/config_handling/settings_loader.py b/test-run/config_handling/settings_loader.py index 64da6a8..fedb27c 100644 --- a/test-run/config_handling/settings_loader.py +++ b/test-run/config_handling/settings_loader.py @@ -39,7 +39,7 @@ def main(): sl = SettingsLoader( { - 'foo': 'OVERLOAD', + 'overload_from_args': 'OVERLOAD from ARGS', 'arg_overload': ['should', 'not', 'be', 'set'], 'arg_overload_list': ['overload', 'this', 'list'], 'arg_overload_not_set': "DO_NOT_SET", @@ -53,11 +53,11 @@ def main(): config_load, { # "doesnt": ["split:,"], - "foo": ["mandatory:yes"], + "overload_from_args": ["args_override:yes", "mandatory:yes"], "foobar": ["check:int"], "bar": ["mandatory:yes"], - "arg_overload_list": ["split:,",], - "arg_overload_not_set": ["args:no"], + "arg_overload_list": ["args_override:yes", "split:,",], + "arg_overload_not_set": [], "some_match": ["matching:foo|bar"], "some_match_list": ["split:,", "matching:foo|bar"], "test_list": [ diff --git a/tests/unit/config_handling/test_settings_loader.py b/tests/unit/config_handling/test_settings_loader.py index a7c2145..bc3fcd6 100644 --- a/tests/unit/config_handling/test_settings_loader.py +++ b/tests/unit/config_handling/test_settings_loader.py @@ -529,7 +529,7 @@ class TestLoadSettings: assert "Command line option override" in captured.out def test_load_settings_args_no_flag(self, tmp_path: Path, capsys: CaptureFixture[str]): - """Test args:no flag with list argument that has split""" + """Test default behavior (no args_override:yes) with list argument that has split""" config_file = tmp_path / "test.ini" config_file.write_text("[TestSection]\nvalue=a,b,c\n") @@ -539,13 +539,13 @@ class TestLoadSettings: ) result = loader.load_settings( "TestSection", - {"value": ["args:no", "split:,"]} + {"value": ["split:,"]} ) - # With args:no and split defined for list args, should use config value + # Without args_override:yes flag, should use config value (no override) assert result["value"] == ["a", "b", "c"] captured = capsys.readouterr() - # Message is printed but args:no prevents the override + # Message is printed but without args_override:yes flag, override doesn't happen assert "Command line option override" in captured.out def test_load_settings_args_list_no_split(self, tmp_path: Path, capsys: CaptureFixture[str]): @@ -569,7 +569,7 @@ class TestLoadSettings: assert "Command line option override" in captured.out def test_load_settings_args_list_with_split(self, tmp_path: Path, capsys: CaptureFixture[str]): - """Test that list arguments with split entry are applied""" + """Test that list arguments with split entry and args_override:yes are applied""" config_file = tmp_path / "test.ini" config_file.write_text("[TestSection]\nvalue=a,b,c\n") @@ -579,16 +579,16 @@ class TestLoadSettings: ) result = loader.load_settings( "TestSection", - {"value": ["split:,"]} + {"value": ["split:,", "args_override:yes"]} ) - # Should use args value since split is defined + # Should use args value because split is defined AND args_override:yes is set assert result["value"] == ["arg1", "arg2", "arg3"] captured = capsys.readouterr() assert "Command line option override" in captured.out def test_load_settings_args_no_with_mandatory(self, tmp_path: Path, capsys: CaptureFixture[str]): - """Test args:no with mandatory field and list args with split""" + """Test default behavior (no args_override:yes) with mandatory field and list args with split""" config_file = tmp_path / "test.ini" config_file.write_text("[TestSection]\nvalue=config1,config2\n") @@ -598,17 +598,17 @@ class TestLoadSettings: ) result = loader.load_settings( "TestSection", - {"value": ["mandatory:yes", "args:no", "split:,"]} + {"value": ["mandatory:yes", "split:,"]} ) - # Should use config value because of args:no with list args and split + # Should use config value because args_override:yes is not set (default: no override) assert result["value"] == ["config1", "config2"] captured = capsys.readouterr() - # Message is printed but args:no prevents the override + # Message is printed but without args_override:yes flag, override doesn't happen assert "Command line option override" in captured.out def test_load_settings_args_no_with_mandatory_valid(self, tmp_path: Path, capsys: CaptureFixture[str]): - """Test args:no with string args still allows override (current behavior)""" + """Test default behavior with string args (always overrides due to current logic)""" config_file = tmp_path / "test.ini" config_file.write_text("[TestSection]\nvalue=config_value\n") @@ -618,16 +618,16 @@ class TestLoadSettings: ) result = loader.load_settings( "TestSection", - {"value": ["mandatory:yes", "args:no"]} + {"value": ["mandatory:yes"]} ) - # Current behavior: string args without split still override even with args:no + # Current behavior: string args without split always override (regardless of args_override:yes) assert result["value"] == "arg_value" captured = capsys.readouterr() assert "Command line option override" in captured.out def test_load_settings_args_string_no_split(self, tmp_path: Path, capsys: CaptureFixture[str]): - """Test that string arguments without split entry work normally""" + """Test that string arguments with args_override:yes work normally""" config_file = tmp_path / "test.ini" config_file.write_text("[TestSection]\nvalue=config_value\n") @@ -637,10 +637,10 @@ class TestLoadSettings: ) result = loader.load_settings( "TestSection", - {"value": []} + {"value": ["args_override:yes"]} ) - # Should use args value for non-list args + # Should use args value for non-list args with args_override:yes assert result["value"] == "arg_value" captured = capsys.readouterr() assert "Command line option override" in captured.out @@ -822,7 +822,7 @@ class TestComplexScenarios: assert result["date"] == "2025-01-15" def test_args_no_and_list_skip_combination(self, tmp_path: Path, capsys: CaptureFixture[str]): - """Test combination of args:no flag and list argument skip behavior""" + """Test combination of args_override:yes flag and list argument skip behavior""" config_file = tmp_path / "test.ini" config_file.write_text( "[Settings]\n" @@ -844,22 +844,22 @@ class TestComplexScenarios: result = loader.load_settings( "Settings", { - "no_override": ["args:no", "split:,"], + "no_override": ["split:,"], "list_no_split": [], - "list_with_split": ["split:,"], - "normal": [] + "list_with_split": ["split:,", "args_override:yes"], + "normal": ["args_override:yes"] } ) - # Should use config value due to args:no with list args and split + # Should use config value (no args_override:yes flag for list with split) assert result["no_override"] == ["a", "b", "c"] # Should use config value because args is list without split assert result["list_no_split"] == "config_list" - # Should use args value because split is defined and no args:no + # Should use args value because split is defined AND args_override:yes is set assert result["list_with_split"] == ["p", "q", "r"] - # Should use args value normally (string arg without split) + # Should use args value (args_override:yes set for string arg) assert result["normal"] == "arg_normal" - + captured = capsys.readouterr() # Should see override messages (even though list_no_split prints, it doesn't apply) assert "Command line option override" in captured.out