summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_threading.py8
-rw-r--r--Lib/threading.py9
2 files changed, 15 insertions, 2 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index e309a54..195c4e8 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -276,13 +276,17 @@ class ThreadTests(unittest.TestCase):
weak_cyclic_object = weakref.ref(cyclic_object)
cyclic_object.thread.join()
del cyclic_object
- self.assertEquals(None, weak_cyclic_object())
+ self.assertEquals(None, weak_cyclic_object(),
+ msg=('%d references still around' %
+ sys.getrefcount(weak_cyclic_object())))
raising_cyclic_object = RunSelfFunction(should_raise=True)
weak_raising_cyclic_object = weakref.ref(raising_cyclic_object)
raising_cyclic_object.thread.join()
del raising_cyclic_object
- self.assertEquals(None, weak_raising_cyclic_object())
+ self.assertEquals(None, weak_raising_cyclic_object(),
+ msg=('%d references still around' %
+ sys.getrefcount(weak_raising_cyclic_object())))
class ThreadingExceptionTests(unittest.TestCase):
diff --git a/Lib/threading.py b/Lib/threading.py
index 86153b0..eebe10a 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -392,6 +392,9 @@ class Thread(_Verbose):
# shutdown and thus raises an exception about trying to perform some
# operation on/with a NoneType
__exc_info = _sys.exc_info
+ # Keep sys.exc_clear too to clear the exception just before
+ # allowing .join() to return.
+ __exc_clear = _sys.exc_clear
def __init__(self, group=None, target=None, name=None,
args=(), kwargs=None, verbose=None):
@@ -527,6 +530,12 @@ class Thread(_Verbose):
else:
if __debug__:
self._note("%s.__bootstrap(): normal return", self)
+ finally:
+ # Prevent a race in
+ # test_threading.test_no_refcycle_through_target when
+ # the exception keeps the target alive past when we
+ # assert that it's dead.
+ self.__exc_clear()
finally:
with _active_limbo_lock:
self.__stop()