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' 'loops'
>>> sorted(config.transport.items()) >>> 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 We can output a configuration in a form that is ready for loading
just by converting it to a string representation. 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' transport.userName = 'loops'
ui.web.port = 8081 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) >>> os.unlink(fn)
Scheduling Scheduling
========== ==========

View file

@ -27,15 +27,21 @@ from zope.interface import implements
from loops.agent.interfaces import IConfigurator from loops.agent.interfaces import IConfigurator
class Configurator(object): _not_found = object()
class Configurator(dict):
implements(IConfigurator) implements(IConfigurator)
def __init__(self, *sections, **kw): def __init__(self, *sections, **kw):
for s in sections: for s in sections:
setattr(self, s, ConfigSection()) setattr(self, s, ConfigSection(s))
self.filename = kw.get('filename') self.filename = kw.get('filename')
def __getitem__(self, key):
return getattr(self, key, ConfigSection(key))
def load(self, p=None, filename=None): def load(self, p=None, filename=None):
if p is None: if p is None:
fn = self.getConfigFile(filename) fn = self.getConfigFile(filename)
@ -45,7 +51,7 @@ class Configurator(object):
f.close() f.close()
if p is None: if p is None:
return return
exec p in self.__dict__ exec p in self
def save(self, filename=None): def save(self, filename=None):
fn = self.getConfigFile(filename) fn = self.getConfigFile(filename)
@ -78,8 +84,14 @@ class Configurator(object):
class ConfigSection(list): class ConfigSection(list):
__name__ = '???'
def __init__(self, name=None):
if name is not None:
self.__name__ = name
def __getattr__(self, attr): def __getattr__(self, attr):
value = ConfigSection() value = ConfigSection(attr)
setattr(self, attr, value) setattr(self, attr, value)
return value return value
@ -99,12 +111,28 @@ class ConfigSection(list):
if isinstance(value, (str, int)): if isinstance(value, (str, int)):
yield name, value 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): def collect(self, ident, result):
for idx, element in enumerate(self): for idx, element in enumerate(self):
element.collect('%s[%i]' % (ident, idx), result) element.collect('%s[%i]' % (ident, idx), result)
for name, value in self.__dict__.items(): for name, value in self.__dict__.items():
if isinstance(value, ConfigSection): if isinstance(value, ConfigSection):
value.collect('%s.%s' % (ident, name), result) 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))) 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.internet.defer import Deferred
from twisted.trial import unittest from twisted.trial import unittest
from loops.agent.core import Agent
from loops.agent.schedule import Job 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__) baseDir = os.path.dirname(__file__)
@ -57,6 +61,8 @@ class Test(unittest.TestCase):
def test_suite(): def test_suite():
if ignore:
return standard_unittest.TestSuite() # do nothing
flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
return standard_unittest.TestSuite(( return standard_unittest.TestSuite((
#standard_unittest.makeSuite(Test), #standard_unittest.makeSuite(Test),