[Python-checkins] r61013 - in python/trunk/Lib: test/test_threading.py threading.py

jeffrey.yasskin python-checkins at python.org
Sat Feb 23 21:40:36 CET 2008


Author: jeffrey.yasskin
Date: Sat Feb 23 21:40:35 2008
New Revision: 61013

Modified:
   python/trunk/Lib/test/test_threading.py
   python/trunk/Lib/threading.py
Log:
Followup to r61011: Also avoid the reference cycle when the Thread's target
raises an exception.


Modified: python/trunk/Lib/test/test_threading.py
==============================================================================
--- python/trunk/Lib/test/test_threading.py	(original)
+++ python/trunk/Lib/test/test_threading.py	Sat Feb 23 21:40:35 2008
@@ -256,23 +256,31 @@
 
     def test_no_refcycle_through_target(self):
         class RunSelfFunction(object):
-            def __init__(self):
+            def __init__(self, should_raise):
                 # The links in this refcycle from Thread back to self
                 # should be cleaned up when the thread completes.
+                self.should_raise = should_raise
                 self.thread = threading.Thread(target=self._run,
                                                args=(self,),
                                                kwargs={'yet_another':self})
                 self.thread.start()
 
             def _run(self, other_ref, yet_another):
-                pass
+                if self.should_raise:
+                    raise SystemExit
 
-        cyclic_object = RunSelfFunction()
+        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())
+
 
 class ThreadingExceptionTests(unittest.TestCase):
     # A RuntimeError should be raised if Thread.start() is called

Modified: python/trunk/Lib/threading.py
==============================================================================
--- python/trunk/Lib/threading.py	(original)
+++ python/trunk/Lib/threading.py	Sat Feb 23 21:40:35 2008
@@ -442,11 +442,13 @@
         _sleep(0.000001)    # 1 usec, to let the thread run (Solaris hack)
 
     def run(self):
-        if self.__target:
-            self.__target(*self.__args, **self.__kwargs)
-        # Avoid a refcycle if the thread is running a function with an
-        # argument that has a member that points to the thread.
-        del self.__target, self.__args, self.__kwargs
+        try:
+            if self.__target:
+                self.__target(*self.__args, **self.__kwargs)
+        finally:
+            # Avoid a refcycle if the thread is running a function with
+            # an argument that has a member that points to the thread.
+            del self.__target, self.__args, self.__kwargs
 
     def __bootstrap(self):
         # Wrapper around the real bootstrap code that ignores


More information about the Python-checkins mailing list