From a1e70fc729d0861b9c8091352bd452ee5860149c 2018-08-28 22:06:29 From: Matthias Bussonnier Date: 2018-08-28 22:06:29 Subject: [PATCH] Test that using wrong runner/coroutine pair does not crash. Make sure that if the coroutine runner encounter an exception (likely when encountering the wrong coroutine from another aio library), it is set on the result and does not crash the interpreter. --- diff --git a/IPython/core/interactiveshell.py b/IPython/core/interactiveshell.py index 0f6e3a8..8e22b0d 100644 --- a/IPython/core/interactiveshell.py +++ b/IPython/core/interactiveshell.py @@ -2829,7 +2829,14 @@ class InteractiveShell(SingletonConfigurable): return interactivity if interactivity == 'async': - return self.loop_runner(coro) + try: + return self.loop_runner(coro) + except Exception as e: + info = ExecutionInfo(raw_cell, store_history, silent, shell_futures) + result = ExecutionResult(info) + result.error_in_exec = e + self.showtraceback(running_compiled_code=True) + return result return _pseudo_sync_runner(coro) @asyncio.coroutine diff --git a/IPython/core/tests/test_async_helpers.py b/IPython/core/tests/test_async_helpers.py index c219a0f..6bf64e2 100644 --- a/IPython/core/tests/test_async_helpers.py +++ b/IPython/core/tests/test_async_helpers.py @@ -13,6 +13,7 @@ from IPython.testing.decorators import skip_without ip = get_ipython() iprc = lambda x: ip.run_cell(dedent(x)).raise_error() +iprc_nr = lambda x: ip.run_cell(dedent(x)) if sys.version_info > (3, 5): from IPython.core.async_helpers import _should_be_async @@ -251,5 +252,26 @@ if sys.version_info > (3, 5): def test_autoawait_trio(self): iprc("%autoawait trio") + @skip_without('trio') + def test_autoawait_trio_wrong_sleep(self): + iprc("%autoawait trio") + res = iprc_nr(""" + import asyncio + await asyncio.sleep(0) + """) + with nt.assert_raises(TypeError): + res.raise_error() + + @skip_without('trio') + def test_autoawait_asyncio_wrong_sleep(self): + iprc("%autoawait asyncio") + res = iprc_nr(""" + import trio + await trio.sleep(0) + """) + with nt.assert_raises(RuntimeError): + res.raise_error() + + def tearDown(self): ip.loop_runner = "asyncio"