Skip to content

Commit

Permalink
Always set debugger to true in kernelspec (#1191)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthomas23 committed Jan 13, 2024
1 parent 1e3bb9d commit 4868558
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 19 deletions.
2 changes: 1 addition & 1 deletion ipykernel/kernelspec.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def get_kernel_dict(extra_arguments: list[str] | None = None) -> dict[str, Any]:
"argv": make_ipkernel_cmd(extra_arguments=extra_arguments),
"display_name": "Python %i (ipykernel)" % sys.version_info[0],
"language": "python",
"metadata": {"debugger": _is_debugpy_available},
"metadata": {"debugger": True},
}


Expand Down
98 changes: 80 additions & 18 deletions tests/test_debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@

seq = 0

# Skip if debugpy is not available
pytest.importorskip("debugpy")
# Tests support debugpy not being installed, in which case the tests don't do anything useful
# functionally as the debug message replies are usually empty dictionaries, but they confirm that
# ipykernel doesn't block, or segfault, or raise an exception.
try:
import debugpy
except ImportError:
debugpy = None


def wait_for_debug_request(kernel, command, arguments=None, full_reply=False):
Expand Down Expand Up @@ -85,15 +90,21 @@ def test_debug_initialize(kernel):
"locale": "en",
},
)
assert reply["success"]
if debugpy:
assert reply["success"]
else:
assert reply == {}


def test_attach_debug(kernel_with_debug):
reply = wait_for_debug_request(
kernel_with_debug, "evaluate", {"expression": "'a' + 'b'", "context": "repl"}
)
assert reply["success"]
assert reply["body"]["result"] == ""
if debugpy:
assert reply["success"]
assert reply["body"]["result"] == ""
else:
assert reply == {}


def test_set_breakpoints(kernel_with_debug):
Expand All @@ -104,7 +115,11 @@ def test_set_breakpoints(kernel_with_debug):
f(2, 3)"""

r = wait_for_debug_request(kernel_with_debug, "dumpCell", {"code": code})
source = r["body"]["sourcePath"]
if debugpy:
source = r["body"]["sourcePath"]
else:
assert r == {}
source = "non-existent path"

reply = wait_for_debug_request(
kernel_with_debug,
Expand All @@ -115,20 +130,29 @@ def test_set_breakpoints(kernel_with_debug):
"sourceModified": False,
},
)
assert reply["success"]
assert len(reply["body"]["breakpoints"]) == 1
assert reply["body"]["breakpoints"][0]["verified"]
assert reply["body"]["breakpoints"][0]["source"]["path"] == source
if debugpy:
assert reply["success"]
assert len(reply["body"]["breakpoints"]) == 1
assert reply["body"]["breakpoints"][0]["verified"]
assert reply["body"]["breakpoints"][0]["source"]["path"] == source
else:
assert reply == {}

r = wait_for_debug_request(kernel_with_debug, "debugInfo")

def func(b):
return b["source"]

assert source in map(func, r["body"]["breakpoints"])
if debugpy:
assert source in map(func, r["body"]["breakpoints"])
else:
assert r == {}

r = wait_for_debug_request(kernel_with_debug, "configurationDone")
assert r["success"]
if debugpy:
assert r["success"]
else:
assert r == {}


def test_stop_on_breakpoint(kernel_with_debug):
Expand All @@ -139,7 +163,11 @@ def test_stop_on_breakpoint(kernel_with_debug):
f(2, 3)"""

r = wait_for_debug_request(kernel_with_debug, "dumpCell", {"code": code})
source = r["body"]["sourcePath"]
if debugpy:
source = r["body"]["sourcePath"]
else:
assert r == {}
source = "some path"

wait_for_debug_request(kernel_with_debug, "debugInfo")

Expand All @@ -157,6 +185,10 @@ def test_stop_on_breakpoint(kernel_with_debug):

kernel_with_debug.execute(code)

if not debugpy:
# Cannot stop on breakpoint if debugpy not installed
return

# Wait for stop on breakpoint
msg: dict = {"msg_type": "", "content": {}}
while msg.get("msg_type") != "debug_event" or msg["content"].get("event") != "stopped":
Expand All @@ -175,7 +207,11 @@ def f(a, b):
f(2, 3)"""

r = wait_for_debug_request(kernel_with_debug, "dumpCell", {"code": code})
source = r["body"]["sourcePath"]
if debugpy:
source = r["body"]["sourcePath"]
else:
assert r == {}
source = "some path"

wait_for_debug_request(kernel_with_debug, "debugInfo")

Expand All @@ -193,6 +229,10 @@ def f(a, b):

kernel_with_debug.execute(code)

if not debugpy:
# Cannot stop on breakpoint if debugpy not installed
return

# Wait for stop on breakpoint
msg: dict = {"msg_type": "", "content": {}}
while msg.get("msg_type") != "debug_event" or msg["content"].get("event") != "stopped":
Expand All @@ -216,15 +256,21 @@ def test_rich_inspect_not_at_breakpoint(kernel_with_debug):
def func(v):
return v["name"]

assert var_name in list(map(func, r["body"]["variables"]))
if debugpy:
assert var_name in list(map(func, r["body"]["variables"]))
else:
assert r == {}

reply = wait_for_debug_request(
kernel_with_debug,
"richInspectVariables",
{"variableName": var_name},
)

assert reply["body"]["data"] == {"text/plain": f"'{value}'"}
if debugpy:
assert reply["body"]["data"] == {"text/plain": f"'{value}'"}
else:
assert reply == {}


def test_rich_inspect_at_breakpoint(kernel_with_debug):
Expand All @@ -235,7 +281,11 @@ def test_rich_inspect_at_breakpoint(kernel_with_debug):
f(2, 3)"""

r = wait_for_debug_request(kernel_with_debug, "dumpCell", {"code": code})
source = r["body"]["sourcePath"]
if debugpy:
source = r["body"]["sourcePath"]
else:
assert r == {}
source = "some path"

wait_for_debug_request(
kernel_with_debug,
Expand All @@ -253,6 +303,10 @@ def test_rich_inspect_at_breakpoint(kernel_with_debug):

kernel_with_debug.execute(code)

if not debugpy:
# Cannot stop on breakpoint if debugpy not installed
return

# Wait for stop on breakpoint
msg: dict = {"msg_type": "", "content": {}}
while msg.get("msg_type") != "debug_event" or msg["content"].get("event") != "stopped":
Expand Down Expand Up @@ -304,7 +358,11 @@ def my_test():

# Init debugger and set breakpoint
r = wait_for_debug_request(kernel_with_debug, "dumpCell", {"code": code})
source = r["body"]["sourcePath"]
if debugpy:
source = r["body"]["sourcePath"]
else:
assert r == {}
source = "some path"

wait_for_debug_request(
kernel_with_debug,
Expand All @@ -323,6 +381,10 @@ def my_test():
# Execute code
kernel_with_debug.execute(code)

if not debugpy:
# Cannot stop on breakpoint if debugpy not installed
return

# Wait for stop on breakpoint
msg: dict = {"msg_type": "", "content": {}}
while msg.get("msg_type") != "debug_event" or msg["content"].get("event") != "stopped":
Expand Down

0 comments on commit 4868558

Please sign in to comment.