[PEAK] FYI: bug in binding.Component and config.ConfigMap
Phillip J. Eby
pje at telecommunity.com
Mon Aug 30 00:33:26 EDT 2004
I just discovered a problem with binding.Component and config.ConfigMap
with respect to their "lazy immutability". If you use e.g. config.lookup()
or other mechanism to search for a configuration value, and an individual
Component has no value specified for that key, this does *not* preclude you
from later defining that key.
This is a pretty serious error, from the point of view of PEAK's design
goals, but if you're not aware of this, you may actually have written code
that relies on this faulty behavior.
>>> from peak.api import *
>>> root = config.makeRoot()
>>> c = binding.Component(root)
>>> t1 = config.lookup(c, storage.ITransactionService)
>>> t2 = config.lookup(c, storage.ITransactionService)
>>> t1 is t2
As you can see, we created a *new* transaction service, and registered it
with a component that we previously tried to look up a transaction service
for. What *should* have happened is that the 'registerProvider()'
operation should have raised an 'AlreadyRead' exception, indicating that
some code has already relied on finding 't1'. It should not be possible to
then change to using 't2' instead, since this leads to an inconsistent
This problem only occurs when *no* providers of any kind have been
registered with the component instance. At some point I put in some code
to avoid "unnecessarily" creating a configuration map for individual
components during lookups. This "saves" creating a configuration map for
every component, at the cost of a possibly inconsistent configuration view.
Unfortunately, the fix is high-impact: changing it to the correct behavior
may significantly increase memory consumption for binding.Component
subclasses. It will also slow down some configuration lookups. And
finally, it will break code that relies on the current behavior.
Therefore, I just wanted to give everybody a heads-up that I intend to fix
this behavior, because it has the potential to create extremely
hard-to-find configuration bugs, where some components see a different
configuration than others, depending on *when* they did their lookups.
More information about the PEAK