def producer(*, name = None, metric = call_default):
def wrapper(func):<EOL><INDENT>def instrumenter(name_, *args, **kwargs):<EOL><INDENT>t = time.time()<EOL>try:<EOL><INDENT>ret = func(*args, **kwargs)<EOL><DEDENT>except Exception:<EOL><INDENT>metric(name_, <NUM_LIT:0>, time.time() - t)<EOL>raise<EOL><DEDENT>else:<EOL><INDENT>metric(name_, len(ret), time.time() - t)<EOL>return ret<EOL><DEDENT><DEDENT>name_ = name if name is not None else func.__module__ + '<STR_LIT:.>' +func.__name__<EOL>class instrument_decorator(object): <EOL><INDENT>@wraps(func)<EOL>def __call__(self, *args, **kwargs):<EOL><INDENT>return instrumenter(name_, *args, **kwargs)<EOL><DEDENT>def __get__(self, instance, class_):<EOL><INDENT>name_ = name if name is not None else"<STR_LIT:.>".join((class_.__module__, class_.__name__, func.__name__))<EOL>@wraps(func)<EOL>def wrapped_method(*args, **kwargs):<EOL><INDENT>return instrumenter(name_, instance, *args, **kwargs)<EOL><DEDENT>return wrapped_method<EOL><DEDENT><DEDENT>return instrument_decorator()<EOL><DEDENT>return wrapper<EOL>
Decorator to measure a function that produces many items.

    The function should return an object that supports ``__len__`` (ie, a
    list). If the function returns an iterator, use :func:`all` instead.

    :arg function metric: f(name, count, total_time)
    :arg str name: name for the metric