Files
nx_post_support/server/src/_debug_server.py
T
Christoph Brandau 33cf282b0a feat(debug): enable Python debug workflow and debug server integration
Adds an end-to-end Python debug workflow for the extension.
Includes a new prepare-debug.ps1 script and a VS Code task.
Extends the Python server and extension to coordinate a debug session and safe startup.

- Add prepare-debug.ps1 and a VS Code task to build the debug bundle
- Enable Python debug wiring in the server and tests
- Ensure a single stable Python debug session during startup
2026-08-17 11:02:22 +02:00

73 lines
2.3 KiB
Python

# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
"""Debugging support for LSP."""
import os
import pathlib
import runpy
import sys
import time
def update_sys_path(path_to_add: str) -> None:
"""Add given path to `sys.path`."""
if path_to_add not in sys.path and os.path.isdir(path_to_add):
sys.path.append(path_to_add)
def _debug_endpoint() -> tuple[str, int]:
host = os.getenv("NXPS_DEBUG_HOST", "127.0.0.1")
raw_port = os.getenv("NXPS_DEBUG_PORT", "5678")
try:
port = int(raw_port)
except ValueError as error:
raise RuntimeError(f"Invalid NXPS_DEBUG_PORT: {raw_port!r}") from error
if not 1 <= port <= 65535:
raise RuntimeError(f"NXPS_DEBUG_PORT is outside the valid range: {port}")
return host, port
def _connect_debugger(debugpy, host: str, port: int, timeout: float = 15.0) -> None:
deadline = time.monotonic() + timeout
last_error: OSError | None = None
while time.monotonic() < deadline:
try:
debugpy.connect((host, port))
debugpy.wait_for_client()
return
except (ConnectionRefusedError, OSError) as error:
last_error = error
time.sleep(0.25)
raise RuntimeError(
f"Could not connect debugpy to {host}:{port} within {timeout:.0f} seconds"
) from last_error
def main() -> None:
# Ensure debugger is loaded before we load anything else, so server
# initialization and module-level feature registration can be debugged.
debugger_path = os.getenv("DEBUGPY_PATH")
if not debugger_path:
raise RuntimeError("DEBUGPY_PATH is missing in Python debug mode")
if pathlib.Path(debugger_path).name.casefold() == "debugpy":
debugger_path = os.fspath(pathlib.Path(debugger_path).parent)
update_sys_path(debugger_path)
# pylint: disable=wrong-import-position,import-error
import debugpy
host, port = _debug_endpoint()
print(f"debugpy: waiting for VS Code at {host}:{port}", file=sys.stderr)
_connect_debugger(debugpy, host, port)
print("debugpy: VS Code attached; starting language server", file=sys.stderr)
server_path = os.fspath(pathlib.Path(__file__).parent / "lsp_server.py")
runpy.run_path(server_path, run_name="__main__")
if __name__ == "__main__":
main()