summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim@python.org>2013-09-09 23:48:24 (GMT)
committerTim Peters <tim@python.org>2013-09-09 23:48:24 (GMT)
commit72460fa68ba98f5aa94cdc842070884403c0fc73 (patch)
treec35fa089da52dce5cb1f10c373ce19b9b90e76c8
parentb5e9ac9ec63f2d437515edd2cbce31c5774e9dbd (diff)
downloadcpython-72460fa68ba98f5aa94cdc842070884403c0fc73.zip
cpython-72460fa68ba98f5aa94cdc842070884403c0fc73.tar.gz
cpython-72460fa68ba98f5aa94cdc842070884403c0fc73.tar.bz2
Get "stopped" back into repr(Thread) when appropriate.
Due to recent changes, a Thread doesn't know that it's over before someone calls .join() or .is_alive(). That meant repr(Thread) continued to include "started" (and not "stopped") before one of those methods was called, even if hours passed since the thread ended. Repaired that.
-rw-r--r--Lib/test/test_threading.py25
-rw-r--r--Lib/threading.py1
2 files changed, 26 insertions, 0 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index 75ae247..c39d5e2 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -573,6 +573,31 @@ class ThreadTests(BaseTestCase):
# And verify the thread disposed of _tstate_lock.
self.assertTrue(t._tstate_lock is None)
+ def test_repr_stopped(self):
+ # Verify that "stopped" shows up in repr(Thread) appropriately.
+ started = _thread.allocate_lock()
+ finish = _thread.allocate_lock()
+ started.acquire()
+ finish.acquire()
+ def f():
+ started.release()
+ finish.acquire()
+ t = threading.Thread(target=f)
+ t.start()
+ started.acquire()
+ self.assertIn("started", repr(t))
+ finish.release()
+ # "stopped" should appear in the repr in a reasonable amount of time.
+ # Implementation detail: as of this writing, that's trivially true
+ # if .join() is called, and almost trivially true if .is_alive() is
+ # called. The detail we're testing here is that "stopped" shows up
+ # "all on its own".
+ LOOKING_FOR = "stopped"
+ for i in range(500):
+ if LOOKING_FOR in repr(t):
+ break
+ time.sleep(0.01)
+ self.assertIn(LOOKING_FOR, repr(t)) # we waited at least 5 seconds
class ThreadJoinOnShutdown(BaseTestCase):
diff --git a/Lib/threading.py b/Lib/threading.py
index 1ad22a4..26d1018 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -574,6 +574,7 @@ class Thread:
status = "initial"
if self._started.is_set():
status = "started"
+ self.is_alive() # easy way to get ._is_stopped set when appropriate
if self._is_stopped:
status = "stopped"
if self._daemonic: