# Path: paco/gather.py
# @asyncio.coroutine
# def gather(*coros_or_futures, limit=0, loop=None, timeout=None,
#            preserve_order=False, return_exceptions=False):
#     """
#     Return a future aggregating results from the given coroutine objects
#     with a concurrency execution limit.
# 
#     If all the tasks are done successfully, the returned future’s result is
#     the list of results (in the order of the original sequence,
#     not necessarily the order of results arrival).
# 
#     If return_exceptions is `True`, exceptions in the tasks are treated the
#     same as successful results, and gathered in the result list; otherwise,
#     the first raised exception will be immediately propagated to the
#     returned future.
# 
#     All futures must share the same event loop.
# 
#     This functions is mostly compatible with Python standard
#     ``asyncio.gather``, but providing ordered results and concurrency control
#     flow.
# 
#     This function is a coroutine.
# 
#     Arguments:
#         *coros_or_futures (coroutines|list): an iterable collection yielding
#             coroutines functions or futures.
#         limit (int): max concurrency limit. Use ``0`` for no limit.
#         timeout can be used to control the maximum number
#             of seconds to wait before returning. timeout can be an int or
#             float. If timeout is not specified or None, there is no limit to
#             the wait time.
#         preserve_order (bool): preserves results order.
#         return_exceptions (bool): returns exceptions as valid results.
#         loop (asyncio.BaseEventLoop): optional event loop to use.
# 
#     Returns:
#         list: coroutines returned results.
# 
#     Usage::
# 
#         async def sum(x, y):
#             return x + y
# 
#         await paco.gather(
#             sum(1, 2),
#             sum(None, 'str'),
#             return_exceptions=True)
#         # => [3, TypeError("unsupported operand type(s) for +: 'NoneType' and 'str'")]  # noqa
# 
#     """
#     # If no coroutines to schedule, return empty list (as Python stdlib)
#     if len(coros_or_futures) == 0:
#         return []
# 
#     # Support iterable as first argument for better interoperability
#     if len(coros_or_futures) == 1 and isiter(coros_or_futures[0]):
#         coros_or_futures = coros_or_futures[0]
# 
#     # Pre-initialize results
#     results = [None] * len(coros_or_futures) if preserve_order else []
# 
#     # Create concurrent executor
#     pool = ConcurrentExecutor(limit=limit, loop=loop)
# 
#     # Iterate and attach coroutine for defer scheduling
#     for index, coro in enumerate(coros_or_futures):
#         # Validate coroutine object
#         if asyncio.iscoroutinefunction(coro):
#             coro = coro()
#         if not asyncio.iscoroutine(coro):
#             raise TypeError(
#                 'paco: only coroutines or coroutine functions allowed')
# 
#         # Add coroutine to the executor pool
#         pool.add(collect(coro, index, results,
#                          preserve_order=preserve_order,
#                          return_exceptions=return_exceptions))
# 
#     # Wait until all the tasks finishes
#     yield from pool.run(timeout=timeout, return_exceptions=return_exceptions)
# 
#     # Returns aggregated results
#     return results


import asyncio
from .gather import gather
        timeout (int/float):
            maximum number of seconds to wait before returning.
        return_exceptions (bool):
            exceptions in the tasks are treated the same as successful results,
            instead of raising them.
        loop (asyncio.BaseEventLoop):
            optional event loop to use.
        *args (mixed):
            optional variadic argument to pass to the coroutines function.

    Returns:
        list: coroutines returned results.

    Raises:
        TypeError: in case of invalid coroutine object.
        ValueError: in case of empty set of coroutines or futures.
        TimeoutError: if execution takes more than expected.

    Usage::

        async def sum(x, y):
            return x + y

        await paco.series(
            sum(1, 2),
            sum(2, 3),
            sum(3, 4))
        # => [3, 5, 7]

    """

# Path: paco/gather.py
# @asyncio.coroutine
# def gather(*coros_or_futures, limit=0, loop=None, timeout=None,
#            preserve_order=False, return_exceptions=False):
#     """
#     Return a future aggregating results from the given coroutine objects
#     with a concurrency execution limit.
# 
#     If all the tasks are done successfully, the returned future’s result is
#     the list of results (in the order of the original sequence,
#     not necessarily the order of results arrival).
# 
#     If return_exceptions is `True`, exceptions in the tasks are treated the
#     same as successful results, and gathered in the result list; otherwise,
#     the first raised exception will be immediately propagated to the
#     returned future.
# 
#     All futures must share the same event loop.
# 
#     This functions is mostly compatible with Python standard
#     ``asyncio.gather``, but providing ordered results and concurrency control
#     flow.
# 
#     This function is a coroutine.
# 
#     Arguments:
#         *coros_or_futures (coroutines|list): an iterable collection yielding
#             coroutines functions or futures.
#         limit (int): max concurrency limit. Use ``0`` for no limit.
#         timeout can be used to control the maximum number
#             of seconds to wait before returning. timeout can be an int or
#             float. If timeout is not specified or None, there is no limit to
#             the wait time.
#         preserve_order (bool): preserves results order.
#         return_exceptions (bool): returns exceptions as valid results.
#         loop (asyncio.BaseEventLoop): optional event loop to use.
# 
#     Returns:
#         list: coroutines returned results.
# 
#     Usage::
# 
#         async def sum(x, y):
#             return x + y
# 
#         await paco.gather(
#             sum(1, 2),
#             sum(None, 'str'),
#             return_exceptions=True)
#         # => [3, TypeError("unsupported operand type(s) for +: 'NoneType' and 'str'")]  # noqa
# 
#     """
#     # If no coroutines to schedule, return empty list (as Python stdlib)
#     if len(coros_or_futures) == 0:
#         return []
# 
#     # Support iterable as first argument for better interoperability
#     if len(coros_or_futures) == 1 and isiter(coros_or_futures[0]):
#         coros_or_futures = coros_or_futures[0]
# 
#     # Pre-initialize results
#     results = [None] * len(coros_or_futures) if preserve_order else []
# 
#     # Create concurrent executor
#     pool = ConcurrentExecutor(limit=limit, loop=loop)
# 
#     # Iterate and attach coroutine for defer scheduling
#     for index, coro in enumerate(coros_or_futures):
#         # Validate coroutine object
#         if asyncio.iscoroutinefunction(coro):
#             coro = coro()
#         if not asyncio.iscoroutine(coro):
#             raise TypeError(
#                 'paco: only coroutines or coroutine functions allowed')
# 
#         # Add coroutine to the executor pool
#         pool.add(collect(coro, index, results,
#                          preserve_order=preserve_order,
#                          return_exceptions=return_exceptions))
# 
#     # Wait until all the tasks finishes
#     yield from pool.run(timeout=timeout, return_exceptions=return_exceptions)
# 
#     # Returns aggregated results
#     return results


# Path: paco/series.py
import asyncio
from .gather import gather

        timeout (int/float):
            maximum number of seconds to wait before returning.
        return_exceptions (bool):
            exceptions in the tasks are treated the same as successful results,
            instead of raising them.
        loop (asyncio.BaseEventLoop):
            optional event loop to use.
        *args (mixed):
            optional variadic argument to pass to the coroutines function.

    Returns:
        list: coroutines returned results.

    Raises:
        TypeError: in case of invalid coroutine object.
        ValueError: in case of empty set of coroutines or futures.
        TimeoutError: if execution takes more than expected.

    Usage::

        async def sum(x, y):
            return x + y

        await paco.series(
            sum(1, 2),
            sum(2, 3),
            sum(3, 4))
        # => [3, 5, 7]

    """

    return (yield from gather(*coros_or_futures,