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

Chris McDonough chrism at plope.com
Mon Nov 23 23:03:44 EST 2009


Matthew Wilkes wrote:
> Hi Chris,
> 
> On 2009-11-24, at 0324, Chris McDonough wrote:
> 
>> In repoze.bfg, we've actually decided to use a subclass of the component
>> registry which also inherits from "dict".  This makes it possible to 
>> spell
>> common unnamed "utility" registrations and lookups as:
>>
>> utility = SomeUtilityImplementation()
>> registry['someutility'] = utility
> 
> While I'm all for simplification, this makes very little sense to me.  
> If this is an unnamed registration why is there a name ('someutility') 
> involved?
> 
> If it was a named registration against Interface, or if the key was an 
> interface/dotted name that'd make sense.

You may have Zope Component Developer's Eyes, a common disease in these parts. ;-)

If you haven't already, you might take a look at the example after the 
paragraph that starts with "But we recognize that developers who my want to 
extend the framework..." within:

<http://docs.repoze.org/bfg/1.1/designdefense.html#ameliorations>

> Could you expand on what the key is supposed to represent?

Sure.  Let's take an example from repoze.bfg itself.

repoze.bfg allows an application developer to register a "root factory" for a 
given application.  There is only ever one of these for any application, and 
thus only one ever needs to be registered.

For purposes of example, a root factory might be the "root" method of a 
particular ZODB connection, e.g. "root = conn.root()".  It's a callable that 
returns the sole root object for a given application.  For purposes of example, 
let's pretend it's this:

   def root_factory(environ):
       return {}

Under the hood, the system does something like this when a root factory needs 
to be registered:

   from repoze.bfg.interfaces import IRootFactory
   from zope.component import getSiteManager

   reg = getSiteManager()
   reg.registerUtility(root_factory, IRootFactory)

Then when the system needs to look it up again, it needs to do this:

   root_factory = getUtility(IRootFactory)

If you notice, there is no "key" for this utility other than the IRootFactory 
interface (it's unnamed).  In this case, also, there will never be a 
registration made against a subclass of IRootFactory.  In this scenario, if we 
weren't using ZCA at all, we'd probably do something like this:

   reg = get_some_registry()
   reg['root_factory'] = root_factory

In a system like this, there are no interfaces; the string 'root_factory' 
performs the same job as the IRootFactory interface for registration and 
lookup.  I'd like to make the ZCA registry operate like this.  There's really 
no reason for there to be an interface hanging around to represent this thing: 
we're using the ZCA as a complicated dictionary here.

It would also obviously be possible to just add a dictionary instance attribute 
to a registry, so instead of subclassing Components from dict, you might do:

reg = getSiteManager()
reg.simple['root_factory'] = root_factory

To be honest, I don't mind one way or another; I'd just like to push whatever 
we do upstream if possible.  If we move too far away from the stock ZCA 
facilities, it becomes harder to integrate Zope apps into BFG and vice versa.

- C



More information about the Zope-Dev mailing list