Matthew Wilkes wrote:
On 2009-11-24, at 0521, Chris McDonough wrote:
I don't think I understand. Could you provide an example?
Sure!
I think this is the same thing that Martin suggested, but here's some code which should make it clearer.
First, we create an object that we want to be accessible from this lookup:
class Root(dict): pass
Then, we register that as a utility in the global site manager
manager = zope.component.getGlobalSiteManager() manager.registerUtility(Root(), zope.interface.Interface, name="root")
This can then be found with:
manager.getUtility(zope.interface.Interface, name="root")
As you can see, the special interface code has disappeared, leaving things only keyed on a string, the utility name.
We can then set up an adapter, something like this:
from zope.interface import Interface, implements from zope.component import adapts from zope.component.interfaces import IComponentRegistry
class IDictInterface(Interface):
def __getitem__(key): pass
def __setitem__(key, value): pass
def __delitem__(key): pass
class DictInterface(object):
implements(IDictInterface) adapts(IComponentRegistry)
def __init__(self, manager): self.manager = manager
def __getitem__(self, key): return self.manager.getUtility(Interface, name=key)
def __setitem__(self, key, value): self.manager.registerUtility(value, Interface, name=key)
def __delitem__(self, key): self.manager.unregisterUtility(provided=Interface, name=key)
manager.registerAdapter(DictInterface)
(N.B: rough sample code)
Once you have one of these objects instantiated your example code will work fine:
def root_factory(environ): ... return {} ... reg=IDictInterface(zope.component.getGlobalSiteManager()) reg['root_factory'] = root_factory print reg['root_factory'] <function root_factory at 0x100628e60> print zope.component.getUtility(zope.interface.Interface, name="root_factory") <function root_factory at 0x100628e60>
Thanks. Yup. I would be +1 on this if the registry itself implemented IDictInterface. If that was untenable, if all the above code lived in the zope.component package itself, and you had an API that manifested an IDictInterface object when you asked for a "utilities" attribute, that would also be acceptable, as long as you could do: reg.utils['root_factory'] = RootFactory Where the registry implementation would implement a propery for "utils": class Components(object): @property def utils(self, name): api = self.queryAdapter(IDictInterface, None) if api is None: api = DictInterface(self) return api In reality, this will be slow, and nobody is going to override IDictInterface, so it would probably be better as: class Components(object): def __init__(self, name='', bases=()): self.utils = DictInterface(self) - C