add all options even if already set by user

This commit is contained in:
Emmanuel Garette 2019-07-28 09:15:31 +02:00 committed by Emmanuel Garette
parent dcc7510676
commit 528d16ec88
3 changed files with 136 additions and 109 deletions

View file

@ -290,17 +290,18 @@ def test_leadership_modif_mandatory(json):
'leader.follower_choice': [None], 'leader.follower_choice': [None],
'leader.follower_integer': [None], 'leader.follower_integer': [None],
'leader.follower_submulti': [['255.255.255.128']]} 'leader.follower_submulti': [['255.255.255.128']]}
output2 = """usage: prog.py --leader.leader ['192.168.1.1'] [-h] output2 = """usage: prog.py --leader.leader "192.168.1.1" [-h]
[--leader.leader [LEADER [LEADER ...]]]
[--leader.pop-leader INDEX] [--leader.pop-leader INDEX]
[--leader.follower INDEX [FOLLOWER]] [--leader.follower INDEX [FOLLOWER]]
--leader.follower_submulti --leader.follower_submulti INDEX
INDEX [FOLLOWER_SUBMULTI ...] [FOLLOWER_SUBMULTI ...]
[--leader.follower_integer INDEX [FOLLOWER_INTEGER]] [--leader.follower_integer INDEX [FOLLOWER_INTEGER]]
[--leader.follower_boolean INDEX] [--leader.follower_boolean INDEX]
[--leader.no-follower_boolean INDEX] [--leader.no-follower_boolean INDEX]
[--leader.follower_choice INDEX [{opt1,opt2}]] [--leader.follower_choice INDEX [{opt1,opt2}]]
--leader.follower_mandatory --leader.follower_mandatory INDEX
INDEX FOLLOWER_MANDATORY FOLLOWER_MANDATORY
prog.py: error: the following arguments are required: --leader.follower_submulti""" prog.py: error: the following arguments are required: --leader.follower_submulti"""
config = get_config(json, with_mandatory=True) config = get_config(json, with_mandatory=True)

View file

@ -131,7 +131,10 @@ root:
def test_readme_help_modif_positional(json): def test_readme_help_modif_positional(json):
output = """usage: prog.py str [-h] [-v] [-nv] --str STR output = """usage: prog.py "str" [-h] [-v] [-nv] --str STR {str,list,int,none}
positional arguments:
{str,list,int,none} choice the sub argument
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -152,12 +155,17 @@ optional arguments:
def test_readme_help_modif(json): def test_readme_help_modif(json):
output = """usage: prog.py str --str toto [-h] [-v] [-nv] output = """usage: prog.py "str" --str "toto" [-h] [-v] [-nv] --str STR
{str,list,int,none}
positional arguments:
{str,list,int,none} choice the sub argument
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-v, --verbosity increase output verbosity -v, --verbosity increase output verbosity
-nv, --no-verbosity -nv, --no-verbosity
--str STR string option
""" """
parser = TiramisuCmdlineParser(get_config(json), 'prog.py') parser = TiramisuCmdlineParser(get_config(json), 'prog.py')
f = StringIO() f = StringIO()
@ -172,10 +180,15 @@ optional arguments:
def test_readme_help_modif_short1(json): def test_readme_help_modif_short1(json):
output = """usage: prog.py str --verbosity [-h] --str STR output = """usage: prog.py "str" -v [-h] [-v] [-nv] --str STR {str,list,int,none}
positional arguments:
{str,list,int,none} choice the sub argument
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-v, --verbosity increase output verbosity
-nv, --no-verbosity
--str STR string option --str STR string option
""" """
parser = TiramisuCmdlineParser(get_config(json), 'prog.py') parser = TiramisuCmdlineParser(get_config(json), 'prog.py')
@ -191,10 +204,15 @@ optional arguments:
def test_readme_help_modif_short_no(json): def test_readme_help_modif_short_no(json):
output = """usage: prog.py str --verbosity [-h] --str STR output = """usage: prog.py "str" -v [-h] [-v] [-nv] --str STR {str,list,int,none}
positional arguments:
{str,list,int,none} choice the sub argument
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
-v, --verbosity increase output verbosity
-nv, --no-verbosity
--str STR string option --str STR string option
""" """
parser = TiramisuCmdlineParser(get_config(json), 'prog.py') parser = TiramisuCmdlineParser(get_config(json), 'prog.py')
@ -258,7 +276,7 @@ prog.py: error: the following arguments are required: cmd
def test_readme_mandatory(json): def test_readme_mandatory(json):
output = """usage: prog.py str [-h] [-v] [-nv] --str STR output = """usage: prog.py "str" [-h] [-v] [-nv] --str STR {str,list,int,none}
prog.py: error: the following arguments are required: --str prog.py: error: the following arguments are required: --str
""" """
parser = TiramisuCmdlineParser(get_config(json), 'prog.py') parser = TiramisuCmdlineParser(get_config(json), 'prog.py')
@ -274,7 +292,7 @@ prog.py: error: the following arguments are required: --str
def test_readme_mandatory_tree(json): def test_readme_mandatory_tree(json):
output = """usage: prog.py str [-h] [-v] [-nv] --root.str STR output = """usage: prog.py "str" [-h] [-v] [-nv] --root.str STR {str,list,int,none}
prog.py: error: the following arguments are required: --root.str prog.py: error: the following arguments are required: --root.str
""" """
parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py') parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py')
@ -290,7 +308,7 @@ prog.py: error: the following arguments are required: --root.str
def test_readme_mandatory_tree_flatten(json): def test_readme_mandatory_tree_flatten(json):
output = """usage: prog.py str [-h] [-v] [-nv] --str STR output = """usage: prog.py "str" [-h] [-v] [-nv] --str STR {str,list,int,none}
prog.py: error: the following arguments are required: --str prog.py: error: the following arguments are required: --str
""" """
parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py', fullpath=False) parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py', fullpath=False)
@ -306,7 +324,7 @@ prog.py: error: the following arguments are required: --str
def test_readme_cross(json): def test_readme_cross(json):
output = """usage: prog.py none [-h] [-v] [-nv] output = """usage: prog.py "none" [-h] [-v] [-nv] {str,list,int,none}
prog.py: error: unrecognized arguments: --int prog.py: error: unrecognized arguments: --int
""" """
parser = TiramisuCmdlineParser(get_config(json), 'prog.py') parser = TiramisuCmdlineParser(get_config(json), 'prog.py')
@ -322,7 +340,7 @@ prog.py: error: unrecognized arguments: --int
def test_readme_cross_tree(json): def test_readme_cross_tree(json):
output = """usage: prog.py none [-h] [-v] [-nv] output = """usage: prog.py "none" [-h] [-v] [-nv] {str,list,int,none}
prog.py: error: unrecognized arguments: --int prog.py: error: unrecognized arguments: --int
""" """
parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py') parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py')
@ -338,7 +356,7 @@ prog.py: error: unrecognized arguments: --int
def test_readme_cross_tree_flatten(json): def test_readme_cross_tree_flatten(json):
output = """usage: prog.py none [-h] [-v] [-nv] output = """usage: prog.py "none" [-h] [-v] [-nv] {str,list,int,none}
prog.py: error: unrecognized arguments: --int prog.py: error: unrecognized arguments: --int
""" """
parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py', fullpath=False) parser = TiramisuCmdlineParser(get_config(json, True), 'prog.py', fullpath=False)

View file

@ -19,13 +19,14 @@ from gettext import gettext as _
try: try:
from tiramisu import Config from tiramisu import Config
from tiramisu.error import PropertiesOptionError, RequirementError from tiramisu.error import PropertiesOptionError, RequirementError, LeadershipError
except ModuleNotFoundError: except ModuleNotFoundError:
Config = None Config = None
from tiramisu_json_api.error import PropertiesOptionError from tiramisu_api.error import PropertiesOptionError
RequirementError = PropertiesOptionError RequirementError = PropertiesOptionError
LeadershipError = ValueError
try: try:
from tiramisu_json_api import Config as ConfigJson from tiramisu__api import Config as ConfigJson
if Config is None: if Config is None:
Config = ConfigJson Config = ConfigJson
except ModuleNotFoundError: except ModuleNotFoundError:
@ -284,7 +285,7 @@ class TiramisuCmdlineParser(ArgumentParser):
def _parse_known_args(self, args=None, namespace=None): def _parse_known_args(self, args=None, namespace=None):
try: try:
namespace_, args_ = super()._parse_known_args(args, namespace) namespace_, args_ = super()._parse_known_args(args, namespace)
except ValueError as err: except (ValueError, LeadershipError) as err:
self.error(err) self.error(err)
if args != args_ and args_ and args_[0].startswith(self.prefix_chars): if args != args_ and args_ and args_[0].startswith(self.prefix_chars):
# option that was disabled are no more disable # option that was disabled are no more disable
@ -297,7 +298,7 @@ class TiramisuCmdlineParser(ArgumentParser):
formatter_class=self.formatter_class, formatter_class=self.formatter_class,
epilog=self.epilog, epilog=self.epilog,
fullpath=self.fullpath) fullpath=self.fullpath)
namespace_, args_ = new_parser._parse_known_args(args_, namespace) namespace_, args_ = new_parser._parse_known_args(args_, new_parser.namespace)
else: else:
if self._registries['action']['help'].needs: if self._registries['action']['help'].needs:
# display help only when all variables assignemnt are done # display help only when all variables assignemnt are done
@ -327,7 +328,11 @@ class TiramisuCmdlineParser(ArgumentParser):
is_short_name = self._is_short_name(name, 'longargument' in properties) is_short_name = self._is_short_name(name, 'longargument' in properties)
self.prog += ' {}'.format(self._gen_argument(name, is_short_name)) self.prog += ' {}'.format(self._gen_argument(name, is_short_name))
if type != 'boolean': if type != 'boolean':
self.prog += f' {value}' if isinstance(value, list):
for val in value:
self.prog += f' "{val}"'
else:
self.prog += f' "{value}"'
def _config_list(self, def _config_list(self,
config: Config, config: Config,
@ -372,6 +377,7 @@ class TiramisuCmdlineParser(ArgumentParser):
group = super() group = super()
actions = {} actions = {}
leadership_len = None leadership_len = None
options_is_not_default = {}
for obj, force_no, force_del in self._config_list(config, prefix, _forhelp, group, level): for obj, force_no, force_del in self._config_list(config, prefix, _forhelp, group, level):
option = obj.option option = obj.option
name = option.name() name = option.name()
@ -379,6 +385,8 @@ class TiramisuCmdlineParser(ArgumentParser):
raise ValueError(_('name cannot startswith "{}"').format(self.prefix_chars)) raise ValueError(_('name cannot startswith "{}"').format(self.prefix_chars))
if option.issymlinkoption(): if option.issymlinkoption():
symlink_name = option.name(follow_symlink=True) symlink_name = option.name(follow_symlink=True)
if symlink_name in options_is_not_default:
options_is_not_default[symlink_name]['name'] = name
if symlink_name in actions: if symlink_name in actions:
for action in actions[symlink_name]: for action in actions[symlink_name]:
action.add_argument(option) action.add_argument(option)
@ -401,13 +409,11 @@ class TiramisuCmdlineParser(ArgumentParser):
else: else:
properties = obj.property.get() properties = obj.property.get()
kwargs = _BuildKwargs(name, option, self, properties, force_no, force_del) kwargs = _BuildKwargs(name, option, self, properties, force_no, force_del)
if not option.isfollower() and _forhelp and not obj.owner.isdefault() and value is not None: if not option.isfollower() and _forhelp and not obj.owner.isdefault() and value is not None and not force_no:
if not force_no: options_is_not_default[option.name()] = {'properties': properties,
self._option_is_not_default(properties, 'type': option.type(),
option.type(), 'name': name,
name, 'value': value}
value)
else:
if 'positional' in properties: if 'positional' in properties:
if option.type() == 'boolean': if option.type() == 'boolean':
raise ValueError(_('boolean option must not be positional')) raise ValueError(_('boolean option must not be positional'))
@ -485,6 +491,8 @@ class TiramisuCmdlineParser(ArgumentParser):
pass pass
#raise NotImplementedError('not supported yet') #raise NotImplementedError('not supported yet')
actions.setdefault(option.name(), []).append(kwargs) actions.setdefault(option.name(), []).append(kwargs)
for option_is_not_default in options_is_not_default.values():
self._option_is_not_default(**option_is_not_default)
for values in actions.values(): for values in actions.values():
for value in values: for value in values:
args, kwargs = value.get() args, kwargs = value.get()