summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_threading.py8
-rw-r--r--Lib/threading.py7
-rw-r--r--Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst2
3 files changed, 14 insertions, 3 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index 9e4972e..4a91eef 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -251,6 +251,14 @@ class ThreadTests(BaseTestCase):
#Issue 29376
self.assertTrue(threading._active[tid].is_alive())
self.assertRegex(repr(threading._active[tid]), '_DummyThread')
+
+ # Issue gh-106236:
+ with self.assertRaises(RuntimeError):
+ threading._active[tid].join()
+ threading._active[tid]._started.clear()
+ with self.assertRaises(RuntimeError):
+ threading._active[tid].is_alive()
+
del threading._active[tid]
# PyThreadState_SetAsyncExc() is a CPython-only gimmick, not (currently)
diff --git a/Lib/threading.py b/Lib/threading.py
index df27387..e036cb8 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -1451,11 +1451,12 @@ class _DummyThread(Thread):
pass
def is_alive(self):
- assert not self._is_stopped and self._started.is_set()
- return True
+ if not self._is_stopped and self._started.is_set():
+ return True
+ raise RuntimeError("thread is not alive")
def join(self, timeout=None):
- assert False, "cannot join a dummy thread"
+ raise RuntimeError("cannot join a dummy thread")
# Global API functions
diff --git a/Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst b/Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst
new file mode 100644
index 0000000..036bdb6
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst
@@ -0,0 +1,2 @@
+Replace ``assert`` statements with ``raise RuntimeError`` in
+:mod:`threading`, so that ``_DummyThread`` cannot be joined even with ``-OO``.