from typing import Iterator from typing_extensions import NoReturn import sys import traceback from contextlib import contextmanager @contextmanager def catch_errors(module_path: str, line: int) -> Iterator[None]: try: yield except Exception: crash_report(module_path, line) def crash_report(module_path: str, line: int) -> 'NoReturn': # Adapted from report_internal_error in mypy err = sys.exc_info()[1] tb = traceback.extract_stack()[:-4] # Excise all the traceback from the test runner for i, x in enumerate(tb): if x.name == 'pytest_runtest_call': tb = tb[i + 1:] break tb2 = traceback.extract_tb(sys.exc_info()[2])[1:] print('Traceback (most recent call last):') for s in traceback.format_list(tb + tb2): print(s.rstrip('\n')) print(f'{module_path}:{line}: {type(err).__name__}: {err}') raise SystemExit(2)