diff --git a/test/test_readme.py b/test/test_readme.py index e026fcf..b90f022 100644 --- a/test/test_readme.py +++ b/test/test_readme.py @@ -109,6 +109,26 @@ root: assert f.getvalue() == output +def test_readme_help_modif(): + output = """usage: prog.py str [-h] [-v] --str STR + +optional arguments: + -h, --help show this help message and exit + -v, --verbosity increase output verbosity + --str STR string option +""" + parser = TiramisuCmdlineParser(get_config(), 'prog.py') + f = StringIO() + with redirect_stdout(f): + try: + parser.parse_args(['str', '--help']) + except SystemExit as err: + assert str(err) == "0" + else: + raise Exception('must raises') + assert f.getvalue() == output + + def test_readme_positional_mandatory(): output = """usage: prog.py [-h] [-v] {str,list,int,none} prog.py: error: the following arguments are required: cmd @@ -158,7 +178,7 @@ prog.py: error: the following arguments are required: cmd def test_readme_mandatory(): - output = """usage: prog.py [-h] [-v] --str STR {str,list,int,none} + output = """usage: prog.py str [-h] [-v] --str STR prog.py: error: the following arguments are required: --str """ parser = TiramisuCmdlineParser(get_config(), 'prog.py') @@ -174,7 +194,7 @@ prog.py: error: the following arguments are required: --str def test_readme_mandatory_tree(): - output = """usage: prog.py [-h] [-v] --root.str STR {str,list,int,none} + output = """usage: prog.py str [-h] [-v] --root.str STR prog.py: error: the following arguments are required: --root.str """ parser = TiramisuCmdlineParser(get_config(True), 'prog.py') @@ -190,7 +210,7 @@ prog.py: error: the following arguments are required: --root.str def test_readme_mandatory_tree_flatten(): - output = """usage: prog.py [-h] [-v] --str STR {str,list,int,none} + output = """usage: prog.py str [-h] [-v] --str STR prog.py: error: the following arguments are required: --str """ parser = TiramisuCmdlineParser(get_config(True), 'prog.py', fullpath=False) @@ -206,7 +226,7 @@ prog.py: error: the following arguments are required: --str def test_readme_cross(): - output = """usage: prog.py [-h] [-v] {str,list,int,none} + output = """usage: prog.py none [-h] [-v] prog.py: error: unrecognized arguments: --int """ parser = TiramisuCmdlineParser(get_config(), 'prog.py') @@ -222,7 +242,7 @@ prog.py: error: unrecognized arguments: --int def test_readme_cross_tree(): - output = """usage: prog.py [-h] [-v] {str,list,int,none} + output = """usage: prog.py none [-h] [-v] prog.py: error: unrecognized arguments: --int """ parser = TiramisuCmdlineParser(get_config(True), 'prog.py') @@ -238,7 +258,7 @@ prog.py: error: unrecognized arguments: --int def test_readme_cross_tree_flatten(): - output = """usage: prog.py [-h] [-v] {str,list,int,none} + output = """usage: prog.py none [-h] [-v] prog.py: error: unrecognized arguments: --int """ parser = TiramisuCmdlineParser(get_config(True), 'prog.py', fullpath=False) diff --git a/tiramisu_cmdline_parser/tiramisu_cmdline_parser.py b/tiramisu_cmdline_parser/tiramisu_cmdline_parser.py index 16bbe2d..30e7c6c 100644 --- a/tiramisu_cmdline_parser/tiramisu_cmdline_parser.py +++ b/tiramisu_cmdline_parser/tiramisu_cmdline_parser.py @@ -182,55 +182,60 @@ class TiramisuCmdlineParser(ArgumentParser): if option.issymlinkoption(): actions[option.name(follow_symlink=True)][0].insert(0, self._gen_argument(option.name(), properties)) continue - if 'positional' in properties: - if not 'mandatory' in properties: - raise ValueError('"positional" argument must be "mandatory" too') - args = [option.path()] - if _forhelp: - kwargs['default'] = obj.value.default() - else: - kwargs['default'] = obj.value.get() - kwargs['nargs'] = '?' + if _forhelp and not obj.owner.isdefault() and obj.value.get(): + self.prog += ' {}'.format(obj.value.get()) else: - kwargs['dest'] = option.path() - kwargs['default'] = SUPPRESS - args = [self._gen_argument(name, properties)] - if _forhelp and 'mandatory' in properties: - kwargs['required'] = True - if option.type() == 'boolean': - if 'mandatory' in properties: - raise ValueError('"mandatory" property is not allowed for BoolOption') - #if not isinstance(option.default(), bool): - # raise ValueError('default value is mandatory for BoolOption') - if obj.value.get() is False: - action = 'store_true' - else: - action = 'store_false' - kwargs['action'] = action - else: - if _forhelp: - value = obj.value.default() - else: - value = obj.value.get() - if value not in [None, []]: - #kwargs['default'] = kwargs['const'] = option.default() - #kwargs['action'] = 'store_const' - kwargs['nargs'] = '?' - if option.ismulti(): - if _forhelp and 'mandatory' in properties: - kwargs['nargs'] = '+' + if 'positional' in properties: + if not 'mandatory' in properties: + raise ValueError('"positional" argument must be "mandatory" too') + if _forhelp: + args = [option.path()] + kwargs['default'] = obj.value.default() else: - kwargs['nargs'] = '*' - if option.type() == 'string': - pass - elif option.type() == 'integer': - kwargs['type'] = int - elif option.type() == 'choice': - kwargs['choices'] = obj.value.list() + args = [option.path()] + kwargs['default'] = obj.value.get() + kwargs['nargs'] = '?' else: - pass - #raise NotImplementedError('not supported yet') - actions[option.name()] = (args, kwargs) + kwargs['dest'] = option.path() + kwargs['default'] = SUPPRESS + args = [self._gen_argument(name, properties)] + if _forhelp and 'mandatory' in properties: + kwargs['required'] = True + + if option.type() == 'boolean': + if 'mandatory' in properties: + raise ValueError('"mandatory" property is not allowed for BoolOption') + #if not isinstance(option.default(), bool): + # raise ValueError('default value is mandatory for BoolOption') + if obj.value.get() is False: + action = 'store_true' + else: + action = 'store_false' + kwargs['action'] = action + else: + if _forhelp: + value = obj.value.default() + else: + value = obj.value.get() + if value not in [None, []]: + #kwargs['default'] = kwargs['const'] = option.default() + #kwargs['action'] = 'store_const' + kwargs['nargs'] = '?' + if option.ismulti(): + if _forhelp and 'mandatory' in properties: + kwargs['nargs'] = '+' + else: + kwargs['nargs'] = '*' + if option.type() == 'string': + pass + elif option.type() == 'integer': + kwargs['type'] = int + elif option.type() == 'choice': + kwargs['choices'] = obj.value.list() + else: + pass + #raise NotImplementedError('not supported yet') + actions[option.name()] = (args, kwargs) for args, kwargs in actions.values(): group.add_argument(*args, **kwargs) @@ -279,14 +284,12 @@ class TiramisuCmdlineParser(ArgumentParser): _forhelp=True) return super(TiramisuCmdlineParser, help_formatter).format_usage(*args, **kwargs) - def format_help(self, - *args, - **kwargs): + def format_help(self): help_formatter = TiramisuCmdlineParser(self.config, self.prog, fullpath=self.fullpath, _forhelp=True) - return super(TiramisuCmdlineParser, help_formatter).format_help(*args, **kwargs) + return super(TiramisuCmdlineParser, help_formatter).format_help() def get_config(self): return self.config