@@ -3157,3 +3157,60 @@ def __enter__(self):
31573157 def __exit__ (self , * exc_info ):
31583158 sys .unraisablehook = self ._old_hook
31593159 del self .unraisable
3160+
3161+
3162+ class catch_threading_exception :
3163+ """
3164+ Context manager catching threading.Thread exception using
3165+ threading.excepthook.
3166+
3167+ Attributes set when an exception is catched:
3168+
3169+ * exc_type
3170+ * exc_value
3171+ * exc_traceback
3172+ * thread
3173+
3174+ See threading.excepthook() documentation for these attributes.
3175+
3176+ These attributes are deleted at the context manager exit.
3177+
3178+ Usage:
3179+
3180+ with support.catch_threading_exception() as cm:
3181+ # code spawning a thread which raises an exception
3182+ ...
3183+
3184+ # check the thread exception, use cm attributes:
3185+ # exc_type, exc_value, exc_traceback, thread
3186+ ...
3187+
3188+ # exc_type, exc_value, exc_traceback, thread attributes of cm no longer
3189+ # exists at this point
3190+ # (to avoid reference cycles)
3191+ """
3192+
3193+ def __init__ (self ):
3194+ self .exc_type = None
3195+ self .exc_value = None
3196+ self .exc_traceback = None
3197+ self .thread = None
3198+ self ._old_hook = None
3199+
3200+ def _hook (self , args ):
3201+ self .exc_type = args .exc_type
3202+ self .exc_value = args .exc_value
3203+ self .exc_traceback = args .exc_traceback
3204+ self .thread = args .thread
3205+
3206+ def __enter__ (self ):
3207+ self ._old_hook = threading .excepthook
3208+ threading .excepthook = self ._hook
3209+ return self
3210+
3211+ def __exit__ (self , * exc_info ):
3212+ threading .excepthook = self ._old_hook
3213+ del self .exc_type
3214+ del self .exc_value
3215+ del self .exc_traceback
3216+ del self .thread
0 commit comments