t.start()
t.join()
+ def test_dummy_thread_on_interpreter_shutdown(self):
+ # GH-130522: When `threading` held a reference to itself and then a
+ # _DummyThread() object was created, destruction of the dummy thread
+ # would emit an unraisable exception at shutdown, due to a lock being
+ # destroyed.
+ code = """if True:
+ import sys
+ import threading
+
+ threading.x = sys.modules[__name__]
+ x = threading._DummyThread()
+ """
+ rc, out, err = assert_python_ok("-c", code)
+ self.assertEqual(rc, 0)
+ self.assertEqual(out, b"")
+ self.assertEqual(err, b"")
+
class ThreadRunFail(threading.Thread):
def run(self):
# the related _DummyThread will be kept forever!
_thread_local_info._track_dummy_thread_ref = self
- def __del__(self):
+ def __del__(self, _active_limbo_lock=_active_limbo_lock, _active=_active):
with _active_limbo_lock:
if _active.get(self._tident) is self._dummy_thread:
_active.pop(self._tident, None)