Like any other API, the protocols declaration API has certain expectations regarding its parameters. These expectations are documented and referenced in code using interfaces defined in the protocols.interfaces module. (The interfaces are also exported directly from the top level of the protocols package.)
You will rarely use or subclass any of these interface objects, unless you are customizing or extending the system. Four of the interfaces exist exclusively for documentation purposes, while the rest are used in adapt() calls made by the API.
First, let's look at the documentation-only interfaces. It is not necessary for you to declare that an object supports these interfaces, and the protocols package never tries to adapt() objects to them.
The protocols package supplies two functions that provide this interface: NO_ADAPTER_NEEDED and DOES_NOT_SUPPORT. NO_ADAPTER_NEEDED is used to declare that an object provides a protocol directly, and thus it returns the object passed into it, rather than some kind of adapter. DOES_NOT_SUPPORT is used to declare that an object does not support a protocol, even with an adapter. (Since this is the default case, DOES_NOT_SUPPORT is rarely used, except to indicate that a subclass does not support an interface that one of its superclasses does.)
The other three interfaces are critical to the operation of the declaration API, and thus must be supported by objects supplied to it. The protocols package supplies and registers various adapter classes that provide these interfaces on behalf of many commonly used Python object types. So, for each interface, we will list ``known supporters'' of that interface, whether they are classes supplied by protocols, or built-in types that are automatically adapted to the interface.
We will not, however, go into details here about the methods and behavior required by each interface. (Those details can be found in section 1.1.9.)
The protocols package supplies two implementations of this interface: Protocol and InterfaceClass. Thus, any Interface subclass or Protocol instance is automatically considered to provide IOpenProtocol. Note: Interface is an instance of InterfaceClass, and thus provides IOpenProtocol. But if you create an instance of an Interface, that object does not provide IOpenProtocol, because the interfaces provided by an object and its class (or its instances) can be different.
In addition to its built-in implementations, the protocols package also supplies and can declare adapter factories that adapt Zope X3 and Twisted's interface objects to the IOpenProtocol interface, thus allowing you to use Zope and Twisted interfaces in calls to the declaration API. Similar adapters for other frameworks' interfaces may be added, if there is sufficient demand and/or contributed code, and the frameworks' authors do not add the adapters to their frameworks.
Support for this interface is optional, since types that don't support it can still have their instances be adapted by IOpenProtocol objects. The protocols package does not supply any implementations or adapters for this interface, either. It is intended primarily as a hook for classes to be able to receive notification about protocol declarations for their instances.
That's what the IOpenProvider interface is for. An IOpenProvider is an object with a __conform__ method, that can be told (via the declaration API) what protocols it provides (or supports via an IAdapterFactory).
Notice that this is different from IOpenImplementor, which deals with an class or type's instances. IOpenProvider deals with the object itself. A single object can potentially be both an IOpenProvider and an IOpenImplementor, if it is a class or type.
The protocols package supplies and declares an adapter factory that
can adapt most Python objects to support this interface, assuming that they
have a __dict__
attribute. Thus, it is acceptable to pass a Python
function, module, or instance of a ``classic'' class to any declaration API
that expects an IOpenProvider argument.
We'll talk more about making protocol declarations for individual objects (as opposed to types) in section 1.1.6, ``Protocol Declarations for Individual Objects''.