Skip to content

Commit

Permalink
introduce strict concept to config... now mocking config sections by …
Browse files Browse the repository at this point in the history
…default
  • Loading branch information
mjdorma committed Aug 10, 2013
1 parent 8c506d7 commit c0b5757
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
16 changes: 12 additions & 4 deletions funconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ def wrapper(**kwargs):
for k in kwargs_set.difference(func_defaults_set):
kwargs.pop(k)
return func(**kwargs)

funcsig = signature(func)
parameters = []
for arg, param in funcsig.parameters.items():
Expand Down Expand Up @@ -446,19 +447,23 @@ class Config(MutableMapping):
the defaults of a variable kwargs function.
"""

__slots__ = ('_sections', '_reserved', '_lookup')
__slots__ = ('_sections', '_reserved', '_lookup', '_strict')

def __init__(self, filenames=[]):
def __init__(self, filenames=[], strict=False):
"""Construct a new Config object.
This is the root object for a function configuration set. It is the
container for the configuration sections.
:param filenames: YAML configuration files.
:type filenames: list of filepaths
:param strict: Raise :py:class:`ConfigAttributeError` if a
:py:class:`ConfigSection` doesn't exist
:type strict: False
"""
self._sections = {}
self._lookup = {}
self._strict = strict
self.read(filenames)

def read(self, filenames):
Expand Down Expand Up @@ -547,8 +552,11 @@ def __getattribute__(self, y):
return super(Config, self).__getattribute__(y)
else:
if y not in self._sections:
msg = "Config object has no section '%s'" % (y)
raise ConfigAttributeError(msg)
if not self._strict:
self._sections[y] = ConfigSection(y, {})
else:
msg = "Config object has no section '%s'" % (y)
raise ConfigAttributeError(msg)
return self._sections[y]

def __setattr__(self, x, y):
Expand Down
11 changes: 9 additions & 2 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ def test_print_config(self, mock_open):
self.assertEqual(len(config.bbb), 4)

@patch('__builtin__.open')
def test_accessing_attributes(self, mock_open):
def test_accessing_strict_attributes(self, mock_open):
mock_open.return_value = StringIO(TEST_CONFIG)
config = funconf.Config('mocked.conf')
self.assertEqual(config.aaa.int, 4)
config.aaa.int = 5
self.assertEqual(config.aaa.int, 5)
self.assertRaises(funconf.ConfigAttributeError, getattr, config, 'nope')
self.assertRaises(funconf.ConfigAttributeError, getattr, config.aaa,
'nope')

Expand All @@ -87,6 +86,14 @@ def test_broken_yaml(self, mock_open):
self.assertRaises(yaml.scanner.ScannerError,
funconf.Config, 'mocked.conf')

def test_strict_config(self):
config = funconf.Config(strict=True)
self.assertRaises(funconf.ConfigAttributeError, getattr, config, 'nope')

def test_not_strict_config(self):
config = funconf.Config()
self.assertTrue(dict(config.foo) == {})

def test_file_doesnt_exist(self):
funconf.Config(['blaoo.con'])

Expand Down

0 comments on commit c0b5757

Please sign in to comment.