Skip to content

Commit

Permalink
hide already-awaited coroutines from the user
Browse files Browse the repository at this point in the history
  • Loading branch information
gottadiveintopython committed Jul 6, 2020
1 parent ad1d35e commit b48d8cc
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 7 deletions.
21 changes: 14 additions & 7 deletions asynckivy/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,23 @@ def step_coro(*args, **kwargs):
class Task:
'''(internal)'''
__slots__ = ('coro', 'done', 'result', 'done_callback')
def __init__(self, coro, *, done_callback=None):
self.coro = coro
def __init__(self):
self.coro = None
self.done = False
self.result = None
self.done_callback = None
def run(self, coro, *, done_callback=None):
if self.coro is not None:
raise Exception("'run()' can be called only once.")
self.done_callback = done_callback
async def _run(self):
self.result = await self.coro
self.coro = start(self._wrapper(coro))
async def _wrapper(self, inner_coro):
self.result = await inner_coro
self.done = True
if self.done_callback is not None:
self.done_callback()
def cancel(self):
self.coro.close()


@types.coroutine
Expand All @@ -54,9 +61,9 @@ def done_callback():
n_coros_left -= 1
if n_coros_left == 0:
step_coro()
tasks = tuple(Task(coro, done_callback=done_callback) for coro in coros)
for task in tasks:
start(task._run())
tasks = tuple(Task() for coro in coros)
for task, coro in zip(tasks, coros):
task.run(coro, done_callback=done_callback)

if n_coros_left <= 0:
return tasks
Expand Down
48 changes: 48 additions & 0 deletions examples/github_issue/#11.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.button import Button
import asynckivy as ak


KV_CODE = '''
BoxLayout:
orientation: 'vertical'
Label:
id: label
font_size: 50
Button:
id: button
font_size: 50
'''

class TestApp(App):
def build(self):
return Builder.load_string(KV_CODE)
def on_start(self):
async def some_task():
label = self.root.ids.label
button = self.root.ids.button
label.text = '--'
button.text = 'start spinning'
await ak.event(button, 'on_press')
button.text = 'stop'
tasks = await ak.or_(
ak.event(button, 'on_press'),
spinning(label),
)
tasks[1].coro.close() # 'tasks[1].cancel()' is preferable
self.root.remove_widget(button)
label.text = 'fin.'
ak.start(some_task())


async def spinning(label):
import itertools
sleep_for_10th_of_a_second = await ak.create_sleep(.1)
for stick in itertools.cycle('\ | / --'.split()):
label.text = stick
await sleep_for_10th_of_a_second()


if __name__ == '__main__':
TestApp().run()

0 comments on commit b48d8cc

Please sign in to comment.