"""Test async/await integration""" from distutils.version import LooseVersion as V import sys import pytest import IPython from .utils import execute, flush_channels, start_new_kernel, TIMEOUT from .test_message_spec import validate_message KC = KM = None def setup_function(): """start the global kernel (if it isn't running) and return its client""" global KM, KC KM, KC = start_new_kernel() flush_channels(KC) def teardown_function(): KC.stop_channels() KM.shutdown_kernel(now=True) skip_without_async = pytest.mark.skipif( sys.version_info < (3, 5) or V(IPython.__version__) < V("7.0"), reason="IPython >=7 with async/await required", ) @skip_without_async def test_async_await(): flush_channels(KC) msg_id, content = execute("import asyncio; await asyncio.sleep(0.1)", KC) assert content["status"] == "ok", content @pytest.mark.parametrize("asynclib", ["asyncio", "trio", "curio"]) @skip_without_async def test_async_interrupt(asynclib, request): try: __import__(asynclib) except ImportError: pytest.skip("Requires %s" % asynclib) request.addfinalizer(lambda: execute("%autoawait asyncio", KC)) flush_channels(KC) msg_id, content = execute("%autoawait " + asynclib, KC) assert content["status"] == "ok", content flush_channels(KC) msg_id = KC.execute( "print('begin'); import {0}; await {0}.sleep(5)".format(asynclib) ) busy = KC.get_iopub_msg(timeout=TIMEOUT) validate_message(busy, "status", msg_id) assert busy["content"]["execution_state"] == "busy" echo = KC.get_iopub_msg(timeout=TIMEOUT) validate_message(echo, "execute_input") stream = KC.get_iopub_msg(timeout=TIMEOUT) # wait for the stream output to be sure kernel is in the async block validate_message(stream, "stream") assert stream["content"]["text"] == "begin\n" KM.interrupt_kernel() reply = KC.get_shell_msg()["content"] assert reply["status"] == "error", reply assert reply["ename"] in {"CancelledError", "KeyboardInterrupt"} flush_channels(KC)