Files
cpython/Lib/_pyrepl/_threading_handler.py
Jelle Zijlstra e2118b0ac2 gh-149985: Remove future annotations and if TYPE_CHECKING in pyrepl (#149992)
`from __future__ import annotations` is soft-deprecated now that evaluation
of annotations is always deferred. `if TYPE_CHECKING` can often be replaced
with lazy imports.
2026-08-25 16:48:54 -07:00

54 lines
1.5 KiB
Python

from dataclasses import dataclass, field
import traceback
lazy from threading import ExceptHookArgs
lazy from .reader import Reader
def install_threading_hook(reader: Reader) -> None:
import threading
@dataclass
class ExceptHookHandler:
lock: threading.Lock = field(default_factory=threading.Lock)
messages: list[str] = field(default_factory=list)
def show(self) -> int:
count = 0
with self.lock:
if not self.messages:
return 0
reader.restore()
for tb in self.messages:
count += 1
if tb:
print(tb)
self.messages.clear()
reader.scheduled_commands.append("ctrl-c")
reader.prepare()
return count
def add(self, s: str) -> None:
with self.lock:
self.messages.append(s)
def exception(self, args: ExceptHookArgs) -> None:
lines = traceback.format_exception(
args.exc_type,
args.exc_value,
args.exc_traceback,
colorize=reader.can_colorize,
) # type: ignore[call-overload]
pre = f"\nException in {args.thread.name}:\n" if args.thread else "\n"
tb = pre + "".join(lines)
self.add(tb)
def __call__(self) -> int:
return self.show()
handler = ExceptHookHandler()
reader.threading_hook = handler
threading.excepthook = handler.exception