From: <pj...@us...> - 2011-01-21 01:18:41
|
Revision: 7186 http://jython.svn.sourceforge.net/jython/?rev=7186&view=rev Author: pjenvey Date: 2011-01-21 01:18:35 +0000 (Fri, 21 Jan 2011) Log Message: ----------- o fix threading.local subclassing problems with __init__ arguments o fastGetDict doesn't need to synchronize around a ThreadLocal initialization fixes #1667 thanks Kelly Campbell Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/modules/thread/PyLocal.java Added Paths: ----------- trunk/jython/Lib/test/test_threading_local_jy.py Added: trunk/jython/Lib/test/test_threading_local_jy.py =================================================================== --- trunk/jython/Lib/test/test_threading_local_jy.py (rev 0) +++ trunk/jython/Lib/test/test_threading_local_jy.py 2011-01-21 01:18:35 UTC (rev 7186) @@ -0,0 +1,61 @@ +"""Test for thread locals""" +import random +import sys +import threading +import time +import unittest +from test import test_support +from threading import local + +class LocalStuff(local): + def __init__(self, stuff, foo=1): + local.__init__(self) + self.stuff = stuff + self.foo = foo + +class TestThread(threading.Thread): + def __init__(self, stuff, name): + threading.Thread.__init__(self) + self.stuff = stuff + self.name = name + self.errors = [] + + def run(self): + for i in xrange(10): + try: + self.stuff.stuff = self.name + myStuff = self.stuff.stuff + time.sleep(random.random() * 2) + if myStuff != self.stuff.stuff: + self.errors.append("myStuff should equal self.stuff.stuff") + if self.stuff.foo != 1: + self.errors.append("foo should be 1") + except TypeError, te: + self.errors.append("TypeError: %s" % te) + except: + self.errors.append("unexpected error: %s" % sys.exc_info()[0] ) + + def getErrors(self): + return self.errors + +class ThreadLocalConstructorTestCase(unittest.TestCase): + + def test_construct_locals(self): + """Ensures that constructing a local can have arguments""" + stuff = LocalStuff("main stuff") + threads = [] + for i in xrange(20): + threads.append(TestThread(stuff, name=("thread-%d" % i))) + threads[i].start() + for i in xrange(20): + threads[i].join() + errors = threads[i].getErrors() + self.assertEquals(0, len(errors), errors) + + +def test_main(): + test_support.run_unittest(ThreadLocalConstructorTestCase) + + +if __name__ == "__main__": + test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2011-01-10 23:29:19 UTC (rev 7185) +++ trunk/jython/NEWS 2011-01-21 01:18:35 UTC (rev 7186) @@ -1,5 +1,9 @@ Jython NEWS +Jython 2.5.2 + Bugs Fixed + - [ 1667 ] thread.local subclasses with constructor params fail + Jython 2.5.2rc3 Bugs Fixed - [ 1674 ] PDB crashes under the JSR-223 scripting engine Modified: trunk/jython/src/org/python/modules/thread/PyLocal.java =================================================================== --- trunk/jython/src/org/python/modules/thread/PyLocal.java 2011-01-10 23:29:19 UTC (rev 7185) +++ trunk/jython/src/org/python/modules/thread/PyLocal.java 2011-01-21 01:18:35 UTC (rev 7186) @@ -1,3 +1,4 @@ +/* Copyright (c) Jython Developers */ package org.python.modules.thread; import org.python.core.Py; @@ -6,7 +7,6 @@ import org.python.core.PyObject; import org.python.core.PyType; import org.python.expose.ExposedGet; -import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedSet; import org.python.expose.ExposedType; @@ -28,9 +28,8 @@ public PyLocal(PyType subType) { super(subType); - // Because the instantiation of a type instance in PyType.invoke_new_ - // calls dispatch__init__, we call tdict.set here so dispatch__init__ - // doesn't get called a second time for a thread in fastGetDict + // Don't lazy load the underlying dict in the insantiating thread; that would call + // __init__ a the second time tdict.set(new PyDictionary()); } @@ -40,29 +39,24 @@ PyType subtype, PyObject[] args, String[] keywords) { + PyObject[] where = new PyObject[1]; + subtype.lookup_where("__init__", where); + if (where[0] == PyObject.TYPE && args.length > 0) { + throw Py.TypeError("Initialization arguments are not supported"); + } + PyLocal newobj; if (new_.getWrappedType() == subtype) { newobj = new PyLocal(); } else { newobj = new PyLocalDerived(subtype); } - if (init) { - newobj._local___init__(args, keywords); - } + newobj.args = args; + newobj.keywords = keywords; + return newobj; } - @ExposedMethod - final void _local___init__(PyObject[] args, String[] keywords) { - PyObject[] where = new PyObject[1]; - getType().lookup_where("__init__", where); - if (where[0] == TYPE && args.length > 0) { - throw Py.TypeError("Initialization arguments are not supported"); - } - this.args = args; - this.keywords = keywords; - } - @Override @ExposedGet(name = "__dict__") public PyObject getDict() { @@ -76,7 +70,7 @@ } @Override - public synchronized PyObject fastGetDict() { + public PyObject fastGetDict() { PyDictionary ldict = tdict.get(); if (ldict == null) { ldict = new PyDictionary(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |