Merge branch 'cleverdevil/config-dict' into cleverdevil/master
* cleverdevil/config-dict: Fixing configuration to correctly handle forced dictionaries Minor PEP8 changes
This commit is contained in:
@@ -3,9 +3,15 @@ import inspect
|
|||||||
import os
|
import os
|
||||||
import string
|
import string
|
||||||
|
|
||||||
|
|
||||||
IDENTIFIER = re.compile(r'[a-z_](\w)*$', re.IGNORECASE)
|
IDENTIFIER = re.compile(r'[a-z_](\w)*$', re.IGNORECASE)
|
||||||
STRING_FORMAT = re.compile(r'{pecan\.conf(?P<var>([.][a-z_][\w]*)+)+?}', re.IGNORECASE)
|
STRING_FORMAT = re.compile(r'{pecan\.conf(?P<var>([.][a-z_][\w]*)+)+?}', re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigDict(dict):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ConfigString(object):
|
class ConfigString(object):
|
||||||
def __init__(self, format_string):
|
def __init__(self, format_string):
|
||||||
self.raw_string = format_string
|
self.raw_string = format_string
|
||||||
@@ -37,24 +43,20 @@ class ConfigString(object):
|
|||||||
def contains_formatting(value):
|
def contains_formatting(value):
|
||||||
return STRING_FORMAT.match(value)
|
return STRING_FORMAT.match(value)
|
||||||
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
def __init__(self, conf_dict={}):
|
def __init__(self, conf_dict={}):
|
||||||
self.update(conf_dict)
|
self.update(conf_dict)
|
||||||
|
|
||||||
def update(self, conf_dict):
|
def update(self, conf_dict):
|
||||||
__force_dict__ = False
|
|
||||||
# first check the keys for correct
|
|
||||||
|
|
||||||
if isinstance(conf_dict, dict):
|
if isinstance(conf_dict, dict):
|
||||||
if '__force_dict__' in conf_dict:
|
|
||||||
del conf_dict['__force_dict__']
|
|
||||||
__force_dict__ = True
|
|
||||||
iterator = conf_dict.iteritems()
|
iterator = conf_dict.iteritems()
|
||||||
else:
|
else:
|
||||||
iterator = iter(conf_dict)
|
iterator = iter(conf_dict)
|
||||||
|
|
||||||
for k,v in iterator:
|
for k,v in iterator:
|
||||||
if not IDENTIFIER.match(k) and not __force_dict__:
|
if not IDENTIFIER.match(k):
|
||||||
raise ValueError('\'%s\' is not a valid indentifier' % k)
|
raise ValueError('\'%s\' is not a valid indentifier' % k)
|
||||||
|
|
||||||
cur_val = self.__dict__.get(k)
|
cur_val = self.__dict__.get(k)
|
||||||
@@ -71,9 +73,10 @@ class Config(object):
|
|||||||
return self.__dict__[key]
|
return self.__dict__[key]
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict) and not isinstance(value, ConfigDict):
|
||||||
if value.get('__force_dict__'):
|
if value.get('__force_dict__'):
|
||||||
self.__dict__[key] = value
|
del value['__force_dict__']
|
||||||
|
self.__dict__[key] = ConfigDict(value)
|
||||||
else:
|
else:
|
||||||
self.__dict__[key] = Config(value)
|
self.__dict__[key] = Config(value)
|
||||||
elif isinstance(value, str) and ConfigString.contains_formatting(value):
|
elif isinstance(value, str) and ConfigString.contains_formatting(value):
|
||||||
@@ -99,7 +102,6 @@ class Config(object):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def conf_from_module(module):
|
def conf_from_module(module):
|
||||||
if isinstance(module, str):
|
if isinstance(module, str):
|
||||||
module = import_module(module)
|
module = import_module(module)
|
||||||
@@ -108,6 +110,7 @@ def conf_from_module(module):
|
|||||||
|
|
||||||
return conf_from_dict(module_dict)
|
return conf_from_dict(module_dict)
|
||||||
|
|
||||||
|
|
||||||
def conf_from_file(filepath):
|
def conf_from_file(filepath):
|
||||||
abspath = os.path.abspath(os.path.expanduser(filepath))
|
abspath = os.path.abspath(os.path.expanduser(filepath))
|
||||||
conf_dict = {}
|
conf_dict = {}
|
||||||
@@ -117,6 +120,7 @@ def conf_from_file(filepath):
|
|||||||
|
|
||||||
return conf_from_dict(conf_dict)
|
return conf_from_dict(conf_dict)
|
||||||
|
|
||||||
|
|
||||||
def conf_from_dict(conf_dict):
|
def conf_from_dict(conf_dict):
|
||||||
conf = Config()
|
conf = Config()
|
||||||
|
|
||||||
@@ -138,6 +142,7 @@ def conf_from_dict(conf_dict):
|
|||||||
conf()
|
conf()
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
|
|
||||||
def import_module(conf):
|
def import_module(conf):
|
||||||
if conf.endswith('.py'):
|
if conf.endswith('.py'):
|
||||||
conf = conf[:-3]
|
conf = conf[:-3]
|
||||||
@@ -164,17 +169,20 @@ def import_module(conf):
|
|||||||
|
|
||||||
return conf_mod
|
return conf_mod
|
||||||
|
|
||||||
|
|
||||||
def initconf():
|
def initconf():
|
||||||
import default_config
|
import default_config
|
||||||
conf = conf_from_module(default_config)
|
conf = conf_from_module(default_config)
|
||||||
conf()
|
conf()
|
||||||
return conf
|
return conf
|
||||||
|
|
||||||
|
|
||||||
def set_config(name):
|
def set_config(name):
|
||||||
if '/' in name:
|
if '/' in name:
|
||||||
_runtime_conf.update(conf_from_file(name))
|
_runtime_conf.update(conf_from_file(name))
|
||||||
else:
|
else:
|
||||||
_runtime_conf.update_with_module(name)
|
_runtime_conf.update_with_module(name)
|
||||||
|
|
||||||
|
|
||||||
_runtime_conf = initconf()
|
_runtime_conf = initconf()
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ class TestConf(TestCase):
|
|||||||
self.assertEqual(conf.server.host, '1.1.1.1')
|
self.assertEqual(conf.server.host, '1.1.1.1')
|
||||||
self.assertEqual(conf.server.port, '8081')
|
self.assertEqual(conf.server.port, '8081')
|
||||||
|
|
||||||
|
|
||||||
def test_update_set_default_config(self):
|
def test_update_set_default_config(self):
|
||||||
"""Update an empty configuration with the default values"""
|
"""Update an empty configuration with the default values"""
|
||||||
|
|
||||||
@@ -50,7 +49,6 @@ class TestConf(TestCase):
|
|||||||
|
|
||||||
def test_update_force_dict(self):
|
def test_update_force_dict(self):
|
||||||
"""Update an empty configuration with the default values"""
|
"""Update an empty configuration with the default values"""
|
||||||
|
|
||||||
conf = configuration.initconf()
|
conf = configuration.initconf()
|
||||||
conf.update_with_module('forcedict')
|
conf.update_with_module('forcedict')
|
||||||
|
|
||||||
@@ -62,11 +60,11 @@ class TestConf(TestCase):
|
|||||||
self.assertEqual(conf.server.host, '0.0.0.0')
|
self.assertEqual(conf.server.host, '0.0.0.0')
|
||||||
self.assertEqual(conf.server.port, '8080')
|
self.assertEqual(conf.server.port, '8080')
|
||||||
|
|
||||||
self.assertEqual(type(conf.beaker), dict)
|
self.assertTrue(isinstance(conf.beaker, dict))
|
||||||
self.assertEqual(conf.beaker['session.key'], 'key')
|
self.assertEqual(conf.beaker['session.key'], 'key')
|
||||||
self.assertEqual(conf.beaker['session.type'], 'cookie')
|
self.assertEqual(conf.beaker['session.type'], 'cookie')
|
||||||
self.assertEqual(conf.beaker['session.validate_key'], '1a971a7df182df3e1dec0af7c6913ec7')
|
self.assertEqual(conf.beaker['session.validate_key'], '1a971a7df182df3e1dec0af7c6913ec7')
|
||||||
self.assertTrue(conf.beaker.get('__force_dict__'), None)
|
self.assertEqual(conf.beaker.get('__force_dict__'), None)
|
||||||
|
|
||||||
def test_update_config_fail_bad_attribute(self):
|
def test_update_config_fail_bad_attribute(self):
|
||||||
conf = configuration.initconf()
|
conf = configuration.initconf()
|
||||||
@@ -124,6 +122,9 @@ class TestConf(TestCase):
|
|||||||
configuration.set_config('config')
|
configuration.set_config('config')
|
||||||
self.assertEqual(_runtime_conf.server.host, '1.1.1.1')
|
self.assertEqual(_runtime_conf.server.host, '1.1.1.1')
|
||||||
|
|
||||||
|
def test_config_set_from_module_with_extension(self):
|
||||||
|
configuration.set_config('config.py')
|
||||||
|
self.assertEqual(_runtime_conf.server.host, '1.1.1.1')
|
||||||
|
|
||||||
def test_config_string(self):
|
def test_config_string(self):
|
||||||
s = '{pecan.conf.app}'
|
s = '{pecan.conf.app}'
|
||||||
|
|||||||
Reference in New Issue
Block a user