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 |