diff -r edfa42003c34 Lib/test/test_threading.py --- a/Lib/test/test_threading.py Thu Mar 27 11:35:52 2008 +0100 +++ b/Lib/test/test_threading.py Thu Mar 27 13:33:25 2008 +0100 @@ -2,6 +2,7 @@ import test.test_support from test.test_support import verbose +import gc import random import sys import threading @@ -272,17 +273,25 @@ class ThreadTests(unittest.TestCase): if self.should_raise: raise SystemExit - cyclic_object = RunSelfFunction(should_raise=False) - weak_cyclic_object = weakref.ref(cyclic_object) - cyclic_object.thread.join() - del cyclic_object - self.assertEquals(None, weak_cyclic_object()) + try: + # Disable the gc during the tests, to guarantee that refcounting + # is sufficient to deallocate the RunSelfFunction object. + gc.disable() - 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()) + cyclic_object = RunSelfFunction(should_raise=False) + weak_cyclic_object = weakref.ref(cyclic_object) + cyclic_object.thread.join() + del cyclic_object + self.assertEquals(None, 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()) + + finally: + gc.enable() class ThreadingExceptionTests(unittest.TestCase): diff -r edfa42003c34 Lib/threading.py --- a/Lib/threading.py Thu Mar 27 11:35:52 2008 +0100 +++ b/Lib/threading.py Thu Mar 27 13:33:25 2008 +0100 @@ -392,6 +392,7 @@ class Thread(_Verbose): # shutdown and thus raises an exception about trying to perform some # operation on/with a NoneType __exc_info = _sys.exc_info + __exc_clear = _sys.exc_clear def __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None): @@ -489,6 +490,7 @@ class Thread(_Verbose): try: self.run() except SystemExit: + self.__exc_clear() if __debug__: self._note("%s.__bootstrap(): raised SystemExit", self) except: @@ -499,8 +501,11 @@ class Thread(_Verbose): # _sys) in case sys.stderr was redefined since the creation of # self. if _sys: - _sys.stderr.write("Exception in thread %s:\n%s\n" % - (self.getName(), _format_exc())) + try: + _sys.stderr.write("Exception in thread %s:\n%s\n" % + (self.getName(), _format_exc())) + finally: + self.__exc_clear() else: # Do the best job possible w/o a huge amt. of code to # approximate a traceback (code ideas from @@ -524,6 +529,7 @@ class Thread(_Verbose): # hog; deleting everything else is just for thoroughness finally: del exc_type, exc_value, exc_tb + self.__exc_clear() else: if __debug__: self._note("%s.__bootstrap(): normal return", self)