modlink_studio.debug_bootstrap

 1from __future__ import annotations
 2
 3import ctypes
 4import logging
 5import sys
 6import threading
 7
 8logger = logging.getLogger(__name__)
 9
10
11def install_debug_bootstrap() -> None:
12    _ensure_debug_console()
13    _install_debug_exception_hooks()
14
15
16def _install_debug_exception_hooks() -> None:
17    previous_sys_excepthook = sys.excepthook
18    previous_thread_excepthook = threading.excepthook
19
20    def _sys_excepthook(exc_type, exc_value, exc_traceback) -> None:
21        if issubclass(exc_type, KeyboardInterrupt):
22            previous_sys_excepthook(exc_type, exc_value, exc_traceback)
23            return
24        logger.critical(
25            "Unhandled exception reached the main thread",
26            exc_info=(exc_type, exc_value, exc_traceback),
27        )
28        previous_sys_excepthook(exc_type, exc_value, exc_traceback)
29
30    def _thread_excepthook(args: threading.ExceptHookArgs) -> None:
31        if issubclass(args.exc_type, KeyboardInterrupt):
32            previous_thread_excepthook(args)
33            return
34        thread_name = args.thread.name if args.thread is not None else "<unknown>"
35        logger.critical(
36            "Unhandled exception reached background thread %s",
37            thread_name,
38            exc_info=(args.exc_type, args.exc_value, args.exc_traceback),
39        )
40        previous_thread_excepthook(args)
41
42    sys.excepthook = _sys_excepthook
43    threading.excepthook = _thread_excepthook
44
45
46def _ensure_debug_console() -> None:
47    if sys.platform != "win32":
48        return
49
50    kernel32 = ctypes.windll.kernel32
51    if kernel32.GetConsoleWindow():
52        return
53
54    attach_parent_process = ctypes.c_uint(-1).value
55    attached = bool(kernel32.AttachConsole(attach_parent_process))
56    if not attached:
57        error_code = kernel32.GetLastError()
58        if error_code != 5 and not kernel32.AllocConsole():
59            return
60
61    sys.stdout = open("CONOUT$", "w", encoding="utf-8", buffering=1, errors="replace")
62    sys.stderr = open("CONOUT$", "w", encoding="utf-8", buffering=1, errors="replace")
63    sys.stdin = open("CONIN$", encoding="utf-8", errors="replace")
logger = <Logger modlink_studio.debug_bootstrap (WARNING)>
def install_debug_bootstrap() -> None:
12def install_debug_bootstrap() -> None:
13    _ensure_debug_console()
14    _install_debug_exception_hooks()