Source code for argdeco.arguments

"""argdeco.arguments -- manage arguments


"""

import logging, inspect
logger = logging.getLogger('argparse.arguments')

from argparse import Action


[docs]class ArgAction(Action): '''Internal class to handle argument actions There are two ways ''' def set_arg_func(self, arg_func): self.arg_func = arg_func def __call__(self, parser, namespace, values, option_string=None): if self.arg_func.__code__.co_argcount == 1: setattr(namespace, self.dest, self.arg_func(values)) else: self.arg_func(self, parser, namespace, values, option_string)
[docs]class arg(object): """Represent arguments passed with add_argument() to an argparser See https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument """ def __init__(self, *args, **opts): if 'config' in opts: self.config_name = opts.pop('config') if 'config_name' in opts: self.config_name = opts.pop('config_name') self.args = args self.opts = opts def apply(self, parser, command, context=''): if hasattr(self, 'config_name'): config_name = self.config_name else: config_name = '.'.join([context, self.dest]) logger.debug("do register_config_map: context=%s, self.dest=%s, config_name=%s", context, self.dest, config_name) command.register_config_map(context, self.dest, config_name) if 'dest' not in self.opts and not self.args[0][0].isalnum(): self.opts['dest'] = self.dest logger.debug("apply: %s", self) parser.add_argument(*self.args, **self.opts) def __getattr__(self, name): if name == 'dest': dest = self.opts.get('dest') if not dest: for a in self.args: if a.startswith('--'): dest = a[2:].replace('-', '_') break if not dest: for a in self.args: if a.startswith('-'): dest = a[1:].replace('-', '_') break if not dest: dest = self.args[0] self.dest = dest return self.dest # if name == 'config_name': # import rpdb2 ; rpdb2.start_embedded_debugger('foo') # # path = [self.dest] # cmd = self.command # while cmd: # if cmd.name: # path.append(cmd.name) # cmd = cmd.parent # self.config_name = '.'.join(reversed(path)) # return self.config_name raise AttributeError(name) # for a in self.args: # if a.startswith('') # # cmd = # self.command def __repr__(self): return "arg(%s, %s)" % (self.args, self.opts) def __call__(self, *args, **kwargs): # factory for other arg if not (len(args) == 1 and inspect.isfunction(args[0])): _args = self.args if len(args): _args = args _opts = self.opts.copy() _opts.update(**kwargs) return arg(*_args, **_opts) func = args[0] self.func = func def arg_action_factory(*args, **kwargs): a = ArgAction(*args, **kwargs) a.set_arg_func(func) return a self.opts['action'] = arg_action_factory return self
[docs]class opt(arg): """Option action="store_true" """ def apply(self, parser, command, context=''): logger.debug("apply: %s", self) self.opts['action'] = 'store_true' self.opts['default'] = False arg.apply(self, parser, command, context)
[docs]class group(arg): """Argument group This class is a wrapper for :py:meth:`argparse.ArgumentParser.add_argument_group`. Usage:: @main( group( arg('--first'), arg('--second'), title="group title", description=''' Here some group description ''' ) ) def _main(first, second): pass """ def apply(self, parser, command, context='', method='add_argument_group'): more_args = self.opts.pop('args', []) group = getattr(parser, method)(**self.opts) for a in self.args: a.apply(group, command) for a in more_args: a.apply(group, command)
[docs]class mutually_exclusive(group): """Mutually exclusive argument group Usage:: @main( mutually_exclusive( arg('--first'), arg('--second'), title="group title", description=''' Here some group description ''' ) ) def _main(first, second): pass """ def apply(self, parser, command, context=''): group.apply(self, parser, command, context, 'add_mutually_exclusive_group')