Source code for paco.decorator

import asyncio
from inspect import isfunction
from .assertions import assert_corofunction


def decorate(fn):
    """
    Generic decorator for coroutines helper functions allowing
    multiple variadic initialization arguments.

    This function is intended to be used internally.

    Arguments:
        fn (function): target function to decorate.

    Raises:
        TypeError: if function or coroutine function is not provided.

    Returns:
        function: decorated function.
    """
    if not isfunction(fn):
        raise TypeError('fn must be a callable object')

    def decorator(*args, **kw):
        for arg in args:
            if asyncio.iscoroutinefunction(arg):
                return fn(*args, **kw)

        # Explicit argument must be at least a coroutine
        if len(args) and args[0] is None:
            raise TypeError('first argument cannot be None')

        def wrapper(coro, *_args, **_kw):
            assert_corofunction(coro=coro)
            # Merge call arguments
            _args = ((coro,) + (args + _args))
            kw.update(_kw)
            return fn(*_args, **kw)
        return wrapper
    return decorator