1.1.9.3 protocols.adapters -- ``Adapter arithmetic'' support
Description: protocols.adapters -- ``Adapter arithmetic'' support
Keywords: ref

###
1.1.9.3 `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.