# Path: paco/decorator.py
# 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('paco: fn must be a callable object')
# 
#     @functools.wraps(fn)
#     def decorator(*args, **kw):
#         # If coroutine object is passed
#         for arg in args:
#             if iscoro_or_corofunc(arg):
#                 return fn(*args, **kw)
# 
#         # Explicit argument must be at least a coroutine
#         if len(args) and args[0] is None:
#             raise TypeError('paco: first argument cannot be empty')
# 
#         def wrapper(coro, *_args, **_kw):
#             # coro must be a valid type
#             if not iscoro_or_corofunc(coro):
#                 raise TypeError('paco: first argument must be a '
#                                 'coroutine or coroutine function')
# 
#             # Merge call arguments
#             _args = ((coro,) + (args + _args))
#             kw.update(_kw)
# 
#             # Trigger original decorated function
#             return fn(*_args, **kw)
#         return wrapper
#     return decorator
# 
# Path: paco/assertions.py
# def assert_corofunction(**kw):
#     """
#     Asserts if a given values are a coroutine function.
# 
#     Arguments:
#         **kw (mixed): value to check if it is an iterable.
# 
#     Raises:
#         TypeError: if assertion fails.
#     """
#     for name, value in kw.items():
#         if not asyncio.iscoroutinefunction(value):
#             raise TypeError(
#                 'paco: {} must be a coroutine function'.format(name))


import asyncio
from .decorator import decorate
from .assertions import assert_corofunction
    This is similar to `paco.partial()`.

    This function can be used as decorator.

    arguments:
        coro (coroutinefunction): coroutine function to wrap.
        *args (mixed): mixed variadic arguments for partial application.
        *kwargs (mixed): mixed variadic keyword arguments for partial
            application.

    Raises:
        TypeError: if coro argument is not a coroutine function.

    Returns:
        coroutinefunction: wrapped coroutine function.

    Usage::

        async def hello(name, mark='!'):
            print('Hello, {name}{mark}'.format(name=name, mark=mark))

        hello_mike = paco.apply(hello, 'Mike')
        await hello_mike()
        # => Hello, Mike!

        hello_mike = paco.apply(hello, 'Mike', mark='?')
        await hello_mike()
        # => Hello, Mike?

    """

# Path: paco/decorator.py
# 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('paco: fn must be a callable object')
# 
#     @functools.wraps(fn)
#     def decorator(*args, **kw):
#         # If coroutine object is passed
#         for arg in args:
#             if iscoro_or_corofunc(arg):
#                 return fn(*args, **kw)
# 
#         # Explicit argument must be at least a coroutine
#         if len(args) and args[0] is None:
#             raise TypeError('paco: first argument cannot be empty')
# 
#         def wrapper(coro, *_args, **_kw):
#             # coro must be a valid type
#             if not iscoro_or_corofunc(coro):
#                 raise TypeError('paco: first argument must be a '
#                                 'coroutine or coroutine function')
# 
#             # Merge call arguments
#             _args = ((coro,) + (args + _args))
#             kw.update(_kw)
# 
#             # Trigger original decorated function
#             return fn(*_args, **kw)
#         return wrapper
#     return decorator
# 
# Path: paco/assertions.py
# def assert_corofunction(**kw):
#     """
#     Asserts if a given values are a coroutine function.
# 
#     Arguments:
#         **kw (mixed): value to check if it is an iterable.
# 
#     Raises:
#         TypeError: if assertion fails.
#     """
#     for name, value in kw.items():
#         if not asyncio.iscoroutinefunction(value):
#             raise TypeError(
#                 'paco: {} must be a coroutine function'.format(name))


# Path: paco/apply.py
import asyncio
from .decorator import decorate
from .assertions import assert_corofunction

    This is similar to `paco.partial()`.

    This function can be used as decorator.

    arguments:
        coro (coroutinefunction): coroutine function to wrap.
        *args (mixed): mixed variadic arguments for partial application.
        *kwargs (mixed): mixed variadic keyword arguments for partial
            application.

    Raises:
        TypeError: if coro argument is not a coroutine function.

    Returns:
        coroutinefunction: wrapped coroutine function.

    Usage::

        async def hello(name, mark='!'):
            print('Hello, {name}{mark}'.format(name=name, mark=mark))

        hello_mike = paco.apply(hello, 'Mike')
        await hello_mike()
        # => Hello, Mike!

        hello_mike = paco.apply(hello, 'Mike', mark='?')
        await hello_mike()
        # => Hello, Mike?

    """

    assert_corofunction(coro=coro)