mozilla/configman — pull request #29 by twobraids (2012-03-23 23:32:26+00:00)
Title: Parentage

One of the interesting problems that I've encountered in working with configman is that class instantiated from references need to have configuration information about themselves as well as global configuration. For example, let's say we have this hierarchy

config
config.logger
config.source
config.source.class1
config.source.class1.kls
config.source.class1.param1
config.source.class1.param2

where 'n', 'source' and 'class1' are all namespaces. 'logger' is an object to do logging. 'kls' is a python class. 'param1' and 'param2' are requirements of the class in 'kls'.

if we try to instantiate 'kls', we're tempted to do so like this:

config.source.class1.kls(config)

but that would be wrong. 'kls' will end up looking for its requirements 'param1' and 'param2' directly in 'config' rather than way down the hierarchy in 'config.source.class1'. 'kls' doesn't know where it is in the hierarchy. The correct way to instantiate 'kls' is like this:

config.source.class1.kls(config.source.class1)

that aims 'kls' at the right level of the hierarchy to find its parameters. Unfortunately, that cuts off 'kls' from the opportunity to use parameters (like 'logger') found all the way down in 'config'.

The solution proposed here is to back thread the config hierarchy with weakref references to parents. This change adds two private parameters to each level of the hierarchy: '_parent' is a reference to the parent dict; '_root' - a reference to the base dict of the hierarchy.

From the original hierarchy above, the 'kls' can access all it needs like this:

def __init__(self, config):
self.param1 = config.param1
self.param2 = config.param2
config._root..logger.info("done with instantiation")