2 Configuration Utility Module
4 This module contains functions to load and verify very simple configuration
5 files. Python supports ".ini" files, which suck, so this module is used
8 Example Configuration File:
10 include /path/to/other.cf
12 # these values are the same:
13 name_protected = "Michael Spang"
14 name_unprotected = Michael Spang
16 # these values are not the same:
20 # this value is an integer
23 # this value is not an integer
26 # this is a key with no value
29 # this key contains whitespace
30 white space = sure, why not
32 # these two lines are treated as one
33 long line = first line \
39 'name_protected': 'Michael Spang',
40 'name_unprotected:' 'Michael Spang',
44 'arbitrary_string': '2',
46 'white space': 'sure, why not'
47 'long line': 'first line \n second line'
49 ... (data from other.cf) ...
53 from curses.ascii import isspace
56 class ConfigurationException(Exception):
57 """Exception class for incomplete and incorrect configurations."""
60 def read(filename, included=None):
61 """Function to read a configuration file into a dictionary."""
65 if filename in included:
67 included.append(filename)
70 conffile = open(filename)
72 raise ConfigurationException('unable to read configuration file: "%s"' % filename)
78 line = conffile.readline()
84 line = line[:line.find('#')]
86 # combine lines when the newline is escaped with \
87 while len(line) > 1 and line[-2] == '\\':
88 line = line[:-2] + line[-1]
89 next = conffile.readline()
96 # process include statements
97 if line.find("include") == 0 and isspace(line[7]):
99 filename = line[8:].strip()
100 options.update(read(filename, included))
103 # split 'key = value' into key and value and strip results
104 pair = map(str.strip, line.split('=', 1))
106 # found key and value
110 # found quoted string?
111 if val[0] == val[-1] == '"':
114 # unquoted, found float?
127 # found only key, value = None
128 elif len(pair[0]) > 1:
135 def check_string_fields(filename, field_list, cfg):
136 """Function to verify thatfields are strings."""
138 for field in field_list:
139 if field not in cfg or type(cfg[field]) is not str:
140 raise ConfigurationException('expected string value for option "%s" in "%s"' % (field, filename))
142 def check_integer_fields(filename, field_list, cfg):
143 """Function to verify that fields are integers."""
145 for field in field_list:
146 if field not in cfg or type(cfg[field]) not in (int, long):
147 raise ConfigurationException('expected numeric value for option "%s" in "%s"' % (field, filename))
149 def check_float_fields(filename, field_list, cfg):
150 """Function to verify that fields are integers or floats."""
152 for field in field_list:
153 if field not in cfg or type(cfg[field]) not in (float, long, int):
154 raise ConfigurationException('expected float value for option "%s" in "%s"' % (field, filename))