Hi, this is a long message with a lot of replies to things that I don't agree with. Since I realize that making those points over and over again doesn't get us anywhere, I'd like to point out first that I'm going to implement Martijn's suggestions anyway on one of my branches, hoping that seeing more actual code to talk about might help getting to more consensus.
Martijn Faassen wrote: >>> * It'd be nice if __call__ came back with a LookupError instead of a >>> TypeError, but how to get from A to B without breakage? >> >> It's not possible without breakage. > > Unless we create a zope.interface specific LookupError which subclasses > both the built-in LookupError and TypeError. zope.component's > ComponentLookupError should subclass this special LookupError then. Technically true, so my statement was admittedly too strong. I just don't feel comfortable with the idea, which may well be just because it's the "let's make both exceptions work sowmehow" solution to me instead of the clear change I thought we were considering. OTOH, it's not that big an issue either, so I guess I'd be fine with it. >>> * the methods can be on zope.interface even if zope.component isn't >>> installed. They will behave as if the component registry is empty. >> >> This isn't covered by the consensus you mentioned above as far as I'm >> concerned. > > Yeah, I put that in so we can reach consensus on it. I thought Tres had a > good idea going on there that makes the plugin behavior a lot cleaner. Hm, I can't help feeling pushed into this. While this plugin stuff is indeed nice *assuming* that we want all the zope.component concepts in zope.interface, it doesn't contribute to the decision about *whether* we want that in the first place. >>> IFoo.adapt(context) raises LookupError, unless the context provides >>> IFoo, in which case it returns context. >>> >>> IFoo.adapt(context, default=default) returns default unless context >>> provides IFoo, in which case it returns context. >>> >>> IFoo.utility() raises LookupError. >> >> IFoo.utility(default=default) returns default >> >> I think looking at that API explains why we have trouble with having >> stub methods defined by zope.interface: these methods contain enough >> information about component concepts to blur the distinction between >> zope.interface and zope.component, but they still lie about the actual >> method signature. > > I don't understand you: why do you say they lie about their method > signature? They should have the same signature and have a well-defined > behavior if zope.component is not installed: there is nothing registered > at all. zope.interface provides a plugin point that allows one to plug > lookup behavior into it. When I wrote that, I was assuming that we were talking about patching interfaces with methods that have zope.component's full lookup semantics, including `name` and `context` parameters - which abviously would change the signatures. If we're talking about something that doesn't add those parameters, there's no lie involved but I don't see how our lookup methods could then access the full feature set of zope.component's lookups. > In that case, I want the real contract to be in zope.interface. That's > where the methods are, after all. We need to talk about the concept of an > adapter and a utility briefly in zope.interface and defer to > zope.component as the most common implementation. We already have this > kind of behavior going on anyway with __call__() (even though not > documented!). Well, we obviously disagree completely about this. The existing __call__ method is neither a good example of a zope.component lookup API, nor do I think that it was fortunate to wire up the adaptation concept in zope.interface through __call__ in the first place. I'd rather try to loosen this reference to component concepts than use it as a reason for adding more. > You'll have to go into more detail. Why does it feel wrong to you? Because it is just another way of encoding the zope.component details within zope.interface. I would love to add a plugin API that is generic enough to apply equally to other uses of interfaces than component lookup, and that would allow implementations of component lookup with different concepts and different lookup methods than those of zope.component. > Why is it a problem that the zope.interface package gains knowledge about > adaptation (which it always had, anyway) (and which, IMO, it shouldn't have in the first place) > and utility lookup? Because if we're serious about making interfaces more of a language feature, they should at their core be reduced to *being* mostly information (maybe with a bit of verification code) instead of extended to *doing* things that derive mainly from *our* particular ways of using them. > Because to > the user of those methods on Interface, it looks exactly like the > packa > does have such knowledge. We shouldn't lie.ge I don't think that we lie as long as we state that we have a plugin system of any kind (including monkey-patching, for the sake of discussion). Speaking about lies again, I also consider it a kind of lie to say that we provide a plugin system if it turns out in the end that it isn't much good for anything but the one particular plugin provided by zope.component. > In fact, let me propose the following plugin point instead, reducing it to > a single method: > > class ILookupPlugin(Interface): > def lookup(interface, contexts): > """Look up an object that provides interface, given contexts. > > contexts may be an empty list, or contain one or more entries. > > Raises LookupError if an object providing the interface cannot be > found. > """ > > Then __call__ and adapt and utility can be implemented by using > "lookup()". Anything plugging into zope.interface would then have to only > plug in a single method. Would this in your mind still include a list of hooks whose behaviour needs to be coordinated by the Interface methods (which affects at least how exceptions are caught or propagated), or are we talking about a single plugin being registered at a time? I'd prefer the latter as it's more straight-forward. Or are there really compelling use cases for registering more than one hook at the same time? -- Thomas _______________________________________________ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )