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: