99from _pytest .stash import StashKey
1010
1111
12+ fault_handler_original_stderr_fd_key = StashKey [int ]()
1213fault_handler_stderr_fd_key = StashKey [int ]()
13- fault_handler_originally_enabled_key = StashKey [bool ]()
1414
1515
1616def pytest_addoption (parser : Parser ) -> None :
@@ -24,8 +24,15 @@ def pytest_addoption(parser: Parser) -> None:
2424def pytest_configure (config : Config ) -> None :
2525 import faulthandler
2626
27- config .stash [fault_handler_stderr_fd_key ] = os .dup (get_stderr_fileno ())
28- config .stash [fault_handler_originally_enabled_key ] = faulthandler .is_enabled ()
27+ # at teardown we want to restore the original faulthandler fileno
28+ # but faulthandler has no api to return the original fileno
29+ # so here we stash the stderr fileno to be used at teardown
30+ # sys.stderr and sys.__stderr__ may be closed or patched during the session
31+ # so we can't rely on their values being good at that point (#11572).
32+ stderr_fileno = get_stderr_fileno ()
33+ if faulthandler .is_enabled ():
34+ config .stash [fault_handler_original_stderr_fd_key ] = stderr_fileno
35+ config .stash [fault_handler_stderr_fd_key ] = os .dup (stderr_fileno )
2936 faulthandler .enable (file = config .stash [fault_handler_stderr_fd_key ])
3037
3138
@@ -37,9 +44,10 @@ def pytest_unconfigure(config: Config) -> None:
3744 if fault_handler_stderr_fd_key in config .stash :
3845 os .close (config .stash [fault_handler_stderr_fd_key ])
3946 del config .stash [fault_handler_stderr_fd_key ]
40- if config .stash .get (fault_handler_originally_enabled_key , False ):
41- # Re-enable the faulthandler if it was originally enabled.
42- faulthandler .enable (file = get_stderr_fileno ())
47+ # Re-enable the faulthandler if it was originally enabled.
48+ if fault_handler_original_stderr_fd_key in config .stash :
49+ faulthandler .enable (config .stash [fault_handler_original_stderr_fd_key ])
50+ del config .stash [fault_handler_original_stderr_fd_key ]
4351
4452
4553def get_stderr_fileno () -> int :
0 commit comments