Skip to content

Commit 52e790f

Browse files
committed
Abort individual subshell on exception
1 parent c8c7b62 commit 52e790f

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

ipykernel/kernelbase.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,15 @@ async def dispatch_shell(self, msg, /, stream=None, subshell_id: str | None = No
393393
stream = self.shell_stream
394394

395395
# Only abort execute requests
396-
if self._aborting and msg_type == "execute_request":
397-
self._send_abort_reply(self.shell_stream, msg, idents)
398-
self._publish_status_and_flush("idle", "shell", stream)
399-
return
396+
if msg_type == "execute_request":
397+
if subshell_id is None:
398+
aborting = self._aborting # type:ignore[unreachable]
399+
else:
400+
aborting = self.shell_channel_thread.manager.get_subshell_aborting(subshell_id)
401+
if aborting:
402+
self._send_abort_reply(self.shell_stream, msg, idents)
403+
self._publish_status_and_flush("idle", "shell", stream)
404+
return
400405

401406
# Print some info about this message and leave a '--->' marker, so it's
402407
# easier to trace visually the message chain when debugging. Each

ipykernel/subshell_manager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ def get_shell_channel_stream(self, subshell_id: str | None) -> ZMQStream:
113113
with self._lock_cache:
114114
return self._cache[subshell_id].shell_channel_stream
115115

116+
def get_subshell_aborting(self, subshell_id: str) -> bool:
117+
"""Get the aborting flag of the specified subshell."""
118+
return self._cache[subshell_id].aborting
119+
116120
def list_subshell(self) -> list[str]:
117121
"""Return list of current subshell ids.
118122

tests/test_subshells.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ def test_shutdown_with_subshell():
209209
assert not km.is_alive()
210210

211211

212-
@pytest.mark.parametrize("are_subshells", [(False, True)])
212+
@pytest.mark.parametrize("are_subshells", [(False, True), (True, False), (True, True)])
213213
def test_execute_stop_on_error(are_subshells):
214214
# Based on test_message_spec.py::test_execute_stop_on_error, testing that exception
215215
# in one subshell aborts execution queue in that subshell but not others.
@@ -221,7 +221,6 @@ def test_execute_stop_on_error(are_subshells):
221221

222222
msg_ids = []
223223

224-
# msg = execute_request(kc, "print('ok')", subshell_ids[0])
225224
msg = execute_request(
226225
kc, "import asyncio; await asyncio.sleep(1); raise ValueError()", subshell_ids[0]
227226
)

0 commit comments

Comments
 (0)