crash.py 926 B

12345678910111213141516171819202122232425262728293031
  1. from __future__ import annotations
  2. import sys
  3. import traceback
  4. from contextlib import contextmanager
  5. from typing import Iterator, NoReturn
  6. @contextmanager
  7. def catch_errors(module_path: str, line: int) -> Iterator[None]:
  8. try:
  9. yield
  10. except Exception:
  11. crash_report(module_path, line)
  12. def crash_report(module_path: str, line: int) -> NoReturn:
  13. # Adapted from report_internal_error in mypy
  14. err = sys.exc_info()[1]
  15. tb = traceback.extract_stack()[:-4]
  16. # Excise all the traceback from the test runner
  17. for i, x in enumerate(tb):
  18. if x.name == "pytest_runtest_call":
  19. tb = tb[i + 1 :]
  20. break
  21. tb2 = traceback.extract_tb(sys.exc_info()[2])[1:]
  22. print("Traceback (most recent call last):")
  23. for s in traceback.format_list(tb + tb2):
  24. print(s.rstrip("\n"))
  25. print(f"{module_path}:{line}: {type(err).__name__}: {err}")
  26. raise SystemExit(2)