blob: 761952376338b1d1e3611822d7e7444125d9787f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
"""
A module that monkey patches the standard asyncio module to add an
idle_call() method to the main loop. This method is used to execute a
callback whenever the loop is not busy handling anything else. This means
that it is a callback with lower priority than IO, timer, or even
call_soon() ones. These callback are called only once each.
"""
import asyncio
from asyncio import events
from functools import wraps
import collections
def idle_call(self, callback):
if asyncio.iscoroutinefunction(callback):
raise TypeError("coroutines cannot be used with idle_call()")
handle = events.Handle(callback, [], self)
self._idle.append(handle)
def my_run_once(self):
if self._idle:
self._ready.append(events.Handle(lambda: None, (), self))
real_run_once(self)
if self._idle:
handle = self._idle.popleft()
handle._run()
cls = asyncio.get_event_loop().__class__
cls._idle = collections.deque()
cls.idle_call = idle_call
real_run_once = cls._run_once
cls._run_once = my_run_once
def coroutine_wrapper(func):
"""
Make sure the result of a function call is a coroutine
if the ``coroutine`` keyword argument is true.
"""
def wrap_coro(result):
if asyncio.iscoroutinefunction(result):
return result
else:
return asyncio.coroutine(lambda: result)()
@wraps(func)
def wrapper(*args, **kwargs):
if kwargs.get('coroutine', False):
return wrap_coro(func(*args, **kwargs))
else:
return func(*args, **kwargs)
return wrapper
|