From 4e3aaea8d5fc2a85b3a6ea9ab43bbeef930f7fe1 Mon Sep 17 00:00:00 2001 From: Stefan Hacker Date: Mon, 20 Dec 2010 02:46:04 +0100 Subject: [PATCH] Expand config module for arbitrary section reading --- config.py | 43 +++++++++++++++++++++++++++++++------------ config_test.py | 10 ++++++++++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/config.py b/config.py index 4f7dbbf..838d570 100644 --- a/config.py +++ b/config.py @@ -30,6 +30,7 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import ConfigParser +import types class Config(object): """ @@ -40,32 +41,50 @@ class Config(object): if (filename and not default) or \ (not filename and not default): return + sections = set(default.iterkeys()) if filename: cfg = ConfigParser.ConfigParser() cfg.optionxform = str cfg.read(filename) - - for h,v in default.iteritems(): - if not v: + sections.update(cfg.sections()) + + for section in sections: + if type(section) == types.FunctionType: continue + + match = None + for default_section in default.iterkeys(): + try: + if section == default_section or \ + (type(default_section) == types.FunctionType and default_section(section)): + match = default_section + break + except ValueError: + continue + + if match == None: + continue + + optiondefaults = default[match] + + if not optiondefaults: # Output this whole section as a list of raw key/value tuples if not filename: - self.__dict__[h] = [] + self.__dict__[section] = [] else: try: - self.__dict__[h] = cfg.items(h) + self.__dict__[section] = cfg.items(section) except ConfigParser.NoSectionError: - self.__dict__[h] = [] + self.__dict__[section] = [] else: - self.__dict__[h] = Config() - for name, conv, vdefault in v: - + self.__dict__[section] = Config() + for name, conv, vdefault in optiondefaults: if not filename: - self.__dict__[h].__dict__[name] = vdefault + self.__dict__[section].__dict__[name] = vdefault else: try: - self.__dict__[h].__dict__[name] = conv(cfg.get(h, name)) + self.__dict__[section].__dict__[name] = conv(cfg.get(section, name)) except (ValueError, ConfigParser.NoSectionError, ConfigParser.NoOptionError): - self.__dict__[h].__dict__[name] = vdefault + self.__dict__[section].__dict__[name] = vdefault def x2bool(s): """Helper function to convert strings from the config to bool""" diff --git a/config_test.py b/config_test.py index c675e0f..6f9bbc0 100644 --- a/config_test.py +++ b/config_test.py @@ -33,6 +33,7 @@ import unittest from config import Config, x2bool from tempfile import mkstemp import os +import re def create_file(content = None): """ @@ -53,12 +54,18 @@ domination = True somestr = Blabla somenum = 10 testfallbacknum = asdas +[Server_10] +value = False +[Server_9] +[Server_2] +value = True """ cfg_default = {'world':(('domination', x2bool, False), ('somestr', str, "fail"), ('somenum', int, 0), ('somenumtest', int, 1)), + (lambda x: re.match("Server_\d+",x)):(('value', x2bool, True),), 'somethingelse':(('bla', str, "test"),)} def setUp(self): @@ -102,6 +109,9 @@ testfallbacknum = asdas assert(cfg.world.somenum == 10) self.assertRaises(AttributeError, getattr, cfg.world, "testfallbacknum") assert(cfg.somethingelse.bla == "test") + assert(cfg.Server_10.value == False) + assert(cfg.Server_2.value == True) + assert(cfg.Server_9.value == True) finally: os.remove(path)