implement combo config parser

allows all options to be overridden by command line.

e.g.
[watchd]
threads=10
debug=false

--watch.threads=50 --debug=true
This commit is contained in:
rofl0r
2019-01-08 02:17:04 +00:00
parent e7b8d526c0
commit f16f754b0e
5 changed files with 131 additions and 67 deletions

86
comboparse.py Normal file
View File

@@ -0,0 +1,86 @@
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):
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,
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)
# TEST CODE
def _main():
config = ComboParser('config.ini')
config.add_item('watchd', 'debug', bool, False, 'turn additional debug info on', False)
config.add_item('watchd', 'float', float, 0.1, 'a float test', True)
config.add_item('watchd', 'strupp', str, "sup", 'a str test', False)
config.add_item('common', 'tor_host', str, '127.0.0.1:9050', 'address of tor proxy', True)
config.load()
print config.watchd.debug
print config.watchd.float
print config.watchd.strupp
print config.common.tor_host
if __name__ == '__main__':
_main()