Source code for spy.decorators

from functools import partial, wraps

from .core import _accepts_context, _call_fragment_body, collect, DROP, many as _many

__all__ = ['accumulate', 'callable', 'filter', 'many']

decorators = []


def decorator(*names, doc=None):
    def wrapperer(_spy_decorator):
        @wraps(_spy_decorator)
        def wrapper(fn):
            if _accepts_context(fn):
                xfn = partial(_call_fragment_body, fn)
            else:
                xfn = partial(_drop_context, fn)

            @wraps(fn)
            def wrapped(v, context=None):
                _spy_callable = fn  # noqa: F841
                _spy_value = v  # noqa: F841
                return _spy_decorator(xfn, v, context)
            return wrapped

        wrapper.decorator_names = names
        wrapper.decorator_help = doc
        decorators.append(wrapper)
        return wrapper
    return wrapperer


def _drop_context(fn, v, context):
    return _call_fragment_body(fn, v)


[docs]@decorator('--accumulate', '-a', doc='Pass an iterator of yielded values to this fragment') def accumulate(fn, v, context): return fn(collect(context), context)
[docs]@decorator('--callable', '-c', doc='Call the result of this fragment') def callable(fn, v, context): result = fn(v, context) return result(v)
[docs]@decorator('--filter', '-f', doc='Treat this fragment as a predicate to filter data') def filter(fn, v, context): result = fn(v, context) return v if result else DROP
[docs]@decorator('--many', '-m', doc='Iterate over this fragment') def many(fn, v, context): result = fn(v, context) return _many(result)