@@ -74,9 +74,11 @@ def collect_thread_exception(config: Config) -> None:
74
74
try :
75
75
warnings .warn (pytest .PytestUnhandledThreadExceptionWarning (msg ))
76
76
except pytest .PytestUnhandledThreadExceptionWarning as e :
77
- # This except happens when the warning is treated as an error
77
+ # This except happens when the warning is treated as an error (e.g. `-Werror`).
78
78
if meta .exc_value is not None :
79
- # Exceptions have a better way to show the traceback
79
+ # Exceptions have a better way to show the traceback, but
80
+ # warnings do not, so hide the traceback from the msg and
81
+ # set the cause so the traceback shows up in the right place.
80
82
e .args = (meta .cause_msg ,)
81
83
e .__cause__ = meta .exc_value
82
84
errors .append (e )
@@ -109,6 +111,9 @@ def thread_exception_hook(
109
111
append : Callable [[ThreadExceptionMeta | BaseException ], object ],
110
112
) -> None :
111
113
try :
114
+ # we need to compute these strings here as they might change after
115
+ # the excepthook finishes and before the metadata object is
116
+ # collected by a pytest hook
112
117
thread_name = "<unknown>" if args .thread is None else args .thread .name
113
118
summary = f"Exception in thread { thread_name } "
114
119
traceback_message = "\n \n " + "" .join (
@@ -132,6 +137,11 @@ def thread_exception_hook(
132
137
)
133
138
except BaseException as e :
134
139
append (e )
140
+ # Raising this will cause the exception to be logged twice, once in our
141
+ # collect_thread_exception and once by the unraisablehook plugin
142
+ # (exceptions raised from this hook are 'unraisable')
143
+ # which is fine - this should never happen anyway and if it does
144
+ # it should probably be reported as a pytest bug.
135
145
raise
136
146
137
147
0 commit comments