Mercurial > hg > ConfigOptionParser
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:3081763b099b |
|---|---|
| 1 from optparse import OptionParser | |
| 2 from ConfigParser import ConfigParser | |
| 3 | |
| 4 ### duplicate/extend ConfigParser functions as we can't use them directly :( | |
| 5 | |
| 6 def getlist(string, separator=','): | |
| 7 """returns a list from a string given a separator""" | |
| 8 string = string.strip() | |
| 9 if not string: | |
| 10 return [] | |
| 11 return [i.strip() for i in string.split(separator)] | |
| 12 | |
| 13 def getboolean(string): | |
| 14 return string.lower() == 'true' | |
| 15 | |
| 16 | |
| 17 class Undefined(object): | |
| 18 def __init__(self, default): | |
| 19 self.default=default | |
| 20 | |
| 21 class ConfigOptionParser(OptionParser): | |
| 22 def __init__(self, defaults_section='DEFAULTS', dict_section=None, | |
| 23 variables=None, **kwargs): | |
| 24 """ | |
| 25 - defaults_section: section of .ini to look for configuration variables | |
| 26 - dict_section: section of .ini to return as a dictionary | |
| 27 - variables: attr on returned options to parse dictionary from command line | |
| 28 """ | |
| 29 self.defaults_section = defaults_section | |
| 30 self.dict_section = dict_section | |
| 31 self.variables = variables | |
| 32 if self.dict_section and not self.variables: | |
| 33 self.variables = dict_section | |
| 34 OptionParser.__init__(self, **kwargs) | |
| 35 OptionParser.add_option(self, | |
| 36 '-c', '--config', dest='config', action='append', | |
| 37 help='ini file to read from') | |
| 38 | |
| 39 def add_option(self, *args, **kwargs): | |
| 40 kwargs['default'] = Undefined(kwargs.get('default')) | |
| 41 OptionParser.add_option(self, *args, **kwargs) | |
| 42 | |
| 43 def parse_args(self, args=None, values=None): | |
| 44 options, args = OptionParser.parse_args(self, args, values) | |
| 45 | |
| 46 # get defaults from the configuration parser | |
| 47 defaults = {} | |
| 48 config = ConfigParser() | |
| 49 if options.config: | |
| 50 config.read(options.config) | |
| 51 if self.defaults_section in config.sections(): | |
| 52 defaults = dict(config.items(self.defaults_section, raw=True)) | |
| 53 | |
| 54 # option dict | |
| 55 option_dict = dict([(i.dest, i) for i in self.option_list | |
| 56 if i.dest not in ('config', 'help')]) | |
| 57 | |
| 58 # conversion functions for .ini data | |
| 59 conversions = { 'store_true': getboolean, | |
| 60 'store_false': getboolean, | |
| 61 'append': getlist } | |
| 62 | |
| 63 # fill in the defaults not set from the command line | |
| 64 for key, value in options.__dict__.items(): | |
| 65 | |
| 66 # don't override command line arguments! they win! | |
| 67 if isinstance(value, Undefined): | |
| 68 | |
| 69 if key in defaults and key in option_dict: | |
| 70 # fill in options from .ini files | |
| 71 | |
| 72 option = option_dict[key] | |
| 73 | |
| 74 # converstion function | |
| 75 function = conversions.get(option.action, lambda x: x) | |
| 76 | |
| 77 setattr(options, key, function(defaults[key])) | |
| 78 else: | |
| 79 # set from option defaults | |
| 80 setattr(options, key, value.default) | |
| 81 | |
| 82 # get variables from dict_section and command line arguments | |
| 83 # TODO: could do this first then interpolate the config file from these | |
| 84 variables = {} | |
| 85 if self.dict_section in config.sections(): | |
| 86 variables.update(dict(config.items(self.dict_section, raw=True))) | |
| 87 if self.variables: | |
| 88 variables.update(dict([i.split('=',1) for i in args if '=' in i])) | |
| 89 args = [i for i in args if '=' not in i] | |
| 90 setattr(options, self.variables, variables) | |
| 91 | |
| 92 return (options, args) | |
| 93 |
