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