diff --git a/clikernel/core.py b/clikernel/core.py index 0266a69..4d58788 100644 --- a/clikernel/core.py +++ b/clikernel/core.py @@ -151,7 +151,10 @@ async def execute_outs(self:Client, code): "Run `code` in the current kernel; nbformat-style output dicts (or a protocol note string)" if not self.kc: return 'no kernel: call `connect` first' try: return await self.kc.run(code) - except DeadKernelError: return 'NOTE: the kernel process died. `connect` to create or attach to another.' + except DeadKernelError: + await self.kc.aclose() + self.kc = None + return 'NOTE: the kernel process died. The next `execute` will create another, or call `connect` to attach to one.' @patch async def execute(self:Client, code): diff --git a/nbs/00_core.ipynb b/nbs/00_core.ipynb index 57bb706..b383268 100644 --- a/nbs/00_core.ipynb +++ b/nbs/00_core.ipynb @@ -308,7 +308,10 @@ " \"Run `code` in the current kernel; nbformat-style output dicts (or a protocol note string)\"\n", " if not self.kc: return 'no kernel: call `connect` first'\n", " try: return await self.kc.run(code)\n", - " except DeadKernelError: return 'NOTE: the kernel process died. `connect` to create or attach to another.'\n", + " except DeadKernelError:\n", + " await self.kc.aclose()\n", + " self.kc = None\n", + " return 'NOTE: the kernel process died. The next `execute` will create another, or call `connect` to attach to one.'\n", "\n", "@patch\n", "async def execute(self:Client, code):\n", @@ -634,6 +637,7 @@ "await c2.mgr.shutdown_kernel(c2.kid) # killed behind our back\n", "res = await c2.execute('1+1')\n", "assert res.startswith('NOTE') # a concise note, not a traceback\n", + "assert c2.kc is None # the next execute can auto-connect instead of reusing a dead ws\n", "await c2.connect()\n", "test_eq(await c2.execute('1+1'), '2') # and connecting again recovers\n", "await c2.stop()"