from ConfigParser import SafeConfigParser, NoOptionError from argparse import ArgumentParser import sys class _Dummy(): pass class ComboParser(object): def __init__(self, ini): self.items = [] self.cparser = SafeConfigParser() self.aparser = ArgumentParser() self.ini = ini self.items = [] self.loaded = False def add_item(self, section, name, type, default, desc, required): def str2bool(val): return val in ['True', 'true', '1', 'yes'] self.items.append({ 'section':section, 'name':name, 'type':type, 'default':default, 'required':required, }) self.aparser.add_argument( '--%s.%s'%(section, name), help='%s, default: (%s)'%(desc, str(default)), type=type if type is not bool else str2bool, default=None, required=False ) def load(self): if self.loaded: return self.loaded = True try: self.cparser.read(self.ini) except: pass args = self.aparser.parse_args() for item in self.items: try: obj = getattr(self, item['section']) except AttributeError: setattr(self, item['section'], _Dummy()) obj = getattr(self, item['section']) setattr(obj, item['name'], item['default']) inner = getattr(obj, item['name']) item['found'] = True try: if item['type'] is bool : inner = self.cparser.getboolean(item['section'], item['name']) elif item['type'] is float: inner = self.cparser.getfloat(item['section'], item['name']) elif item['type'] is int : inner = self.cparser.getint(item['section'], item['name']) elif item['type'] is str : inner = self.cparser.get(item['section'], item['name']) except NoOptionError: item['found'] = False try: arg = getattr(args, '%s.%s'%(item['section'], item['name'])) if arg is not None: inner = arg item['found'] = True except: pass if not item['found']: if item['required']: sys.stderr.write('error: required config item "%s" not found in section "%s" of "%s"!\n'%(item['name'], item['section'], self.ini)) sys.exit(1) else: sys.stderr.write('warning: assigned default value of "%s" to "%s.%s"\n'%(str(item['default']), item['section'], item['name'])) setattr(obj, item['name'], inner)