[Zope-dev] implementing zope.component 4.0

Chris McDonough chrism at plope.com
Mon Nov 30 13:51:40 EST 2009


Shane Hathaway wrote:
> Martijn Faassen wrote:
>> Given some feedback about backwards compatibility, I'm leaning to the 
>> following adjusted scenario:
>>
>> * allow IFoo((a, b)) for multi adaptation. This breaks tuple adaptation. 
>> It's not as pretty as IFoo(a, b), but it's pretty tolerable and it *is* 
>> actually symmetric with registration.
>>
>> * deprecate a non-explicit default such as IFoo(a, default), require 
>> IFoo(a, default=default)
> 
> While this short spelling of component lookup is attractive and sensible 
> for Zopistas, I wonder if it ever really was the best idea.  When a 
> developer encounters the IFoo() pattern for the first time, what is 
> he/she going to type into a search engine to find out what it means?  I 
> can't think of any search phrase that is likely to give a good answer.

When he can't Google, a maintenance developer with no prior ZCA exposure 
literally sees "IFoo()" (without any args) is going to find the definition for 
"IFoo" and it will be a class.  He will believe that calling it will give him 
back an instance.  This is just consistent with all prior experience he has if 
he's a Python programmer.

Furthermore he'll believe he "owns" the resulting object, because normal 
classes are always constructors that create a new object.

It just can't be obvious to him that "IFoo()" will almost always return some 
"shared" object (a utility) that isn't an instance of the "class" defined by 
the IFoo definition.

And if a developer is doing maintenance work, he can't afford to track down the 
docs and become enraptured by the world we create where this isn't the case.

> JQuery has a similar issue, but because JQuery is a smaller framework, 
> the JQuery folks simply put that info right near the top of their 
> documentation.  I'm not sure we can do that quite as effectively.
> 
> For an alternate spelling, consider what happens when component lookup 
> fails: you get a ComponentLookupError.  "Lookup" is interesting.  It 
> doesn't yet have any meaning in zope.interface, so I think using a 
> method named lookup() would make code more comprehensible.  You would 
> use it like this:
> 
>  >>> IFoo.lookup(a)
> <SomeAdapter instance at ...>
>  >>> IFoo.lookup(a, b)
> <SomeMultiAdapter instance at ...>
>  >>> IFoo.lookup(c)
> Traceback...
> ComponentLookupError(...)
>  >>> IFoo.lookup(c, default='missing')
> 'missing'
>  >>> IMyUtility.lookup()
> <MyUtility instance at ...>
> 
> When developers encounter this for the first time, they might type 
> "zope.interface lookup" in a search engine.  That phrase has a 
> reasonable chance of hitting good documentation.

> What do you think?

+ 1 with the following caveat:

I think that method name should probably be "adapt"; "lookup"  should maybe be 
a separate method reserved for passing bare interfaces rather than objects 
which implement interfaces, e.g:

   >>> IFoo.lookup(IBar)
   <class FooBarAdapter>

This would be consistent with the nomenclature in the current zope.interface 
AdapterRegistry API.

If it would help to change the resulting error message to "adaptation error" 
when ".adapt" is called, e.g.:

   >>> IFoo.adapt(c, default='missing')
   Traceback...
   AdaptationError(...)

That would be possible too obviously through the magic of subclassing.

I think adding methods to the registry object with the same names but slightly 
different signatures would go hand in hand with such a change:

   class Components(...):
       def lookup(self, required, *provided, name=''):
           ...

       def adapt(self, required, *provided, name=''):
           ...


   sm = getSiteManager()
   sm.lookup(IFoo, IBar)
   sm.adapt(IFoo, bar)

- C



More information about the Zope-Dev mailing list