""" Wraps various asyncio functions """ import asyncio import sys from functools import partial from cloudbot.util.func_utils import call_with_args def wrap_future(fut, *, loop=None): """ Wraps asyncio.ensure_future() :param fut: The awaitable, future, or coroutine to wrap :param loop: The loop to run in :return: The wrapped future """ return asyncio.ensure_future(fut, loop=loop) async def run_func(loop, func, *args, **kwargs): part = partial(func, *args, **kwargs) if asyncio.iscoroutine(func) or asyncio.iscoroutinefunction(func): return await part() return await loop.run_in_executor(None, part) async def run_func_with_args(loop, func, arg_data, executor=None): if asyncio.iscoroutine(func): raise TypeError('A coroutine function or a normal, non-async callable are required') if asyncio.iscoroutinefunction(func): coro = call_with_args(func, arg_data) else: coro = loop.run_in_executor(executor, call_with_args, func, arg_data) return await coro def run_coroutine_threadsafe(coro, loop): """ Runs a coroutine in a threadsafe manner :type coro: coroutine :type loop: asyncio.AbstractEventLoop """ if not asyncio.iscoroutine(coro): raise TypeError('A coroutine object is required') if sys.version_info < (3, 5, 1): loop.call_soon_threadsafe(partial(wrap_future, coro, loop=loop)) else: asyncio.run_coroutine_threadsafe(coro, loop) def create_future(loop=None): if loop is None: loop = asyncio.get_event_loop() if sys.version_info < (3, 5, 2): return asyncio.Future(loop=loop) return loop.create_future()