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

Chris McDonough chrism at plope.com
Tue Nov 24 00:21:06 EST 2009

Matthew Wilkes wrote:
>> 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.
> Right, but I think mixing the two is just going to be confusing.  Your 
> alternative spelling may well be useful, but only if it works within the 
> confines of the ZCA itself, otherwise you're just hijacking the 
> component root for your own (nefarious) purposes.
> A lookup keyed entirely on strings and not interfaces is perfectly 
> possible using the ZCA, just register your utility to provide 
> z.i.Interface and name it.  Your semantics are the same as the simple 
> dictionary use-case, but it doesn't force people to choose one means of 
> access over another.

I don't think I understand.  Could you provide an example?

> Creating shim methods for the dict-interface (or a useful subset) could 
> hook in registration, querying and unregistration of utilities in a 
> vaguely sensible way.
> But, here is where the ZCA eyes come back into play, I wouldn't add this 
> to the ZCA itself.  One reason being that Hanno's been working on a more 
> useful persistent component root for Zope that brings in bits of OFS, 
> hooking a dict in there would just be confusing.

I don't really have enough context to understand how it would be confusing, but 
I trust that it would.  Persistent registries are traversable?

> So, if only there was a way of specifying a new set of functions and 
> defining a way of mapping them onto an existing object…
> I'd say make an adapter that adds the dict interface as a wrapper around 
> named utilities and provide that to BFG users.  That way you don't 
> pollute the namespace of the ZCA object, interoperability with other 
> code is maintained and you get your user-friendly interface.

Using a helper wrapper for utility registration here is not useful if it 
requires the developer to understand interfaces, so such wrapper would need to 
look like this:

class UnnamedUtilityWrapper(object):
     def __init__(self, registry):
         self._mappings = {'root_factory':IRootFactory, 'settings':ISettings}
         self.registry = registry

     def __getitem__(self, name):
         return self.registry.getUtility(self._mappings[name])

     def __setitem__(self, name, value):
         return self.registry.registerUtility(value, self._mappings[name])

      ... the remainder of the dictionary interface ...

And that would just be silly from the perspective of someone reading the code 
for the first time.  It would be even more confusing if you came across it than 
would use of the ZCA registerUtility/getUtility APIs.

In practice, I don't actually find it very useful to register somthing that you 
know will be a singleton as a literal ZCA utility, anyway, because there's 
exactly one lookup pattern: set it, get it.  I don't think I've ever performed 
an unnamed utility lookup expecting that a "more specific" implementation of a 
utility might be returned because I've passed some subtype of a more general 
interface.  How about you?

On the other hand the registry in BFG is the single place that "contains 
configuration", and a root factory is definitely configuration.

Ok, so be it, we will diverge.  Shame, that, because it will mean that software 
libraries composed expecting the r.bfg registry may not work under Zope, 
further fracturing things.

- C

More information about the Zope-Dev mailing list