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

Chris McDonough chrism at plope.com
Tue Nov 24 00:40:05 EST 2009


Martin Aspeli wrote:
> We need to make sure that we're not inventing a different way to achieve 
> something which is already possible. This will lead to confusion, 
> because people will have to know "which way" is applicable in a given 
> situation, and the distinction will seem arbitrary.

I fear we are indeed inventing a different way to achieve something which is 
already possible.  We aren't doing it arbitrarily, though: the current way just 
requires the use of an interface instead of a string.  Interface usage for such 
a simple pattern implies a cognitive load that appears to exceed the pain point 
of most Python developers who are not already familiar with Zope.  So we'd like 
to ameliorate that as best we can.

  >> 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.
> 
> I think there is a reason, though you may not agree it's a good one. The 
> interface makes a promise about what the component is supposed to be 
> able to do. We don't enforce that in our duck-typing programming 
> language, but I think there is value in being able to say, "I want an 
> object that conforms to this interface (i.e. delivers what the interface 
> promises) - please get me the best one you've got".

That is indeed the promise.  But obviously the object you get back needn't 
*actually* implement the interface you asked for; it's only conventional.  It 
is the same with a dictionary lookup: if you document that, for your 
application, reg['root_factory'] will return an object implementing 
IRootFactory, it's pretty much equivalent as far as I can tell.  Use of the ZCA 
API to store and retrieve instances implementing an interface isn't required to 
get benefit out of the existence of that interface.

>> 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.
> 
> I whole-heartedly agree, and I think it's important that we use the 
> momentum behind BFG (and other consumers of the ZTK) to drive the ZTK 
> forward. Anything else would be stupid.
> 
> I'm still concerned that your proposal basically leaves us with two ways 
> of implementing the singleton pattern with the ZCA, and I'm not sure 
> that's in our best interest. I'd be interested to hear your thoughts 
> further, though.

I guess I can only point at the rationales in 
<http://docs.repoze.org/bfg/1.1/designdefense.html#bfg-uses-the-zope-component-architecture-zca>

> Off the top of my head, another way to think of this *might* be to say 
> that the 'dict access' is basically looking up a *named* utility 
> providing a very generic marker interface, e.g. 
> zope.component.interfaces.IUtility or even just 
> zope.interface.Interface. That way reg['foo'] == getUtility(IUtility, 
> name='foo'). Obviously, assignment would register in the same way.
> 
> I'm not sure it's "better", though. :)

That would also be fine, and it would normalize things a bit, although the 
implementation would be harder and it would result in slower lookups.  But if 
it made folks feel better than inheriting from dict, I'd be +1 on it.

- C


More information about the Zope-Dev mailing list