diff options
author | Anthon van der Neut <anthon@mnt.org> | 2014-03-17 10:18:36 +0100 |
---|---|---|
committer | Anthon van der Neut <anthon@mnt.org> | 2014-03-17 10:18:36 +0100 |
commit | 677f099cdbbf5d4e313640bf47358fe77ffcf880 (patch) | |
tree | 4b9999e7beb4dbef76a600348257d5ffc258de9e | |
parent | e98fae6e8f96464dad291dea62887f6d9db2657a (diff) | |
download | ruamel.std.argparse-677f099cdbbf5d4e313640bf47358fe77ffcf880.tar.gz |
added sub_parser, global_option, global_only_option, create_argument_parser
These can be inserted into and update by using ruamel_util_updateprogram
-rw-r--r-- | __init__.py | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/__init__.py b/__init__.py index 0796ac7..eef0950 100644 --- a/__init__.py +++ b/__init__.py @@ -98,3 +98,123 @@ class SmartFormatter(argparse.HelpFormatter): if action.option_strings or action.nargs in defaulting_nargs: help += ' (default: %(default)s)' return help + + +# decorators + +# decorate method as a subparser, ToDo: signature +def sub_parser(*args, **kw): + class Decorator(object): + def __init__(self): + self.target = None + + def __call__(self, target): + self.target = target + target.sub_parser = {'args': args, 'kw': kw} + target.option = self.option + return target + + def option(self, *a, **k): + """ after a method xyz is decorated as sub_parser, you can add + options with: + @xyz.option('--force') + def force(self): + pass + + if option argument is a short option ('-F'), add the long + option based on the function name + if no option argument, add function_name if 'nargs' in k + else add long option based on function name + """ + # here check if a is option name else take from function + def option_func(*args): + """called with the original function that is decorated + add function name to last options element + """ + self.target.options[-1]['fun'] = args[0].__name__ + pass + + if not hasattr(self.target, "options"): + self.target.options = [] + self.target.options.append({'args': a, 'kw': k}) + return option_func + decorator = Decorator() + return decorator + + +# global options can come before and after a sub_parser, ToDo: signature +def global_option(*args, **kw): + def decorator(target): + target.global_option = {'args': args, 'kw': kw} + return target + return decorator + + +# global only options can come before a sub_parser only, ToDo: signature +def global_only_option(*args, **kw): + def decorator(target): + target.global_only_option = {'args': args, 'kw': kw} + return target + return decorator + + +def create_argument_parser(self, *args, **keywords): + argument_parser = argparse.ArgumentParser(**keywords) + self._subparsers = None + for x in dir(self): + if x.startswith('_'): + continue + method = getattr(self, x) + if hasattr(method, "sub_parser"): + if self._subparsers is None: + self._subparsers = argument_parser.add_subparsers( + dest="subparser_name", help='sub-command help') + #(name, aliases=aliases, help=help) + arg = method.sub_parser['args'] + if not arg or not isinstance(arg[0], basestring): + arg = list(arg) + arg.insert(0, x) + sp = self._subparsers.add_parser(*arg, + **method.sub_parser['kw']) + sp.set_defaults(func=method) + + #print x, method.sub_parser + if hasattr(method, "options"): + for o in method.options: + #print 'arg1', o + arg = list(o['args']) + fun_name = o.get('fun') + if arg: + # short option name only, add long option name + # based on function name + if len(arg[0]) == 2 and arg[0][0] == '-': + if (fun_name): + arg.insert(0, '--' + fun_name) + else: + # no option name + if o['kw'].get('nargs') == '+': + # file names etc, no leading dashes + arg.insert(0, fun_name) + else: + # add long option based on function name + arg.insert(0, '--' + fun_name) + #print 'arg2', arg + sp.add_argument(*arg, **o['kw']) + #print ' opt:', x, method.options + if hasattr(method, "global_only_option"): + arg, kw = method.global_only_option + argument_parser.add_argument(*arg, **kw) + for x in dir(self): + if x.startswith('_'): + continue + method = getattr(self, x) + if hasattr(method, "global_option"): + for name in self._subparsers._name_parser_map: + sp = self._subparsers._name_parser_map[name] + arg = method.global_option['args'] + if arg and not arg[0].startswith('--'): + arg = list(arg) + arg.insert(0, '--' + x) + sp.add_argument(*arg, **method.global_option['kw']) + return argument_parser + |