def async_run(coroutines): future = Future() outcomes = [None] * len(coroutines) for i, co in enumerate(coroutines): try: next(co) except StopIteration as ex: outcomes[i] = ex.value except Exception as ex: future.set_exception(ex) return future, None if all(value is not None for value in outcomes): future.set_result(outcomes) return future, None def _resume(to_completion=False): nonlocal outcomes if future.done(): raise RuntimeError("'async_run' done already") for i, co in enumerate(coroutines): if outcomes[i] is None: try: co.send(to_completion) except StopIteration as ex: outcomes[i] = ex.value except Exception as ex: future.set_exception(ex) return if to_completion or all(value is not None for value in outcomes): future.set_result(outcomes) return future, _resume
def test_set_exception_invokes_callbacks(self): called = False def cb(fut): nonlocal called called = True f = Future() f.add_done_callback(cb) f.set_exception('Anything') assert called
def test_await_exception(self): f = Future() async def coro(): nonlocal f return await f c = coro() c.send(None) f.set_exception(RuntimeError('test exception')) with self.assertRaises(RuntimeError): c.send(None)
def test_set_exception_schedules_callbacks(self): executor = DummyExecutor() f = Future(executor=executor) f.add_done_callback(lambda f: None) f.set_exception('Anything') self.assertTrue(executor.done_callbacks)
def test_set_exception(self): f = Future() f.set_exception('Sentinel Exception') self.assertEqual('Sentinel Exception', f.exception()) self.assertTrue(f.done())