Skip to content

Commit 854dfab

Browse files
pythongh-113148: Handle exceptions from threading.atexit functions
1 parent 2dad1e0 commit 854dfab

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

Lib/test/test_interpreters/test_api.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,43 @@ def task():
599599

600600
self.assertEqual(os.read(r_interp, 1), FINISHED)
601601

602+
def test_subthreads_raise_exception_from_atexit(self):
603+
r_interp, w_interp = self.pipe()
604+
605+
FINISHED = b'F'
606+
607+
prev_excepthook = threading.excepthook
608+
interp = interpreters.create()
609+
interp.exec(f"""if True:
610+
from io import StringIO
611+
import os
612+
import threading
613+
import time
614+
615+
threading.excepthook = lambda args: args
616+
617+
done = False
618+
def notify_fini():
619+
global done
620+
done = True
621+
622+
def raise_exception():
623+
raise Exception('AtexitException')
624+
threading._register_atexit(notify_fini)
625+
threading._register_atexit(raise_exception)
626+
627+
def task():
628+
while not done:
629+
time.sleep(0.1)
630+
os.write({w_interp}, {FINISHED!r})
631+
t = threading.Thread(target=task)
632+
t.start()
633+
""")
634+
interp.close()
635+
636+
self.assertEqual(threading.excepthook, prev_excepthook)
637+
self.assertEqual(os.read(r_interp, 1), FINISHED)
638+
602639
def test_created_with_capi(self):
603640
script = dedent(f"""
604641
import {interpreters.__name__} as interpreters

Lib/threading.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,11 @@ def _shutdown():
15461546
# Call registered threading atexit functions before threads are joined.
15471547
# Order is reversed, similar to atexit.
15481548
for atexit_call in reversed(_threading_atexits):
1549-
atexit_call()
1549+
try:
1550+
atexit_call()
1551+
except:
1552+
th = current_thread()
1553+
th._invoke_excepthook(th)
15501554

15511555
if _is_main_interpreter():
15521556
_main_thread._handle._set_done()

0 commit comments

Comments
 (0)