Assorted decorator functions.


Assorted decorator functions.

## Function `cached(*da, **dkw)`

Decorator to cache the result of a method and keep a revision
counter for changes.
The revision supports the `@revised` decorator.

This decorator may be used in 2 modes.
Directly:

    @cached
    def method(self, ...)

or indirectly:

    @cached(poll_delay=0.25)
    def method(self, ...)

Optional keyword arguments:
* `attr_name`: the basis name for the supporting attributes.
  Default: the name of the method.
* `poll_delay`: minimum time between polls; after the first
  access, subsequent accesses before the `poll_delay` has elapsed
  will return the cached value.
  Default: `None`, meaning no poll delay.
* `sig_func`: a signature function, which should be significantly
  cheaper than the method. If the signature is unchanged, the
  cached value will be returned. The signature function
  expected the instance (`self`) as its first parameter.
  Default: `None`, meaning no signature function;
  the first computed value will be kept and never updated.
* `unset_value`: the value to return before the method has been
  called successfully.
  Default: `None`.

If the method raises an exception, this will be logged and
the method will return the previously cached value.

An example use of this decorator might be to keep a "live"
configuration data structure, parsed from a configuration
file which might be modified after the program starts. One
might provide a signature function which called `os.stat()` on
the file to check for changes before invoking a full read and
parse of the file.

## Function `decorator(deco)`

Wrapper for decorator functions to support optional keyword arguments.

Examples:

    @decorator
    def dec(func, **dkw):
      ...
    @dec
    def func1(...):
      ...
    @dec(foo='bah')
    def func2(...):
      ...

## Function `strable(*da, **dkw)`

Decorator for functions which may accept a `str`
instead of their core type.

Parameters:
* `func`: the function to decorate
* `open_func`: the "open" factory to produce the core type form
  the string if a string is provided; the default is the builtin
  "open" function

The usual (and default) example is a function to process an
open file, designed to be handed a file object but which may
be called with a filename. If the first argument is a `str`
then that file is opened and the function called with the
open file.

Examples:

    @strable
    def count_lines(f):
      return len(line for line in f)

    class Recording:
      "Class representing a video recording."
      ...
    @strable
    def process_video(r, open_func=Recording):
      ... do stuff with `r` as a Recording instance ...
