[Zope3-dev] Re: IMPORTANT: How to look up adapters
Tres Seaver
tseaver at zope.com
Fri Jul 2 12:27:59 EDT 2004
Jim Fulton wrote:
>
> For simple adaptation, where you adapt a single object to a single
> interface without a name providing qualification, you should call the
> interface:
>
> adapter = iface(ob)
>
> If you want to provide a default to be used if the adapter
> can't be found, just pass it as an additional argument:
>
> adapter = iface(ob, default)
>
> Note that if the object already provides the interface, then
> the object is returned. Otherwise, if the object conforms
> to the interface (has a __conform__ that returns a non-None
> value for the interface), then the __conform__ method will
> be used to create the adapter.
>
> This syntax has only been around for a couple of months.
> It appears that a number of people haven't heard about it,
> as I've recently noticed new code using the old syntax:
>
> adapter = getAdapter(ob, iface)
>
> We have a problem with the old syntax.
>
> We used to have four functions, getAdapter, queryAdapter,
> getNamedAdapter, queryNamedAdapter. The "Named" methods had
> different sematics than the non-"Named" methods. The non-
> "Named" methods would return the object if the object already
> provided the interface. They would also return the result of
> calling the __conform__ method on the object, if present and if
> it's result was not None. The "Named" methods didn't consider
> whether the object aleady provided or conformed to the interface.
> The rational for this was that the name in a named-adapter
> lookup is an interface qualifier. An object cannot provide
> or conform to a qualified interface. A qualifid interface
> can only be provided through adapter lookup.
>
> Now it happens that the un-"Named" methods allowed a name argument
> to be provided. This was for backward compatability and lasted
> much longer than it should have. They generated deprecation warnings
> if non-empty names were provided.
>
> In an attempt to simplify the API just before the beta, the "Named"
> and un-"Named" methods were incorrectly merged. This was based on the
> observation that they both seemed to take the same arguments. I
> wasn't paying close enough attention and OKed this. :( This led
> to the following problem. With the current remaining
> queryAdapter and getAdapter functions, the name argument is ignored if
> the object provides or conforms to the interface. This is a latent
> bug that hasn't bitten us yet, AFAIK, because we aren't making very heavy
> use of named adapters yet. This will be more of a problem in the future.
>
> There are two ways I can fix this:
>
> 1. I can add back the "Named" methods and remove the name argument
> from the un-"Named" methods.
>
> 2. I can give the current un-"Named" methods the semantics of the
> old "Named" methods. This means that queryAdapter and getAdapter
> will no longer consider whether an object provides or conforms to an
> interface.
>
> We don't really need to call getAdapter or queryAdapter to
> get the old behavior, because we can just call the interfaces.
> Being able to get a simple adapter either by calling get/queryAdapter
> or by calling the interface violates Python's "one way to do it"
> philosophy.
>
> There is one case where calling an interface isn't equivalent to
> get/queryAdapter. If you want to supply a context argument to specify
> a different place to look up adapters, you can't pass it to the
> interface. This is an extreme edge case. I know of no place in the
> Zope 3 tree where this is needed, but it is something we want to
> allow. I propose to provide new functions: getSpecialAdapter and
> querySpecialAdapter. These functions will require a context to be
> specified and will return the object if it provides the requested
> interface and will use __conform__ if it conforms to the interface.
How about 'getAdapterInContext' and 'queryAdapterInContext', instead?
> Both of these options are backward inconpatible. While I'm not happy about
> doing this after the beta, it's better than doing it after the final
> release.
>
> I prefer option 2 because:
>
> - It provides a single way to do simple adaptation
>
> - It provides simpler names for named-adapter lookup, which
> are more consistent with multi-adapter (also named) lookup.
>
> - It requires the least code change.
>
> It's unclear which option is the least impact on add-on
> software. I don't know how many people are still doing
> simple-adapter lookup with getAdapter and queryAdapter.
> With the change, these calls will break, because the name
> argument will be required. On the one hand, breakage is bad,
> but, the breakage should be obvious.
>
> I'm going to go ahead and do this (ootion 2). Perhaps I'll
> change my mind if there are loud objections, but I hope there
> won't be. :)
+1 on the general plan.
Tres.
--
===============================================================
Tres Seaver tseaver at zope.com
Zope Corporation "Zope Dealers" http://www.zope.com
More information about the Zope3-dev
mailing list