mirror of
https://github.com/python/cpython.git
synced 2025-10-31 21:51:50 +00:00
Prevent classes like:
class RunSelfFunction(object):
def __init__(self):
self.thread = threading.Thread(target=self._run)
self.thread.start()
def _run(self):
pass
from creating a permanent cycle between the object and the thread by having the
Thread delete its references to the object when it completes.
As an example of the effect of this bug, paramiko.Transport inherits from
Thread to avoid it.
This commit is contained in:
parent
1beea27299
commit
3414ea9ed9
2 changed files with 23 additions and 0 deletions
|
|
@ -8,6 +8,7 @@
|
|||
import thread
|
||||
import time
|
||||
import unittest
|
||||
import weakref
|
||||
|
||||
# A trivial mutable counter.
|
||||
class Counter(object):
|
||||
|
|
@ -253,6 +254,25 @@ def test_enumerate_after_join(self):
|
|||
finally:
|
||||
sys.setcheckinterval(old_interval)
|
||||
|
||||
def test_no_refcycle_through_target(self):
|
||||
class RunSelfFunction(object):
|
||||
def __init__(self):
|
||||
# The links in this refcycle from Thread back to self
|
||||
# should be cleaned up when the thread completes.
|
||||
self.thread = threading.Thread(target=self._run,
|
||||
args=(self,),
|
||||
kwargs={'yet_another':self})
|
||||
self.thread.start()
|
||||
|
||||
def _run(self, other_ref, yet_another):
|
||||
pass
|
||||
|
||||
cyclic_object = RunSelfFunction()
|
||||
weak_cyclic_object = weakref.ref(cyclic_object)
|
||||
cyclic_object.thread.join()
|
||||
del cyclic_object
|
||||
self.assertEquals(None, weak_cyclic_object())
|
||||
|
||||
|
||||
class ThreadingExceptionTests(unittest.TestCase):
|
||||
# A RuntimeError should be raised if Thread.start() is called
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue