Mercurial > hg > ConfigOptionParser
diff configoptionparser/__init__.py @ 0:3081763b099b
initial commit of ConfigOptionParser
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Thu, 20 May 2010 08:47:35 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configoptionparser/__init__.py Thu May 20 08:47:35 2010 -0700 @@ -0,0 +1,93 @@ +from optparse import OptionParser +from ConfigParser import ConfigParser + +### duplicate/extend ConfigParser functions as we can't use them directly :( + +def getlist(string, separator=','): + """returns a list from a string given a separator""" + string = string.strip() + if not string: + return [] + return [i.strip() for i in string.split(separator)] + +def getboolean(string): + return string.lower() == 'true' + + +class Undefined(object): + def __init__(self, default): + self.default=default + +class ConfigOptionParser(OptionParser): + def __init__(self, defaults_section='DEFAULTS', dict_section=None, + variables=None, **kwargs): + """ + - defaults_section: section of .ini to look for configuration variables + - dict_section: section of .ini to return as a dictionary + - variables: attr on returned options to parse dictionary from command line + """ + self.defaults_section = defaults_section + self.dict_section = dict_section + self.variables = variables + if self.dict_section and not self.variables: + self.variables = dict_section + OptionParser.__init__(self, **kwargs) + OptionParser.add_option(self, + '-c', '--config', dest='config', action='append', + help='ini file to read from') + + def add_option(self, *args, **kwargs): + kwargs['default'] = Undefined(kwargs.get('default')) + OptionParser.add_option(self, *args, **kwargs) + + def parse_args(self, args=None, values=None): + options, args = OptionParser.parse_args(self, args, values) + + # get defaults from the configuration parser + defaults = {} + config = ConfigParser() + if options.config: + config.read(options.config) + if self.defaults_section in config.sections(): + defaults = dict(config.items(self.defaults_section, raw=True)) + + # option dict + option_dict = dict([(i.dest, i) for i in self.option_list + if i.dest not in ('config', 'help')]) + + # conversion functions for .ini data + conversions = { 'store_true': getboolean, + 'store_false': getboolean, + 'append': getlist } + + # fill in the defaults not set from the command line + for key, value in options.__dict__.items(): + + # don't override command line arguments! they win! + if isinstance(value, Undefined): + + if key in defaults and key in option_dict: + # fill in options from .ini files + + option = option_dict[key] + + # converstion function + function = conversions.get(option.action, lambda x: x) + + setattr(options, key, function(defaults[key])) + else: + # set from option defaults + setattr(options, key, value.default) + + # get variables from dict_section and command line arguments + # TODO: could do this first then interpolate the config file from these + variables = {} + if self.dict_section in config.sections(): + variables.update(dict(config.items(self.dict_section, raw=True))) + if self.variables: + variables.update(dict([i.split('=',1) for i in args if '=' in i])) + args = [i for i in args if '=' not in i] + setattr(options, self.variables, variables) + + return (options, args) +