Source code for pydeps.arguments

from __future__ import print_function, unicode_literals
import warnings
import json
import argparse
from .pycompat import configparser

try:
    unicode

    def is_string(v):
        return isinstance(v, (str, unicode))
except NameError:
[docs] def is_string(v): return isinstance(v, str)
DEFAULT_NONE = '____'
[docs]def boolval(v): if isinstance(v, bool): return v if isinstance(v, int): return bool(v) if is_string(v): v = v.lower() if v in {'j', 'y', 'ja', 'yes', '1', 'true'}: return True if v in {'n', 'nei', 'no', '0', 'false'}: return False raise ValueError("Don't know how to convert %r to bool" % v)
[docs]def listval(v): if is_string(v): return [x for x in v.split() if x.strip()] if isinstance(v, (list, tuple)): return v raise ValueError("Don't know how to convert %r to list" % v)
[docs]def identity(v): return v
typefns = { 'BOOL': boolval, 'INT': int, 'LIST': listval }
[docs]class Argument(object): def __init__(self, *flags, **args): self._args = args self._flags = flags # self.__dict__.update(args) def __json__(self): return self.__dict__
[docs] def typename(self): if 'kind' in self._args: return self._args['kind'] if self._args.get('action') in {'store_true', 'store_false'}: return 'BOOL' tp = self._args.get('type') if tp is not None: return tp.__name__.upper() v = self._args.get('default') if v is None: return DEFAULT_NONE return v.__class__.__name__.upper()
[docs] def argname(self): if 'dest' in self._args: return self._args['dest'] return self._flags[-1].lstrip('-').replace('-', '_')
[docs] def default(self): if 'default' in self._args: return self._args['default'] if self._args.get('action') == 'store_true': return False if self._args.get('action') == 'store_false': return True return '___'
[docs] def add_to_parser(self, parser): args = self._args args.pop('default', None) # remove default value args.pop('kind', None) # remove our attributes if args.get('action') in {'store_true', 'store_false'}: args['default'] = None parser.add_argument(*self._flags, **args)
[docs]class Namespace(object): def __init__(self, ns): self.ns = ns def __repr__(self): return json.dumps(vars(self.ns), indent=4, sort_keys=True)
[docs] def items(self): return list(dict(vars(self.ns)).items())
def __getitem__(self, key): return getattr(self.ns, key) def __setitem__(self, key, val): setattr(self.ns, key, val) def __delitem__(self, key): delattr(self.ns, key) def __getattr__(self, key): return getattr(self.ns, key)
[docs]class Arguments(object): def __init__(self, config_files=None, debug=False, *posargs, **kwargs): # passthrough to argparse self.posargs = posargs self.kwargs = kwargs # print("CONFIG_FILES:", config_files) self.debug = debug self.arglist = [] self.args = {} self.config_files = config_files self.argtypes = {} self.defaults = {}
[docs] def parse_args(self, argv): config = [] if self.config_files: conf = configparser.SafeConfigParser() conf.read(self.config_files) try: config = conf.items("pydeps") except (configparser.NoOptionError, configparser.NoSectionError): warnings.warn(' '.join(""" Couldn't find a [pydeps] section in your config files %r -- or it was empty """.split()) % (self.config_files,)) p = argparse.ArgumentParser(*self.posargs, **self.kwargs) for arg in self.arglist: arg.add_to_parser(p) args = Namespace(p.parse_args(argv)) for key, val in config: if key not in self.args: warnings.warn("Your .pydeps file contained %s = %s which doesn't match any argument" % (key, val)) continue argval = args[key] confval = val typeval = self.argtypes[key] typfn = typefns[typeval] if argval is None: args[key] = typfn(confval) for key, val in args.items(): if val in (None, DEFAULT_NONE): default = self.defaults.get(key) if default == DEFAULT_NONE: default = None args[key] = default del args['config'] return args.ns
[docs] def add(self, *flags, **kwargs): arg = Argument(*flags, **kwargs) self.arglist.append(arg) argname = arg.argname() self.args[argname] = arg self.argtypes[argname] = arg.typename() self.defaults[argname] = arg.default()
def __repr__(self): return json.dumps(dict( types=self.argtypes, defaults=self.defaults, ), indent=4, sort_keys=True)