Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import io 

2import os 

3import sys 

4 

5import pytest 

6 

7 

8def pytest_addoption(parser): 

9 help = ( 

10 "Dump the traceback of all threads if a test takes " 

11 "more than TIMEOUT seconds to finish.\n" 

12 "Not available on Windows." 

13 ) 

14 parser.addini("faulthandler_timeout", help, default=0.0) 

15 

16 

17def pytest_configure(config): 

18 import faulthandler 

19 

20 # avoid trying to dup sys.stderr if faulthandler is already enabled 

21 if faulthandler.is_enabled(): 

22 return 

23 

24 stderr_fd_copy = os.dup(_get_stderr_fileno()) 

25 config.fault_handler_stderr = os.fdopen(stderr_fd_copy, "w") 

26 faulthandler.enable(file=config.fault_handler_stderr) 

27 

28 

29def _get_stderr_fileno(): 

30 try: 

31 return sys.stderr.fileno() 

32 except (AttributeError, io.UnsupportedOperation): 

33 # python-xdist monkeypatches sys.stderr with an object that is not an actual file. 

34 # https://docs.python.org/3/library/faulthandler.html#issue-with-file-descriptors 

35 # This is potentially dangerous, but the best we can do. 

36 return sys.__stderr__.fileno() 

37 

38 

39def pytest_unconfigure(config): 

40 import faulthandler 

41 

42 faulthandler.disable() 

43 # close our dup file installed during pytest_configure 

44 f = getattr(config, "fault_handler_stderr", None) 

45 if f is not None: 

46 # re-enable the faulthandler, attaching it to the default sys.stderr 

47 # so we can see crashes after pytest has finished, usually during 

48 # garbage collection during interpreter shutdown 

49 config.fault_handler_stderr.close() 

50 del config.fault_handler_stderr 

51 faulthandler.enable(file=_get_stderr_fileno()) 

52 

53 

54@pytest.hookimpl(hookwrapper=True) 

55def pytest_runtest_protocol(item): 

56 timeout = float(item.config.getini("faulthandler_timeout") or 0.0) 

57 if timeout > 0: 

58 import faulthandler 

59 

60 stderr = item.config.fault_handler_stderr 

61 faulthandler.dump_traceback_later(timeout, file=stderr) 

62 try: 

63 yield 

64 finally: 

65 faulthandler.cancel_dump_traceback_later() 

66 else: 

67 yield 

68 

69 

70@pytest.hookimpl(tryfirst=True) 

71def pytest_enter_pdb(): 

72 """Cancel any traceback dumping due to timeout before entering pdb. 

73 """ 

74 import faulthandler 

75 

76 faulthandler.cancel_dump_traceback_later() 

77 

78 

79@pytest.hookimpl(tryfirst=True) 

80def pytest_exception_interact(): 

81 """Cancel any traceback dumping due to an interactive exception being 

82 raised. 

83 """ 

84 import faulthandler 

85 

86 faulthandler.cancel_dump_traceback_later()