[Zope-dev] make zope.component.registry.Components inherit from dict?

Chris McDonough chrism at plope.com
Tue Nov 24 01:22:11 EST 2009


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



More information about the Zope-Dev mailing list