From: <pj...@us...> - 2009-05-21 04:11:07
|
Revision: 6361 http://jython.svn.sourceforge.net/jython/?rev=6361&view=rev Author: pjenvey Date: 2009-05-21 04:10:49 +0000 (Thu, 21 May 2009) Log Message: ----------- fix open(os.devnull, 'w') on Windows Modified Paths: -------------- trunk/jython/.classpath trunk/jython/build.xml trunk/jython/src/org/python/core/io/FileIO.java Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-05-20 15:09:43 UTC (rev 6360) +++ trunk/jython/.classpath 2009-05-21 04:10:49 UTC (rev 6361) @@ -17,5 +17,6 @@ <classpathentry kind="lib" path="extlibs/asm-3.1.jar"/> <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/> <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/> + <classpathentry kind="lib" path="extlibs/jna-posix.jar"/> <classpathentry kind="output" path="bugtests/classes"/> </classpath> Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-05-20 15:09:43 UTC (rev 6360) +++ trunk/jython/build.xml 2009-05-21 04:10:49 UTC (rev 6361) @@ -158,6 +158,7 @@ <pathelement path="${extlibs.dir}/asm-3.1.jar" /> <pathelement path="${extlibs.dir}/asm-commons-3.1.jar" /> <pathelement path="${extlibs.dir}/constantine-0.4.jar" /> + <pathelement path="${extlibs.dir}/jna-posix.jar"/> </path> <available property="informix.present" classname="com.informix.jdbc.IfxDriver" classpath="${informix.jar}" /> Modified: trunk/jython/src/org/python/core/io/FileIO.java =================================================================== --- trunk/jython/src/org/python/core/io/FileIO.java 2009-05-20 15:09:43 UTC (rev 6360) +++ trunk/jython/src/org/python/core/io/FileIO.java 2009-05-21 04:10:49 UTC (rev 6361) @@ -13,6 +13,7 @@ import java.nio.channels.FileChannel; import com.kenai.constantine.platform.Errno; +import org.jruby.ext.posix.util.Platform; import org.python.core.Py; import org.python.core.util.FileUtil; import org.python.core.util.RelativeFile; @@ -162,12 +163,14 @@ try { fileChannel.truncate(0); } catch (IOException ioe) { - // On Solaris and Linux, ftruncate(3C) returns EINVAL - // if not a regular file whereas, e.g., - // open("/dev/null", "w") works fine. Because we have - // to simulate the "w" mode in Java, we suppress the - // exception. - if (ioe.getMessage().equals("Invalid argument")) { + // On Solaris and Linux, ftruncate(3C) returns EINVAL if not a regular + // file whereas, e.g., open(os.devnull, "w") works. Likewise Windows + // returns ERROR_INVALID_FUNCTION. Because we have to simulate the "w" + // mode in Java, we suppress the exception. + String message = ioe.getMessage(); + if (((Platform.IS_SOLARIS || Platform.IS_LINUX) + && Errno.EINVAL.description().equals(message)) + || (Platform.IS_WINDOWS && "Incorrect function".equals(message))) { return; } throw Py.IOError(ioe); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-24 02:53:58
|
Revision: 6372 http://jython.svn.sourceforge.net/jython/?rev=6372&view=rev Author: pjenvey Date: 2009-05-24 02:53:41 +0000 (Sun, 24 May 2009) Log Message: ----------- use $py.class instead of just .class for the imp.PY_COMPILED suffix Modified Paths: -------------- trunk/jython/Lib/test/test_chdir.py trunk/jython/src/org/python/modules/imp.java Modified: trunk/jython/Lib/test/test_chdir.py =================================================================== --- trunk/jython/Lib/test/test_chdir.py 2009-05-23 20:33:14 UTC (rev 6371) +++ trunk/jython/Lib/test/test_chdir.py 2009-05-24 02:53:41 UTC (rev 6372) @@ -14,9 +14,8 @@ import zipimport from test import test_support -COMPILED_SUFFIX = sys.platform.startswith('java') and '$py.class' or \ - [suffix for suffix, mode, type in imp.get_suffixes() - if type == imp.PY_COMPILED][0] +COMPILED_SUFFIX = [suffix for suffix, mode, type in imp.get_suffixes() + if type == imp.PY_COMPILED][0] EXECUTABLE = sys.executable or \ (sys.platform.startswith('java') and 'jython' or None) Modified: trunk/jython/src/org/python/modules/imp.java =================================================================== --- trunk/jython/src/org/python/modules/imp.java 2009-05-23 20:33:14 UTC (rev 6371) +++ trunk/jython/src/org/python/modules/imp.java 2009-05-24 02:53:41 UTC (rev 6372) @@ -253,7 +253,7 @@ return new PyList(new PyObject[] {new PyTuple(new PyString(".py"), new PyString("r"), Py.newInteger(PY_SOURCE)), - new PyTuple(new PyString(".class"), + new PyTuple(new PyString("$py.class"), new PyString("rb"), Py.newInteger(PY_COMPILED)),}); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-05-26 19:45:33
|
Revision: 6385 http://jython.svn.sourceforge.net/jython/?rev=6385&view=rev Author: fwierzbicki Date: 2009-05-26 19:44:21 +0000 (Tue, 26 May 2009) Log Message: ----------- RC3 numbering Modified Paths: -------------- trunk/jython/NEWS trunk/jython/README.txt trunk/jython/build.xml Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-05-26 19:24:16 UTC (rev 6384) +++ trunk/jython/NEWS 2009-05-26 19:44:21 UTC (rev 6385) @@ -1,12 +1,12 @@ Jython NEWS -Jython 2.5.0 +Jython 2.5.0 rc3 Bugs fixed - [ 1344 ] setName semantics of threading.Thread different to CPython - Fixed JLine console on cygwin - [ 1348 ] muti-threaded issue, maybe threads cannot exit -Jython 2.5.0 a0 - rc1 +Jython 2.5.0 a0 - rc2 Bugs fixed (new numbering due to move to Roundup) - [ 1188 ] Patch against trunk to handle SecurityExceptions - [ 1271 ] Bean property accessors in derived class overide methods in base class Modified: trunk/jython/README.txt =================================================================== --- trunk/jython/README.txt 2009-05-26 19:24:16 UTC (rev 6384) +++ trunk/jython/README.txt 2009-05-26 19:44:21 UTC (rev 6385) @@ -1,15 +1,9 @@ -Welcome to Jython 2.5rc2 +Welcome to Jython 2.5rc3 ======================== -This is the second release candidate of the 2.5 version of Jython (about 10 -minutes after the first). It fixes a windows bug with our jline support on -windows. Below is the RC1 notes: +This is the third release candidate of the 2.5 version of Jython. It partially +fixes JLine on Cygwin and some threading issues. -It contains bug fixes and polish since the last beta. One especially nice bit -of polish is that jline is enabled by default now, and so using up and down -arrows should work out of the box. If no major bugs are found this release -will get re-labled and released as the production version of 2.5.0. - The release was compiled on Mac OS X with JDK 5 and requires JDK 5 to run. Please try this out and report any bugs at http://bugs.jython.org. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-05-26 19:24:16 UTC (rev 6384) +++ trunk/jython/build.xml 2009-05-26 19:44:21 UTC (rev 6385) @@ -187,13 +187,13 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5rc2+"/> - <property name="jython.version.noplus" value="2.5rc2"/> + <property name="jython.version" value="2.5rc3+"/> + <property name="jython.version.noplus" value="2.5rc3"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> <property name="jython.micro_version" value="0"/> <property name="jython.release_level" value="${PY_RELEASE_LEVEL_GAMMA}"/> - <property name="jython.release_serial" value="2"/> + <property name="jython.release_serial" value="3"/> <condition property="do.snapshot.build"> <isset property="snapshot.revision" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-26 21:57:40
|
Revision: 6387 http://jython.svn.sourceforge.net/jython/?rev=6387&view=rev Author: pjenvey Date: 2009-05-26 21:57:38 +0000 (Tue, 26 May 2009) Log Message: ----------- abspath relative $PRG symlinks so sys.executable can work. fix from jruby thanks Roland Walter fixes #1357 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/shell/jython Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-05-26 19:46:24 UTC (rev 6386) +++ trunk/jython/NEWS 2009-05-26 21:57:38 UTC (rev 6387) @@ -1,5 +1,9 @@ Jython NEWS +Jython 2.5.0 + Bugs fixed + - [ 1357 ] no sys.executable when script runner is a relative link + Jython 2.5.0 rc3 Bugs fixed - [ 1344 ] setName semantics of threading.Thread different to CPython Modified: trunk/jython/src/shell/jython =================================================================== --- trunk/jython/src/shell/jython 2009-05-26 19:46:24 UTC (rev 6386) +++ trunk/jython/src/shell/jython 2009-05-26 21:57:38 UTC (rev 6387) @@ -29,7 +29,11 @@ ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '.*/.*' > /dev/null; then - PRG="$link" + if expr "$link" : '^/' > /dev/null; then + PRG="$link" + else + PRG="`dirname ${PRG}`/${link}" + fi else PRG="`dirname $PRG`/$link" fi This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-27 02:42:24
|
Revision: 6390 http://jython.svn.sourceforge.net/jython/?rev=6390&view=rev Author: pjenvey Date: 2009-05-27 02:42:18 +0000 (Wed, 27 May 2009) Log Message: ----------- o fix file repr w/ windows paths and unicode o remove no longer needed test_repr workarounds Modified Paths: -------------- trunk/jython/Lib/test/test_repr.py trunk/jython/src/org/python/core/PyFile.java Modified: trunk/jython/Lib/test/test_repr.py =================================================================== --- trunk/jython/Lib/test/test_repr.py 2009-05-27 01:47:54 UTC (rev 6389) +++ trunk/jython/Lib/test/test_repr.py 2009-05-27 02:42:18 UTC (rev 6390) @@ -130,13 +130,10 @@ def test_file(self): fp = open(unittest.__file__) self.failUnless(repr(fp).startswith( - # XXX: Jython doesn't use hex ids - # "<open file '%s', mode 'r' at 0x" % unittest.__file__)) - "<open file '%s', mode 'r' at " % unittest.__file__)) + "<open file '%s', mode 'r' at 0x" % unittest.__file__)) fp.close() self.failUnless(repr(fp).startswith( - # "<closed file '%s', mode 'r' at 0x" % unittest.__file__)) - "<closed file '%s', mode 'r' at " % unittest.__file__)) + "<closed file '%s', mode 'r' at 0x" % unittest.__file__)) def test_lambda(self): self.failUnless(repr(lambda x: x).startswith( @@ -149,8 +146,7 @@ eq(repr(hash), '<built-in function hash>') # Methods self.failUnless(repr(''.split).startswith( - # '<built-in method split of str object at 0x')) - '<built-in method split of str object at ')) + '<built-in method split of str object at 0x')) def test_xrange(self): import warnings @@ -197,11 +193,9 @@ class C: def foo(cls): pass x = staticmethod(C.foo) - #self.failUnless(repr(x).startswith('<staticmethod object at 0x')) - self.failUnless(repr(x).startswith('<staticmethod object at ')) + self.failUnless(repr(x).startswith('<staticmethod object at 0x')) x = classmethod(C.foo) - #self.failUnless(repr(x).startswith('<classmethod object at 0x')) - self.failUnless(repr(x).startswith('<classmethod object at ')) + self.failUnless(repr(x).startswith('<classmethod object at 0x')) def test_unsortable(self): # Repr.repr() used to call sorted() on sets, frozensets and dicts @@ -283,8 +277,7 @@ from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import bar # Module name may be prefixed with "test.", depending on how run. self.failUnless(repr(bar.bar).startswith( - # "<class %s.bar at 0x" % bar.__name__)) - "<class %s.bar at " % bar.__name__)) + "<class %s.bar at 0x" % bar.__name__)) def test_instance(self): touch(os.path.join(self.subpkgname, 'baz'+os.extsep+'py'), '''\ @@ -294,8 +287,7 @@ from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import baz ibaz = baz.baz() self.failUnless(repr(ibaz).startswith( - # "<%s.baz instance at 0x" % baz.__name__)) - "<%s.baz instance at " % baz.__name__)) + "<%s.baz instance at 0x" % baz.__name__)) def test_method(self): eq = self.assertEquals @@ -310,8 +302,7 @@ # Bound method next iqux = qux.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa() self.failUnless(repr(iqux.amethod).startswith( - # '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x' \ - '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at ' \ + '<bound method aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.amethod of <%s.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa instance at 0x' \ % (qux.__name__,) )) def test_builtin_function(self): Modified: trunk/jython/src/org/python/core/PyFile.java =================================================================== --- trunk/jython/src/org/python/core/PyFile.java 2009-05-27 01:47:54 UTC (rev 6389) +++ trunk/jython/src/org/python/core/PyFile.java 2009-05-27 02:42:18 UTC (rev 6390) @@ -493,20 +493,13 @@ @ExposedMethod(names = {"__str__", "__repr__"}, doc = BuiltinDocs.file___str___doc) final String file_toString() { - StringBuilder s = new StringBuilder("<"); - if (file.closed()) { - s.append("closed "); - } else { - s.append("open "); + String state = file.closed() ? "closed" : "open"; + String id = Py.idstr(this); + if (name instanceof PyUnicode) { + String escapedName = PyString.encode_UnicodeEscape(name.toString(), false); + return String.format("<%s file u'%s', mode '%s' at %s>", state, escapedName, mode, id); } - s.append("file "); - s.append(name.__repr__()); - s.append(", mode '"); - s.append(mode); - s.append("' at "); - s.append(Py.idstr(this)); - s.append(">"); - return s.toString(); + return String.format("<%s file '%s', mode '%s' at %s>", state, name, mode, id); } public String toString() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-05-27 14:38:09
|
Revision: 6396 http://jython.svn.sourceforge.net/jython/?rev=6396&view=rev Author: fwierzbicki Date: 2009-05-27 14:38:04 +0000 (Wed, 27 May 2009) Log Message: ----------- fix for http://bugs.jython.org/issue1358: Simple pogram fails to parse in Jython 2.5rc3, but parses OK with CPython. Before this fix we failed to parse 1 \ # 2 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/grammar/Python.g Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-05-27 06:44:07 UTC (rev 6395) +++ trunk/jython/NEWS 2009-05-27 14:38:04 UTC (rev 6396) @@ -2,6 +2,7 @@ Jython 2.5.0 Bugs fixed + - [ 1358 ] Simple pogram fails to parse in Jython 2.5rc3, but parses OK with CPython - [ 1357 ] no sys.executable when script runner is a relative link Jython 2.5.0 rc3 Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2009-05-27 06:44:07 UTC (rev 6395) +++ trunk/jython/grammar/Python.g 2009-05-27 14:38:04 UTC (rev 6396) @@ -1800,7 +1800,8 @@ */ CONTINUED_LINE : '\\' ('\r')? '\n' (' '|'\t')* { $channel=HIDDEN; } - ( nl=NEWLINE { + ( c1=COMMENT + | nl=NEWLINE { if (!partial) { emit(new CommonToken(NEWLINE,nl.getText())); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-05-27 16:12:41
|
Revision: 6397 http://jython.svn.sourceforge.net/jython/?rev=6397&view=rev Author: fwierzbicki Date: 2009-05-27 16:12:33 +0000 (Wed, 27 May 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1354: core language failures in interactive interpreter PythonPartial was not allowing for multiple dedents on incomplete input in interactive mode. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/grammar/PythonPartial.g Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-05-27 14:38:04 UTC (rev 6396) +++ trunk/jython/NEWS 2009-05-27 16:12:33 UTC (rev 6397) @@ -2,6 +2,7 @@ Jython 2.5.0 Bugs fixed + - [ 1354 ] core language failures in interactive interpreter - [ 1358 ] Simple pogram fails to parse in Jython 2.5rc3, but parses OK with CPython - [ 1357 ] no sys.executable when script runner is a relative link Modified: trunk/jython/grammar/PythonPartial.g =================================================================== --- trunk/jython/grammar/PythonPartial.g 2009-05-27 14:38:04 UTC (rev 6396) +++ trunk/jython/grammar/PythonPartial.g 2009-05-27 16:12:33 UTC (rev 6397) @@ -300,7 +300,7 @@ suite : simple_stmt | NEWLINE (EOF - |DEDENT EOF + | (DEDENT)+ EOF |INDENT (stmt)+ (DEDENT |EOF ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-29 02:34:53
|
Revision: 6418 http://jython.svn.sourceforge.net/jython/?rev=6418&view=rev Author: pjenvey Date: 2009-05-29 02:34:44 +0000 (Fri, 29 May 2009) Log Message: ----------- o fix comparison between Java objects of different types patch from Geoffrey French fixes #1338 o avoid test_nonexistent_import_with_security in odd environments like virtualenvs Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyJavaType.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-05-29 01:46:19 UTC (rev 6417) +++ trunk/jython/Lib/test/test_java_integration.py 2009-05-29 02:34:44 UTC (rev 6418) @@ -381,11 +381,36 @@ self.assertTrue(first_file <= first_date) self.assertTrue(first_date > first_file) self.assertTrue(first_date >= first_file) + + def test_equals(self): + # Test for bug #1338 + a = range(5) + + x = ArrayList() + x.addAll(a) + + y = Vector() + y.addAll(a) + + z = ArrayList() + z.addAll(range(1, 6)) + + self.assertTrue(x.equals(y)) + self.assertEquals(x, y) + self.assertTrue(not (x != y)) + + self.assertTrue(not x.equals(z)) + self.assertNotEquals(x, z) + self.assertTrue(not (x == z)) class SecurityManagerTest(unittest.TestCase): def test_nonexistent_import_with_security(self): + script = test_support.findfile("import_nonexistent.py") + home = os.path.realpath(sys.prefix) + if not os.path.commonprefix((home, os.path.realpath(script))) == home: + # script must lie within python.home for this test to work + return policy = test_support.findfile("python_home.policy") - script = test_support.findfile("import_nonexistent.py") self.assertEquals(subprocess.call([sys.executable, "-J-Dpython.cachedir.skip=true", "-J-Djava.security.manager", "-J-Djava.security.policy=%s" % policy, script]), 0) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-05-29 01:46:19 UTC (rev 6417) +++ trunk/jython/NEWS 2009-05-29 02:34:44 UTC (rev 6418) @@ -5,6 +5,10 @@ - [ 1354 ] core language failures in interactive interpreter - [ 1358 ] Simple pogram fails to parse in Jython 2.5rc3, but parses OK with CPython - [ 1357 ] no sys.executable when script runner is a relative link + - [ 1338 ] Comparing Java objects to each other fails when classes of values do not match + Fix file's repr with Windows paths + Fix urllib and urllib2 path handling on Windows + Fix r'\Jython25' not considered an abspath on Windows Jython 2.5.0 rc3 Bugs fixed Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2009-05-29 01:46:19 UTC (rev 6417) +++ trunk/jython/src/org/python/core/PyJavaType.java 2009-05-29 02:34:44 UTC (rev 6418) @@ -510,16 +510,16 @@ @Override public PyObject __call__(PyObject o) { Object proxy = self.getJavaProxy(); - Object oAsJava = o.__tojava__(proxy.getClass()); - return proxy.equals(oAsJava) ? Py.True : Py.False; + Object oProxy = o.getJavaProxy(); + return proxy.equals(oProxy) ? Py.True : Py.False; } }); addMethod(new PyBuiltinMethodNarrow("__ne__", 1) { @Override public PyObject __call__(PyObject o) { Object proxy = self.getJavaProxy(); - Object oAsJava = o.__tojava__(proxy.getClass()); - return !proxy.equals(oAsJava) ? Py.True : Py.False; + Object oProxy = o.getJavaProxy(); + return !proxy.equals(oProxy) ? Py.True : Py.False; } }); addMethod(new PyBuiltinMethodNarrow("__hash__") { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-30 03:22:30
|
Revision: 6424 http://jython.svn.sourceforge.net/jython/?rev=6424&view=rev Author: pjenvey Date: 2009-05-30 02:08:23 +0000 (Sat, 30 May 2009) Log Message: ----------- o parse raw unicode escapes o add \U support and fix handling of EOF during a truncated escape in the raw unicode escape decoder fixes #1355 Modified Paths: -------------- trunk/jython/Lib/test/test_unicode_jy.py trunk/jython/NEWS trunk/jython/src/org/python/antlr/GrammarActions.java trunk/jython/src/org/python/core/codecs.java Modified: trunk/jython/Lib/test/test_unicode_jy.py =================================================================== --- trunk/jython/Lib/test/test_unicode_jy.py 2009-05-30 00:46:58 UTC (rev 6423) +++ trunk/jython/Lib/test/test_unicode_jy.py 2009-05-30 02:08:23 UTC (rev 6424) @@ -51,6 +51,29 @@ self.assertEqual(ord(bar[2]), 92) self.assertEqual(ord(bar[3]), 110) + for baz in ur'Hello\u0020World !', ur'Hello\U00000020World !': + self.assertEqual(len(baz), 13, repr(baz)) + self.assertEqual(repr(baz), "u'Hello World !'") + self.assertEqual(ord(baz[5]), 32) + + quux = ur'\U00100000' + self.assertEqual(repr(quux), "u'\\U00100000'") + if sys.maxunicode == 0xffff: + self.assertEqual(len(quux), 2) + self.assertEqual(ord(quux[0]), 56256) + self.assertEqual(ord(quux[1]), 56320) + else: + self.assertEqual(len(quux), 1) + self.assertEqual(ord(quux), 1048576) + + def test_raw_unicode_escape(self): + foo = u'\U00100000' + self.assertEqual(foo.encode('raw_unicode_escape'), '\\U00100000') + self.assertEqual(foo.encode('raw_unicode_escape').decode('raw_unicode_escape'), + foo) + for bar in '\\u', '\\u000', '\\U00000': + self.assertRaises(UnicodeDecodeError, bar.decode, 'raw_unicode_escape') + def test_encode_decimal(self): self.assertEqual(int(u'\u0039\u0032'), 92) self.assertEqual(int(u'\u0660'), 0) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-05-30 00:46:58 UTC (rev 6423) +++ trunk/jython/NEWS 2009-05-30 02:08:23 UTC (rev 6424) @@ -9,6 +9,7 @@ Fix file's repr with Windows paths Fix urllib and urllib2 path handling on Windows Fix r'\Jython25' not considered an abspath on Windows + Fix handling of raw unicode escapes Jython 2.5.0 rc3 Bugs fixed Modified: trunk/jython/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/jython/src/org/python/antlr/GrammarActions.java 2009-05-30 00:46:58 UTC (rev 6423) +++ trunk/jython/src/org/python/antlr/GrammarActions.java 2009-05-30 02:08:23 UTC (rev 6424) @@ -9,6 +9,7 @@ import org.python.core.PyLong; import org.python.core.PyString; import org.python.core.PyUnicode; +import org.python.core.codecs; import org.python.antlr.ast.alias; import org.python.antlr.ast.arguments; import org.python.antlr.ast.boolopType; @@ -441,8 +442,12 @@ ustring); } } else if (raw) { - // Raw str without an encoding or raw unicode: simply passthru + // Raw str without an encoding or raw unicode string = string.substring(start, end); + if (ustring) { + // Raw unicode: handle unicode escapes + string = codecs.PyUnicode_DecodeRawUnicodeEscape(string, "strict"); + } } else { // Plain unicode: already decoded, just handle escapes string = PyString.decode_UnicodeEscape(string, start, end, "strict", ustring); Modified: trunk/jython/src/org/python/core/codecs.java =================================================================== --- trunk/jython/src/org/python/core/codecs.java 2009-05-30 00:46:58 UTC (rev 6423) +++ trunk/jython/src/org/python/core/codecs.java 2009-05-30 02:08:23 UTC (rev 6424) @@ -920,45 +920,54 @@ private static char[] hexdigit = "0123456789ABCDEF".toCharArray(); // The modified flag is used by cPickle. - public static String PyUnicode_EncodeRawUnicodeEscape(String str, - String errors, - boolean modifed) { - - int size = str.length(); + public static String PyUnicode_EncodeRawUnicodeEscape(String str, String errors, + boolean modifed) { StringBuilder v = new StringBuilder(str.length()); - for (int i = 0; i < size; i++) { - char ch = str.charAt(i); - if (ch >= 256 || (modifed && (ch == '\n' || ch == '\\'))) { + for (Iterator<Integer> iter = new PyUnicode(str).newSubsequenceIterator(); + iter.hasNext();) { + int codePoint = iter.next(); + if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { + // Map 32-bit characters to '\\Uxxxxxxxx' + v.append("\\U"); + v.append(hexdigit[(codePoint >> 28) & 0xF]); + v.append(hexdigit[(codePoint >> 24) & 0xF]); + v.append(hexdigit[(codePoint >> 20) & 0xF]); + v.append(hexdigit[(codePoint >> 16) & 0xF]); + v.append(hexdigit[(codePoint >> 12) & 0xF]); + v.append(hexdigit[(codePoint >> 8) & 0xF]); + v.append(hexdigit[(codePoint >> 4) & 0xF]); + v.append(hexdigit[codePoint & 0xF]); + } else if (codePoint >= 256 || (modifed && (codePoint == '\\' || codePoint == '\n'))) { + // Map 16-bit chararacters to '\\uxxxx' v.append("\\u"); - v.append(hexdigit[(ch >>> 12) & 0xF]); - v.append(hexdigit[(ch >>> 8) & 0xF]); - v.append(hexdigit[(ch >>> 4) & 0xF]); - v.append(hexdigit[ch & 0xF]); + v.append(hexdigit[(codePoint >> 12) & 0xF]); + v.append(hexdigit[(codePoint >> 8) & 0xF]); + v.append(hexdigit[(codePoint >> 4) & 0xF]); + v.append(hexdigit[codePoint & 0xF]); } else { - v.append(ch); + v.append((char)codePoint); } } return v.toString(); } - public static String PyUnicode_DecodeRawUnicodeEscape(String str, - String errors) { + public static String PyUnicode_DecodeRawUnicodeEscape(String str, String errors) { int size = str.length(); StringBuilder v = new StringBuilder(size); + for (int i = 0; i < size;) { char ch = str.charAt(i); - /* Non-escape characters are interpreted as Unicode ordinals */ + // Non-escape characters are interpreted as Unicode ordinals if (ch != '\\') { v.append(ch); i++; continue; } - /* - * \\u-escapes are only interpreted iff the number of leading - * backslashes is odd - */ + + // \\u-escapes are only interpreted if the number of leading backslashes is + // odd int bs = i; while (i < size) { ch = str.charAt(i); @@ -968,34 +977,37 @@ v.append(ch); i++; } - if (((i - bs) & 1) == 0 || i >= size || ch != 'u') { + if (((i - bs) & 1) == 0 || i >= size || (ch != 'u' && ch != 'U')) { continue; } v.setLength(v.length() - 1); + int count = ch == 'u' ? 4 : 8; i++; - /* \\uXXXX with 4 hex digits */ - int x = 0, d = 0, j = 0; - for (; j < 4; j++) { - ch = str.charAt(i + j); - d = Character.digit(ch, 16); - if (d == -1) { + + // \\uXXXX with 4 hex digits, \Uxxxxxxxx with 8 + int codePoint = 0, asDigit = -1; + for (int j = 0; j < count; i++, j++) { + if (i == size) { + // EOF in a truncated escape + asDigit = -1; break; } - x = ((x << 4) & ~0xF) + d; + + ch = str.charAt(i); + asDigit = Character.digit(ch, 16); + if (asDigit == -1) { + break; + } + codePoint = ((codePoint << 4) & ~0xF) + asDigit; } - if (d == -1) { - i = codecs.insertReplacementAndGetResume(v, - errors, - "unicodeescape", - str, - bs, - i + j, - "truncated \\uXXXX"); + if (asDigit == -1) { + i = codecs.insertReplacementAndGetResume(v, errors, "rawunicodeescape", str, bs, i, + "truncated \\uXXXX"); } else { - i += 4; - v.append((char) x); + v.appendCodePoint(codePoint); } } + return v.toString(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-30 21:20:12
|
Revision: 6429 http://jython.svn.sourceforge.net/jython/?rev=6429&view=rev Author: pjenvey Date: 2009-05-30 21:20:11 +0000 (Sat, 30 May 2009) Log Message: ----------- ensure open file handles are closed Modified Paths: -------------- trunk/jython/Lib/test/test_classpathimporter.py trunk/jython/src/org/python/core/util/importer.java Modified: trunk/jython/Lib/test/test_classpathimporter.py =================================================================== --- trunk/jython/Lib/test/test_classpathimporter.py 2009-05-30 06:49:08 UTC (rev 6428) +++ trunk/jython/Lib/test/test_classpathimporter.py 2009-05-30 21:20:11 UTC (rev 6429) @@ -68,7 +68,6 @@ os.path.join(compile_path, 'jar_pkg', 'prefer_compiled$py.class')) zip.close() - zip = zipfile.ZipFile(jar) Thread.currentThread().contextClassLoader = test_support.make_jar_classloader(jar) import flat_in_jar Modified: trunk/jython/src/org/python/core/util/importer.java =================================================================== --- trunk/jython/src/org/python/core/util/importer.java 2009-05-30 06:49:08 UTC (rev 6428) +++ trunk/jython/src/org/python/core/util/importer.java 2009-05-30 21:20:11 UTC (rev 6429) @@ -188,16 +188,19 @@ Bundle bundle = makeBundle(searchPath, tocEntry); byte[] codeBytes; - if (isbytecode) { - try { - codeBytes = imp.readCode(fullname, bundle.inputStream, true); - } catch (IOException ioe) { - throw Py.ImportError(ioe.getMessage() + "[path=" + fullSearchPath + "]"); + try { + if (isbytecode) { + try { + codeBytes = imp.readCode(fullname, bundle.inputStream, true); + } catch (IOException ioe) { + throw Py.ImportError(ioe.getMessage() + "[path=" + fullSearchPath + "]"); + } + } else { + codeBytes = imp.compileSource(fullname, bundle.inputStream, fullSearchPath); } - } else { - codeBytes = imp.compileSource(fullname, bundle.inputStream, fullSearchPath); + } finally { + bundle.close(); } - bundle.close(); if (codeBytes == null) { // bad magic number or non-matching mtime in byte code, try next This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-30 22:46:33
|
Revision: 6430 http://jython.svn.sourceforge.net/jython/?rev=6430&view=rev Author: pjenvey Date: 2009-05-30 22:46:21 +0000 (Sat, 30 May 2009) Log Message: ----------- quiet a simple unchecked warning pervading the ast nodes Modified Paths: -------------- trunk/jython/ast/asdl_antlr.py trunk/jython/src/org/python/antlr/PythonTree.java Modified: trunk/jython/ast/asdl_antlr.py =================================================================== --- trunk/jython/ast/asdl_antlr.py 2009-05-30 21:20:11 UTC (rev 6429) +++ trunk/jython/ast/asdl_antlr.py 2009-05-30 22:46:21 UTC (rev 6430) @@ -441,7 +441,7 @@ self.emit("", 0) # The visitChildren() method - self.emit("public void traverse(VisitorIF visitor) throws Exception {", depth) + self.emit("public void traverse(VisitorIF<?> visitor) throws Exception {", depth) for f in fields: if self.bltinnames.has_key(str(f.type)): continue Modified: trunk/jython/src/org/python/antlr/PythonTree.java =================================================================== --- trunk/jython/src/org/python/antlr/PythonTree.java 2009-05-30 21:20:11 UTC (rev 6429) +++ trunk/jython/src/org/python/antlr/PythonTree.java 2009-05-30 22:46:21 UTC (rev 6430) @@ -176,6 +176,7 @@ node.setChildIndex(index); } + @Override public String toString() { if (isNil()) { return "None"; @@ -245,7 +246,7 @@ throw new RuntimeException("Unexpected node: " + this); } - public void traverse(VisitorIF visitor) throws Exception { + public void traverse(VisitorIF<?> visitor) throws Exception { throw new RuntimeException("Cannot traverse node: " + this); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-31 21:42:26
|
Revision: 6435 http://jython.svn.sourceforge.net/jython/?rev=6435&view=rev Author: pjenvey Date: 2009-05-31 21:42:09 +0000 (Sun, 31 May 2009) Log Message: ----------- remove the no longer needed exposed {str,unicode}.toString Modified Paths: -------------- trunk/jython/Lib/unicodedata.py trunk/jython/src/org/python/core/PyString.java trunk/jython/src/org/python/core/PyUnicode.java Modified: trunk/jython/Lib/unicodedata.py =================================================================== --- trunk/jython/Lib/unicodedata.py 2009-05-31 14:50:48 UTC (rev 6434) +++ trunk/jython/Lib/unicodedata.py 2009-05-31 21:42:09 UTC (rev 6435) @@ -209,7 +209,7 @@ normalizer_form = _forms[form] except KeyError: raise ValueError('invalid normalization form') - return Normalizer.normalize(unistr.toString(), normalizer_form) + return Normalizer.normalize(unistr, normalizer_form) except ImportError: pass Modified: trunk/jython/src/org/python/core/PyString.java =================================================================== --- trunk/jython/src/org/python/core/PyString.java 2009-05-31 14:50:48 UTC (rev 6434) +++ trunk/jython/src/org/python/core/PyString.java 2009-05-31 21:42:09 UTC (rev 6435) @@ -116,12 +116,6 @@ return string; } - //XXX: need doc - @ExposedMethod - final String str_toString() { - return toString(); - } - public String internedString() { if (interned) return string; Modified: trunk/jython/src/org/python/core/PyUnicode.java =================================================================== --- trunk/jython/src/org/python/core/PyUnicode.java 2009-05-31 14:50:48 UTC (rev 6434) +++ trunk/jython/src/org/python/core/PyUnicode.java 2009-05-31 21:42:09 UTC (rev 6435) @@ -1431,10 +1431,4 @@ } return sb.toString(); } - - //needs doc - @ExposedMethod/*(doc = BuiltinDocs.unicode_toString_doc)*/ - final String unicode_toString() { - return toString(); - } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-03 07:53:06
|
Revision: 6440 http://jython.svn.sourceforge.net/jython/?rev=6440&view=rev Author: cgroves Date: 2009-06-03 07:53:04 +0000 (Wed, 03 Jun 2009) Log Message: ----------- Only add the proxy class for a PyJavaType to the mro once. Fixes issue1363 Modified Paths: -------------- trunk/jython/Lib/test/test_java_subclasses.py trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_java_subclasses.py =================================================================== --- trunk/jython/Lib/test/test_java_subclasses.py 2009-06-02 08:23:27 UTC (rev 6439) +++ trunk/jython/Lib/test/test_java_subclasses.py 2009-06-03 07:53:04 UTC (rev 6440) @@ -225,6 +225,17 @@ self.assertEquals(10, SecondSubclass().callGetValue()) + def test_deep_subclasses(self): + '''Checks for http://bugs.jython.org/issue1363. + + Inheriting several classes deep from a Java class caused inconsistent MROs.''' + from java.lang import Object + class A(Object): pass + class B(A): pass + class C(B): pass + class D(C): pass + d = D() + """ public abstract class Abstract { public Abstract() { Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-06-02 08:23:27 UTC (rev 6439) +++ trunk/jython/src/org/python/core/PyType.java 2009-06-03 07:53:04 UTC (rev 6440) @@ -869,6 +869,7 @@ } PyObject[] computeMro(MROMergeState[] toMerge, List<PyObject> mro) { + boolean addedProxy = false; scan : for (int i = 0; i < toMerge.length; i++) { if (toMerge[i].isMerged()) { continue scan; @@ -880,7 +881,7 @@ continue scan; } } - if (!(this instanceof PyJavaType) && candidate instanceof PyJavaType + if (!addedProxy && !(this instanceof PyJavaType) && candidate instanceof PyJavaType && candidate.javaProxy != null && PyProxy.class.isAssignableFrom(((Class<?>)candidate.javaProxy)) && candidate.javaProxy != javaProxy) { @@ -889,6 +890,7 @@ // This exposes the methods from the proxy generated for this class in addition to // those generated for the superclass while allowing methods from the superclass to // remain visible from the proxies. + addedProxy = true; mro.add(PyType.fromClass(((Class<?>)javaProxy))); } mro.add(candidate); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-06-04 02:22:35
|
Revision: 6444 http://jython.svn.sourceforge.net/jython/?rev=6444&view=rev Author: pjenvey Date: 2009-06-04 01:41:03 +0000 (Thu, 04 Jun 2009) Log Message: ----------- fix subclasses getter properties being disabled when it has a setter and the parent only has a setter thanks doublep fixes #1333 Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/core/PyJavaType.java Added Paths: ----------- trunk/jython/tests/java/org/python/tests/Child2.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-06-04 01:35:46 UTC (rev 6443) +++ trunk/jython/Lib/test/test_java_integration.py 2009-06-04 01:41:03 UTC (rev 6444) @@ -20,7 +20,7 @@ from javax.swing.tree import TreePath from org.python.core.util import FileUtil -from org.python.tests import BeanImplementation, Child, Listenable, CustomizableMapHolder +from org.python.tests import BeanImplementation, Child, Child2, Listenable, CustomizableMapHolder from org.python.tests.mro import (ConfusedOnGetitemAdd, FirstPredefinedGetitem, GetitemAdder) class InstantiationTest(unittest.TestCase): @@ -75,6 +75,13 @@ c.id = 16 self.assertEquals(16, c.id) + def test_inheriting_half_bean_issue1333(self): + # http://bugs.jython.org/issue1333 + c = Child2() + self.assertEquals("blah", c.value) + c.value = "bleh" + self.assertEquals("Child2 bleh", c.value) + def test_awt_hack(self): # We ignore several deprecated methods in java.awt.* in favor of bean properties that were # addded in Java 1.1. This tests that one of those bean properties is visible. Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2009-06-04 01:35:46 UTC (rev 6443) +++ trunk/jython/src/org/python/core/PyJavaType.java 2009-06-04 01:41:03 UTC (rev 6444) @@ -420,10 +420,11 @@ // up, it'll be rejected below if (prop.setMethod == null) { prop.setMethod = superProp.setMethod; - } else if (superProp.myType == prop.setMethod.getParameterTypes()[0]) { - // Otherwise, we must not have a get method. Only take a get method if the type - // on it agrees with the set method we already have. The bean on this type - // overrides a conflicting one o the parent + } else if (prop.getMethod == null + && superProp.myType == prop.setMethod.getParameterTypes()[0]) { + // Only take a get method if the type on it agrees with the set method + // we already have. The bean on this type overrides a conflicting one + // of the parent prop.getMethod = superProp.getMethod; prop.myType = superProp.myType; } Added: trunk/jython/tests/java/org/python/tests/Child2.java =================================================================== --- trunk/jython/tests/java/org/python/tests/Child2.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/Child2.java 2009-06-04 01:41:03 UTC (rev 6444) @@ -0,0 +1,13 @@ +package org.python.tests; + +public class Child2 extends Parent { + + public String getValue() { + return value; + } + + @Override + public void setValue(String value) { + this.value = "Child2 " + value; + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-06-05 04:40:11
|
Revision: 6450 http://jython.svn.sourceforge.net/jython/?rev=6450&view=rev Author: pjenvey Date: 2009-06-05 04:39:58 +0000 (Fri, 05 Jun 2009) Log Message: ----------- document the cause of test_getweakrefs: the compiler Modified Paths: -------------- trunk/jython/Lib/test/test_weakref.py trunk/jython/src/org/python/compiler/CodeCompiler.java Modified: trunk/jython/Lib/test/test_weakref.py =================================================================== --- trunk/jython/Lib/test/test_weakref.py 2009-06-04 07:29:23 UTC (rev 6449) +++ trunk/jython/Lib/test/test_weakref.py 2009-06-05 04:39:58 UTC (rev 6450) @@ -338,11 +338,10 @@ del ref2 extra_collect() if test_support.is_jython: - # XXX: Likely a Jython bug: the following inline declared - # [ref1] list isn't garbage collected no matter how many - # times we force gc.collect(), which prevents ref1 from - # being garbage collected after it's del'd below. So we - # explicitly delete our list + # XXX: Jython bug: the compiler creates a hard reference to + # the following inline declared [ref1] during + # 'weakref.getweakrefs(o) == [ref1]'. See + # CodeCompiler.makeArray for more info ref1_list = [ref1] self.assert_(weakref.getweakrefs(o) == ref1_list, #self.assert_(weakref.getweakrefs(o) == [ref1], Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-06-04 07:29:23 UTC (rev 6449) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-06-05 04:39:58 UTC (rev 6450) @@ -323,6 +323,11 @@ } public int makeArray(java.util.List<? extends PythonTree> nodes) throws Exception { + // XXX: This should produce an array on the stack (if possible) instead of a local + // the caller is responsible for freeing. All callers are incorrectly freeing the + // array reference -- they do call freeLocal, but without nullifying the reference + // in the local. This is causing short term memory leaks + // (e.g. test_weakref.test_getweakrefs) int n; if (nodes == null) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-06-06 13:07:41
|
Revision: 6459 http://jython.svn.sourceforge.net/jython/?rev=6459&view=rev Author: zyasoft Date: 2009-06-06 13:07:39 +0000 (Sat, 06 Jun 2009) Log Message: ----------- Now nulls out arrays allocated by CodeCompiler#makeArray where it will be not be potentially kept (__call__ is the one case where this is not definitively known at the callsite, in certain corner cases). This allows for more immediate GC and fixes weakref issues seen in the commit for r6450. Bumped bytecode magic. Modified Paths: -------------- trunk/jython/Lib/test/test_weakref.py trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/core/imp.java Modified: trunk/jython/Lib/test/test_weakref.py =================================================================== --- trunk/jython/Lib/test/test_weakref.py 2009-06-06 07:20:33 UTC (rev 6458) +++ trunk/jython/Lib/test/test_weakref.py 2009-06-06 13:07:39 UTC (rev 6459) @@ -337,19 +337,8 @@ ref2 = weakref.ref(o, self.callback) del ref2 extra_collect() - if test_support.is_jython: - # XXX: Jython bug: the compiler creates a hard reference to - # the following inline declared [ref1] during - # 'weakref.getweakrefs(o) == [ref1]'. See - # CodeCompiler.makeArray for more info - ref1_list = [ref1] - self.assert_(weakref.getweakrefs(o) == ref1_list, - #self.assert_(weakref.getweakrefs(o) == [ref1], - "list of refs does not match") - del ref1_list - else: - self.assert_(weakref.getweakrefs(o) == [ref1], - "list of refs does not match") + self.assert_(weakref.getweakrefs(o) == [ref1], + "list of refs does not match") del ref1 extra_collect() Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-06-06 07:20:33 UTC (rev 6458) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-06-06 13:07:39 UTC (rev 6459) @@ -356,6 +356,14 @@ return array; } + // nulls out an array of references + public void freeArray(int array) { + code.aload(array); + code.aconst_null(); + code.invokestatic("java/util/Arrays", "fill", "(" + $objArr + $obj + ")V"); + code.freeLocal(array); + } + public void getDocString(java.util.List<stmt> suite) throws Exception { if (suite.size() > 0 && suite.get(0) instanceof Expr && ((Expr) suite.get(0)).getInternalValue() instanceof Str) @@ -403,6 +411,8 @@ ScopeInfo scope = module.getScopeInfo(node); + // NOTE: this is attached to the constructed PyFunction, so it cannot be nulled out + // with freeArray, unlike other usages of makeArray here int defaults = makeArray(scope.ac.getDefaults()); code.new_("org/python/core/PyFunction"); @@ -429,7 +439,6 @@ applyDecorators(node.getInternalDecorator_list()); set(new Name(node,node.getInternalName(), expr_contextType.Store)); - //doDecorators(node,node.getInternalDecorator_list(), node.getInternalName()); return null; } @@ -1668,7 +1677,7 @@ code.aload(argArray); code.freeLocal(argArray); stackConsume(2); // target + ts - code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObjArr + ")" + $pyObj); + code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObjArr + ")" + $pyObj);// freeArray(argArray); break; } } @@ -1774,8 +1783,8 @@ code.new_("org/python/core/PyTuple"); code.dup(); code.aload(dims); - code.freeLocal(dims); code.invokespecial("org/python/core/PyTuple", "<init>", "(" + $pyObjArr + ")V"); + freeArray(dims); return null; } @@ -1852,8 +1861,8 @@ code.dup(); code.aload(content); - code.freeLocal(content); code.invokespecial("org/python/core/PyTuple", "<init>", "(" + $pyObjArr + ")V"); + freeArray(content); return null; } @@ -1867,8 +1876,8 @@ code.new_("org/python/core/PyList"); code.dup(); code.aload(content); - code.freeLocal(content); code.invokespecial("org/python/core/PyList", "<init>", "(" + $pyObjArr + ")V"); + freeArray(content); return null; } @@ -1926,8 +1935,8 @@ code.new_("org/python/core/PyDictionary"); code.dup(); code.aload(content); - code.freeLocal(content); code.invokespecial("org/python/core/PyDictionary", "<init>", "(" + $pyObjArr + ")V"); + freeArray(content); return null; } @@ -1974,7 +1983,6 @@ } else { code.invokespecial("org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObjArr + ")V"); } - return null; } @@ -2016,7 +2024,6 @@ code.ldc(name); code.aload(baseArray); - code.freeLocal(baseArray); ScopeInfo scope = module.getScopeInfo(node); @@ -2041,6 +2048,7 @@ //Assign this new class to the given name set(new Name(node,node.getInternalName(), expr_contextType.Store)); //doDecorators(node,node.getInternalDecorator_list(), node.getInternalName()); + freeArray(baseArray); return null; } @@ -2207,8 +2215,6 @@ int emptyArray = makeArray(new ArrayList<expr>()); code.aload(emptyArray); - code.freeLocal(emptyArray); - scope.setup_closure(); scope.dump(); @@ -2254,6 +2260,7 @@ loadThreadState(); code.swap(); code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + ")" + $pyObj); + freeArray(emptyArray); return null; } Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2009-06-06 07:20:33 UTC (rev 6458) +++ trunk/jython/src/org/python/core/imp.java 2009-06-06 13:07:39 UTC (rev 6459) @@ -20,7 +20,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - public static final int APIVersion = 21; + public static final int APIVersion = 22; public static final int NO_MTIME = -1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-06-06 20:51:41
|
Revision: 6460 http://jython.svn.sourceforge.net/jython/?rev=6460&view=rev Author: pjenvey Date: 2009-06-06 20:50:29 +0000 (Sat, 06 Jun 2009) Log Message: ----------- fix utf8/utf16 decoders stateful mode argument being switched around fixes #1368 Modified Paths: -------------- trunk/jython/Lib/test/test_unicode_jy.py trunk/jython/src/org/python/modules/_codecs.java Modified: trunk/jython/Lib/test/test_unicode_jy.py =================================================================== --- trunk/jython/Lib/test/test_unicode_jy.py 2009-06-06 13:07:39 UTC (rev 6459) +++ trunk/jython/Lib/test/test_unicode_jy.py 2009-06-06 20:50:29 UTC (rev 6460) @@ -82,6 +82,11 @@ self.assertEqual(float(u'\u0663.\u0661'), 3.1) self.assertEqual(complex(u'\u0663.\u0661'), 3.1+0j) + def test_unstateful_end_of_data(self): + # http://bugs.jython.org/issue1368 + for encoding in 'utf-8', 'utf-16', 'utf-16-be', 'utf-16-le': + self.assertRaises(UnicodeDecodeError, '\xe4'.decode, encoding) + def test_formatchar(self): self.assertEqual('%c' % 255, '\xff') self.assertRaises(OverflowError, '%c'.__mod__, 256) Modified: trunk/jython/src/org/python/modules/_codecs.java =================================================================== --- trunk/jython/src/org/python/modules/_codecs.java 2009-06-06 13:07:39 UTC (rev 6459) +++ trunk/jython/src/org/python/modules/_codecs.java 2009-06-06 20:50:29 UTC (rev 6460) @@ -67,9 +67,9 @@ } public static PyTuple utf_8_decode(String str, String errors, boolean final_) { - int[] consumed = final_ ? new int[1] : null; + int[] consumed = final_ ? null : new int[1]; return decode_tuple(codecs.PyUnicode_DecodeUTF8Stateful(str, errors, consumed), - final_ ? consumed[0] : str.length()); + final_ ? str.length() : consumed[0]); } public static PyTuple utf_8_encode(String str) { @@ -431,9 +431,9 @@ public static PyTuple utf_16_decode(String str, String errors, boolean final_) { int[] bo = new int[] { 0 }; - int[] consumed = final_ ? new int[1] : null; + int[] consumed = final_ ? null : new int[1]; return decode_tuple(decode_UTF16(str, errors, bo, consumed), - final_ ? consumed[0] : str.length()); + final_ ? str.length() : consumed[0]); } public static PyTuple utf_16_le_decode(String str) { @@ -446,9 +446,9 @@ public static PyTuple utf_16_le_decode(String str, String errors, boolean final_) { int[] bo = new int[] { -1 }; - int[] consumed = final_ ? new int[1] : null; + int[] consumed = final_ ? null : new int[1]; return decode_tuple(decode_UTF16(str, errors, bo, consumed), - final_ ? consumed[0] : str.length()); + final_ ? str.length() : consumed[0]); } public static PyTuple utf_16_be_decode(String str) { @@ -461,9 +461,9 @@ public static PyTuple utf_16_be_decode(String str, String errors, boolean final_) { int[] bo = new int[] { 1 }; - int[] consumed = final_ ? new int[1] : null; + int[] consumed = final_ ? null : new int[1]; return decode_tuple(decode_UTF16(str, errors, bo, consumed), - final_ ? consumed[0] : str.length()); + final_ ? str.length() : consumed[0]); } public static PyTuple utf_16_ex_decode(String str) { @@ -481,10 +481,10 @@ public static PyTuple utf_16_ex_decode(String str, String errors, int byteorder, boolean final_) { int[] bo = new int[] { 0 }; - int[] consumed = final_ ? new int[1] : null; + int[] consumed = final_ ? null : new int[1]; String decoded = decode_UTF16(str, errors, bo, consumed); return new PyTuple(Py.newString(decoded), - Py.newInteger(final_ ? consumed[0] : str.length()), + Py.newInteger(final_ ? str.length() : consumed[0]), Py.newInteger(bo[0])); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-06-06 21:41:50
|
Revision: 6462 http://jython.svn.sourceforge.net/jython/?rev=6462&view=rev Author: pjenvey Date: 2009-06-06 21:40:48 +0000 (Sat, 06 Jun 2009) Log Message: ----------- revert the standalone jar workaround for now, we'll revisit this post 2.5 Modified Paths: -------------- trunk/jython/Lib/subprocess.py trunk/jython/src/org/python/core/PySystemState.java Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-06-06 20:56:01 UTC (rev 6461) +++ trunk/jython/Lib/subprocess.py 2009-06-06 21:40:48 UTC (rev 6462) @@ -547,9 +547,7 @@ # Parse command line arguments for Windows _win_oses = ['nt'] - _JYTHON_JAR = 'jython.jar' _cmdline2list = None - _forcecmdline2list = None _escape_args = None _shell_command = None @@ -613,19 +611,13 @@ """Setup the shell command and the command line argument escape function depending on the underlying platform """ - global _cmdline2list, _forcecmdline2list, _escape_args, _shell_command + global _cmdline2list, _escape_args, _shell_command if os._name in _win_oses: - _cmdline2list = _forcecmdline2list = cmdline2list + _cmdline2list = cmdline2list _escape_args = lambda args: [list2cmdline([arg]) for arg in args] else: - _cmdline2list = lambda arg: [arg] - def _forcecmdline2list(arg): - import shlex - try: - return shlex.split(arg) - except ValueError: - return [arg] + _cmdline2list = lambda args: [args] _escape_args = lambda args: args os_info = os._os_map.get(os._name) @@ -1225,28 +1217,6 @@ builder_env.putAll(merge_env) - def _should_run_jar(self, args): - """Determine if command should be run via jar -jar. - - When running the standalone Jython jar without the official - command line script runner (e.g. java -jar jython.jar) - sys.executable cannot be determined, so Jython sets it to - the path to jython.jar. - - This detects when a subprocess command executable is that - special sys.executable value. - """ - if not sys.executable or not sys.executable.endswith(_JYTHON_JAR): - # Not applicable - return False - - args = (_forcecmdline2list(args) - if isinstance(args, types.StringTypes) else list(args)) - if not args: - return False - return args[0] == sys.executable - - def _execute_child(self, args, executable, preexec_fn, close_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, @@ -1255,10 +1225,7 @@ errread, errwrite): """Execute program (Java version)""" - run_jar = self._should_run_jar(args) if isinstance(args, types.StringTypes): - if run_jar: - args = 'java -jar ' + args args = _cmdline2list(args) else: args = list(args) @@ -1267,8 +1234,6 @@ # posix. Windows passes unicode through, however if any(not isinstance(arg, (str, unicode)) for arg in args): raise TypeError('args must contain only strings') - if run_jar: - args = ['java', '-jar'] + args args = _escape_args(args) if shell: Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-06-06 20:56:01 UTC (rev 6461) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-06-06 21:40:48 UTC (rev 6462) @@ -858,7 +858,7 @@ // Initialize the path (and add system defaults) defaultPath = initPath(registry, standalone, jarFileName); defaultArgv = initArgv(argv); - defaultExecutable = initExecutable(registry, jarFileName); + defaultExecutable = initExecutable(registry); // Set up the known Java packages initPackages(registry); // Finish up standard Python initialization... @@ -961,23 +961,16 @@ } /** - * Determine the default sys.executable value from the registry. Returns Py.None is no - * executable can be found. - * - * @param props - * a Properties registry - * @param jarFileName - * used as executable if python.executable not otherwise specified + * Determine the default sys.executable value from the + * registry. Returns Py.None is no executable can be found. + * + * @param props a Properties registry * @return a PyObject path string or Py.None */ - private static PyObject initExecutable(Properties props, String jarFileName) { + private static PyObject initExecutable(Properties props) { String executable = props.getProperty("python.executable"); if (executable == null) { - if (jarFileName != null) { - executable = jarFileName; - } else { - return Py.None; - } + return Py.None; } File executableFile = new File(executable); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-06-08 06:41:39
|
Revision: 6468 http://jython.svn.sourceforge.net/jython/?rev=6468&view=rev Author: pjenvey Date: 2009-06-08 06:41:36 +0000 (Mon, 08 Jun 2009) Log Message: ----------- also special case paths with a single leading '/' (e.g. '/Jython25') as absolute on Windows. add test case for this and leading r'\' (r6413) fixes #1372 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/core/PySystemState.java Added Paths: ----------- trunk/jython/Lib/test/test_nt_paths.py Added: trunk/jython/Lib/test/test_nt_paths.py =================================================================== --- trunk/jython/Lib/test/test_nt_paths.py (rev 0) +++ trunk/jython/Lib/test/test_nt_paths.py 2009-06-08 06:41:36 UTC (rev 6468) @@ -0,0 +1,40 @@ +"""Test path handling on Windows + +Made for Jython. +""" +from __future__ import with_statement +import os +import unittest +from test import test_support + +class NTAbspathTestCase(unittest.TestCase): + + def setUp(self): + with open(test_support.TESTFN, 'w') as fp: + fp.write('foo') + + # Move to the same drive as TESTFN + drive, self.path = os.path.splitdrive(os.path.abspath( + test_support.TESTFN)) + self.orig_cwd = os.getcwd() + os.chdir(os.path.join(drive, os.sep)) + + def tearDown(self): + os.chdir(self.orig_cwd) + os.remove(test_support.TESTFN) + + def test_abspaths(self): + # Ensure r'\TESTFN' and '/TESTFN' are handled as absolute + for path in self.path, self.path.replace('\\', '/'): + with open(path) as fp: + self.assertEqual(fp.read(), 'foo') + + +def test_main(): + if (os._name if test_support.is_jython else os.name) != 'nt': + raise test_support.TestSkipped('NT specific test') + test_support.run_unittest(NTAbspathTestCase) + + +if __name__ == '__main__': + test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-06-08 00:30:12 UTC (rev 6467) +++ trunk/jython/NEWS 2009-06-08 06:41:36 UTC (rev 6468) @@ -11,6 +11,7 @@ - [ 1364 ] SimpleHTTPServer.py contains call to missing os.fstat - [ 1367 ] PIpes (popen2) do not flush their buffer - [ 1368 ] '\xe4'.decode('utf-8') does not raise UnicodeDecodeError but returns u'' + - [ 1372 ] No default drive in Windows file paths - Fix file's repr with Windows paths - Fix urllib and urllib2 path handling on Windows - Fix r'\Jython25' not considered an abspath on Windows Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-06-08 00:30:12 UTC (rev 6467) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-06-08 06:41:36 UTC (rev 6468) @@ -508,8 +508,10 @@ } File file = new File(path); - // Python considers r'\Jython25' an abspath on Windows, unlike java.io.File - if (!file.isAbsolute() && (!Platform.IS_WINDOWS || !path.startsWith("\\"))) { + // Python considers r'\Jython25' and '/Jython25' abspaths on Windows, unlike + // java.io.File + if (!file.isAbsolute() && (!Platform.IS_WINDOWS + || !(path.startsWith("\\") || path.startsWith("/")))) { if (sys == null) { sys = Py.getSystemState(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-08 17:19:06
|
Revision: 6470 http://jython.svn.sourceforge.net/jython/?rev=6470&view=rev Author: fwierzbicki Date: 2009-06-08 17:18:04 +0000 (Mon, 08 Jun 2009) Log Message: ----------- Increment to rc4, also increment API_VERSION since some compiler changes have occured without an update. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/README.txt trunk/jython/build.xml trunk/jython/src/org/python/core/imp.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/NEWS 2009-06-08 17:18:04 UTC (rev 6470) @@ -20,6 +20,8 @@ recompiling due to stale bytecode - Fixed minor short term memory leaks in functions on some lists allocated inline + - Updated imp.APIVersion to 23 as some compiler changes occured since the + last update. Jython 2.5.0 rc3 Bugs fixed Modified: trunk/jython/README.txt =================================================================== --- trunk/jython/README.txt 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/README.txt 2009-06-08 17:18:04 UTC (rev 6470) @@ -1,8 +1,9 @@ -Welcome to Jython 2.5rc3 +Welcome to Jython 2.5rc4 ======================== -This is the third release candidate of the 2.5 version of Jython. It partially -fixes JLine on Cygwin and some threading issues. +This is the fourth release candidate of the 2.5 version of Jython. Many bugs +are fixed in this release, and the regression tests now pass on Windows. See +the NEWS file for details. The release was compiled on Mac OS X with JDK 5 and requires JDK 5 to run. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/build.xml 2009-06-08 17:18:04 UTC (rev 6470) @@ -187,13 +187,13 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5rc3+"/> - <property name="jython.version.noplus" value="2.5rc3"/> + <property name="jython.version" value="2.5rc4+"/> + <property name="jython.version.noplus" value="2.5rc4"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> <property name="jython.micro_version" value="0"/> <property name="jython.release_level" value="${PY_RELEASE_LEVEL_GAMMA}"/> - <property name="jython.release_serial" value="3"/> + <property name="jython.release_serial" value="4"/> <condition property="do.snapshot.build"> <isset property="snapshot.revision" /> Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/src/org/python/core/imp.java 2009-06-08 17:18:04 UTC (rev 6470) @@ -20,7 +20,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - private static final int APIVersion = 22; + private static final int APIVersion = 23; public static final int NO_MTIME = -1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-16 17:18:50
|
Revision: 6475 http://jython.svn.sourceforge.net/jython/?rev=6475&view=rev Author: fwierzbicki Date: 2009-06-16 17:18:28 +0000 (Tue, 16 Jun 2009) Log Message: ----------- Release labels for 2.5.0 final. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/README.txt trunk/jython/build.xml Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-06-11 11:56:08 UTC (rev 6474) +++ trunk/jython/NEWS 2009-06-16 17:18:28 UTC (rev 6475) @@ -1,5 +1,8 @@ Jython NEWS +Jython 2.5.0 + The same as rc4. + Jython 2.5.0 rc4 Bugs fixed - [ 1354 ] core language failures in interactive interpreter Modified: trunk/jython/README.txt =================================================================== --- trunk/jython/README.txt 2009-06-11 11:56:08 UTC (rev 6474) +++ trunk/jython/README.txt 2009-06-16 17:18:28 UTC (rev 6475) @@ -1,9 +1,11 @@ -Welcome to Jython 2.5rc4 -======================== +Welcome to Jython 2.5.0 +======================= -This is the fourth release candidate of the 2.5 version of Jython. Many bugs -are fixed in this release, and the regression tests now pass on Windows. See -the NEWS file for details. +This is the final release of the 2.5.0 version of Jython and brings us up to +language level compatibility with the 2.5 version of CPython. This release has +had a strong focus on CPython compatibility, and so this release of Jython can +run more pure Python apps then any previous release. Please see the NEWS file +for detailed release notes. The release was compiled on Mac OS X with JDK 5 and requires JDK 5 to run. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-06-11 11:56:08 UTC (rev 6474) +++ trunk/jython/build.xml 2009-06-16 17:18:28 UTC (rev 6475) @@ -187,13 +187,13 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5rc4+"/> - <property name="jython.version.noplus" value="2.5rc4"/> + <property name="jython.version" value="2.5.0+"/> + <property name="jython.version.noplus" value="2.5.0"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> <property name="jython.micro_version" value="0"/> - <property name="jython.release_level" value="${PY_RELEASE_LEVEL_GAMMA}"/> - <property name="jython.release_serial" value="4"/> + <property name="jython.release_level" value="${PY_RELEASE_LEVEL_FINAL}"/> + <property name="jython.release_serial" value="0"/> <condition property="do.snapshot.build"> <isset property="snapshot.revision" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-22 06:32:37
|
Revision: 6490 http://jython.svn.sourceforge.net/jython/?rev=6490&view=rev Author: cgroves Date: 2009-06-22 06:32:34 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Add enough of mockrunner to run servlet tests and use that to run the modjy tests and some new PyServlet tests from our regular build. Modified Paths: -------------- trunk/jython/.classpath trunk/jython/build.xml trunk/jython/src/org/python/core/PySystemState.java trunk/jython/tests/modjy/build.xml trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java Added Paths: ----------- trunk/jython/Lib/test/pyservlet/ trunk/jython/Lib/test/pyservlet/__init__.py trunk/jython/Lib/test/pyservlet/basic.py trunk/jython/Lib/test/pyservlet/empty.py trunk/jython/Lib/test/pyservlet/increment.py trunk/jython/Lib/test/pyservlet/updated_basic.py trunk/jython/extlibs/mockrunner-0.4.1/ trunk/jython/extlibs/mockrunner-0.4.1/jar/ trunk/jython/extlibs/mockrunner-0.4.1/jar/commons-logging-1.0.4.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/ trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/servlet.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/jakarta-oro-2.0.8.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/jdom.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/nekohtml.jar trunk/jython/extlibs/mockrunner-0.4.1/lib/ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar trunk/jython/extlibs/mockrunner-0.4.1/readme.txt trunk/jython/tests/modjy/java/org/ trunk/jython/tests/modjy/java/org/python/ trunk/jython/tests/modjy/java/org/python/util/ trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java Property Changed: ---------------- trunk/jython/tests/modjy/ Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/.classpath 2009-06-22 06:32:34 UTC (rev 6490) @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry excluding="com/ziclix/python/sql/handler/InformixDataHandler.java|com/ziclix/python/sql/handler/OracleDataHandler.java" kind="src" output="build/classes" path="src"/> + <classpathentry kind="src" path="tests/modjy/java"/> <classpathentry kind="src" output="build/classes" path="build/gensrc"/> <classpathentry kind="src" output="build/classes" path="tests/java"/> <classpathentry kind="src" path="bugtests/classes"/> @@ -18,5 +19,7 @@ <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/> <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/> <classpathentry kind="lib" path="extlibs/jna-posix.jar"/> + <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/jar/jdom.jar"/> + <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar"/> <classpathentry kind="output" path="bugtests/classes"/> </classpath> Added: trunk/jython/Lib/test/pyservlet/basic.py =================================================================== --- trunk/jython/Lib/test/pyservlet/basic.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/basic.py 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,5 @@ +from javax.servlet.http import HttpServlet + +class basic(HttpServlet): + def doGet(self, req, resp): + resp.getOutputStream().write("Basic text response") Added: trunk/jython/Lib/test/pyservlet/increment.py =================================================================== --- trunk/jython/Lib/test/pyservlet/increment.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/increment.py 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,8 @@ +from javax.servlet.http import HttpServlet + +class increment(HttpServlet): + def __init__(self): + self.counter = 0 + def doGet(self, req, resp): + self.counter += 1 + resp.outputStream.write(str(self.counter)) Added: trunk/jython/Lib/test/pyservlet/updated_basic.py =================================================================== --- trunk/jython/Lib/test/pyservlet/updated_basic.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/updated_basic.py 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,5 @@ +from javax.servlet.http import HttpServlet + +class basic(HttpServlet): + def doGet(self, req, resp): + resp.outputStream.write("Updated text response") Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/build.xml 2009-06-22 06:32:34 UTC (rev 6490) @@ -813,7 +813,7 @@ </jar> </target> - <target name="test" depends="prepare-test,javatest,launchertest,regrtest"/> + <target name="test" depends="prepare-test,javatest,launchertest,regrtest,modjytest"/> <target name="singlejavatest" depends="compile,expose"> <junit haltonfailure="true" fork="true"> <formatter type="brief" usefile="false"/> @@ -842,6 +842,12 @@ </batchtest> </junit> </target> + <target name="modjytest" depends="developer-build"> + <ant dir="tests/modjy"> + <property name="jython_home" value="${dist.dir}"/> + <property name="mockrunner_home" value="${extlibs.dir}/mockrunner-0.4.1"/> + </ant> + </target> <target name="launchertest" depends="developer-build" if="os.family.unix"> <exec executable="${test.shell.dir}/test-jython.sh"> <arg value="${dist.dir}"/> Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/commons-logging-1.0.4.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/commons-logging-1.0.4.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/servlet.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/servlet.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/jakarta-oro-2.0.8.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/jakarta-oro-2.0.8.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/jdom.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/jdom.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/nekohtml.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/nekohtml.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt =================================================================== --- trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt (rev 0) +++ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,135 @@ +This file lists all the jar files provided by Mockrunner and +the required third party libraries for each jar. Please note +that this file is created automatically by analyzing the +compile time dependencies of all classes in the jar. This +is done recursively, i.e. the dependencies of the third-party +jars are recognized as well. If you add all dependend jars +for a specified mockrunner-xyz.jar to your classpath, you +are on the safe side. However, not all listed dependencies +are necessary at runtime in all cases. Especially with the +"all-in-one"-file mockrunner.jar you don't have to add everything +to the classpath. E.g. if you're only using EJB and JMS, you don't have +to add the web related jar files, because the necessary factories and modules +are created when they are used and lazy initialized respectively. +Please note that the Struts test framework only needs CGLib, if custom action +mappings are used. The jasper related jar files are only necessary if +the JasperJspFactory is used. If you only need one technology it's recommended +to use the corresponding jar file instead of the "all-in-one" mockrunner.jar. +E.g. if you only want to use the JDBC test framework, you can use +mockrunner-jdbc.jar. Please note that each mockrunner-xyz.jar file contains a +jarversion.txt which lists the Mockrunner version and the supported JDK and +J2EE version. + +Created: 06/26/2008 05:59 PM + +Jar file name: mockrunner-tag.jar + +Depends on: + +commons-beanutils-1.7.0.jar +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +nekohtml.jar +servlet.jar +xercesImpl.jar +xml-apis.jar + + +Jar file name: mockrunner-jms.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +junit.jar + + +Jar file name: mockrunner-servlet.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +nekohtml.jar +servlet.jar +xercesImpl.jar +xml-apis.jar + + +Jar file name: mockrunner.jar + +Depends on: + +cglib-nodep-2.2.jar +commons-beanutils-1.7.0.jar +commons-digester-1.8.jar +commons-logging-1.0.4.jar +commons-validator-1.3.1.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +jdom.jar +junit.jar +mockejb.jar +nekohtml.jar +servlet.jar +struts.jar +xercesImpl.jar +xml-apis.jar + + +Jar file name: mockrunner-jca.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +junit.jar + + +Jar file name: mockrunner-jdbc.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +xml-apis.jar + + +Jar file name: mockrunner-ejb.jar + +Depends on: + +cglib-nodep-2.2.jar +commons-beanutils-1.7.0.jar +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +junit.jar +mockejb.jar + + +Jar file name: mockrunner-struts.jar + +Depends on: + +cglib-nodep-2.2.jar +commons-beanutils-1.7.0.jar +commons-digester-1.8.jar +commons-logging-1.0.4.jar +commons-validator-1.3.1.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +nekohtml.jar +servlet.jar +struts.jar +xercesImpl.jar +xml-apis.jar Added: trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/readme.txt =================================================================== --- trunk/jython/extlibs/mockrunner-0.4.1/readme.txt (rev 0) +++ trunk/jython/extlibs/mockrunner-0.4.1/readme.txt 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,2 @@ +This contains the minimal set of jars from mockrunner-0.4.1 to run the modjy tests against j2ee1.3 +with jdk1.5. Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-06-22 06:32:34 UTC (rev 6490) @@ -698,10 +698,10 @@ } } - public static Properties getBaseProperties(){ - try{ + public static Properties getBaseProperties() { + try { return System.getProperties(); - }catch(AccessControlException ace){ + } catch (AccessControlException ace) { return new Properties(); } } Property changes on: trunk/jython/tests/modjy ___________________________________________________________________ Added: svn:ignore + build Modified: trunk/jython/tests/modjy/build.xml =================================================================== --- trunk/jython/tests/modjy/build.xml 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/tests/modjy/build.xml 2009-06-22 06:32:34 UTC (rev 6490) @@ -12,16 +12,17 @@ <!-- Jython properties --> - <property name="jython_home" location="${env.JYTHON_HOME}"/> + <property name="jython_home" location="${env.JYTHON_HOME}"/> <property name="jython_jar" value="jython-dev.jar"/> <property name="jython_jar_path" location="${jython_home}/${jython_jar}"/> <property name="jython_cachedir" location="${jython_home}/cachedir"/> + <property name="mockrunner_home" location="${env.MOCKRUNNER_HOME}"/> <target name="init"> - <available property="jython.home.set" file="${env.JYTHON_HOME}" /> - <fail unless="jython.home.set" message="JYTHON_HOME not set" /> - <available property="mockrunner.home.set" file="${env.MOCKRUNNER_HOME}" /> - <fail unless="mockrunner.home.set" message="MOCKRUNNER_HOME not set" /> + <available property="jython_home.exists" file="${jython_home}" /> + <fail unless="jython_home.exists" message="jython_home, ${jython_home}, doesn't exist" /> + <available property="mockrunner_home.exists" file="${mockrunner_home}" /> + <fail unless="mockrunner_home.exists" message="mockrunner_home, ${mockrunner_home}, doesn't exist" /> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> </target> @@ -35,12 +36,7 @@ <target name="do_test" depends="init" description="Run unit tests against a single jdk/servlet combo"> <echo message="Running tests against JDK ${jdk_version}, Servlet ${servlet_version}"/> - <echo message="Clearing jython package cache located at ${jython_home}/cachedir"/> - <delete quiet="true"> - <fileset dir="${jython_cachedir}"/> - </delete> - <property name="mockrunner_home" value="${env.MOCKRUNNER_HOME}"/> <property name="mockrunner_jar" location="${mockrunner_home}/jar"/> <property name="mockrunner_lib" location="${mockrunner_home}/lib/jdk${jdk_version}/${servlet_version}"/> @@ -57,15 +53,13 @@ srcdir="${test_src}" destdir="${build}" classpathref="test.classpath" - debug="on" - /> - - <java - classname="com.xhaus.modjy.ModjyTestBase" - dir="." - fork="yes" - classpathref="test.classpath" - /> + debug="on" + /> + <java classname="com.xhaus.modjy.ModjyTestBase" dir="." fork="yes" + classpathref="test.classpath"> + <sysproperty key="JYTHON_HOME" value="${jython_home}"/> + <sysproperty key="python.cachedir.skip" value="true"/> + </java> </target> <target name="test"> Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 06:32:34 UTC (rev 6490) @@ -1,35 +1,27 @@ /*### # -# Copyright Alan Kennedy. -# +# Copyright Alan Kennedy. +# # You may contact the copyright holder at this uri: -# +# # http://www.xhaus.com/contact/modjy -# +# # The licence under which this code is released is the Apache License v2.0. -# +# # The terms and conditions of this license are listed in a file contained # in the distribution that also contained this file, under the name # LICENSE.txt. -# +# # You may also read a copy of the license at the following web address. -# +# # http://modjy.xhaus.com/LICENSE.txt # ###*/ package com.xhaus.modjy; -import java.io.File; - -import java.util.Map; -import java.util.Iterator; - import junit.framework.*; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServlet; - import com.mockrunner.servlet.BasicServletTestCaseAdapter; import com.mockrunner.mock.web.WebMockObjectFactory; import com.mockrunner.mock.web.MockServletConfig; @@ -37,16 +29,16 @@ import com.mockrunner.mock.web.MockHttpServletRequest; import com.mockrunner.mock.web.MockHttpServletResponse; -import org.jdom.Element; import org.jdom.output.XMLOutputter; import org.python.core.PyObject; +import org.python.util.PyServletTest; import org.python.util.PythonInterpreter; import com.xhaus.modjy.ModjyJServlet; /** - * + * */ public class ModjyTestBase extends BasicServletTestCaseAdapter @@ -226,7 +218,7 @@ throws Exception { super.setUp(); - String jythonHome = System.getenv("JYTHON_HOME"); + String jythonHome = System.getProperty("JYTHON_HOME"); setRealPath(jythonHome, jythonHome); setRealPath("/WEB-INF/"+LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); @@ -267,7 +259,7 @@ baseSetUp(); createServlet(); doGet(); - String result = new XMLOutputter().outputString(getOutputAsJDOMDocument()); + new XMLOutputter().outputString(getOutputAsJDOMDocument()); } public static void main(String args[]) @@ -281,6 +273,7 @@ suite.addTestSuite(ModjyTestReturnIterable.class); suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); + suite.addTestSuite(PyServletTest.class); junit.textui.TestRunner.run(suite); } Added: trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java =================================================================== --- trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java (rev 0) +++ trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,88 @@ +package org.python.util; + +import javax.servlet.ServletException; + +import org.python.core.PyFile; +import com.mockrunner.base.NestedApplicationException; +import com.mockrunner.mock.web.MockServletConfig; +import com.mockrunner.mock.web.MockServletContext; +import com.mockrunner.mock.web.WebMockObjectFactory; +import com.mockrunner.servlet.BasicServletTestCaseAdapter; + +public class PyServletTest extends BasicServletTestCaseAdapter { + public void testGet() { + assertEquals("Basic text response", doGetAndRead("basic")); + } + + public void testNoCallable() { + try { + doGetAndRead("empty"); + fail("Using an empty file for PyServlet should raise a ServletException"); + } catch (NestedApplicationException e) { + assertTrue(e.getRootCause() instanceof ServletException); + } + } + + public void testReload() { + String originalBasic = readTestFile("basic"); + try { + testGet(); + writeToTestFile("basic", readTestFile("updated_basic")); + assertEquals("Updated text response", doGetAndRead("basic")); + } finally { + writeToTestFile("basic", originalBasic); + } + } + + public void testInstanceCaching() { + assertEquals("1", doGetAndRead("increment")); + assertEquals("2", doGetAndRead("increment")); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + MockServletConfig cfg = getWebMockObjectFactory().getMockServletConfig(); + cfg.setInitParameter("python.home", System.getProperty("JYTHON_HOME")); + createServlet(PyServlet.class); + } + + private String doGetAndRead(String testName) { + getWebMockObjectFactory().getMockRequest().setServletPath(getTestPath(testName)); + doGet(); + String result = getOutput(); + clearOutput(); + return result; + } + + private String getTestPath(String testName) { + return "/test/pyservlet/" + testName + ".py"; + } + + private String readTestFile(String testName) { + PyFile in = new PyFile(basePath + getTestPath(testName), "r", 4192); + String result = in.read().toString(); + return result; + } + + private void writeToTestFile(String testName, String newContents) { + PyFile out = new PyFile(basePath + getTestPath(testName), "w", 4192); + out.write(newContents); + out.close(); + } + + @Override + protected WebMockObjectFactory createWebMockObjectFactory() { + return new WebMockObjectFactory() { + @Override public MockServletContext createMockServletContext() { + return new MockServletContext() { + @Override public synchronized String getRealPath(String path) { + return basePath + path; + } + }; + } + }; + } + + private String basePath = System.getProperty("JYTHON_HOME") + "/Lib"; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-22 06:48:55
|
Revision: 6491 http://jython.svn.sourceforge.net/jython/?rev=6491&view=rev Author: cgroves Date: 2009-06-22 06:48:53 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Coding conventions and modernization Modified Paths: -------------- trunk/jython/ACKNOWLEDGMENTS trunk/jython/src/org/python/util/PyServlet.java Modified: trunk/jython/ACKNOWLEDGMENTS =================================================================== --- trunk/jython/ACKNOWLEDGMENTS 2009-06-22 06:32:34 UTC (rev 6490) +++ trunk/jython/ACKNOWLEDGMENTS 2009-06-22 06:48:53 UTC (rev 6491) @@ -33,6 +33,8 @@ Alan Kennedy contributed modjy, which bridges WSGI to the Servlet API + Chris Gokey, David Syer and Finn Bock added PyServlet. + A huge thanks goes to all the members of the jpython/jython mailing lists. Other folks who have contributed to JPython and Jython in ways large and small, in no particular order: Modified: trunk/jython/src/org/python/util/PyServlet.java =================================================================== --- trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 06:32:34 UTC (rev 6490) +++ trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 06:48:53 UTC (rev 6491) @@ -1,27 +1,28 @@ - package org.python.util; -import java.io.*; -import java.util.*; -import javax.servlet.*; -import javax.servlet.http.*; -import org.python.core.*; +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Map; +import java.util.Properties; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import org.python.core.Py; +import org.python.core.PyException; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PySystemState; + /** - * This servlet is used to re-serve Jython servlets. It stores - * bytecode for Jython servlets and re-uses it if the underlying .py - * file has not changed. + * This servlet is used to re-serve Jython servlets. It stores bytecode for Jython servlets and + * re-uses it if the underlying .py file has not changed. * <p> - * Many people have been involved with this class: - * <ul> - * <li>Chris Gokey - * <li>David Syer - * <li>Finn Bock - * </ul> - * If somebody is missing from this list, let us know. - * <p> - * * e.g. http://localhost:8080/test/hello.py * <pre> * @@ -58,40 +59,32 @@ * * </pre> */ - public class PyServlet extends HttpServlet { - private PythonInterpreter interp; - private Hashtable cache = new Hashtable(); - private String rootPath; - - + @Override public void init() { rootPath = getServletContext().getRealPath("/"); - if (!rootPath.endsWith(File.separator)) + if (!rootPath.endsWith(File.separator)) { rootPath += File.separator; - + } Properties props = new Properties(); Properties baseProps = PySystemState.getBaseProperties(); - // Context parameters ServletContext context = getServletContext(); - Enumeration e = context.getInitParameterNames(); + Enumeration<?> e = context.getInitParameterNames(); while (e.hasMoreElements()) { - String name = (String) e.nextElement(); + String name = (String)e.nextElement(); props.put(name, context.getInitParameter(name)); } // Config parameters e = getInitParameterNames(); while (e.hasMoreElements()) { - String name = (String) e.nextElement(); + String name = (String)e.nextElement(); props.put(name, getInitParameter(name)); } - - if(props.getProperty("python.home") == null + if (props.getProperty("python.home") == null && baseProps.getProperty("python.home") == null) { - props.put("python.home", rootPath + "WEB-INF" + - File.separator + "lib"); + props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib"); } PySystemState.initialize(baseProps, props, new String[0]); @@ -107,13 +100,7 @@ PySystemState.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true); } - /** - * Implementation of the HttpServlet main method. - * @param req the request parameter. - * @param res the response parameter. - * @exception ServletException - * @exception IOException - */ + @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { @@ -121,29 +108,30 @@ String spath = (String) req.getAttribute("javax.servlet.include.servlet_path"); if (spath == null) { - spath = ((HttpServletRequest) req).getServletPath(); + spath = ((HttpServletRequest)req).getServletPath(); if (spath == null || spath.length() == 0) { - // Servlet 2.1 puts the path of an extension-matched - // servlet in PathInfo. - spath = ((HttpServletRequest) req).getPathInfo(); + // Servlet 2.1 puts the path of an extension-matched servlet in PathInfo. + spath = ((HttpServletRequest)req).getPathInfo(); } } String rpath = getServletContext().getRealPath(spath); + getServlet(rpath).service(req, res); + } - interp.set("__file__", rpath); - - HttpServlet servlet = getServlet(rpath); - if (servlet != null) - servlet.service(req, res); - else - throw new ServletException("No python servlet found at:" + spath); + @Override + public void destroy() { + super.destroy(); + destroyCache(); } + /** + * Clears the cache of loaded servlets and makes a new PythonInterpreter to service further + * requests. + */ public void reset() { destroyCache(); interp = new PythonInterpreter(null, new PySystemState()); - cache.clear(); - + PySystemState sys = Py.getSystemState(); sys.path.append(new PyString(rootPath)); @@ -154,33 +142,34 @@ private synchronized HttpServlet getServlet(String path) throws ServletException, IOException { - CacheEntry entry = (CacheEntry) cache.get(path); - if (entry == null) + CacheEntry entry = cache.get(path); + if (entry == null || new File(path).lastModified() > entry.date) { return loadServlet(path); - File file = new File(path); - if (file.lastModified() > entry.date) - return loadServlet(path); + } return entry.servlet; } private HttpServlet loadServlet(String path) throws ServletException, IOException { - HttpServlet servlet = null; File file = new File(path); // Extract servlet name from path (strip ".../" and ".py") int start = path.lastIndexOf(File.separator); - if (start < 0) + if (start < 0) { start = 0; - else + } else { start++; + } int end = path.lastIndexOf('.'); - if ((end < 0) || (end <= start)) + if (end < 0 || end <= start) { end = path.length(); + } String name = path.substring(start, end); + HttpServlet servlet; try { + interp.set("__file__", path); interp.execfile(path); PyObject cls = interp.get(name); if (cls == null) { @@ -194,34 +183,31 @@ } servlet = (HttpServlet)o; servlet.init(getServletConfig()); - } catch (PyException e) { throw new ServletException(e); } - CacheEntry entry = new CacheEntry(servlet, file.lastModified()); - cache.put(path, entry); + cache.put(path, new CacheEntry(servlet, file.lastModified())); return servlet; } - public void destroy() { - destroyCache(); - } - private void destroyCache() { - for (Enumeration e = cache.elements(); e.hasMoreElements(); ) { - CacheEntry entry = (CacheEntry) e.nextElement(); + for (CacheEntry entry : cache.values()) { entry.servlet.destroy(); } + cache.clear(); } -} + private static class CacheEntry { + public long date; + public HttpServlet servlet; -class CacheEntry { - public long date; - public HttpServlet servlet; - - CacheEntry(HttpServlet servlet, long date) { - this.servlet= servlet; - this.date = date; + CacheEntry(HttpServlet servlet, long date) { + this.servlet= servlet; + this.date = date; + } } -} + + private PythonInterpreter interp; + private String rootPath; + private Map<String, CacheEntry> cache = Generic.map(); +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-22 08:27:12
|
Revision: 6492 http://jython.svn.sourceforge.net/jython/?rev=6492&view=rev Author: cgroves Date: 2009-06-22 08:27:10 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Add jfeinberg's PyFilter from #1859477. Still need to test this in an actual ServletContainer Modified Paths: -------------- trunk/jython/src/org/python/util/PyServlet.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java Added Paths: ----------- trunk/jython/Lib/test/pyservlet/filter.py trunk/jython/src/org/python/util/PyFilter.java trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java Added: trunk/jython/Lib/test/pyservlet/filter.py =================================================================== --- trunk/jython/Lib/test/pyservlet/filter.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/filter.py 2009-06-22 08:27:10 UTC (rev 6492) @@ -0,0 +1,9 @@ +from javax.servlet import Filter + +class filter(Filter): + def init(self, config): + self.header = config.getInitParameter('header') + + def doFilter(self, req, resp, chain): + resp.setHeader(self.header, "Yup") + chain.doFilter(req, resp) Added: trunk/jython/src/org/python/util/PyFilter.java =================================================================== --- trunk/jython/src/org/python/util/PyFilter.java (rev 0) +++ trunk/jython/src/org/python/util/PyFilter.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -0,0 +1,158 @@ +package org.python.util; + +import java.io.File; +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.python.core.PyException; +import org.python.core.PySystemState; +import org.python.util.PythonInterpreter; + +/** + * Enables you to write Jython modules that inherit from <code>javax.servlet.Filter</code>, and to + * insert them in your servlet container's filter chain, like any Java <code>Filter</code>. + * + * <p> + * Example: + * + * <p> + * <b>/WEB-INF/filters/HeaderFilter.py:</b> + * + * <pre> + * from javax.servlet import Filter + * + * # Module must contain a class with the same name as the module + * # which in turn must implement javax.servlet.Filter + * class HeaderFilter (Filter): + * def init(self, config): + * self.header = config.getInitParameter('header') + * + * def doFilter(self, request, response, chain): + * response.setHeader(self.header, "Yup") + * chain.doFilter(request, response) + * </pre> + * + * <p> + * <b>web.xml:</b> + * </p> + * + * <pre> + * <!-- PyFilter depends on PyServlet --> + * <servlet> + * <servlet-name>PyServlet</servlet-name> + * <servlet-class>org.python.util.PyServlet</servlet-class> + * <load-on-startup>1</load-on-startup> + * </servlet> + * + * <!-- Declare a uniquely-named PyFilter --> + * <filter> + * <filter-name>HeaderFilter</filter-name> + * <filter-class>org.jython.util.PyFilter</filter-class> + * + * <!-- The special param __filter__ gives the context-relative path to the Jython source file --> + * <init-param> + * <param-name>__filter__</param-name> + * <param-value>/WEB-INF/pyfilter/HeaderFilter.py</param-value> + * </init-param> + * + * <!-- Other params are passed on the the Jython filter --> + * <init-param> + * <param-name>header</param-name> + * <param-value>X-LookMaNoJava</param-value> + * </init-param> + * </filter> + * <filter-mapping> + * <filter-name>HeaderFilter</filter-name> + * <url-pattern>/*</url-pattern> + * </filter-mapping> + * </pre> + * + * <p> + * PyFilter depends on initialization code from PyServlet being run. If PyServlet is used to serve + * pages, this code will be executed and PyFilter will work properly. However, if you aren't using + * PyServlet, the initialization code can be invoked as a ServletContextListener instead of as an + * HttpServlet. Use the following in web.xml instead of a servlet tag: + * + * <pre> + * <listener> + * <listener-class>org.python.util.PyServlet</listener-class> + * <load-on-startup>1</load-on-startup> + * </listener> + * </pre> + * + */ +public class PyFilter implements Filter { + public static final String FILTER_PATH_PARAM = "__filter__"; + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + request.setAttribute("pyfilter", this); + getFilter().doFilter(request, response, chain); + } + + public void init(FilterConfig config) throws ServletException { + if (config.getServletContext().getAttribute(PyServlet.INIT_ATTR) == null) { + throw new ServletException("PyServlet has not been initialized, either as a servlet " + + "or as context listener. This must happen before PyFilter is initialized."); + } + this.config = config; + String filterPath = config.getInitParameter(FILTER_PATH_PARAM); + if (filterPath == null) { + throw new ServletException("Missing required param '" + FILTER_PATH_PARAM + "'"); + } + source = new File(getRealPath(config.getServletContext(), filterPath)); + if (!source.exists()) { + throw new ServletException(source.getAbsolutePath() + " does not exist."); + } + interp = new PythonInterpreter(null, new PySystemState()); + } + + private String getRealPath(ServletContext context, String appPath) { + String realPath = context.getRealPath(appPath); + // This madness seems to be necessary on Windows + return realPath.replaceAll("\\\\", "/"); + } + + private Filter getFilter() throws ServletException, IOException { + if (cached == null || source.lastModified() > loadedMtime) { + return loadFilter(); + } + return cached; + } + + private Filter loadFilter() throws ServletException, IOException { + loadedMtime = source.lastModified(); + cached = PyServlet.createInstance(interp, source, Filter.class); + try { + cached.init(config); + } catch (PyException e) { + throw new ServletException(e); + } + return cached; + } + + public void destroy() { + if (cached != null) { + cached.destroy(); + } + if (interp != null) { + interp.cleanup(); + } + } + + private PythonInterpreter interp; + + private FilterConfig config; + + private File source; + + private Filter cached; + + private long loadedMtime; +} Modified: trunk/jython/src/org/python/util/PyServlet.java =================================================================== --- trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 06:48:53 UTC (rev 6491) +++ trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -5,8 +5,12 @@ import java.util.Enumeration; import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -37,7 +41,6 @@ * print >>out, "</body>" * print >>out, "</html>" * out.close() - * return * </pre> * * in web.xml for the PyServlet context: @@ -59,47 +62,76 @@ * * </pre> */ -public class PyServlet extends HttpServlet { +public class PyServlet extends HttpServlet implements ServletContextListener { + + public static final String SKIP_INIT_NAME = "skip_jython_initialization"; + + protected static final String INIT_ATTR = "__jython_initialized__"; + + public void contextInitialized(ServletContextEvent event) { + init(new Properties(), event.getServletContext(), "a ServletContextListener", true); + } + + public void contextDestroyed(ServletContextEvent event) {} + @Override public void init() { - rootPath = getServletContext().getRealPath("/"); - if (!rootPath.endsWith(File.separator)) { - rootPath += File.separator; - } Properties props = new Properties(); - Properties baseProps = PySystemState.getBaseProperties(); - // Context parameters - ServletContext context = getServletContext(); - Enumeration<?> e = context.getInitParameterNames(); - while (e.hasMoreElements()) { - String name = (String)e.nextElement(); - props.put(name, context.getInitParameter(name)); - } - // Config parameters - e = getInitParameterNames(); + Enumeration<?> e = getInitParameterNames(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); props.put(name, getInitParameter(name)); } - if (props.getProperty("python.home") == null - && baseProps.getProperty("python.home") == null) { - props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib"); + init(props, getServletContext(), "the servlet " + getServletConfig().getServletName(), + getServletConfig().getInitParameter(SKIP_INIT_NAME) != null); + } + + /** + * PyServlet's initialization can be performed as a ServletContextListener or as a regular + * servlet, and this is the shared init code. If both initializations are used in a single + * context, the system state initialization code only runs once. + */ + private void init(Properties props, ServletContext context, String initializerName, + boolean initialize) { + rootPath = context.getRealPath("/"); + if (!rootPath.endsWith(File.separator)) { + rootPath += File.separator; } - - PySystemState.initialize(baseProps, props, new String[0]); + if (context.getAttribute(INIT_ATTR) != null) { + if (initialize) { + System.err.println("Jython has already been initialized by " + + context.getAttribute(INIT_ATTR) + + " in this context, not initializing for " + initializerName + ". Add " + + SKIP_INIT_NAME + + " to as an init param to this servlet's configuration to indicate this " + + "is expected."); + } + } else if (initialize) { + context.setAttribute(INIT_ATTR, initializerName); + Properties baseProps = PySystemState.getBaseProperties(); + // Context parameters + Enumeration<?> e = context.getInitParameterNames(); + while (e.hasMoreElements()) { + String name = (String)e.nextElement(); + props.put(name, context.getInitParameter(name)); + } + if (props.getProperty("python.home") == null + && baseProps.getProperty("python.home") == null) { + props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib"); + } + PySystemState.initialize(baseProps, props, new String[0]); + PySystemState.add_package("javax.servlet"); + PySystemState.add_package("javax.servlet.http"); + PySystemState.add_package("javax.servlet.jsp"); + PySystemState.add_package("javax.servlet.jsp.tagext"); + PySystemState.add_classdir(rootPath + "WEB-INF" + File.separator + "classes"); + PySystemState.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true); + } reset(); + } - PySystemState.add_package("javax.servlet"); - PySystemState.add_package("javax.servlet.http"); - PySystemState.add_package("javax.servlet.jsp"); - PySystemState.add_package("javax.servlet.jsp.tagext"); - PySystemState.add_classdir(rootPath + "WEB-INF" + File.separator + "classes"); - - PySystemState.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true); - } - @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException @@ -154,40 +186,44 @@ { File file = new File(path); - // Extract servlet name from path (strip ".../" and ".py") - int start = path.lastIndexOf(File.separator); - if (start < 0) { - start = 0; - } else { - start++; + HttpServlet servlet = createInstance(interp, file, HttpServlet.class); + try { + servlet.init(getServletConfig()); + } catch (PyException e) { + throw new ServletException(e); } - int end = path.lastIndexOf('.'); - if (end < 0 || end <= start) { - end = path.length(); + cache.put(path, new CacheEntry(servlet, file.lastModified())); + return servlet; + } + + protected static <T> T createInstance(PythonInterpreter interp, File file, Class<T> type) + throws ServletException { + Matcher m = FIND_NAME.matcher(file.getName()); + if (!m.find()) { + throw new ServletException("I can't guess the name of the class from " + + file.getAbsolutePath()); } - String name = path.substring(start, end); - - HttpServlet servlet; + String name = m.group(1); try { - interp.set("__file__", path); - interp.execfile(path); + interp.set("__file__", file.getAbsolutePath()); + interp.execfile(file.getAbsolutePath()); PyObject cls = interp.get(name); if (cls == null) { throw new ServletException("No callable (class or function) named " + name + " in " - + path); + + file.getAbsolutePath()); } PyObject pyServlet = cls.__call__(); - Object o = pyServlet.__tojava__(HttpServlet.class); + Object o = pyServlet.__tojava__(type); if (o == Py.NoConversion) { - throw new ServletException("The value from " + name + " must extend HttpServlet"); + throw new ServletException("The value from " + name + " must extend " + + type.getSimpleName()); } - servlet = (HttpServlet)o; - servlet.init(getServletConfig()); + @SuppressWarnings("unchecked") + T asT = (T)o; + return asT; } catch (PyException e) { throw new ServletException(e); } - cache.put(path, new CacheEntry(servlet, file.lastModified())); - return servlet; } private void destroyCache() { @@ -207,6 +243,8 @@ } } + private static final Pattern FIND_NAME = Pattern.compile("([^/]+)\\.py$"); + private PythonInterpreter interp; private String rootPath; private Map<String, CacheEntry> cache = Generic.map(); Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 06:48:53 UTC (rev 6491) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -20,22 +20,20 @@ package com.xhaus.modjy; -import junit.framework.*; +import junit.framework.TestSuite; -import com.mockrunner.servlet.BasicServletTestCaseAdapter; -import com.mockrunner.mock.web.WebMockObjectFactory; -import com.mockrunner.mock.web.MockServletConfig; -import com.mockrunner.mock.web.MockServletContext; -import com.mockrunner.mock.web.MockHttpServletRequest; -import com.mockrunner.mock.web.MockHttpServletResponse; - import org.jdom.output.XMLOutputter; - import org.python.core.PyObject; +import org.python.util.PyFilterTest; import org.python.util.PyServletTest; import org.python.util.PythonInterpreter; -import com.xhaus.modjy.ModjyJServlet; +import com.mockrunner.mock.web.MockHttpServletRequest; +import com.mockrunner.mock.web.MockHttpServletResponse; +import com.mockrunner.mock.web.MockServletConfig; +import com.mockrunner.mock.web.MockServletContext; +import com.mockrunner.mock.web.WebMockObjectFactory; +import com.mockrunner.servlet.BasicServletTestCaseAdapter; /** * @@ -274,6 +272,7 @@ suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); suite.addTestSuite(PyServletTest.class); + suite.addTestSuite(PyFilterTest.class); junit.textui.TestRunner.run(suite); } Added: trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java =================================================================== --- trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java (rev 0) +++ trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -0,0 +1,30 @@ +package org.python.util; + +import javax.servlet.http.HttpServletResponse; + +import com.mockrunner.mock.web.MockFilterConfig; + +public class PyFilterTest extends PyServletTest { + @Override + protected void setUp() throws Exception { + super.setUp(); + setDoChain(true); + } + + public void testFilter() { + getWebMockObjectFactory().getMockRequest().setServletPath(getTestPath("basic")); + doGet(); + assertFalse(((HttpServletResponse)getFilteredResponse()).containsHeader("X-LookMaNoJava")); + clearOutput(); + MockFilterConfig cfg = getWebMockObjectFactory().getMockFilterConfig(); + cfg.setInitParameter(PyFilter.FILTER_PATH_PARAM, getTestPath("filter")); + cfg.setInitParameter("header", "X-LookMaNoJava"); + // Set that PyServlet initialization has run as mockrunner's context doesn't indicate that + // it happened. + getWebMockObjectFactory().getMockServletContext().setAttribute(PyServlet.INIT_ATTR, "true"); + createFilter(PyFilter.class); + doGet(); + HttpServletResponse resp = (HttpServletResponse)getFilteredResponse(); + assertTrue(resp.containsHeader("X-LookMaNoJava")); + } +} Modified: trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java =================================================================== --- trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java 2009-06-22 06:48:53 UTC (rev 6491) +++ trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -47,7 +47,7 @@ createServlet(PyServlet.class); } - private String doGetAndRead(String testName) { + protected String doGetAndRead(String testName) { getWebMockObjectFactory().getMockRequest().setServletPath(getTestPath(testName)); doGet(); String result = getOutput(); @@ -55,7 +55,7 @@ return result; } - private String getTestPath(String testName) { + protected String getTestPath(String testName) { return "/test/pyservlet/" + testName + ".py"; } @@ -84,5 +84,5 @@ }; } - private String basePath = System.getProperty("JYTHON_HOME") + "/Lib"; + protected String basePath = System.getProperty("JYTHON_HOME") + "/Lib"; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-22 08:43:10
|
Revision: 6493 http://jython.svn.sourceforge.net/jython/?rev=6493&view=rev Author: cgroves Date: 2009-06-22 08:43:07 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Windows line endings to unix, tabs to spaces, unused import removal, and general coding standard conformity. Modified Paths: -------------- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java trunk/jython/tests/modjy/build.xml trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestHeaders.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestReturnIterable.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestWSGIStreams.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestWebInf.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestWriteCallable.java Modified: trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,193 +1,201 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import java.io.*; -import java.util.*; -import javax.servlet.*; -import javax.servlet.http.*; -import org.python.core.*; -import org.python.util.*; - -public class ModjyJServlet extends HttpServlet -{ - - protected final static String MODJY_PYTHON_CLASSNAME = "modjy_servlet"; - protected final static String LIB_PYTHON = "/WEB-INF/lib-python"; - protected final static String PTH_FILE_EXTENSION = ".pth"; - - protected PythonInterpreter interp; - protected HttpServlet modjyServlet; - - /** - * Read configuration - * 1. Both context and servlet parameters are included in the set, - * so that the definition of some parameters (e.g python.*) can be shared - * between multiple WSGI servlets. - * 2. servlet params take precedence over context parameters - */ - - protected Properties readConfiguration ( ) - { - Properties props = new Properties(); - // Context parameters - ServletContext context = getServletContext(); - Enumeration e = context.getInitParameterNames(); - while (e.hasMoreElements()) - { - String name = (String) e.nextElement(); - props.put(name, context.getInitParameter(name)); - } - // Servlet parameters override context parameters - e = getInitParameterNames(); - while (e.hasMoreElements()) - { - String name = (String) e.nextElement(); - props.put(name, getInitParameter(name)); - } - return props; - } - - /** - * Initialise the modjy servlet. - * 1. Read the configuration - * 2. Initialise the jython runtime - * 3. Setup, in relation to the J2EE servlet environment - * 4. Create the jython-implemented servlet - * 5. Initialise the jython-implemented servlet - */ - - public void init ( ) - throws ServletException - { - try - { - Properties props = readConfiguration(); - PythonInterpreter.initialize(System.getProperties(), props, new String[0]); - PySystemState systemState = new PySystemState(); - interp = new PythonInterpreter(null, systemState); - setupEnvironment(interp, props, systemState); - try - { interp.exec("from modjy.modjy import "+MODJY_PYTHON_CLASSNAME); } - catch (PyException ix) - { throw new ServletException("Unable to import '"+MODJY_PYTHON_CLASSNAME+ - "': maybe you need to set the 'python.home' parameter?", ix);} - PyObject pyServlet = ((PyType)interp.get(MODJY_PYTHON_CLASSNAME)).__call__(); - Object temp = pyServlet.__tojava__(HttpServlet.class); - if (temp == Py.NoConversion) - throw new ServletException("Corrupted modjy file: cannot find definition of '"+MODJY_PYTHON_CLASSNAME+"' class"); - modjyServlet = (HttpServlet) temp; - modjyServlet.init(this); - } - catch (PyException pyx) - { - throw new ServletException("Exception creating modjy servlet: " + pyx.toString(), pyx); - } - } - - /** - * Actually service the incoming request. - * Simply delegate to the jython servlet. - * - * @param request - The incoming HttpServletRequest - * @param response - The outgoing HttpServletResponse - */ - - public void service ( HttpServletRequest req, HttpServletResponse resp ) - throws ServletException, IOException - { - modjyServlet.service(req, resp); - } - - /** - * Setup the modjy environment, i.e. - * 1. Find the location of the modjy.jar file and add it to sys.path - * 2. Process the WEB-INF/lib-python directory, if it exists - * - * @param interp - The PythinInterpreter used to service requests - * @param props - The properties from which config options are found - * @param systemState - The PySystemState corresponding to the interpreter servicing requests - * @returns A String giving the path to the modjy.jar file (which is used only for error reporting) - */ - - protected void setupEnvironment(PythonInterpreter interp, Properties props, PySystemState systemState) - { - processPythonLib(interp, systemState); - } - - /** - * Do all processing in relation to the lib-python subdirectory of WEB-INF - * - * @param interp - The PythinInterpreter used to service requests - * @param systemState - The PySystemState whose path should be updated - */ - - protected void processPythonLib(PythonInterpreter interp, PySystemState systemState) - { - // Add the lib-python directory to sys.path - String pythonLibPath = getServletContext().getRealPath(LIB_PYTHON); - if (pythonLibPath == null) - return; - File pythonLib = new File(pythonLibPath); - if (!pythonLib.exists()) - return; - systemState.path.append(new PyString(pythonLibPath)); - // Now check for .pth files in lib-python and process each one - String[] libPythonContents = pythonLib.list(); - for (int ix = 0 ; ix < libPythonContents.length ; ix++) - if (libPythonContents[ix].endsWith(PTH_FILE_EXTENSION)) - processPthFile(interp, systemState, pythonLibPath, libPythonContents[ix]); - } - - /** - * Process an individual file .pth file in the lib-python directory - * - * @param systemState - The PySystemState whose path should be updated - * @param pythonLibPath - The actual path to the lib-python directory - * @param pthFilename - The PySystemState whose path should be updated - */ - - protected void processPthFile(PythonInterpreter interp, PySystemState systemState, String pythonLibPath, String pthFilename) - { - try - { - LineNumberReader lineReader = new LineNumberReader(new FileReader(new File(pythonLibPath, pthFilename))); - String line; - while ((line = lineReader.readLine()) != null) - { - line = line.trim(); - if (line.length() == 0) - continue; - if (line.startsWith("#")) - continue; - if (line.startsWith("import")) - interp.exec(line); - File archiveFile = new File(pythonLibPath, line); - String archiveRealpath = archiveFile.getAbsolutePath(); - systemState.path.append(new PyString(archiveRealpath)); - } - } - catch (IOException iox) - { - System.err.println("IOException: " + iox.toString()); - } - } -} +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.util.Enumeration; +import java.util.Properties; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.python.core.Py; +import org.python.core.PyException; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PySystemState; +import org.python.core.PyType; +import org.python.util.PythonInterpreter; + +public class ModjyJServlet extends HttpServlet { + + protected final static String MODJY_PYTHON_CLASSNAME = "modjy_servlet"; + + protected final static String LIB_PYTHON = "/WEB-INF/lib-python"; + + protected final static String PTH_FILE_EXTENSION = ".pth"; + + protected PythonInterpreter interp; + + protected HttpServlet modjyServlet; + + /** + * Read configuration 1. Both context and servlet parameters are included in the set, so that + * the definition of some parameters (e.g python.*) can be shared between multiple WSGI + * servlets. 2. servlet params take precedence over context parameters + */ + protected Properties readConfiguration() { + Properties props = new Properties(); + // Context parameters + ServletContext context = getServletContext(); + Enumeration<?> e = context.getInitParameterNames(); + while (e.hasMoreElements()) { + String name = (String)e.nextElement(); + props.put(name, context.getInitParameter(name)); + } + // Servlet parameters override context parameters + e = getInitParameterNames(); + while (e.hasMoreElements()) { + String name = (String)e.nextElement(); + props.put(name, getInitParameter(name)); + } + return props; + } + + /** + * Initialise the modjy servlet. 1. Read the configuration 2. Initialise the jython runtime 3. + * Setup, in relation to the J2EE servlet environment 4. Create the jython-implemented servlet + * 5. Initialise the jython-implemented servlet + */ + @Override + public void init() throws ServletException { + try { + Properties props = readConfiguration(); + PythonInterpreter.initialize(System.getProperties(), props, new String[0]); + PySystemState systemState = new PySystemState(); + interp = new PythonInterpreter(null, systemState); + setupEnvironment(interp, props, systemState); + try { + interp.exec("from modjy.modjy import " + MODJY_PYTHON_CLASSNAME); + } catch (PyException ix) { + throw new ServletException("Unable to import '" + MODJY_PYTHON_CLASSNAME + + "': maybe you need to set the 'python.home' parameter?", ix); + } + PyObject pyServlet = ((PyType)interp.get(MODJY_PYTHON_CLASSNAME)).__call__(); + Object temp = pyServlet.__tojava__(HttpServlet.class); + if (temp == Py.NoConversion) + throw new ServletException("Corrupted modjy file: cannot find definition of '" + + MODJY_PYTHON_CLASSNAME + "' class"); + modjyServlet = (HttpServlet)temp; + modjyServlet.init(this); + } catch (PyException pyx) { + throw new ServletException("Exception creating modjy servlet: " + pyx.toString(), pyx); + } + } + + /** + * Actually service the incoming request. Simply delegate to the jython servlet. + * + * @param request + * - The incoming HttpServletRequest + * @param response + * - The outgoing HttpServletResponse + */ + @Override + public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, + IOException { + modjyServlet.service(req, resp); + } + + /** + * Setup the modjy environment, i.e. 1. Find the location of the modjy.jar file and add it to + * sys.path 2. Process the WEB-INF/lib-python directory, if it exists + * + * @param interp + * - The PythinInterpreter used to service requests + * @param props + * - The properties from which config options are found + * @param systemState + * - The PySystemState corresponding to the interpreter servicing requests + * @returns A String giving the path to the modjy.jar file (which is used only for error + * reporting) + */ + protected void setupEnvironment(PythonInterpreter interp, + Properties props, + PySystemState systemState) { + processPythonLib(interp, systemState); + } + + /** + * Do all processing in relation to the lib-python subdirectory of WEB-INF + * + * @param interp + * - The PythinInterpreter used to service requests + * @param systemState + * - The PySystemState whose path should be updated + */ + protected void processPythonLib(PythonInterpreter interp, PySystemState systemState) { + // Add the lib-python directory to sys.path + String pythonLibPath = getServletContext().getRealPath(LIB_PYTHON); + if (pythonLibPath == null) + return; + File pythonLib = new File(pythonLibPath); + if (!pythonLib.exists()) + return; + systemState.path.append(new PyString(pythonLibPath)); + // Now check for .pth files in lib-python and process each one + String[] libPythonContents = pythonLib.list(); + for (String libPythonContent : libPythonContents) + if (libPythonContent.endsWith(PTH_FILE_EXTENSION)) + processPthFile(interp, systemState, pythonLibPath, libPythonContent); + } + + /** + * Process an individual file .pth file in the lib-python directory + * + * @param systemState + * - The PySystemState whose path should be updated + * @param pythonLibPath + * - The actual path to the lib-python directory + * @param pthFilename + * - The PySystemState whose path should be updated + */ + protected void processPthFile(PythonInterpreter interp, + PySystemState systemState, + String pythonLibPath, + String pthFilename) { + try { + LineNumberReader lineReader = new LineNumberReader(new FileReader(new File(pythonLibPath, + pthFilename))); + String line; + while ((line = lineReader.readLine()) != null) { + line = line.trim(); + if (line.length() == 0) + continue; + if (line.startsWith("#")) + continue; + if (line.startsWith("import")) + interp.exec(line); + File archiveFile = new File(pythonLibPath, line); + String archiveRealpath = archiveFile.getAbsolutePath(); + systemState.path.append(new PyString(archiveRealpath)); + } + } catch (IOException iox) { + System.err.println("IOException: " + iox.toString()); + } + } +} Modified: trunk/jython/tests/modjy/build.xml =================================================================== --- trunk/jython/tests/modjy/build.xml 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/build.xml 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,103 +1,97 @@ -<project name="modjy" default="test"> - - <description>Modjy test build.xml</description> - - <!-- set global properties for this build --> - - <property name="test_src" location="java"/> - <property name="build" location="build"/> - - <!-- Import the environment --> - <property environment="env"/> - - <!-- Jython properties --> - - <property name="jython_home" location="${env.JYTHON_HOME}"/> - <property name="jython_jar" value="jython-dev.jar"/> - <property name="jython_jar_path" location="${jython_home}/${jython_jar}"/> - <property name="jython_cachedir" location="${jython_home}/cachedir"/> - <property name="mockrunner_home" location="${env.MOCKRUNNER_HOME}"/> - - <target name="init"> - <available property="jython_home.exists" file="${jython_home}" /> - <fail unless="jython_home.exists" message="jython_home, ${jython_home}, doesn't exist" /> - <available property="mockrunner_home.exists" file="${mockrunner_home}" /> - <fail unless="mockrunner_home.exists" message="mockrunner_home, ${mockrunner_home}, doesn't exist" /> - <!-- Create the build directory structure used by compile --> - <mkdir dir="${build}"/> - </target> - - <target name="clean" description="clean up" > - <!-- Delete the ${build} and ${dist} directory trees --> - <delete dir="${build}"/> - </target> - - <!-- Now testing related targets --> - - <target name="do_test" depends="init" description="Run unit tests against a single jdk/servlet combo"> - <echo message="Running tests against JDK ${jdk_version}, Servlet ${servlet_version}"/> - - <property name="mockrunner_home" value="${env.MOCKRUNNER_HOME}"/> - <property name="mockrunner_jar" location="${mockrunner_home}/jar"/> - <property name="mockrunner_lib" location="${mockrunner_home}/lib/jdk${jdk_version}/${servlet_version}"/> - - <path id="test.classpath"> - <pathelement path="${build}"/> - <pathelement path="${jython_jar_path}"/> - <fileset dir="${jython_home}/javalib" includes="**/*.jar"/> - <fileset dir="${mockrunner_jar}" includes="**/*.jar"/> - <fileset dir="${mockrunner_lib}" includes="**/*.jar"/> - </path> - - <javac - srcdir="${test_src}" - destdir="${build}" - classpathref="test.classpath" - debug="on" - /> - <java classname="com.xhaus.modjy.ModjyTestBase" dir="." fork="yes" - classpathref="test.classpath"> - <sysproperty key="JYTHON_HOME" value="${jython_home}"/> - <sysproperty key="python.cachedir.skip" value="true"/> - </java> - </target> - - <target name="test"> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="j2ee1.3"/> - </antcall> - </target> - - <target name="test_java_15" depends="clean"> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="j2ee1.3"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="j2ee1.4"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="jee5"/> - </antcall> - </target> - - <target name="test_java_16" depends="clean"> - <antcall target="do_test"> - <param name="jdk_version" value="1.6"/> - <param name="servlet_version" value="j2ee1.3"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.6"/> - <param name="servlet_version" value="j2ee1.4"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.6"/> - <param name="servlet_version" value="jee5"/> - </antcall> - </target> - -</project> - +<project name="modjy" default="test"> + + <description>Modjy test build.xml</description> + + <!-- set global properties for this build --> + + <property name="test_src" location="java" /> + <property name="build" location="build" /> + + <!-- Import the environment --> + <property environment="env" /> + + <!-- Jython properties --> + + <property name="jython_home" location="${env.JYTHON_HOME}" /> + <property name="jython_jar" value="jython-dev.jar" /> + <property name="jython_jar_path" location="${jython_home}/${jython_jar}" /> + <property name="jython_cachedir" location="${jython_home}/cachedir" /> + <property name="mockrunner_home" location="${env.MOCKRUNNER_HOME}" /> + + <target name="init"> + <available property="jython_home.exists" file="${jython_home}" /> + <fail unless="jython_home.exists" message="jython_home, ${jython_home}, doesn't exist" /> + <available property="mockrunner_home.exists" file="${mockrunner_home}" /> + <fail unless="mockrunner_home.exists" message="mockrunner_home, ${mockrunner_home}, doesn't exist" /> + <!-- Create the build directory structure used by compile --> + <mkdir dir="${build}" /> + </target> + + <target name="clean" description="clean up"> + <!-- Delete the ${build} and ${dist} directory trees --> + <delete dir="${build}" /> + </target> + + <!-- Now testing related targets --> + + <target name="do_test" depends="init" description="Run unit tests against a single jdk/servlet combo"> + <echo message="Running tests against JDK ${jdk_version}, Servlet ${servlet_version}" /> + + <property name="mockrunner_home" value="${env.MOCKRUNNER_HOME}" /> + <property name="mockrunner_jar" location="${mockrunner_home}/jar" /> + <property name="mockrunner_lib" location="${mockrunner_home}/lib/jdk${jdk_version}/${servlet_version}" /> + + <path id="test.classpath"> + <pathelement path="${build}" /> + <pathelement path="${jython_jar_path}" /> + <fileset dir="${jython_home}/javalib" includes="**/*.jar" /> + <fileset dir="${mockrunner_jar}" includes="**/*.jar" /> + <fileset dir="${mockrunner_lib}" includes="**/*.jar" /> + </path> + + <javac srcdir="${test_src}" destdir="${build}" classpathref="test.classpath" debug="on" /> + <java classname="com.xhaus.modjy.ModjyTestBase" dir="." fork="yes" classpathref="test.classpath"> + <sysproperty key="JYTHON_HOME" value="${jython_home}" /> + <sysproperty key="python.cachedir.skip" value="true" /> + </java> + </target> + + <target name="test"> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="j2ee1.3" /> + </antcall> + </target> + + <target name="test_java_15" depends="clean"> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="j2ee1.3" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="j2ee1.4" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="jee5" /> + </antcall> + </target> + + <target name="test_java_16" depends="clean"> + <antcall target="do_test"> + <param name="jdk_version" value="1.6" /> + <param name="servlet_version" value="j2ee1.3" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.6" /> + <param name="servlet_version" value="j2ee1.4" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.6" /> + <param name="servlet_version" value="jee5" /> + </antcall> + </target> + +</project> + Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,224 +1,186 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import java.io.File; - -import org.python.core.PyDictionary; -import org.python.core.PyInteger; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.PyTuple; - -public class ModjyTestAppInvocation extends ModjyTestBase -{ - - protected void appInvocationTestSetUp() - throws Exception - { - baseSetUp(); - setAppDir(""); - setAppFile(""); - setAppName(""); - setAppImportable(""); - } - - String[] importablepathElements = new String[] { - "mock_framework", - "web", - "handlers", - "wsgi_handlers", - }; - - public void testRelativeDirectory ( ) - throws Exception - { - baseSetUp(); - setRealPath("/test_apps_dir", "test_apps_dir"); - setAppDir("$/test_apps_dir"); - setAppFile("simple_app.py"); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("Hello World!", result); - } - - public String setupAppImport ( String appCallableName ) - throws Exception - { - StringBuffer filePathBuffer = new StringBuffer(); - StringBuffer importPath = new StringBuffer(); - for (int ix = 0 ; ix < importablepathElements.length ; ix++) - { - String resourcePath; - String filePath; - filePathBuffer.append(importablepathElements[ix]); - resourcePath = "/WEB-INF/"+LIB_PYTHON_DIR+"/"+filePathBuffer.toString(); - filePath = LIB_PYTHON_TEST_PATH+"/"+filePathBuffer.toString(); - setRealPath(resourcePath, filePath); - filePathBuffer.append("/"); - resourcePath = "/WEB-INF/"+LIB_PYTHON_DIR+"/"+filePathBuffer.toString()+"__init__.py"; - filePath = LIB_PYTHON_TEST_PATH+"/"+filePathBuffer.toString()+"__init__.py"; - setRealPath(resourcePath, filePath); - importPath.append(importablepathElements[ix]); - importPath.append("."); - } - importPath.append(appCallableName); - return importPath.toString(); - } - - public void testAppImportCallable ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerFunction"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("WSGIHandlerFunction called.", result); - } - - public void testAppImportBadInstantiable ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass"); - setAppImportable(importableName); - createServlet(); - doGet(); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - } - - public void testAppImportInstantiable ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass()"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("__call__ counter = 0", result); - } - - public void testAppImportInstantiableCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "1"); - String importableName = setupAppImport("WSGIHandlerClass()"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("__call__ counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("__call__ counter = 1", result); - } - - public void testAppImportInstantiableNotCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "0"); - String importableName = setupAppImport("WSGIHandlerClass()"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("__call__ counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("__call__ counter = 0", result); - } - - public void testAppImportInstantiableMethod ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("handler_fn counter = 0", result); - } - - public void testAppImportInstantiableBadMethod ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn.fn_attr"); - setAppImportable(importableName); - createServlet(); - doGet(); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - } - - public void testAppImportInstantiableMethodCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "1"); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("handler_fn counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("handler_fn counter = 1", result); - } - - public void testAppImportInstantiableMethodNotCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "0"); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("handler_fn counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("handler_fn counter = 0", result); - } - - public void testBadAppImport() - throws Exception - { - appInvocationTestSetUp(); - setAppImportable("never.existed"); - createServlet(); - doGet(); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - } - -} +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +public class ModjyTestAppInvocation extends ModjyTestBase { + + protected void appInvocationTestSetUp() throws Exception { + baseSetUp(); + setAppDir(""); + setAppFile(""); + setAppName(""); + setAppImportable(""); + } + + String[] importablepathElements = new String[] {"mock_framework", + "web", + "handlers", + "wsgi_handlers",}; + + public void testRelativeDirectory() throws Exception { + baseSetUp(); + setRealPath("/test_apps_dir", "test_apps_dir"); + setAppDir("$/test_apps_dir"); + setAppFile("simple_app.py"); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("Hello World!", result); + } + + public String setupAppImport(String appCallableName) throws Exception { + StringBuffer filePathBuffer = new StringBuffer(); + StringBuffer importPath = new StringBuffer(); + for (String importablepathElement : importablepathElements) { + String resourcePath; + String filePath; + filePathBuffer.append(importablepathElement); + resourcePath = "/WEB-INF/" + LIB_PYTHON_DIR + "/" + filePathBuffer.toString(); + filePath = LIB_PYTHON_TEST_PATH + "/" + filePathBuffer.toString(); + setRealPath(resourcePath, filePath); + filePathBuffer.append("/"); + resourcePath = "/WEB-INF/" + LIB_PYTHON_DIR + "/" + filePathBuffer.toString() + + "__init__.py"; + filePath = LIB_PYTHON_TEST_PATH + "/" + filePathBuffer.toString() + "__init__.py"; + setRealPath(resourcePath, filePath); + importPath.append(importablepathElement); + importPath.append("."); + } + importPath.append(appCallableName); + return importPath.toString(); + } + + public void testAppImportCallable() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerFunction"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("WSGIHandlerFunction called.", result); + } + + public void testAppImportBadInstantiable() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass"); + setAppImportable(importableName); + createServlet(); + doGet(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + + public void testAppImportInstantiable() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass()"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("__call__ counter = 0", result); + } + + public void testAppImportInstantiableCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "1"); + String importableName = setupAppImport("WSGIHandlerClass()"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("__call__ counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("__call__ counter = 1", result); + } + + public void testAppImportInstantiableNotCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "0"); + String importableName = setupAppImport("WSGIHandlerClass()"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("__call__ counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("__call__ counter = 0", result); + } + + public void testAppImportInstantiableMethod() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("handler_fn counter = 0", result); + } + + public void testAppImportInstantiableBadMethod() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn.fn_attr"); + setAppImportable(importableName); + createServlet(); + doGet(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + + public void testAppImportInstantiableMethodCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "1"); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("handler_fn counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("handler_fn counter = 1", result); + } + + public void testAppImportInstantiableMethodNotCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "0"); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("handler_fn counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("handler_fn counter = 0", result); + } + + public void testBadAppImport() throws Exception { + appInvocationTestSetUp(); + setAppImportable("never.existed"); + createServlet(); + doGet(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } +} Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,279 +1,247 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import junit.framework.TestSuite; - -import org.jdom.output.XMLOutputter; -import org.python.core.PyObject; -import org.python.util.PyFilterTest; -import org.python.util.PyServletTest; -import org.python.util.PythonInterpreter; - -import com.mockrunner.mock.web.MockHttpServletRequest; -import com.mockrunner.mock.web.MockHttpServletResponse; -import com.mockrunner.mock.web.MockServletConfig; -import com.mockrunner.mock.web.MockServletContext; -import com.mockrunner.mock.web.WebMockObjectFactory; -import com.mockrunner.servlet.BasicServletTestCaseAdapter; - -/** - * - */ - -public class ModjyTestBase extends BasicServletTestCaseAdapter -{ - - final static String DEFAULT_APP_DIR = "test_apps_dir"; - final static String LIB_PYTHON_DIR = "lib-python"; - final static String LIB_PYTHON_TEST_PATH = "lib_python_folder"; - final static String DEFAULT_APP_FILE = "simple_app.py"; - final static String DEFAULT_APP_NAME = "simple_app"; - - public WebMockObjectFactory factory; - public MockServletConfig servletConfig; - public MockServletContext servletContext; - - public WebMockObjectFactory getFactory () - { - if (factory == null) - factory = getWebMockObjectFactory(); - return factory; - } - - public MockServletConfig getConfig () - { - if (servletConfig == null) - servletConfig = getFactory().getMockServletConfig(); - return servletConfig; - } - - public MockServletContext getContext () - { - if (servletContext == null) - servletContext = getFactory().getMockServletContext(); - return servletContext; - } - -// public void dumpContextRealPaths ( ) -// { -// Map pathMap = ((LoggingMockServletContext)getContext()).actualPaths; -// Iterator it = pathMap.keySet().iterator(); -// while (it.hasNext()) -// { -// String pathName = (String) it.next(); -// System.out.println("Path '"+pathName+"'-->'"+pathMap.get(pathName)+"'"); -// } -// } - - public void setInitParameter ( String name, String value ) - { - getConfig().setInitParameter(name, value); - } - - public void setRealPath ( String source, String target ) - { - getContext().setRealPath(source, target); - } - - public void addHeader(String headerName, String headerValue) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.addHeader(headerName, headerValue); - getFactory().addRequestWrapper(request); - } - - public void setBodyContent(String content) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setBodyContent(content); - getFactory().addRequestWrapper(request); - } - - public void setServletContextPath(String path) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setContextPath(path); - getFactory().addRequestWrapper(request); - } - - public void setServletPath(String path) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setServletPath(path); - getFactory().addRequestWrapper(request); - } - - public void setRequestURI(String uri) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setRequestURI(uri); - getFactory().addRequestWrapper(request); - } - - public void setScheme(String scheme) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setScheme(scheme); - getFactory().addRequestWrapper(request); - } - - public void setPathInfo(String pathInfo) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setPathInfo(pathInfo); - getFactory().addRequestWrapper(request); - } - - public void setQueryString(String qString) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setQueryString(qString); - getFactory().addRequestWrapper(request); - } - - public void setProtocol(String protocol) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setProtocol(protocol); - getFactory().addRequestWrapper(request); - } - - public void setServerName(String name) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - // Using setLocalName() here: See here for more: http://docs.sun.com/source/819-0077/J2EE.html - request.setLocalName(name); - getFactory().addRequestWrapper(request); - } - - public void setServerPort(int port) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setLocalPort(port); - getFactory().addRequestWrapper(request); - } - - public void setPythonHome(String app_dir) - { - setInitParameter("python.home", app_dir); - } - - public void setAppDir(String app_dir) - { - setInitParameter("app_directory", app_dir); - } - - public void setAppFile(String app_file) - { - setInitParameter("app_filename", app_file); - } - - public void setAppName(String app_name) - { - setInitParameter("app_callable_name", app_name); - } - - public void setAppImportable(String app_path) - { - setAppDir(""); - setAppFile(""); - setAppName(""); - setInitParameter("app_import_name", app_path); - } - - public MockHttpServletResponse getResponse() - { - MockHttpServletResponse response = (MockHttpServletResponse) getFactory().getWrappedResponse(); - return response; - } - - public int getStatus() - { - MockHttpServletResponse response = (MockHttpServletResponse) getFactory().getWrappedResponse(); - return response.getStatusCode(); - } - - protected void baseSetUp() - throws Exception - { - super.setUp(); - String jythonHome = System.getProperty("JYTHON_HOME"); - setRealPath(jythonHome, jythonHome); - setRealPath("/WEB-INF/"+LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); - setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); - setPythonHome(jythonHome); - setAppDir(DEFAULT_APP_DIR); - setAppFile(DEFAULT_APP_FILE); - setAppName(DEFAULT_APP_NAME); - setInitParameter("exc_handler", "testing"); -// dumpContextRealPaths(); - } - - protected PyObject evalPythonString(String pyString) - { - // Efficiency be damned: it's a testing phase - PythonInterpreter interp = new PythonInterpreter(); - try - { - return interp.eval(pyString); - } - catch (Exception x) - { - System.err.println("Exception evaling '"+pyString+"': " + x); - return null; - } - } - - protected void createServlet() - { - createServlet(ModjyJServlet.class); - // Set zero content: this can be overridden later - setBodyContent(""); - clearOutput(); - } - - // Leave this here as a simple template for a test - public void testHelloWorld() throws Exception - { - baseSetUp(); - createServlet(); - doGet(); - new XMLOutputter().outputString(getOutputAsJDOMDocument()); - } - - public static void main(String args[]) - { - TestSuite suite = new TestSuite(); - suite.addTestSuite(ModjyTestBase.class); - suite.addTestSuite(ModjyTestAppInvocation.class); - suite.addTestSuite(ModjyTestEnviron.class); - suite.addTestSuite(ModjyTestHeaders.class); - suite.addTestSuite(ModjyTestContentHeaders.class); - suite.addTestSuite(ModjyTestReturnIterable.class); - suite.addTestSuite(ModjyTestWebInf.class); - suite.addTestSuite(ModjyTestWSGIStreams.class); - suite.addTestSuite(PyServletTest.class); - suite.addTestSuite(PyFilterTest.class); - junit.textui.TestRunner.run(suite); - } - -} +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +import junit.framework.TestSuite; + +import org.jdom.output.XMLOutputter; +import org.python.core.PyObject; +import org.python.util.PyFilterTest; +import org.python.util.PyServletTest; +import org.python.util.PythonInterpreter; + +import com.mockrunner.mock.web.MockHttpServletRequest; +import com.mockrunner.mock.web.MockHttpServletResponse; +import com.mockrunner.mock.web.MockServletConfig; +import com.mockrunner.mock.web.MockServletContext; +import com.mockrunner.mock.web.WebMockObjectFactory; +import com.mockrunner.servlet.BasicServletTestCaseAdapter; + +public class ModjyTestBase extends BasicServletTestCaseAdapter { + + final static String DEFAULT_APP_DIR = "test_apps_dir"; + + final static String LIB_PYTHON_DIR = "lib-python"; + + final static String LIB_PYTHON_TEST_PATH = "lib_python_folder"; + + final static String DEFAULT_APP_FILE = "simple_app.py"; + + final static String DEFAULT_APP_NAME = "simple_app"; + + public WebMockObjectFactory factory; + + public MockServletConfig servletConfig; + + public MockServletContext servletContext; + + public WebMockObjectFactory getFactory() { + if (factory == null) + factory = getWebMockObjectFactory(); + return factory; + } + + public MockServletConfig getConfig() { + if (servletConfig == null) + servletConfig = getFactory().getMockServletConfig(); + return servletConfig; + } + + public MockServletContext getContext() { + if (servletContext == null) + servletContext = getFactory().getMockServletContext(); + return servletContext; + } + +// public void dumpContextRealPaths ( ) +// { +// Map pathMap = ((LoggingMockServletContext)getContext()).actualPaths; +// Iterator it = pathMap.keySet().iterator(); +// while (it.hasNext()) +// { +// String pathName = (String) it.next(); +// System.out.println("Path '"+pathName+"'-->'"+pathMap.get(pathName)+"'"); +// } +// } + public void setInitParameter(String name, String value) { + getConfig().setInitParameter(name, value); + } + + public void setRealPath(String source, String target) { + getContext().setRealPath(source, target); + } + + public void addHeader(String headerName, String headerValue) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.addHeader(headerName, headerValue); + getFactory().addRequestWrapper(request); + } + + public void setBodyContent(String content) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setBodyContent(content); + getFactory().addRequestWrapper(request); + } + + public void setServletContextPath(String path) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setContextPath(path); + getFactory().addRequestWrapper(request); + } + + public void setServletPath(String path) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setServletPath(path); + getFactory().addRequestWrapper(request); + } + + public void setRequestURI(String uri) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setRequestURI(uri); + getFactory().addRequestWrapper(request); + } + + public void setScheme(String scheme) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setScheme(scheme); + getFactory().addRequestWrapper(request); + } + + public void setPathInfo(String pathInfo) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setPathInfo(pathInfo); + getFactory().addRequestWrapper(request); + } + + public void setQueryString(String qString) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setQueryString(qString); + getFactory().addRequestWrapper(request); + } + + public void setProtocol(String protocol) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setProtocol(protocol); + getFactory().addRequestWrapper(request); + } + + public void setServerName(String name) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + // Using setLocalName() here: See here for more: + // http://docs.sun.com/source/819-0077/J2EE.html + request.setLocalName(name); + getFactory().addRequestWrapper(request); + } + + public void setServerPort(int port) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setLocalPort(port); + getFactory().addRequestWrapper(request); + } + + public void setPythonHome(String app_dir) { + setInitParameter("python.home", app_dir); + } + + public void setAppDir(String app_dir) { + setInitParameter("app_directory", app_dir); + } + + public void setAppFile(String app_file) { + setInitParameter("app_filename", app_file); + } + + public void setAppName(String app_name) { + setInitParameter("app_callable_name", app_name); + } + + public void setAppImportable(String app_path) { + setAppDir(""); + setAppFile(""); + setAppName(""); + setInitParameter("app_import_name", app_path); + } + + public MockHttpServletResponse getResponse() { + MockHttpServletResponse response = (MockHttpServletResponse)getFactory().getWrappedResponse(); + return response; + } + + public int getStatus() { + MockHttpServletResponse response = (MockHttpServletResponse)getFactory().getWrappedResponse(); + return response.getStatusCode(); + } + + protected void baseSetUp() throws Exception { + super.setUp(); + String jythonHome = System.getProperty("JYTHON_HOME"); + setRealPath(jythonHome, jythonHome); + setRealPath("/WEB-INF/" + LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); + setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); + setPythonHome(jythonHome); + setAppDir(DEFAULT_APP_DIR); + setAppFile(DEFAULT_APP_FILE); + setAppName(DEFAULT_APP_NAME); + setInitParameter("exc_handler", "testing"); +// dumpContextRealPaths(); + } + + protected PyObject evalPythonString(String pyString) { + // Efficiency be damned: it's a testing phase + PythonInterpreter interp = new PythonInterpreter(); + try { + return interp.eval(pyString); + } catch (Exception x) { + System.err.println("Exception evaling '" + pyString + "': " + x); + return null; + } + } + + protected void createServlet() { + createServlet(ModjyJServlet.class); + // Set zero content: this can be overridden later + setBodyContent(""); + clearOutput(); + } + + // Leave this here as a simple template for a test + public void testHelloWorld() throws Exception { + baseSetUp(); + createServlet(); + doGet(); + new XMLOutputter().outputString(getOutputAsJDOMDocument()); + } + + public static void main(String args[]) { + TestSuite suite = new TestSuite(); + suite.addTestSuite(ModjyTestBase.class); + suite.addTestSuite(ModjyTestAppInvocation.class); + suite.addTestSuite(ModjyTestEnviron.class); + suite.addTestSuite(ModjyTestHeaders.class); + suite.addTestSuite(ModjyTestContentHeaders.class); + suite.addTestSuite(ModjyTestReturnIterable.class); + suite.addTestSuite(ModjyTestWebInf.class); + suite.addTestSuite(ModjyTestWSGIStreams.class); + suite.addTestSuite(PyServletTest.class); + suite.addTestSuite(PyFilterTest.class); + junit.textui.TestRunner.run(suite); + } +} Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,81 +1,65 @@ /*### # -# Copyright Alan Kennedy. -# +# Copyright Alan Kennedy. +# # You may contact the copyright holder at this uri: -# +# # http://www.xhaus.com/contact/modjy -# +# # The licence under which this code is released is the Apache License v2.0. -# +# # The terms and conditions of this license are listed in a file contained # in the distribution that also contained this file, under the name # LICENSE.txt. -# +# # You may also read a copy of the license at the following web address. -# +# # http://modjy.xhaus.com/LICENSE.txt # ###*/ package com.xhaus.modjy; -import com.mockrunner.base.NestedApplicationException; -import org.python.core.PyException; +public class ModjyTestContentHeaders extends ModjyTestBase { -public class ModjyTestContentHeaders extends ModjyTestBase -{ + // From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 + protected void contentHeaderTestSetUp() throws Exception { + baseSetUp(); + setAppFile("content_header_tests.py"); + } - // From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 + public void doHeaderTest(String appName, String queryString) throws Exception { + contentHeaderTestSetUp(); + setAppName(appName); + createServlet(); + if (queryString != null) + setQueryString(queryString); + doGet(); + } - protected void contentHeaderTestSetUp() - throws Exception - { - baseSetUp(); - setAppFile("content_header_tests.py"); - } + public void doHeaderTest(String appName) throws Exception { + doHeaderTest(appName, null); + } - public void doHeaderTest(String appName, String queryString) - throws Exception - { - contentHeaderTestSetUp(); - setAppName(appName); - createServlet(); - if (queryString != null) - setQueryString(queryString); - doGet(); - } + public void testSetContentLengthHeader() throws Exception { + doHeaderTest("test_set_content_length"); + assertEquals("Status code != 200: ServerError, =='" + getStatus() + "'", 200, getStatus()); + } - public void doHeaderTest(String appName) - throws Exception - { - doHeaderTest(appName, null); - } + public void testSetBadContentLengthHeader() throws Exception { + doHeaderTest("test_set_bad_content_length"); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + assertTrue("Could not find exception 'BadArgument' in output", + getOutput().indexOf("BadArgument") != -1); + } - public void testSetContentLengthHeader ( ) - throws Exception - { - doHeaderTest("test_set_content_length"); - assertEquals("Status code != 200: ServerError, =='"+getStatus()+"'", 200, getStatus()); - } - - public void testSetBadContentLengthHeader ( ) - throws Exception - { - doHeaderTest("test_set_bad_content_length"); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - assertTrue("Could not find exception 'BadArgument' in output", - getOutput().indexOf("BadArgument")!=-1); - } - - public void testInferredContentLength ( ) - throws Exception - { - String appReturn = "Hello World!"; - doHeaderTest("test_inferred_content_length", appReturn); - assertEquals("Status code != 200: ServerError, =='"+getStatus()+"'", 200, getStatus()); - assertEquals("Content-length != '"+appReturn.length()+"', == '"+getResponse().getHeader("content-length")+"' ", - Integer.toString(appReturn.length()), getResponse().getHeader("content-length")); - } - + public void testInferredContentLength() throws Exception { + String appReturn = "Hello World!"; + doHeaderTest("test_inferred_content_length", appReturn); + assertEquals("Status code != 200: ServerError, =='" + getStatus() + "'", 200, getStatus()); + assertEquals("Content-length != '" + appReturn.length() + "', == '" + + getResponse().getHeader("content-length") + "' ", + Integer.toString(appReturn.length()), + getResponse().getHeader("content-length")); + } } Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,328 +1,293 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import org.python.core.PyDictionary; -import org.python.core.PyInteger; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.PyTuple; - -public class ModjyTestEnviron extends ModjyTestBase -{ - - protected void environTestS... [truncated message content] |