Kaydet (Commit) 9900916d authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Merged revisions 83918 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r83918 | antoine.pitrou | 2010-08-10 00:38:19 +0200 (mar., 10 août 2010) | 5 lines

  Issue #3757: thread-local objects now support cyclic garbage collection.
  Thread-local objects involved in reference cycles will be deallocated
  timely by the cyclic GC, even if the underlying thread is still running.
........
üst c751d446
import unittest
from doctest import DocTestSuite
from test import test_support
threading = test_support.import_module('threading')
import weakref
import gc
# Modules under test
_thread = test_support.import_module('thread')
threading = test_support.import_module('threading')
import _threading_local
class Weak(object):
pass
......@@ -13,7 +18,7 @@ def target(local, weaklist):
local.weak = weak
weaklist.append(weakref.ref(weak))
class ThreadingLocalTest(unittest.TestCase):
class BaseLocalTest:
def test_local_refs(self):
self._local_refs(20)
......@@ -21,7 +26,7 @@ class ThreadingLocalTest(unittest.TestCase):
self._local_refs(100)
def _local_refs(self, n):
local = threading.local()
local = self._local()
weaklist = []
for i in range(n):
t = threading.Thread(target=target, args=(local, weaklist))
......@@ -32,9 +37,9 @@ class ThreadingLocalTest(unittest.TestCase):
gc.collect()
self.assertEqual(len(weaklist), n)
# XXX threading.local keeps the local of the last stopped thread alive.
# XXX _threading_local keeps the local of the last stopped thread alive.
deadlist = [weak for weak in weaklist if weak() is None]
self.assertEqual(len(deadlist), n-1)
self.assertIn(len(deadlist), (n-1, n))
# Assignment to the same thread local frees it sometimes (!)
local.someothervar = None
......@@ -48,7 +53,7 @@ class ThreadingLocalTest(unittest.TestCase):
# is created but not correctly set on the object.
# The first member set may be bogus.
import time
class Local(threading.local):
class Local(self._local):
def __init__(self):
time.sleep(0.01)
local = Local()
......@@ -69,7 +74,7 @@ class ThreadingLocalTest(unittest.TestCase):
def test_derived_cycle_dealloc(self):
# http://bugs.python.org/issue6990
class Local(threading.local):
class Local(self._local):
pass
locals = None
passed = [False]
......@@ -121,10 +126,32 @@ class ThreadingLocalTest(unittest.TestCase):
self.assertRaises(TypeError, cls, 1)
class ThreadLocalTest(unittest.TestCase, BaseLocalTest):
_local = _thread._local
# Fails for the pure Python implementation
def test_cycle_collection(self):
class X:
pass
x = X()
x.local = self._local()
x.local.x = x
wr = weakref.ref(x)
del x
gc.collect()
self.assertIs(wr(), None)
class PyThreadingLocalTest(unittest.TestCase, BaseLocalTest):
_local = _threading_local.local
def test_main():
suite = unittest.TestSuite()
suite.addTest(DocTestSuite('_threading_local'))
suite.addTest(unittest.makeSuite(ThreadingLocalTest))
suite.addTest(unittest.makeSuite(ThreadLocalTest))
suite.addTest(unittest.makeSuite(PyThreadingLocalTest))
try:
from thread import _local
......
......@@ -29,6 +29,10 @@ Core and Builtins
Library
-------
- Issue #3757: thread-local objects now support cyclic garbage collection.
Thread-local objects involved in reference cycles will be deallocated
timely by the cyclic GC, even if the underlying thread is still running.
- Issue #6231: Fix xml.etree.ElementInclude to include the tail of the
current node.
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment