protocols.adapters -- ``Adapter arithmetic'' support

The protocols.adapters module provides support for doing ``adapter arithmetic'' such as determining which of two adapter paths is shorter, composing a new adapter from two existing adapters, and updating an adapter registry with a new adapter path. See section 1.1.7 for a more general discussion of adapter arithmetic.

minimumAdapter( a1, a2 [, d1=0, d2=0])
Find the ``shortest'' adapter path, a1 at depth d1, or a2 at depth d2. Assuming a1 and a2 are adapter factories that accept similar input and return similar output, this function returns the one which is the ``shortest path'' between its input and its output. That is, the one with the smallest implication depth (d1 or d2), or, if the depths are equal, then the adapter factory that is composed of the fewest chained factories (as composed by composeAdapters()) is returned. If neither factory is composed of multiple factories, or they are composed of the same number of intermediate adapter factories, then the following preference order is used:

  1. If one of the adapters is NO_ADAPTER_NEEDED, it is returned
  2. If one of the adapters is DOES_NOT_SUPPORT, the other adapter is returned.
  3. If both adapters are the exact same object (i.e. a1 is a2), either one is returned

If none of the above conditions apply, then the adapter precedence is considered ambiguous, and a TypeError is raised.

This function is used by updateWithSimplestAdapter to determine whether a new adapter declaration should result in a registry update. Note that the determination of adapter composition length uses the __adapterCount__ attribute, if present. (It is assumed to be 1 if not present. See composeAdapters() for more details.)

composeAdapters( baseAdapter, baseProtocol, extendingAdapter)
Return a new IAdapterFactory composed of the input adapter factories baseAdapter and extendingAdapter. If either input adapter is DOES_NOT_SUPPORT, DOES_NOT_SUPPORT is returned. If either input adapter is NO_ADAPTER_NEEDED, the other input adapter is returned. Otherwise, a new adapter factory is created that will return extendingAdapter(baseAdapter(object)) when called with object. (Note: the actual implementation verifies that baseAdapter didn't return None before it calls extendingAdapter).

If this function creates a new adapter factory, the factory will have an __adapterCount__ attribute set to the sum of the __adapterCount__ attributes of the input adapter factories. If an input factory does not have an __adapterCount__ attribute, it is assumed to equal 1. This is done so that the minimumAdapter() can compare the length of composed adapter chains.

updateWithSimplestAdapter( mapping, key, adapter, depth)
Treat mapping as an adapter registry, replacing the entry designated by key with an (adapter,depth) tuple, if and only if the new entry would be a ``shorter path'' than the existing entry, if any. (I.e., if minimumAdapter(old, adapter, oldDepth, depth) returns adapter, and adapter is not the existing registered adapter. The function returns a true value if it updates the contents of mapping.

This function is used to manage type-to-protocol, protocol-to-protocol, and object-to-protocol adapter registries, keyed by type or protocol. The mapping argument must be a mapping providing __setitem__() and get() methods. Values stored in the mapping will be (adapter,depth) tuples.