Simple configuration file parser (python)

Python’s ConfigParser works well for INI files but what about config files that are simple key/value options? For example, ConfigParser will not work with files like this:


#Example configuration file
#Foo Bar-er v1.0
foo_dir="/var/lib/foo"
bar_dir="/var/lib/bar"
foo_all_the_bars="1"
bar_all_the_foos = "yes, do it"

Granted, the example above is a poorly written config file however I’m using it as an example to demonstrate the flexibility of configuration parser. So here’s the code:


# SimpleConfigParser
# Inspired by:
# http://www.decalage.info/fr/python/configparser
class SimpleConfigParser():

    def __init__(self, comment_char = '#', option_char = '=', allow_duplicates = False, strip_quotes = True):
        self.comment_char = comment_char
        self.option_char = option_char
        self.allow_duplicates = allow_duplicates
        self.strip_quotes = True

    def parse_config(self, filename):
        self.options = {}
        config_file = open(filename)
        for line in config_file:
            if self.comment_char in line:
                line, comment = line.split(self.comment_char, 1)
            if self.option_char in line:
                option, value = line.split(self.option_char, 1)
                option = option.strip()
                value = value.strip()
                value = value.strip('"\'')
                if self.allow_duplicates:
                    if option in self.options:
                        if not type(self.options[option]) == list:
                            old_value = self.options[option]
                            self.options[option] = [value] + [old_value]
                        else:
                            self.options[option] += [value]
                    else:
                        self.options[option] = value
                else:
                    self.options[option] = value
        config_file.close()
        return self.options

And here’s an example of how you’d use this (assuming you saved the code in a file named ‘simpleconfig.py’ and you saved the example config as ‘example.cfg’):


Python 2.7.3 (default, Aug 1 2012, 05:14:39)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from simpleconfig import SimpleConfigParser
>>> scp = SimpleConfigParser()
>>> scp.parse_config('example.cfg')
{'bar_dir': '/var/lib/bar', 'foo_all_the_bars': '1', 'foo_dir': '/var/lib/foo', 'bar_all_the_foos': 'yes, do it'}
>>>

Also, if you have a config file that has duplicate “options” (nagios.cfg comes to mind), you can do the following:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from simpleconfig import SimpleConfigParser
>>> scp = SimpleConfigParser(allow_duplicates = True)
>>> nagios_config = scp.parse_config('/etc/nagios3/nagios.cfg')
>>> nagios_config['cfg_dir']
['/etc/nagios3/conf.d', '/etc/nagios-plugins/config']
>>> 

Instead of a key/value pair, you’ll get a key with a list as it’s value for each identically named configuration option.