albertz / background-zmq-ipython

Background ZMQ IPython/Jupyter kernel
BSD 2-Clause "Simplified" License
17 stars 4 forks source link

Add support for await syntax ipython #9

Open Dalbasar opened 2 years ago

Dalbasar commented 2 years ago

Since ipython 7 it is possible to directly call coroutines in the jupyter console (and qtconsole) by just typing await any_coroutine(). This is can be very convenient for testing and works great with a plain jupyter console, but not when it is connected to a background zmq ipython kernel: The command gets executed by the kernel, but the command never returns to the client, e.g. executing

import asyncio
async def hello_world():
     print("Hello")
     await asyncio.sleep(0.5)
     print("World")

await hello_world()

results in a ValueError exception in the kernel:

IPython: Start kernel now. pid: 10836, thread: <Thread(IPython kernel, started daemon 11664)> Exception in message handler: Traceback (most recent call last): File "\bzmqipython\lib\site-packages\ipykernel\kernelbase.py", line 261, in dispatch_shell yield gen.maybe_future(handler(stream, idents, msg)) File "\bzmqipython\lib\site-packages\tornado\gen.py", line 762, in run value = future.result() File "\bzmqipython\lib\site-packages\tornado\gen.py", line 769, in run yielded = self.gen.throw(*exc_info) # type: ignore File "\bzmqipython\lib\site-packages\ipykernel\kernelbase.py", line 538, in execute_request reply_content = yield gen.maybe_future( File "\bzmqipython\lib\site-packages\tornado\gen.py", line 762, in run value = future.result() File "\bzmqipython\lib\site-packages\tornado\gen.py", line 234, in wrapper yielded = ctx_run(next, result) File "\bzmqipython\lib\site-packages\ipykernel\ipkernel.py", line 290, in do_execute with self._cancel_on_sigint(coro_future): File "\AppData\Local\Programs\Python\Python39\lib\contextlib.py", line 119, in enter return next(self.gen) File "\bzmqipython\lib\site-packages\ipykernel\ipkernel.py", line 251, in _cancel_on_sigint save_sigint = signal.signal(signal.SIGINT, handle_sigint) File "\AppData\Local\Programs\Python\Python39\lib\signal.py", line 47, in signal handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler)) ValueError: signal only works in main thread of the main interpreter Hello World

Observed with ipykernel==5.5.6 and jupyter-client==6.1.2 with Python 3.9.9 on Windows 10 64bit.