def test_get_nowait_triggers_close(q, fullclose): import asynckivy as ak async def producer1(q): await q.put('A') q.fullclose() if fullclose else q.close() async def producer2(q): with pytest.raises(ak.ClosedResourceError): await q.put('B') async def consumer(q): with pytest.raises(ak.ClosedResourceError if fullclose else ak.EndOfResource): await q.get() p1 = ak.start(producer1(q)) p2 = ak.start(producer2(q)) c = ak.start(consumer(q)) assert not p1.done assert not p2.done assert not c.done assert q.get_nowait() == 'A' assert p1.done assert p2.done assert c.done
def test_complete_iteration(approx, ready_to_sleep): import asynckivy as ak async def job(): l = [v async for v in ak.interpolate(start=0, end=100, step=.3)] assert l == approx([0, 30, 60, 90, 100]) sleep = ready_to_sleep() task = ak.start(job()) for __ in range(130): sleep(.01) assert task.done
def test_propagate_exception(kivy_clock): import asynckivy as ak async def job(executer): with pytest.raises(ZeroDivisionError): await ak.run_in_executer(lambda: 1 / 0, executer) with ThreadPoolExecutor() as executer: task = ak.start(job(executer)) time.sleep(.01) assert not task.done kivy_clock.tick() assert task.done
def test_properly_unbound(ed): import asynckivy as ak async def _test(): nonlocal state state = 'A' await ak.event(ed, 'on_test') state = 'B' await ak.event(ed, 'on_test2') state = 'C' await ak.event(ed, 'on_test') state = 'D' state = '' ak.start(_test()) assert state == 'A' ed.dispatch('on_test') assert state == 'B' ed.dispatch('on_test') assert state == 'B' ed.dispatch('on_test2') assert state == 'C' ed.dispatch('on_test') assert state == 'D'
def test_some_coroutines_immediately_end(self, n_do_nothing): '''github issue #3''' import asynckivy as ak async def do_nothing(): pass async def _test(): tasks = await ak.or_( *(do_nothing() for __ in range(n_do_nothing)), *(ak.Event().wait() for __ in range(3 - n_do_nothing)), ) for task in tasks[:n_do_nothing]: assert task.done for task in tasks[n_do_nothing:]: assert not task.done nonlocal done done = True done = False ak.start(_test()) assert done
def on_start(self): async def animate_label(label): sleep = asynckivy.sleep await sleep(3) while True: label.text = 'This animation' await sleep(1) label.text = 'can be cancelled' await sleep(1) label.text = 'any time' await sleep(1) label.text = 'by touching the screen.' await sleep(1) label = self.root coro = animate_label(label) def on_touch_down(*__): coro.close() label.text = 'The animation was cancelled.' label.bind(on_touch_down=on_touch_down) asynckivy.start(coro)
def test_multiple_tasks(): import asynckivy as ak e = ak.Event() async def _task1(): await e.wait() nonlocal task1_done task1_done = True async def _task2(): await e.wait() nonlocal task2_done task2_done = True task1_done = False task2_done = False ak.start(_task1()) ak.start(_task2()) assert not task1_done assert not task2_done e.set() assert task1_done assert task2_done
def test_thread_id(daemon, kivy_clock): import asynckivy as ak async def job(): before = threading.get_ident() await ak.run_in_thread(lambda: None, daemon=daemon) after = threading.get_ident() assert before == after task = ak.start(job()) time.sleep(.01) assert not task.done kivy_clock.tick() assert task.done
def test_create_sleep(): import time from kivy.clock import Clock import asynckivy as ak async def _task(): nonlocal task_state sleep = await ak.create_sleep(.5) task_state = 'A' await sleep() task_state = 'B' await sleep() task_state = 'C' task_state = None Clock.tick() ak.start(_task()) time.sleep(.2) Clock.tick() assert task_state == 'A' time.sleep(.5) Clock.tick() assert task_state == 'B' time.sleep(.5) Clock.tick() assert task_state == 'C'
def test_filter(ed): import asynckivy as ak async def _test(): await ak.event( ed, 'on_test', filter=lambda *args: args == (ed, 3, 4, ) ) task = ak.start(_test()) assert not task.done ed.dispatch('on_test', 1, 2) assert not task.done ed.dispatch('on_test', 3, 4) assert task.done
def test_event_parameter(ed): import asynckivy as ak async def _test(): r = await ak.event(ed, 'on_test') assert r == (ed, 1, 2, ) r = await ak.event(ed, 'on_test') assert r == (ed, 3, 4, ) # kwarg is ignored task = ak.start(_test()) assert not task.done ed.dispatch('on_test', 1, 2) assert not task.done ed.dispatch('on_test', 3, 4, kwarg='A') assert task.done
def test_thread_id(kivy_clock): import asynckivy as ak async def job(executer): before = threading.get_ident() await ak.run_in_executer(lambda: None, executer) after = threading.get_ident() assert before == after with ThreadPoolExecutor() as executer: task = ak.start(job(executer)) time.sleep(.01) assert not task.done kivy_clock.tick() assert task.done
def test_sleep(): import time from kivy.clock import Clock import asynckivy as ak Clock.tick() task = ak.start(ak.sleep(.1)) assert not task.done Clock.tick() assert not task.done time.sleep(.07) Clock.tick() assert not task.done time.sleep(.07) Clock.tick() assert task.done
def _start_anim(self, *args): if self.children: child = self.children[0] self._coro.close() if not self.do_anim: child.pos = self.pos child.size = self.size return self._coro = ak.start( ak.animate( child, d=self.anim_duration, t=self.anim_transition, x=self.x, y=self.y, width=self.width, height=self.height, ))
def test_sleep_free(): import time from kivy.clock import Clock import asynckivy as ak if not hasattr(Clock, 'create_trigger_free'): pytest.skip("free-type Clock is not available") Clock.tick() task = ak.start(ak.sleep_free(.1)) assert not task.done Clock.tick() assert not task.done time.sleep(.07) Clock.tick() assert not task.done time.sleep(.07) Clock.tick() assert task.done
def test_cancel(ready_to_sleep): from kivy.uix.widget import Widget import asynckivy as ak async def job(w1, w2): async with ak.fade_transition(w1, w2): pass w1 = Widget(opacity=1) w2 = Widget(opacity=2) sleep = ready_to_sleep() task = ak.start(job(w1, w2)) sleep(.1) assert w1.opacity != 1 assert w2.opacity != 2 task.cancel() assert w1.opacity == 1 assert w2.opacity == 2
def test_cancel(ed): import asynckivy as ak async def _test(ed): def filter_func(*args): nonlocal called; called = True return True await ak.event(ed, 'on_test', filter=filter_func) called = False task = ak.start(_test(ed)) assert not task.done assert not called task.close() assert not task.done assert not called ed.dispatch('on_test') assert not task.done assert not called
def test_stop_dispatching(stop_dispatching, expectation): from kivy.uix.widget import Widget from kivy.tests.common import UnitTestTouch import asynckivy as ak async def _test(parent, t): async for __ in ak.rest_of_touch_moves( parent, t, stop_dispatching=stop_dispatching): pass n_touches = { 'move': 0, 'up': 0, } def on_touch_move(*args): n_touches['move'] += 1 def on_touch_up(*args): n_touches['up'] += 1 parent = Widget() child = Widget( on_touch_move=on_touch_move, on_touch_up=on_touch_up, ) parent.add_widget(child) t = UnitTestTouch(0, 0) task = ak.start(_test(parent, t)) for i in range(2): t.grab_current = None parent.dispatch('on_touch_move', t) t.grab_current = parent parent.dispatch('on_touch_move', t) assert n_touches['move'] == expectation[i] t.grab_current = None parent.dispatch('on_touch_up', t) t.grab_current = parent parent.dispatch('on_touch_up', t) assert n_touches['up'] == expectation[2] assert task.done
async def _handle_touch(self, touch): from asynckivy import animate, Event, rest_of_touch_moves, start self._ctx = True self.dispatch('on_press') try: flag_proceed_blinking = Event() flag_proceed_blinking.set() coro_blink = start(self._blink(flag_proceed_blinking)) async for __ in rest_of_touch_moves(self, touch): if self.collide_point(*touch.pos): flag_proceed_blinking.set() else: flag_proceed_blinking.clear() if self.collide_point(*touch.pos): await animate(self, _scaling=.9, d=.05) await animate(self, _scaling=1, d=.05) self.dispatch('on_release') finally: coro_blink.close() self._ctx = None
def test_break_during_iteration(approx, ready_to_sleep): import asynckivy as ak async def job(): l = [] async for v in ak.interpolate(start=0, end=100, step=.3): l.append(v) if v > 50: break assert l == approx([0, 30, 60, ]) await ak.sleep_forever() sleep = ready_to_sleep() task = ak.start(job()) for __ in range(130): sleep(.01) assert not task.done with pytest.raises(StopIteration): task.root_coro.send(None) assert task.done
def test_multiple_tasks_wait_for_the_same_task_to_be_cancelled( wait_for_a, expected_a, wait_for_b, expected_b, ): task1 = ak.Task(ak.sleep_forever()) task2a = ak.Task(task1.wait(wait_for_a)) task2b = ak.Task(task1.wait(wait_for_b)) ak.start(task1) ak.start(task2a) ak.start(task2b) task1.cancel() assert task2a.state is expected_a assert task2b.state is expected_b
def test_cancel_before_getting_excuted(kivy_clock): import time import asynckivy as ak flag = ak.Event() async def job(executer): await ak.run_in_executer(flag.set, executer) with ThreadPoolExecutor(max_workers=1) as executer: executer.submit(time.sleep, .1) task = ak.start(job(executer)) time.sleep(.02) assert not task.done assert not flag.is_set() kivy_clock.tick() task.cancel() assert task.cancelled assert not flag.is_set() time.sleep(.2) assert not flag.is_set()
def test_multiple_tasks_wait_for_the_same_task_to_complete( wait_for_a, expected_a, wait_for_b, expected_b, ): task1 = ak.Task(ak.sleep_forever()) task2a = ak.Task(task1.wait(wait_for_a)) task2b = ak.Task(task1.wait(wait_for_b)) ak.start(task1) ak.start(task2a) ak.start(task2b) with pytest.raises(StopIteration): task1.root_coro.send(None) assert task2a.state is expected_a assert task2b.state is expected_b
def test_break_during_a_for_loop(): from kivy.uix.widget import Widget from kivy.tests.common import UnitTestTouch import asynckivy as ak async def _test(w, t): import weakref nonlocal n_touch_moves weak_w = weakref.ref(w) assert weak_w not in t.grab_list async for __ in ak.rest_of_touch_moves(w, t): assert weak_w in t.grab_list n_touch_moves += 1 if n_touch_moves == 2: break assert weak_w not in t.grab_list await ak.event(w, 'on_touch_up') n_touch_moves = 0 w = Widget() t = UnitTestTouch(0, 0) task = ak.start(_test(w, t)) for expected in ( 1, 2, 2, ): t.grab_current = None w.dispatch('on_touch_move', t) t.grab_current = w w.dispatch('on_touch_move', t) assert n_touch_moves == expected assert not task.done t.grab_current = None w.dispatch('on_touch_up', t) t.grab_current = w w.dispatch('on_touch_up', t) assert n_touch_moves == 2 assert task.done
def test_a_number_of_on_touch_moves_fired(n_touch_moves): from kivy.uix.widget import Widget from kivy.tests.common import UnitTestTouch import asynckivy as ak async def _test(w, t): n = 0 async for __ in ak.rest_of_touch_moves(w, t): n += 1 assert n == n_touch_moves w = Widget() t = UnitTestTouch(0, 0) task = ak.start(_test(w, t)) for __ in range(n_touch_moves): t.grab_current = None w.dispatch('on_touch_move', t) t.grab_current = w w.dispatch('on_touch_move', t) t.grab_current = None w.dispatch('on_touch_up', t) t.grab_current = w w.dispatch('on_touch_up', t) assert task.done
async def _see_if_a_touch_actually_is_a_dragging_gesture(self, touch): tasks = await ak.or_( ak.sleep(self.drag_timeout / 1000.), self._true_when_a_touch_ended_false_when_it_moved_too_much(touch), ) if tasks[0].done: # The given touch is a dragging gesture. if self._can_be_dragged: self._drag_task.cancel() self._drag_task = ak.Task( self._treat_a_touch_as_a_drag(touch, do_transform=True)) ak.start(self._drag_task) else: ak.start( self._simulate_a_normal_touch(touch, do_transform=True)) else: # The given touch is not a dragging gesture. ak.start( self._simulate_a_normal_touch(touch, do_touch_up=tasks[1].result))
def on_touch_down(self, touch): if self._ctx is None and self.collide_point(*touch.opos) \ and not touch.is_mouse_scrolling: ak.start(self._handle_touch(touch)) return True return super().on_touch_down(touch)
def on_start(self): ak.start(self.root.main(db_path=__file__ + r".sqlite3"))
def on_kv_post(self, *args, **kwargs): import asynckivy super().on_kv_post(*args, **kwargs) asynckivy.start(self._async_main())
def on_touch_down(self, touch): if self.collide_point(*touch.opos): ak.start(self.draw_rect(touch)) return True