Skip to content

Commit

Permalink
Fix interrupt reply (#1101)
Browse files Browse the repository at this point in the history
* Fix interrupt

* .

* .

* .

* .
  • Loading branch information
garlandz-db authored Mar 4, 2023
1 parent 287184f commit e46f75b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
25 changes: 17 additions & 8 deletions ipykernel/kernelbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ async def comm_info_request(self, stream, ident, parent):
msg = self.session.send(stream, "comm_info_reply", reply_content, parent, ident)
self.log.debug("%s", msg)

def _send_interupt_children(self):
def _send_interrupt_children(self):
if os.name == "nt":
self.log.error("Interrupt message not supported on Windows")
else:
Expand All @@ -894,18 +894,27 @@ def _send_interupt_children(self):
if pgid and pgid == pid and hasattr(os, "killpg"):
try:
os.killpg(pgid, SIGINT)
return
except OSError:
pass
try:
os.kill(pid, SIGINT)
raise
else:
os.kill(pid, SIGINT)
except OSError:
pass

async def interrupt_request(self, stream, ident, parent):
"""Handle an interrupt request."""
self._send_interupt_children()
content = parent["content"]
content: t.Dict[str, t.Any] = {"status": "ok"}
try:
self._send_interrupt_children()
except OSError as err:
import traceback

content = {
"status": "error",
"traceback": traceback.format_stack(),
"ename": str(type(err).__name__),
"evalue": str(err),
}

self.session.send(stream, "interrupt_reply", content, parent, ident=ident)
return

Expand Down
2 changes: 1 addition & 1 deletion ipykernel/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ async def _wait_for_msg(self):
_, msg = self.session.feed_identities(self._reply)
return self.session.deserialize(msg)

def _send_interupt_children(self):
def _send_interrupt_children(self):
# override to prevent deadlock
pass

Expand Down
15 changes: 14 additions & 1 deletion ipykernel/tests/test_ipkernel_direct.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,21 @@ async def test_comm_info_request(ipkernel):


async def test_direct_interrupt_request(ipkernel):
reply = await ipkernel.test_shell_message("interrupt_request", {})
reply = await ipkernel.test_control_message("interrupt_request", {})
assert reply["header"]["msg_type"] == "interrupt_reply"
assert reply["content"] == {"status": "ok"}

# test failure on interrupt request
def raiseOSError():
raise OSError("evalue")

ipkernel._send_interrupt_children = raiseOSError
reply = await ipkernel.test_control_message("interrupt_request", {})
assert reply["header"]["msg_type"] == "interrupt_reply"
assert reply["content"]["status"] == "error"
assert reply["content"]["ename"] == "OSError"
assert reply["content"]["evalue"] == "evalue"
assert len(reply["content"]["traceback"]) > 0


# TODO: this causes deadlock
Expand Down
19 changes: 16 additions & 3 deletions ipykernel/tests/test_kernel_direct.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,21 @@ async def test_comm_info_request(kernel):


async def test_direct_interrupt_request(kernel):
reply = await kernel.test_shell_message("interrupt_request", {})
reply = await kernel.test_control_message("interrupt_request", {})
assert reply["header"]["msg_type"] == "interrupt_reply"
assert reply["content"] == {"status": "ok"}

# test failure on interrupt request
def raiseOSError():
raise OSError("evalue")

kernel._send_interrupt_children = raiseOSError
reply = await kernel.test_control_message("interrupt_request", {})
assert reply["header"]["msg_type"] == "interrupt_reply"
assert reply["content"]["status"] == "error"
assert reply["content"]["ename"] == "OSError"
assert reply["content"]["evalue"] == "evalue"
assert len(reply["content"]["traceback"]) > 0


async def test_direct_shutdown_request(kernel):
Expand Down Expand Up @@ -145,8 +158,8 @@ async def test_connect_request(kernel):
await kernel.connect_request(kernel.shell_stream, "foo", {})


async def test_send_interupt_children(kernel):
kernel._send_interupt_children()
async def test_send_interrupt_children(kernel):
kernel._send_interrupt_children()


# TODO: this causes deadlock
Expand Down

0 comments on commit e46f75b

Please sign in to comment.