async def test_too_many_stops(self): with trio.move_on_after(1) as scope: async with trio_asyncio.open_loop() as loop: await trio.hazmat.checkpoint() loop.stop() assert not scope.cancelled_caught, \ "Possible deadlock after manual call to loop.stop"
async def async_main( host: str = '127.0.0.1', port: int = 5000, debug: Optional[bool] = None, use_reloader: bool = True, ca_certs: Optional[str] = None, certfile: Optional[str] = None, keyfile: Optional[str] = None, **kwargs: Any, ): """ Modified version of Quart's app.run(). Modification is done to integrate trio_asyncio and Quart together. """ async with trio_asyncio.open_loop() as loop: assert loop == asyncio.get_event_loop() # this line fix problem with aioredis # https://github.com/python-trio/trio-asyncio/issues/63 asyncio._set_running_loop(asyncio.get_event_loop()) if kwargs: warnings.warn( f'Additional arguments, {",".join(kwargs.keys())}, are not supported.\n' 'They may be supported by Hypercorn, which is the ASGI server Quart ' 'uses by default. This method is meant for development and debugging.' ) scheme = 'https' if certfile is not None and keyfile is not None else 'http' print(f'Running on {scheme}://{host}:{port} (CTRL + C to quit)' ) # noqa: T001, T002 await app.run_task(host, port, debug, use_reloader, ca_certs, certfile, keyfile)
async def run_server() -> None: async with trio_asyncio.open_loop(): asyncio._set_running_loop(asyncio.get_event_loop()) # noqa config = HyperConfig() config.bind = [f"127.0.0.1:5000"] config.use_reloader = True await serve(app, config)
async def open_loop(): nonlocal loop if loop is None: async with trio_asyncio.open_loop() as loop: yield loop else: yield loop
async def async_main_wrapper(options, cfg, run_once, t00, run_func): print("R-once", run_once) async with trio_asyncio.open_loop() as loop: await trio_count() rslt = await loop.run_asyncio(run_func, options, cfg, run_once, t00) await trio_count() return rslt
async def _run(self): async with trio_asyncio.open_loop() as loop: self.loop = loop loop.set_debug(True) self.event.set() await loop.wait_stopped()
async def asyncio_loop(): # When a ^C happens, trio send a Cancelled exception to each running # coroutine. We must protect this one to avoid deadlock if it is cancelled # before another coroutine that uses trio-asyncio. with trio.CancelScope() as cancel_scope: cancel_scope.shield = True async with trio_asyncio.open_loop() as loop: yield loop
async def test_get_running_loop(): async with trio_asyncio.open_loop() as loop: try: from asyncio import get_running_loop except ImportError: pass # Python 3.6 else: assert get_running_loop() == loop
async def manage_loop(task_status): try: with trio.CancelScope() as scope: async with trio_asyncio.open_loop() as loop: task_status.started((loop, scope)) await trio.sleep_forever() finally: assert scope.cancelled_caught
async def test_run_task(self): owch = 0 async def nest(x): nonlocal owch owch += x with pytest.raises(RuntimeError): trio_asyncio.run_trio_task(nest, 100) with pytest.raises(RuntimeError): with trio_asyncio.open_loop(): nest(1000) async with trio_asyncio.open_loop(): trio_asyncio.run_trio_task(nest, 1) await trio.sleep(0.05) assert owch == 1
async def test_close_no_stop(self): with pytest.raises(RuntimeError): async with trio_asyncio.open_loop() as loop: def close_no_stop(): loop.close() loop.call_soon(close_no_stop) await trio.sleep(0.1) await loop.wait_closed()
async def _test_same_task(): assert isinstance(asyncio.get_event_loop_policy(), TrioPolicy) def get_loop(i, loop, policy): assert loop == asyncio.get_event_loop() assert policy == asyncio.get_event_loop_policy() async with trio.open_nursery(): async with trio_asyncio.open_loop() as loop1: policy = asyncio.get_event_loop_policy() assert isinstance(policy, TrioPolicy) async with trio_asyncio.open_loop() as loop2: p2 = asyncio.get_event_loop_policy() assert policy is p2, (policy, p2) loop1.call_later(0.1, get_loop, 0, loop1, policy) loop2.call_later(0.1, get_loop, 1, loop2, policy) await trio.sleep(0.2) assert isinstance(asyncio.get_event_loop_policy(), TrioPolicy) assert asyncio._get_running_loop() is None
async def main(browser_port, log, rabbit_user, rabbit_pass, rabbit_host, rabbit_port): if not log: logger.disabled = True async with contextlib.AsyncExitStack() as stack: await stack.enter_async_context(trio_asyncio.open_loop()) nursery = await stack.enter_async_context(trio.open_nursery()) nursery.start_soon(listen_rabbit, rabbit_user, rabbit_pass, rabbit_host, rabbit_port) nursery.start_soon(serve_websocket, process_to_browser, '127.0.0.1', browser_port, None)
async def run_asyncio_loop(nursery, *, task_status=trio.TASK_STATUS_IGNORED): with trio.CancelScope() as cancel_scope: try: async with trio_asyncio.open_loop(): # Starting a coroutine from here make it inherit the access # to the asyncio loop context manager await nursery.start(work_in_trio_no_matter_what) task_status.started(cancel_scope) await trio.sleep_forever() finally: asyncio_loop_closed.set()
async def run_server() -> None: async with trio_asyncio.open_loop(): # trio_asyncio has difficulties with aioredis, workaround here: # https://github.com/python-trio/trio-asyncio/issues/63 (answer from @parity3) asyncio._set_running_loop(asyncio.get_event_loop()) config = HyperConfig() config.bind = [f"0.0.0.0:5000"] config.use_reloader = True app.static_folder = "frontend" await serve(app, config)
async def asyncio_loop(request): # asyncio loop is only needed for triopg if not request.config.getoption("--postgresql"): yield None else: # When a ^C happens, trio send a Cancelled exception to each running # coroutine. We must protect this one to avoid deadlock if it is cancelled # before another coroutine that uses trio-asyncio. with trio.CancelScope(shield=True): async with trio_asyncio.open_loop() as loop: yield loop
async def run(self): ''' Run the downloader, including all concurrent download tasks. When cancelled, all download tasks are also cancelled. :returns: Runs until cancelled. ''' async with trio.open_nursery() as nursery, \ trio_asyncio.open_loop(): async for request in self._recv_channel: await self._semaphore.acquire() self._count += 1 nursery.start_soon(self._download, request)
async def test_tasks_get_cancelled(): record = [] tasks = [] @types.coroutine def aio_yield(): yield async def aio_sleeper(key): try: await asyncio.sleep(10) record.append("expired") finally: try: # Prove that we're still running in the aio loop, not # some GC pass await aio_yield() finally: record.append(key) if "early" in key: tasks.append(asyncio.ensure_future( aio_sleeper("aio late"))) asyncio.get_event_loop().run_trio_task( trio_sleeper, "trio late") async def trio_sleeper(key): try: await trio.sleep_forever() finally: await trio.lowlevel.cancel_shielded_checkpoint() record.append(key) async with trio_asyncio.open_loop() as loop: tasks.append(asyncio.ensure_future(aio_sleeper("aio early"))) loop.run_trio_task(trio_sleeper, "trio early") assert set(record) == {"aio early", "trio early", "trio late"} assert len(tasks) == 2 and tasks[0].done() and not tasks[1].done() # Suppress "Task was destroyed but it was pending!" message tasks[1]._log_traceback = False tasks[1]._log_destroy_pending = False # Suppress the "coroutine ignored GeneratorExit" message while True: try: tasks[1]._coro.throw(SystemExit) except SystemExit: break
async def test_wrong_context_manager_order(): take_down = trio.Event() async def work_in_asyncio(): await asyncio.sleep(0) async def runner(*, task_status=trio.TASK_STATUS_IGNORED): await trio_asyncio.aio_as_trio(work_in_asyncio)() try: task_status.started() await take_down.wait() finally: await trio_asyncio.aio_as_trio(work_in_asyncio)() async with trio.open_nursery() as nursery: async with trio_asyncio.open_loop(): await nursery.start(runner) take_down.set()
async def test_trio_as_fut_throws_after_cancelled(): """If a trio_as_future() future is cancelled, any exception thrown by the Trio task as it unwinds is ignored. (This is somewhat infelicitous, but the asyncio Future API doesn't allow a future to go from cancelled to some other outcome.) """ async def trio_task(): try: await trio.sleep_forever() finally: raise ValueError("hi") async with trio_asyncio.open_loop() as loop: fut = loop.trio_as_future(trio_task) await trio.testing.wait_all_tasks_blocked() fut.cancel() with pytest.raises(asyncio.CancelledError): await fut
async def test_run_trio_task_errors(monkeypatch): async with trio_asyncio.open_loop() as loop: # Test never getting to start the task handle = loop.run_trio_task(trio.sleep_forever) handle.cancel() # Test cancelling the task handle = loop.run_trio_task(trio.sleep_forever) await trio.testing.wait_all_tasks_blocked() handle.cancel() # Helper for the rest of this test, which covers cases where # the Trio task raises an exception async def raise_in_aio_loop(exc): async def raise_it(): raise exc async with trio_asyncio.open_loop() as loop: loop.run_trio_task(raise_it) # We temporarily modify the default exception handler to collect # the exceptions instead of logging or raising them exceptions = [] def collect_exceptions(loop, context): if context.get("exception"): exceptions.append(context["exception"]) else: exceptions.append(RuntimeError(context.get("message") or "unknown")) monkeypatch.setattr( trio_asyncio.TrioEventLoop, "default_exception_handler", collect_exceptions ) expected = [ ValueError("hi"), ValueError("lo"), KeyError(), IndexError() ] await raise_in_aio_loop(expected[0]) with pytest.raises(SystemExit): await raise_in_aio_loop(SystemExit(0)) with pytest.raises(SystemExit): await raise_in_aio_loop(trio.MultiError([expected[1], SystemExit()])) await raise_in_aio_loop(trio.MultiError(expected[2:])) assert exceptions == expected
async def test_contextvars(): import contextvars cvar = contextvars.ContextVar("test_cvar") cvar.set("outer") async def fudge_in_aio(): assert cvar.get() == "outer" cvar.set("middle") await trio_asyncio.trio_as_aio(fudge_in_trio)() assert cvar.get() == "middle" async def fudge_in_trio(): assert cvar.get() == "middle" cvar.set("inner") async with trio_asyncio.open_loop() as loop: await trio_asyncio.aio_as_trio(fudge_in_aio)() assert cvar.get() == "outer"
async def main(routes_number, buses_per_route, emulator_id, refresh_timeout, log, rabbit_user, rabbit_pass, rabbit_host, rabbit_port): if not log: logger.setLevel(logging.ERROR) async with contextlib.AsyncExitStack() as stack: await stack.enter_async_context(trio_asyncio.open_loop()) nursery = await stack.enter_async_context(trio.open_nursery()) send_channel, receive_channel = trio.open_memory_channel(0) processed_routes = 0 nursery.start_soon(process_rabbit, receive_channel, refresh_timeout, rabbit_user, rabbit_pass, rabbit_host, rabbit_port) for route in load_routes(routes_count=routes_number): for bus in range(buses_per_route): random_bus_index = random.randint(99, 9999) random_bus_id = generate_bus_id(route['name'], random_bus_index, emulator_id) nursery.start_soon(run_bus, send_channel, random_bus_id, route) processed_routes += 1 logger.debug(f'buses send {processed_routes}')
async def test_trio_sockets_msg_raw(self, zmq_trio_ctx, autojump_clock): async with trio_asyncio.open_loop(): endpoint = "inproc://test" router = zmq_trio.DealerRouterSocket(zmq_trio_ctx, zmq.ROUTER, side=ServerSide) req = zmq_trio.ReqSocket(zmq_trio_ctx, zmq.REQ, side=ClientSide) with router, req: router.bind(endpoint) req.connect(endpoint) old = b'as' await req.send_msg_raw(old) header, new = await router.recv_msg_raw() assert new == old old = b'df' await router.send_msg_raw(header, old) new = await req.recv_msg_raw() assert new == old
async def start(self): async with trio_asyncio.open_loop(): self.initialize() runner = web.AppRunner(self.web_app) await trio_asyncio.aio_as_trio(runner.setup) site = web.TCPSite(runner, self.app.config.api['host'], self.app.config.api['port'] ) await trio_asyncio.aio_as_trio(site.start) logger.info("REST API Server started at http://{0.api[host]}:{0.api[port]}"\ .format(self.app.config)) self.ready.set() await self.shutdown.wait() await trio_asyncio.aio_as_trio(site.stop) self.dead.set()
async def test_trio_sockets_msg(self, zmq_trio_ctx, autojump_clock): async with trio_asyncio.open_loop(): endpoint = "inproc://test" router = zmq_trio.DealerRouterSocket(zmq_trio_ctx, zmq.ROUTER, side=ServerSide) req = zmq_trio.ReqSocket(zmq_trio_ctx, zmq.REQ, side=ClientSide) with router, req: router.bind(endpoint) req.connect(endpoint) old = analog.Request(1) # type: Message await req.send_msg(old) header, new = await router.recv_msg() assert new == old old = analog.Reply(1, 200) await router.send_msg(header, old) new = await req.recv_msg() assert new == old
async def test_trio_sockets_msgs(self, zmq_trio_ctx, autojump_clock): async with trio_asyncio.open_loop(): endpoint = "inproc://test" router = zmq_trio.DealerRouterSocket(zmq_trio_ctx, zmq.ROUTER, side=ServerSide) req = zmq_trio.ReqSocket(zmq_trio_ctx, zmq.REQ, side=ClientSide) with router, req: router.bind(endpoint) req.connect(endpoint) olds = [analog.Request(0), digital.Request(0)] await req.send_msgs(olds) header, news = await router.recv_msgs() for old, new in zip(olds, news): assert new == old olds = [analog.Reply(0, 100), digital.Reply(0, True)] await router.send_msgs(header, olds) news = await req.recv_msgs() for old, new in zip(olds, news): assert new == old
async def download(self, request, skip_mime=False): ''' Download a requested resource and return it. Note: this is probably not the method you want! Most downloads should be sent through the request channel. This method is only for unusual cases where we want to download one item and return the response directly to the caller, such as a robot.txt or a login page. These responses are not included in job statistics and do not get stored in the database. The caller should apply their own timeout here. :param DownloadRequest request: :param bool skip_mime: If True, the MIME type will not be checked against the policy. :rtype DownloadResponse: ''' async with self._semaphore, trio_asyncio.open_loop(): response = await self._download_asyncio(request, skip_mime=skip_mime) return response
async def test_trio_socket(self, zmq_trio_ctx, autojump_clock): async with trio_asyncio.open_loop(): a, b = (zmq_trio_ctx.socket(zmq.PAIR).configure(hwm=1000, linger=0) for _ in range(2)) with a, b: a.bind('inproc://endpoint') b.connect('inproc://endpoint') with assertTimeoutTrio(1): await b.poll() assert await b.poll(timeout=1) == 0 with assertPassed(1): with assertTimeoutTrio(1): await b.wait() await a.signal() await b.wait() with assertPassed(1): with assertTimeoutTrio(1): await b.recv_multipart_expect((b'foo', b'bar')) await a.send_multipart((b'foo', b'bar')) await b.recv_multipart_expect((b'foo', b'bar'))
async def run(app, *args, _interface=web.TCPSite, **kwargs): """Run an aiohttp web app under Trio. Usage:: from trio_aiohttp import run,get,websocket from aiohttp import web app = web.Application() app.add_routes([get('/', handle_static), websocket('/_ws', run_websock), get('/{name}', handle_static), ]) await run(app, 'localhost', 8080) """ async with trio_asyncio.open_loop(): runner = web.AppRunner(app) await trio_asyncio.run_asyncio(runner.setup) site = _interface(runner, *args, **kwargs) await trio_asyncio.run_asyncio(site.start) try: await trio.sleep(math.inf) finally: await trio_asyncio.run_asyncio(site.stop)
async def run(): adapter = hardware() handler = handlers.merge(HardwareHandler(adapter), ProcessHandler(adapter)) async with trio_asyncio.open_loop(), adapter: await HedgehogServer(ctx, 'tcp://*:{}'.format(port), handler).run()
async def loop(): async with trio_asyncio.open_loop() as loop: try: yield loop finally: await loop.stop().wait()
async def asyncio_loop(): async with trio_asyncio.open_loop() as loop: yield loop
async def raise_in_aio_loop(exc): async def raise_it(): raise exc async with trio_asyncio.open_loop() as loop: loop.run_trio_task(raise_it)
async def test_trio_socket_configure(self, zmq_trio_ctx, autojump_clock): async with trio_asyncio.open_loop(): with zmq_trio_ctx.socket(zmq.PAIR).configure() as socket: do_test_socket_configure(socket)
async def test_no_fixture(): async with trio_asyncio.open_loop(): await use_asyncio()
async def asyncio_fixture_own_loop(): async with trio_asyncio.open_loop(): await use_asyncio() yield None
async def asyncio_loop(): ''' Open an asyncio loop. Useful for things like aiohttp.CookieJar that require a global loop. ''' async with trio_asyncio.open_loop() as loop: yield loop