[Zope-dev] Interfaces vs ZCA concepts

Tres Seaver tseaver at palladion.com
Tue Dec 15 17:40:13 EST 2009


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Martijn Faassen wrote:
> Hey,
> 
> Good to see there's progress!
> 
> Thomas Lotze wrote:
> [snip]
>> Except that I don't like the implications now that I have actually written
>> down the code. I'll describe the problem I see and then suggest an idea that I
>> don't think we've been considering in the discussion two weeks ago:
>>
>> We're intentionally leaking the concept of utilities to zope.interface.
>> Assuming we're entirely fine with this, we still need to decide how much of
>> the particulars of the ZCA we want to bring along: named components, lookup
>> contexts, the ComponentLookupError. My current implementation tries to
>> introduce enough generic behaviour into the `adapt` and `utility` methods so
>> that they don't cause too obvious (conceptual) dependencies of zope.interface
>> on zope.component:
>>
>> * `adapt` and `utility` don't define particular optional arguments but pass
>>   all keyword parameters except for `default` to the component hook which,
>>   being implemented by zope.component, keeps the knowledge about named
>>   adapters and lookup contexts within the latter package.
>>
>> * The hook invokes the `query*` functions to play nice with any other
>>   component hooks and the interface methods raise a TypeError if all of them
>>   fail to find a component.
> 
> A TypeError instead of a ComponentLookupError?
> 
> I was thinking we should keep the behavior as close to zope.component as 
> we can, including ComponentLookupError. Don't you get a 
> ComponentLookupError with the classic adapter hook too? So I'm -1 to 
> making this a TypeError.

+1 to TypeError:  nobody really cares about the type of the error:  code
that wants to be robust about a failure uses the 'query' methods.  As
long as the message is informative enough (which ComponentLookupError
isn't, really) we should be fine.  If we made CLE derive from TypeError,
we could even still be satisfying the contract.

>> However, the generic behaviour gets in our way: the method signatures become
>> useless and hooks lose the possibility of raising useful exceptions.
>>
>> I've tried some variations but as long as the `adapt` and `utility` methods
>> are actually implemented by zope.interface, it will always come down to a
>> compromise that either renders the new methods unusable with anything that's
>> not very much like zope.component, or makes for a half-hearted copy of the
>> functionality we currently have in the zope.component API.
>>
>> I discussed this a bit with Wolfgang as we both don't like this kind of
>> compromise in such core functionality. We came up with the idea that a clean
>> solution would be to keep any implementation of the two methods out of
>> zope.interface and rather inject them into the interface API by code kept
>> entirely within zope.component. We do realise how close to the concept of
>> monkey-patching this comes, but maybe it wouldn't be so bad if we could do it
>> in a more structured way (being intentionally vague here yet).
> 
> I think a monkey patch would be fine. Opinions about making it more 
> structured:

Setting a hook using an API is *not* a "monkey patch":  that term
implies munging a module / class without its knowledge or consent.

> * have dummy implementations in zope.interface that raise 
> NotImplementedError
> 
> * have that NotImplementedError say to look for implementations in 
> zope.component
> 
> * have the docstring of these methods also talk about zope.component
> 
> * have the docstring on the methods that are injected be clear that they 
> are being injected into zope.interface
> 
> That way someone reading the zope.interface code can at least find out 
> that this functionality is injected from zope.component.

- -1 to monkey patching:  I would favor exposing an API in zope.interface
which allowed this kind of pluggability.

> [as an aside it'd be interesting to find out how much of of 
> zope.component functionality could sensibly make it into zope.interface, 
> but that's another project; Gary Poster has some ideas in relation to this]
> 
>> In particular, keeping the concrete `adapt` and `utility` methods out of the
>> core implementation of interfaces would address the concern raised by somebody
>> on this list that we were going to tailor zope.interface too much to the needs
>> of the Zope ecosystem. Uses of interfaces other than adaptation and component
>> lookup could get convenience methods registered by the same mechanism
>> zope.component would end up employing, which is a big conceptual advantage
>> from my point of view.
>>
>> What do people think of this?
> 
> I'm +1 on this general approach. Implementation in zope.component, and 
> inject it into zope.interface during import time.

Not at import time, please:  better to have this happen during startup
(e.g., just before bootstrapping configuration from ZCML or martian).

> I'm still sneakily hoping that in a few years we'll be able to get 
> calling the interface be the one true way of looking up implementations 
> of that interface (utilities and adapters and whatnots), but we'll see.

Me too.



Tres.
- --
===================================================================
Tres Seaver          +1 540-429-0999          tseaver at palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAksoEE0ACgkQ+gerLs4ltQ4cnwCg2LVFDkFJTAujLljTIQDRydWW
sUgAnjJtoGDbmOpOfH3SXy0gisGGn6dp
=nLjA
-----END PGP SIGNATURE-----



More information about the Zope-Dev mailing list