-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtask3.py
More file actions
74 lines (57 loc) · 1.78 KB
/
Copy pathtask3.py
File metadata and controls
74 lines (57 loc) · 1.78 KB
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# coding: utf-8
# In[1]:
import future
from future import Future
# In[2]:
class Task(Future):
"""
Wraps a generator yielding a Future
object and abstracts away the handling of future API
This version adds loop to the task
"""
def __init__(self, loop, gen):
"""
"""
super().__init__(loop)
assert (loop is not None)
self._loop = loop
self.gen = gen
self._loop.call_soon(self.step)
def step(self, snd_val=None, exp=None):
""""""
try:
if exp:
self.gen.throw(exp)
else:
fut = self.gen.send(snd_val)
except StopIteration as e:
self.set_result(snd_val)
except Exception as e:
self.set_exception(e)
else:
#if no exceptions, we need to check what kind
#of generator function we are dealing with
#Why ? Because not all generator functions would
#yield a future.
if isinstance(fut, Future):
fut.add_done_callback(self._fut_done_cb)
elif fut is None:
#The generator yielded noting or None
#so we call step again for finishing off
#the generator execution till the return statement
#or to the next yield statement
self._loop.call_soon(self.step)
def _fut_done_cb(self, fut):
"""
Called if the yielded future by the coroutine
is ready
"""
try:
result = fut.result()
except Exception as e:
self.step(None, e)
else:
#Call the step again to continue
#with the coroutine execution.
self.step(result, None)
pass