1.1.6.1 Convenience Declarations in Class, Interface and Module Bodies

Adapters, interfaces, and protocol implementations are usually defined in Python class statements. To make it more convenient to make protocol declarations for these classes, the protocols package supplies the advise() function. This function can make declarations about a class, simply by being called from the body of that class. It can also be called from the body of a module, to make a declaration about the module.

advise( **kw)
Declare protocol relationships for the containing class or module. All parameters must be supplied as keyword arguments. This function must be called directly from a class or module body, or a SyntaxError results at runtime. Different arguments are accepted, according to whether the function is called within a class or module.

When invoked in the top-level code of a module, this function only accepts the moduleProvides keyword argument. When invoked in the body of a class definition, this function accepts any keyword arguments except moduleProvides. The complete list of keyword arguments follows. Unless otherwise specified, protocols must support the IOpenProtocol interface.

Note: When used in a class body, this function works by temporarily replacing the __metaclass__ of the class. If your class sets an explicit __metaclass__, it must do so before advise() is called, or the protocol declarations will not occur!

Keyword arguments accepted by advise():

instancesProvide = protocols

A sequence of protocols that instances of the containing class provide, without needing an adapter. Supplying this argument is equivalent to calling declareImplementation(containing class,protocols).

instancesDoNotProvide = protocols

A sequence of protocols that instances of the containing class do not provide. This is primarily intended for ``rejecting'' protocols provided or supported by base classes of the containing class. Supplying this argument is equivalent to calling declareImplementation(containing class,instancesDoNotProvide=protocols).

asAdapterForTypes = types

Declare the containing class as an adapter for types, to the protocols listed by the instancesProvide argument (which must also be supplied). Supplying this argument is equivalent to calling declareAdapter(containing class, instancesProvide, forTypes=types). (Note that this means the containing class must be an object that provides IAdapterFactory; i.e., its constructor should accept being called with a single argument: the object to be adapted.)

asAdapterForProtocols = protocols

Declare the containing class as an adapter for protocols, to the protocols listed by the instancesProvide argument (which must also be supplied). Supplying this argument is equivalent to calling declareAdapter(containing class, instancesProvide, forProtocols=types). (Note that this means the containing class must be an object that provides IAdapterFactory; i.e., its constructor should accept being called with a single argument: the object to be adapted.)

factoryMethod = methodName

New in version 0.9.1. When using asAdapterForTypes or asAdapterForProtocols, you can also supply a factory method name, using this keyword. The method named must be a class method, and it will be used in place of the class' normal constructor. (Note that this means the named method must be able to be called with a single argument: the object to be adapted.)

protocolExtends = protocols

Declare that the containing class is a protocol that extends (i.e., implies) the listed protocols. This keyword argument is intended for use inside class statements that themselves define protocols, such as Interface subclasses, and that need to ``inherit'' from incompatible protocols. For example, an Interface cannot directly subclass a Zope interface, because their metaclasses are incompatible. But using protocolExtends works around this:


\begin{verbatim}import protocols
from mypackage import ISomeInterface
from zope....
...ols.advise(
protocolExtends = [ISomeZopeInterface]
)
...

In the above example, IAnotherInterface wants to extend both ISomeInterface and ISomeZopeInterface, but cannot do so directly because the interfaces are of incompatible types. protocolExtends informs the newly created interface that it implies ISomeZopeInterface, even though it isn't derived from it.

Using this keyword argument is equivalent to calling declareAdapter(NO_ADAPTER_NEEDED, protocols, forProtocols=[containing class]). Note that this means that the containing class must be an object that supports IOpenProtocol, such as an Interface subclass.

protocolIsSubsetOf = protocols

Declare that the containing class is a protocol that is implied (extended) by the listed protocols. This is just like protocolExtends, but in the ``opposite direction''. It allows you to declare (in effect) that some other interface is actually a subclass of (extends, implies) this one. See the examples in section 1.1.4 for illustration.

Using this keyword argument is equivalent to calling declareAdapter(NO_ADAPTER_NEEDED, [containing class], forProtocols=protocols).

equivalentProtocols = protocols

New in version 0.9.1. Declare that the containing class is a protocol that is equivalent to the listed protocols. That is, the containing protocol both implies, and is implied by, the listed protocols. This is a convenience feature intended mainly to support the use of generated protocols.

Using this keyword is equivalent to using both the protocolExtends and protocolIsSubsetOf keywords, with the supplied protocols.

classProvides = protocols

Declare that the containing class itself provides the specified protocols. Supplying this argument is equivalent to calling adviseObject(containing class, protocols). Note that this means that the containing class may need to support the IOpenProvider interface. The protocols package supplies default adapters to support IOpenProvider for both classic and new-style classes, as long as they do not have custom __conform__ methods. See section 1.1.6, ``Protocol Declarations for Individual Objects'' for more details.

classDoesNotProvide = protocols

Declare that the containing class itself does not provide the specified protocols. This is for classes that need to reject inherited class-level classProvides declarations. Supplying this argument is equivalent to calling adviseObject(containing class, doesNotProvide=protocols), and the IOpenProvider requirements mentioned above for classProvides apply here as well.

moduleProvides = protocols
(module context only)
A sequence of protocols that the enclosing module provides. Equivalent to adviseObject(containing module, protocols).