Implement qoc fixes

Fix fstring
Add comments explaining execution of normalize_config with defaults arg
Fix not removing file or cmdline settings in persistent groups
Fix a bug in get_namespace when config is a namespace
Add additional tests
This commit is contained in:
Timmy Welch 2023-02-20 01:59:40 -08:00
parent 69800f01b6
commit ba645eb7c6
No known key found for this signature in database
2 changed files with 40 additions and 9 deletions

View File

@ -197,7 +197,7 @@ class Setting:
if dest:
dest_name = dest
if not dest_name.isidentifier():
raise Exception('Cannot use {dest_name} in a namespace')
raise Exception(f'Cannot use {dest_name} in a namespace')
internal_name = f'{prefix}_{dest_name}'.lstrip('_')
return internal_name, dest_name, flag
@ -304,10 +304,15 @@ def normalize_config(
if (setting.cmdline and cmdline) or (setting.file and file):
# Ensures the option exists with the default if not already set
value, default = get_option(options, setting)
if not default or default and defaults:
if not default or (default and defaults):
# User has set a custom value or has requested the default value
group_options[setting_name] = value
elif setting_name in group_options:
# defaults have been requested to be removed
del group_options[setting_name]
elif setting_name in group_options:
# Setting type (file or cmdline) has not been requested and should be removed for persistent groups
del group_options[setting_name]
normalized[group_name] = group_options
return Config(normalized, definitions)
@ -374,7 +379,7 @@ def get_namespace(config: Config[T], defaults: bool = True, persistent: bool = T
"""
if isinstance(config.values, Namespace):
options, definitions = normalize_config(config)
options, definitions = normalize_config(config, defaults=defaults, persistent=persistent)
else:
options, definitions = config
namespace = Namespace()
@ -459,7 +464,7 @@ def parse_cmdline(
description: str,
epilog: str,
args: list[str] | None = None,
config: Namespace | Config[T] | None = None,
config: ns[T] = None,
) -> Config[Values]:
"""
Creates an `argparse.ArgumentParser` from cmdline settings in `self.definitions`.

View File

@ -59,7 +59,7 @@ def test_get_defaults(settngs_manager):
assert defaults['']['test'] == 'hello'
def test_get_namespace(settngs_manager):
def test_get_defaults_namespace(settngs_manager):
settngs_manager.add_setting('--test', default='hello')
defaults, _ = settngs_manager.get_namespace(settngs_manager.defaults())
assert defaults.test == 'hello'
@ -67,8 +67,8 @@ def test_get_namespace(settngs_manager):
def test_get_namespace_with_namespace(settngs_manager):
settngs_manager.add_setting('--test', default='hello')
defaults, _ = settngs_manager.get_namespace(argparse.Namespace(test='hello'))
assert defaults.test == 'hello'
defaults, _ = settngs_manager.get_namespace(argparse.Namespace(test='success'))
assert defaults.test == 'success'
def test_get_defaults_group(settngs_manager):
@ -97,6 +97,20 @@ def test_cmdline_only(settngs_manager):
assert 'test2' in file_normalized['tst2']
def test_cmdline_only_persistent_group(settngs_manager):
settngs_manager.add_persistent_group('tst', lambda parser: parser.add_setting('--test', default='hello', file=False))
settngs_manager.add_group('tst2', lambda parser: parser.add_setting('--test2', default='hello', cmdline=False))
file_normalized, _ = settngs_manager.normalize_config(settngs_manager.defaults(), file=True)
cmdline_normalized, _ = settngs_manager.normalize_config(settngs_manager.defaults(), cmdline=True)
assert 'test' in cmdline_normalized['tst']
assert 'test2' not in cmdline_normalized['tst2']
assert 'test' not in file_normalized['tst']
assert 'test2' in file_normalized['tst2']
def test_normalize(settngs_manager):
settngs_manager.add_group('tst', lambda parser: parser.add_setting('--test', default='hello'))
settngs_manager.add_persistent_group('persistent', lambda parser: parser.add_setting('--world', default='world'))
@ -118,11 +132,13 @@ def test_normalize(settngs_manager):
assert 'test' in normalized['tst']
assert normalized['tst']['test'] == 'hello'
assert normalized['persistent']['hello'] == 'success'
assert normalized['persistent']['world'] == 'world'
assert not hasattr(normalized_namespace, 'test')
assert hasattr(normalized_namespace, 'tst_test')
assert normalized_namespace.tst_test == 'hello'
assert normalized_namespace.persistent_hello == 'success'
assert normalized_namespace.persistent_world == 'world'
def test_clean_config(settngs_manager):
@ -151,15 +167,25 @@ def test_parse_cmdline(settngs_manager):
assert normalized['tst']['test'] == 'success'
def test_parse_cmdline_with_namespace(settngs_manager):
namespaces = (
lambda definitions: settngs.Config({'tst': {'test': 'fail', 'test2': 'success'}}, definitions),
lambda definitions: settngs.Config(argparse.Namespace(tst_test='fail', tst_test2='success'), definitions),
lambda definitions: argparse.Namespace(tst_test='fail', tst_test2='success'),
)
@pytest.mark.parametrize('ns', namespaces)
def test_parse_cmdline_with_namespace(settngs_manager, ns):
settngs_manager.add_group('tst', lambda parser: parser.add_setting('--test', default='hello', cmdline=True))
settngs_manager.add_group('tst', lambda parser: parser.add_setting('--test2', default='fail', cmdline=True))
normalized, _ = settngs_manager.parse_cmdline(
['--test', 'success'], namespace=settngs.Config({'tst': {'test': 'fail'}}, settngs_manager.definitions),
['--test', 'success'], namespace=ns(settngs_manager.definitions),
)
assert 'test' in normalized['tst']
assert normalized['tst']['test'] == 'success'
assert normalized['tst']['test2'] == 'success'
def test_parse_file(settngs_manager, tmp_path):