1.1.9.6 protocols.advice -- Metaclasses and other ``Magic''
Description: protocols.advice -- Metaclasses and other ``Magic''
Keywords: ref

### 1.1.9.6 `protocols.advice` -- Metaclasses and other ``Magic''

This module provides a variety of utility functions and classes used by the `protocols` package. None of them are really specific to the `protocols` package, and so may be useful to other libraries or applications.

`addClassAdvisor`( | callback [, depth=`2`])

  Set up callback to be called with the containing class, once it is created. This function is designed to be called by an ``advising'' function (such as `protocols.advise()`) executed in the body of a class suite. The ``advising'' function supplies a callback that it wishes to have executed when the containing class is created. The callback will be given one argument: the newly created containing class. The return value of the callback will be used in place of the class, so the callback should return the input if it does not wish to replace the class.

  The optional depth argument determines the number of frames between this function and the targeted class suite. depth defaults to 2, since this skips this function's frame and one calling function frame. If you use this function from a function called directly in the class suite, the default will be correct, otherwise you will need to determine the correct depth yourself.

  This function works by installing a special class factory function in place of the `__metaclass__` of the containing class. Therefore, only callbacks after the last `__metaclass__` assignment in the containing class will be executed. Be sure that classes using ``advising'' functions declare any `__metaclass__` first, to ensure all callbacks are run.

`isClassAdvisor`( | ob)

  Returns truth if ob is a class advisor function. This is used to determine if a `__metaclass__` value is a ``magic'' metaclass installed by `addClassAdvisor()`. If so, then ob will have a `previousMetaclass` attribute pointing to the previous metaclass, if any, and a `callback` attribute containing the callback that was given to `addClassAdvisor()`.

`getFrameInfo`( | frame)

  Return a `(kind,module,locals,globals)` tuple for the supplied frame object. The returned kind is a string: either ``exec'', ``module'', ``class'', ``function call'', or ``unknown''. module is the module object the frame is/was executed in, or `None` if the frame's globals could not be correlated with a module in `sys.modules`. locals and globals are the frame's local and global dictionaries, respectively. Note that they can be the same dictionary, and that modifications to locals may not have any effect on the execution of the frame.

  This function is used by functions like `addClassAdvisor()` and `advise()` to verify where they're being called from, and to work their respective magics.

`getMRO`( | ob [, extendedClassic=`False`])

  Return an iterable over the ``method resolution order'' of ob. If ob is a ``new-style'' class or type, this returns its `__mro__` attribute. If ob is a ``classic'' class, this returns `classicMRO(ob,extendedClassic)`. If ob is not a class or type of any kind, a one-element sequence containing just ob is returned.

`classicMRO`( | ob [, extendedClassic=`False`])

  Return an iterator over the ``method resolution order'' of classic class ob, following the ``classic'' method resolution algorithm of recursively traversing `__bases__` from left to right. (Note that this may return the same class more than once, for some inheritance graphs.) If varextendedClassic is a true value, `InstanceType` and `object` are added at the end of the iteration. This is used by `Protocol` objects to allow generic adapters for `InstanceType` and `object` to be used with ``classic'' class instances.

`determineMetaclass`( | bases [, explicit_mc=`None`])

  Determine the metaclass that would be used by Python, given a non-empty sequence of base classes, and an optional explicitly supplied `__metaclass__`. Returns `ClassType` if all bases are ``classic'' and there is no explicit_mc. Raises `TypeError` if the bases' metaclasses are incompatible, just like Python would.

`minimalBases`( | classes)

  Return the shortest ordered subset of the input sequence classes that still contains the ``most specific'' classes. That is, the result sequence contains only classes that are not subclasses of each other. This function is used by `determineMetaclass()` to narrow down its list of candidate metaclasses, but is also useful for dynamically generating metaclasses.

`mkRef`( | ob [, callable])

  If ob is weak-referenceable, returns `weakref.ref(ob,callable)`. Otherwise, returns a `StrongRef(ob)`, emulating the interface of `weakref.ref()`. This is used by code that wants to use weak references, but may be given objects that are not weak-referenceable. Note that callable, if supplied, will not be called if ob is not weak-referenceable.

class `StrongRef`( | ob)

  An object that emulates the interface of `weakref.ref()`. When called, an instance of `StrongRef` will return the ob it was created for. Also, it will hash the same as ob and compare equal to it. Thus, it can be used as a dictionary key, as long as the underlying object can. Of course, since it is not really a weak reference, it does not contribute to the garbage collection of the underlying object, and may in fact hinder it, since it holds a live reference to the object.