diff options
-rw-r--r-- | Lib/test/test_threading.py | 8 | ||||
-rw-r--r-- | Lib/threading.py | 7 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2023-06-29-15-10-44.gh-issue-106236.EAIX4l.rst | 2 |
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``. |