Allow adding settings to existing groups

Calling add_group or add_persistent_group twice will add any new
settings defined.

Raise a ValueError if add_group or add_persistent_group is called during
a call to add_group or add_persistent_group.
This commit is contained in:
Timmy Welch 2023-02-19 18:07:14 -08:00
parent 41cf2dc7cd
commit d07cf9949b
No known key found for this signature in database
2 changed files with 56 additions and 5 deletions

View File

@ -150,6 +150,11 @@ class Setting:
def __repr__(self) -> str: # pragma: no cover
return self.__str__()
def __eq__(self, other: object) -> bool:
if not isinstance(other, Setting):
return NotImplemented
return self.__dict__ == other.__dict__
def get_dest(self, prefix: str, names: Sequence[str], dest: str | None) -> tuple[str, str, bool]:
dest_name = None
flag = False
@ -496,13 +501,15 @@ class Manager:
def add_group(self, name: str, group: Callable[[Manager], None], exclusive_group: bool = False) -> None:
"""
The primary way to add define options on this class
The primary way to add define options on this class.
Args:
name: The name of the group to define
group: A function that registers individual options using :meth:`add_setting`
exclusive_group: If this group is an argparse exclusive group
"""
if self.current_group_name != '':
raise ValueError('Sub groups are not allowed')
self.current_group_name = name
self.exclusive_group = exclusive_group
group(self)
@ -511,16 +518,23 @@ class Manager:
def add_persistent_group(self, name: str, group: Callable[[Manager], None], exclusive_group: bool = False) -> None:
"""
The primary way to add define options on this class
The primary way to add define options on this class.
This group allows existing values to persist even if there is no corresponding setting defined for it.
Args:
name: The name of the group to define
group: A function that registers individual options using :meth:`add_setting`
exclusive_group: If this group is an argparse exclusive group
"""
if self.current_group_name != '':
raise ValueError('Sub groups are not allowed')
self.current_group_name = name
self.exclusive_group = exclusive_group
self.definitions[self.current_group_name] = Group(True, {})
if self.current_group_name in self.definitions:
if not self.definitions[self.current_group_name].persistent:
raise ValueError('Group already existis and is not persistent')
else:
self.definitions[self.current_group_name] = Group(True, {})
group(self)
self.current_group_name = ''
self.exclusive_group = False

View File

@ -2,6 +2,7 @@ from __future__ import annotations
import argparse
import json
from collections import defaultdict
import pytest
@ -141,7 +142,7 @@ def test_clean_config(settngs_manager):
assert cleaned['persistent']['hello'] == 'success'
def test_parse_cmdline(settngs_manager, tmp_path):
def test_parse_cmdline(settngs_manager):
settngs_manager.add_group('tst', lambda parser: parser.add_setting('--test', default='hello', cmdline=True))
normalized, _ = settngs_manager.parse_cmdline(['--test', 'success'])
@ -150,7 +151,7 @@ def test_parse_cmdline(settngs_manager, tmp_path):
assert normalized['tst']['test'] == 'success'
def test_parse_cmdline_with_namespace(settngs_manager, tmp_path):
def test_parse_cmdline_with_namespace(settngs_manager):
settngs_manager.add_group('tst', lambda parser: parser.add_setting('--test', default='hello', cmdline=True))
normalized, _ = settngs_manager.parse_cmdline(
@ -286,6 +287,42 @@ def test_cli_explicit_default(settngs_manager, tmp_path):
assert normalized['tst']['test'] == 'success'
def test_adding_to_existing_group(settngs_manager, tmp_path):
def default_to_regular(d):
if isinstance(d, defaultdict):
d = {k: default_to_regular(v) for k, v in d.items()}
return d
settngs_manager.add_group('tst', lambda parser: parser.add_setting('--test', default='success'))
settngs_manager.add_group('tst', lambda parser: parser.add_setting('--test2', default='success'))
def tst(parser):
parser.add_setting('--test', default='success')
parser.add_setting('--test2', default='success')
settngs_manager2 = settngs.Manager()
settngs_manager2.add_group('tst', tst)
assert default_to_regular(settngs_manager.definitions) == default_to_regular(settngs_manager2.definitions)
def test_adding_to_existing_persistent_group(settngs_manager, tmp_path):
def default_to_regular(d):
if isinstance(d, defaultdict):
d = {k: default_to_regular(v) for k, v in d.items()}
return d
settngs_manager.add_persistent_group('tst', lambda parser: parser.add_setting('--test', default='success'))
settngs_manager.add_persistent_group('tst', lambda parser: parser.add_setting('--test2', default='success'))
def tst(parser):
parser.add_setting('--test', default='success')
parser.add_setting('--test2', default='success')
settngs_manager2 = settngs.Manager()
settngs_manager2.add_persistent_group('tst', tst)
assert default_to_regular(settngs_manager.definitions) == default_to_regular(settngs_manager2.definitions)
def test_example(capsys, tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
settings_file = tmp_path / 'settings.json'