provide short-hand syntax for config with repeated entries for one section

git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2057 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-09-19 07:23:35 +00:00
parent d131771839
commit 9d888cefe8
3 changed files with 55 additions and 10 deletions

View file

@ -80,7 +80,7 @@ it with a default if not found, in one statement.
'loops'
>>> sorted(config.transport.items())
[('serverURL', 'http://loops.cy55.de'), ('userName', 'loops')]
[('__name__', 'transport'), ('serverURL', 'http://loops.cy55.de'), ('userName', 'loops')]
We can output a configuration in a form that is ready for loading
just by converting it to a string representation.
@ -112,11 +112,22 @@ for storage; normally it would be stored in the users home directory.
transport.userName = 'loops'
ui.web.port = 8081
Cleaning up up...
The simplified syntax
---------------------
>>> config.load('''
... ui(
... web(
... port=11080,
... ))''')
>>> print config.ui.web.port
11080
Cleaning up
-----------
>>> os.unlink(fn)
Scheduling
==========

View file

@ -27,15 +27,21 @@ from zope.interface import implements
from loops.agent.interfaces import IConfigurator
class Configurator(object):
_not_found = object()
class Configurator(dict):
implements(IConfigurator)
def __init__(self, *sections, **kw):
for s in sections:
setattr(self, s, ConfigSection())
setattr(self, s, ConfigSection(s))
self.filename = kw.get('filename')
def __getitem__(self, key):
return getattr(self, key, ConfigSection(key))
def load(self, p=None, filename=None):
if p is None:
fn = self.getConfigFile(filename)
@ -45,7 +51,7 @@ class Configurator(object):
f.close()
if p is None:
return
exec p in self.__dict__
exec p in self
def save(self, filename=None):
fn = self.getConfigFile(filename)
@ -78,8 +84,14 @@ class Configurator(object):
class ConfigSection(list):
__name__ = '???'
def __init__(self, name=None):
if name is not None:
self.__name__ = name
def __getattr__(self, attr):
value = ConfigSection()
value = ConfigSection(attr)
setattr(self, attr, value)
return value
@ -99,12 +111,28 @@ class ConfigSection(list):
if isinstance(value, (str, int)):
yield name, value
def __call__(self, *args, **kw):
for s in args:
if isinstance(s, ConfigSection):
# should we update an existing entry?
#old = getattr(self, s.__name__, None)
#if old is not None: # this would have to be done recursively
# old.__dict__.update(s.__dict__)
# for elem in s:
# old.append(elem)
#else:
# or just keep the new one?
setattr(self, s.__name__, s)
for k, v in kw.items():
setattr(self, k, v)
return self
def collect(self, ident, result):
for idx, element in enumerate(self):
element.collect('%s[%i]' % (ident, idx), result)
for name, value in self.__dict__.items():
if isinstance(value, ConfigSection):
value.collect('%s.%s' % (ident, name), result)
elif isinstance(value, (str, int)):
elif name != '__name__' and isinstance(value, (str, int)):
result.append('%s.%s = %s' % (ident, name, repr(value)))

View file

@ -13,9 +13,13 @@ from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.trial import unittest
from loops.agent.core import Agent
from loops.agent.schedule import Job
try:
from loops.agent.core import Agent # needs twisted.internet.task.coiterate
ignore = False
except ImportError: # wrong environment, skip all loops.agent tests
print 'Skipping loops.agent'
ignore = True
baseDir = os.path.dirname(__file__)
@ -57,6 +61,8 @@ class Test(unittest.TestCase):
def test_suite():
if ignore:
return standard_unittest.TestSuite() # do nothing
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
return standard_unittest.TestSuite((
#standard_unittest.makeSuite(Test),