You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <nr...@us...> - 2009-07-23 05:15:01
|
Revision: 6567 http://jython.svn.sourceforge.net/jython/?rev=6567&view=rev Author: nriley Date: 2009-07-23 05:14:58 +0000 (Thu, 23 Jul 2009) Log Message: ----------- Merged revisions 6285,6541,6551,6559-6565 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/branches/jsr223 ........ r6285 | zyasoft | 2009-05-02 01:13:13 -0500 (Sat, 02 May 2009) | 2 lines Some initial code, just to get it going. ........ r6541 | nriley | 2009-07-17 00:27:51 -0500 (Fri, 17 Jul 2009) | 1 line JSR 223 support for compile and eval of Strings. ........ r6551 | nriley | 2009-07-20 12:35:01 -0500 (Mon, 20 Jul 2009) | 1 line JSR 223: test Python exceptions as well as syntax errors. ........ r6559 | nriley | 2009-07-22 16:15:39 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: support for compile and eval with Readers. ........ r6560 | nriley | 2009-07-22 18:51:47 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: fix comments in ParserFacade. ........ r6561 | nriley | 2009-07-22 18:52:00 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: set PySystemState for separate compile/execute. ........ r6562 | nriley | 2009-07-22 18:52:08 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: standardize argument naming. ........ r6563 | nriley | 2009-07-22 18:52:19 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: bindings support. ........ r6564 | nriley | 2009-07-22 22:12:10 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: getInterface support; clean up and factor exception transformation. ........ r6565 | nriley | 2009-07-22 22:12:52 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: Invocable implementation. ........ Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/build.xml trunk/jython/src/org/python/core/ParserFacade.java trunk/jython/src/org/python/util/PythonInterpreter.java Added Paths: ----------- trunk/jython/src/META-INF/ trunk/jython/src/META-INF/services/ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory trunk/jython/src/org/python/jsr223/ trunk/jython/src/org/python/jsr223/PyScriptEngine.java trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java trunk/jython/tests/java/org/python/jsr223/ trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java Removed Paths: ------------- trunk/jython/src/META-INF/services/ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory trunk/jython/src/org/python/jsr223/PyScriptEngine.java trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java Property Changed: ---------------- trunk/jython/ trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java Property changes on: trunk/jython ___________________________________________________________________ Modified: svnmerge-integrated - /branches/jsr223:1-6284 /branches/pbcvm:1-6045 + /branches/jsr223:1-6566 /branches/pbcvm:1-6045 Modified: svn:mergeinfo - /branches/newstyle-java-types:5564-5663,5666-5729 + /branches/jsr223:6285-6565 /branches/newstyle-java-types:5564-5663,5666-5729 Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/CoreExposed.includes 2009-07-23 05:14:58 UTC (rev 6567) @@ -43,6 +43,7 @@ org/python/core/PyXRange.class org/python/modules/PyStruct.class org/python/modules/PyTeeIterator.class +org/python/jsr223/PyScriptEngineScope.class org/python/modules/_codecs$EncodingMap.class org/python/modules/_collections/PyDefaultDict.class org/python/modules/_collections/PyDeque.class Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/build.xml 2009-07-23 05:14:58 UTC (rev 6567) @@ -506,6 +506,10 @@ </copy> <!-- grammar must now be up to date --> <property name="antlr.notneeded" value="true" /> + + <copy todir="${compile.dir}/META-INF/services"> + <fileset dir="${source.dir}/META-INF/services" /> + </copy> </target> <!-- Deleted: trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory =================================================================== --- branches/jsr223/src/META-INF/services/javax.script.ScriptEngineFactory 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory 2009-07-23 05:14:58 UTC (rev 6567) @@ -1 +0,0 @@ -org.python.jsr223.PyScriptEngineFactory Copied: trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory (from rev 6565, branches/jsr223/src/META-INF/services/javax.script.ScriptEngineFactory) =================================================================== --- trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory (rev 0) +++ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1 @@ +org.python.jsr223.PyScriptEngineFactory Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -10,6 +10,7 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; +import java.io.StringReader; import java.io.Writer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; @@ -108,6 +109,34 @@ } /** + * Parse Python source as either an expression (if possible) or module. + * + * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish + * between scripts which return values and those which do not, nor do they make the + * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) + */ + public static mod parseExpressionOrModule(Reader reader, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + // first, try parsing as an expression + return parse(bufReader, CompileMode.eval, filename, cflags ); + } catch (Throwable t) { + try { + // then, try parsing as a module + bufReader.reset(); + return parse(bufReader, CompileMode.exec, filename, cflags); + } catch (Throwable tt) { + throw fixParseError(bufReader, tt, filename); + } + } finally { + close(bufReader); + } + } + + /** * Internal parser entry point. * * Users of this method should call fixParseError on any Throwable thrown @@ -130,6 +159,21 @@ } } + public static mod parse(Reader reader, + CompileMode kind, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + return parse(bufReader, kind, filename, cflags ); + } catch (Throwable t) { + throw fixParseError(bufReader, t, filename); + } finally { + close(bufReader); + } + } + public static mod parse(InputStream stream, CompileMode kind, String filename, @@ -222,6 +266,22 @@ } } + private static ExpectedEncodingBufferedReader prepBufReader(Reader reader, + CompilerFlags cflags, + String filename) + throws IOException { + cflags.source_is_utf8 = true; + cflags.encoding = "utf-8"; + + BufferedReader bufferedReader = new BufferedReader(reader); + bufferedReader.mark(MARK_LIMIT); + if (findEncoding(bufferedReader) != null) + throw new ParseException("encoding declaration in Unicode string"); + bufferedReader.reset(); + + return new ExpectedEncodingBufferedReader(bufferedReader, null); + } + private static ExpectedEncodingBufferedReader prepBufReader(InputStream input, CompilerFlags cflags, String filename, @@ -289,20 +349,10 @@ CompilerFlags cflags, String filename) throws IOException { - byte[] stringBytes; - if (cflags.source_is_utf8) { - // Passed unicode, re-encode the String to raw bytes - // NOTE: This could be more efficient if we duplicate - // prepBufReader/adjustForBOM/readEncoding to work on Readers, instead of - // encoding - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Writer w = new OutputStreamWriter(out, "utf-8"); - w.write(string); - w.close(); - stringBytes = out.toByteArray(); - } else { - stringBytes = StringUtil.toBytes(string); - } + if (cflags.source_is_utf8) + return prepBufReader(new StringReader(string), cflags, filename); + + byte[] stringBytes = StringUtil.toBytes(string); return prepBufReader(new ByteArrayInputStream(stringBytes), cflags, filename, true, false); } Deleted: trunk/jython/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,210 +0,0 @@ -package org.python.jsr223; - -import java.lang.reflect.Method; -import org.python.core.*; -import java.io.Reader; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import javax.script.AbstractScriptEngine; -import javax.script.Bindings; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptException; -import javax.script.SimpleBindings; -import org.python.util.PythonInterpreter; - -public class PyScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { - - private final PythonInterpreter interp; - private final ScriptEngineFactory factory; - private final PyModule module; - - PyScriptEngine(ScriptEngineFactory factory) { - this.factory = factory; - interp = new PythonInterpreter(new PyScriptEngineScope(this, context)); - module = (PyModule)Py.getSystemState().modules.__finditem__("__main__"); - } - - public Object eval(String script, ScriptContext context) throws ScriptException { - return eval(compileScript(script, context)); - } - - private Object eval(PyCode code) throws ScriptException { - try { - return interp.eval(code).__tojava__(Object.class); - } catch (PyException pye) { - throw scriptException(pye); - } - } - - public Object eval(Reader reader, ScriptContext context) throws ScriptException { - return eval(compileScript(reader, context)); - } - - public Bindings createBindings() { - return new SimpleBindings(); - } - - public ScriptEngineFactory getFactory() { - return factory; - } - - public CompiledScript compile(String script) throws ScriptException { - return new PyCompiledScript(compileScript(script, context)); - } - - public CompiledScript compile(Reader reader) throws ScriptException { - return new PyCompiledScript(compileScript(reader, context)); - } - - private PyCode compileScript(String script, ScriptContext context) throws ScriptException { - try { - String filename = (String) context.getAttribute(ScriptEngine.FILENAME); - if (filename == null) - return interp.compile(script); - else - return interp.compile(script, filename); - } catch (PyException pye) { - throw scriptException(pye); - } - } - - private PyCode compileScript(Reader reader, ScriptContext context) throws ScriptException { - try { - String filename = (String) context.getAttribute(ScriptEngine.FILENAME); - if (filename == null) - return interp.compile(reader); - else - return interp.compile(reader, filename); - } catch (PyException pye) { - throw scriptException(pye); - } - } - - public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { - try { - if (!(thiz instanceof PyObject)) - thiz = Py.java2py(thiz); - return ((PyObject) thiz).invoke(name, java2py(args)).__tojava__(Object.class); - } catch (PyException pye) { - return throwInvokeException(pye, name); - } - } - - public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { - try { - PyObject function = interp.get(name); - if (function == null) - throw new NoSuchMethodException(name); - return function.__call__(java2py(args)).__tojava__(Object.class); - } catch (PyException pye) { - return throwInvokeException(pye, name); - } - } - - public <T> T getInterface(Class<T> clazz) { - return getInterface(module, clazz); - } - - public <T> T getInterface(Object obj, Class<T> clazz) { - if (obj == null) - throw new IllegalArgumentException("object expected"); - if (clazz == null || !clazz.isInterface()) - throw new IllegalArgumentException("interface expected"); - final Object thiz = Py.java2py(obj); - return (T) Proxy.newProxyInstance( - clazz.getClassLoader(), - new Class[] { clazz }, - new InvocationHandler() { - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - try { - return ((PyObject) thiz).invoke(method.getName(), java2py(args)).__tojava__(Object.class); - } catch (PyException pye) { - return throwInvokeException(pye, method.getName()); - } - } - }); - } - - private static Object throwInvokeException(PyException pye, String methodName) - throws ScriptException, NoSuchMethodException { - if (Py.matchException(pye, Py.AttributeError)) { - throw new NoSuchMethodException(methodName); - } - throw scriptException(pye); - } - - private static ScriptException scriptException(PyException pye) { - ScriptException se = null; - try { - pye.normalize(); - - PyObject type = pye.type; - PyObject value = pye.value; - PyTraceback tb = pye.traceback; - - if (__builtin__.isinstance(value, Py.SyntaxError)) { - PyObject filename = value.__findattr__("filename"); - PyObject lineno = value.__findattr__("lineno"); - PyObject offset = value.__findattr__("offset"); - value = value.__findattr__("msg"); - - se = new ScriptException( - Py.formatException(type, value), - filename == null ? "<script>" : filename.toString(), - lineno == null ? 0 : lineno.asInt(), - offset == null ? 0 : offset.asInt()); - } else if (tb != null) { - String filename; - if (tb.tb_frame == null || tb.tb_frame.f_code == null) - filename = null; - else - filename = tb.tb_frame.f_code.co_filename; - - se = new ScriptException( - Py.formatException(type, value), - filename, - tb.tb_lineno); - } else { - se = new ScriptException(Py.formatException(type, value)); - } - se.initCause(pye); - return se; - } catch (Exception ee) { - se = new ScriptException(pye); - } - return se; - } - - private static PyObject[] java2py(Object[] args) { - PyObject wrapped[] = new PyObject[args.length]; - for (int i = 0; i < args.length; i++) { - wrapped[i] = Py.java2py(args[i]); - } - return wrapped; - } - - private class PyCompiledScript extends CompiledScript { - private PyCode code; - private PySystemState systemState; - - PyCompiledScript(PyCode code) { - this.code = code; - this.systemState = Py.getSystemState(); - } - - public ScriptEngine getEngine() { - return PyScriptEngine.this; - } - - public Object eval(ScriptContext ctx) throws ScriptException { - // can't read filename from context at this point - Py.setSystemState(systemState); - return PyScriptEngine.this.eval(code); - } - } -} Copied: trunk/jython/src/org/python/jsr223/PyScriptEngine.java (from rev 6565, branches/jsr223/src/org/python/jsr223/PyScriptEngine.java) =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngine.java (rev 0) +++ trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,210 @@ +package org.python.jsr223; + +import java.lang.reflect.Method; +import org.python.core.*; +import java.io.Reader; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import javax.script.AbstractScriptEngine; +import javax.script.Bindings; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptException; +import javax.script.SimpleBindings; +import org.python.util.PythonInterpreter; + +public class PyScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { + + private final PythonInterpreter interp; + private final ScriptEngineFactory factory; + private final PyModule module; + + PyScriptEngine(ScriptEngineFactory factory) { + this.factory = factory; + interp = new PythonInterpreter(new PyScriptEngineScope(this, context)); + module = (PyModule)Py.getSystemState().modules.__finditem__("__main__"); + } + + public Object eval(String script, ScriptContext context) throws ScriptException { + return eval(compileScript(script, context)); + } + + private Object eval(PyCode code) throws ScriptException { + try { + return interp.eval(code).__tojava__(Object.class); + } catch (PyException pye) { + throw scriptException(pye); + } + } + + public Object eval(Reader reader, ScriptContext context) throws ScriptException { + return eval(compileScript(reader, context)); + } + + public Bindings createBindings() { + return new SimpleBindings(); + } + + public ScriptEngineFactory getFactory() { + return factory; + } + + public CompiledScript compile(String script) throws ScriptException { + return new PyCompiledScript(compileScript(script, context)); + } + + public CompiledScript compile(Reader reader) throws ScriptException { + return new PyCompiledScript(compileScript(reader, context)); + } + + private PyCode compileScript(String script, ScriptContext context) throws ScriptException { + try { + String filename = (String) context.getAttribute(ScriptEngine.FILENAME); + if (filename == null) + return interp.compile(script); + else + return interp.compile(script, filename); + } catch (PyException pye) { + throw scriptException(pye); + } + } + + private PyCode compileScript(Reader reader, ScriptContext context) throws ScriptException { + try { + String filename = (String) context.getAttribute(ScriptEngine.FILENAME); + if (filename == null) + return interp.compile(reader); + else + return interp.compile(reader, filename); + } catch (PyException pye) { + throw scriptException(pye); + } + } + + public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { + try { + if (!(thiz instanceof PyObject)) + thiz = Py.java2py(thiz); + return ((PyObject) thiz).invoke(name, java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, name); + } + } + + public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { + try { + PyObject function = interp.get(name); + if (function == null) + throw new NoSuchMethodException(name); + return function.__call__(java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, name); + } + } + + public <T> T getInterface(Class<T> clazz) { + return getInterface(module, clazz); + } + + public <T> T getInterface(Object obj, Class<T> clazz) { + if (obj == null) + throw new IllegalArgumentException("object expected"); + if (clazz == null || !clazz.isInterface()) + throw new IllegalArgumentException("interface expected"); + final Object thiz = Py.java2py(obj); + return (T) Proxy.newProxyInstance( + clazz.getClassLoader(), + new Class[] { clazz }, + new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try { + return ((PyObject) thiz).invoke(method.getName(), java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, method.getName()); + } + } + }); + } + + private static Object throwInvokeException(PyException pye, String methodName) + throws ScriptException, NoSuchMethodException { + if (pye.match(Py.AttributeError)) { + throw new NoSuchMethodException(methodName); + } + throw scriptException(pye); + } + + private static ScriptException scriptException(PyException pye) { + ScriptException se = null; + try { + pye.normalize(); + + PyObject type = pye.type; + PyObject value = pye.value; + PyTraceback tb = pye.traceback; + + if (__builtin__.isinstance(value, Py.SyntaxError)) { + PyObject filename = value.__findattr__("filename"); + PyObject lineno = value.__findattr__("lineno"); + PyObject offset = value.__findattr__("offset"); + value = value.__findattr__("msg"); + + se = new ScriptException( + Py.formatException(type, value), + filename == null ? "<script>" : filename.toString(), + lineno == null ? 0 : lineno.asInt(), + offset == null ? 0 : offset.asInt()); + } else if (tb != null) { + String filename; + if (tb.tb_frame == null || tb.tb_frame.f_code == null) + filename = null; + else + filename = tb.tb_frame.f_code.co_filename; + + se = new ScriptException( + Py.formatException(type, value), + filename, + tb.tb_lineno); + } else { + se = new ScriptException(Py.formatException(type, value)); + } + se.initCause(pye); + return se; + } catch (Exception ee) { + se = new ScriptException(pye); + } + return se; + } + + private static PyObject[] java2py(Object[] args) { + PyObject wrapped[] = new PyObject[args.length]; + for (int i = 0; i < args.length; i++) { + wrapped[i] = Py.java2py(args[i]); + } + return wrapped; + } + + private class PyCompiledScript extends CompiledScript { + private PyCode code; + private PySystemState systemState; + + PyCompiledScript(PyCode code) { + this.code = code; + this.systemState = Py.getSystemState(); + } + + public ScriptEngine getEngine() { + return PyScriptEngine.this; + } + + public Object eval(ScriptContext ctx) throws ScriptException { + // can't read filename from context at this point + Py.setSystemState(systemState); + return PyScriptEngine.this.eval(code); + } + } +} Deleted: trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngineFactory.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,95 +0,0 @@ -package org.python.jsr223; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import org.python.Version; -import org.python.core.Py; - -public class PyScriptEngineFactory implements ScriptEngineFactory { - - public String getEngineName() { - return "jython"; - } - - public String getEngineVersion() { - return String.format("%s.%s.%s", Version.PY_MAJOR_VERSION, Version.PY_MINOR_VERSION, Version.PY_MICRO_VERSION); - } - - public List<String> getExtensions() { - return Collections.unmodifiableList(Arrays.asList("py")); - } - - public String getLanguageName() { - return "python"; - } - - public String getLanguageVersion() { - return "2.5.0"; - } - - public Object getParameter(String key) { - if (key.equals(ScriptEngine.ENGINE)) { - return getEngineName(); - } else if (key.equals(ScriptEngine.ENGINE_VERSION)) { - return getEngineVersion(); - } else if (key.equals(ScriptEngine.NAME)) { - return getEngineName(); - } else if (key.equals(ScriptEngine.LANGUAGE)) { - return getLanguageName(); - } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) { - return getLanguageVersion(); - } else if (key.equals("THREADING")) { - return "MULTITHREADED"; - } else { - return null; - } - - } - - public String getMethodCallSyntax(String obj, String m, String... args) { - StringBuilder buffer = new StringBuilder(); - buffer.append(String.format("%s.%s(", obj, m)); - int i = args.length; - for (String arg : args) { - buffer.append(arg); - if (i-- > 0) { - buffer.append(", "); - } - } - buffer.append(")"); - return buffer.toString(); - } - - // presumably a unicode string - public String getOutputStatement(String toDisplay) { - StringBuilder buffer = new StringBuilder(toDisplay.length() + 8); - buffer.append("print "); - buffer.append(Py.newUnicode(toDisplay).__repr__()); - return buffer.toString(); - } - - public String getProgram(String... statements) { - StringBuilder buffer = new StringBuilder(); - for (String statement : statements) { - buffer.append(statement); - buffer.append("\n"); - } - return buffer.toString(); - } - - public ScriptEngine getScriptEngine() { - return new PyScriptEngine(this); - } - - public List<String> getMimeTypes() { - return Collections.EMPTY_LIST; - } - - public List<String> getNames() { - return Collections.unmodifiableList(Arrays.asList("python", "jython")); - } - -} Copied: trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java (from rev 6565, branches/jsr223/src/org/python/jsr223/PyScriptEngineFactory.java) =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java (rev 0) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,95 @@ +package org.python.jsr223; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import org.python.Version; +import org.python.core.Py; + +public class PyScriptEngineFactory implements ScriptEngineFactory { + + public String getEngineName() { + return "jython"; + } + + public String getEngineVersion() { + return String.format("%s.%s.%s", Version.PY_MAJOR_VERSION, Version.PY_MINOR_VERSION, Version.PY_MICRO_VERSION); + } + + public List<String> getExtensions() { + return Collections.unmodifiableList(Arrays.asList("py")); + } + + public String getLanguageName() { + return "python"; + } + + public String getLanguageVersion() { + return "2.5.0"; + } + + public Object getParameter(String key) { + if (key.equals(ScriptEngine.ENGINE)) { + return getEngineName(); + } else if (key.equals(ScriptEngine.ENGINE_VERSION)) { + return getEngineVersion(); + } else if (key.equals(ScriptEngine.NAME)) { + return getEngineName(); + } else if (key.equals(ScriptEngine.LANGUAGE)) { + return getLanguageName(); + } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) { + return getLanguageVersion(); + } else if (key.equals("THREADING")) { + return "MULTITHREADED"; + } else { + return null; + } + + } + + public String getMethodCallSyntax(String obj, String m, String... args) { + StringBuilder buffer = new StringBuilder(); + buffer.append(String.format("%s.%s(", obj, m)); + int i = args.length; + for (String arg : args) { + buffer.append(arg); + if (i-- > 0) { + buffer.append(", "); + } + } + buffer.append(")"); + return buffer.toString(); + } + + // presumably a unicode string + public String getOutputStatement(String toDisplay) { + StringBuilder buffer = new StringBuilder(toDisplay.length() + 8); + buffer.append("print "); + buffer.append(Py.newUnicode(toDisplay).__repr__()); + return buffer.toString(); + } + + public String getProgram(String... statements) { + StringBuilder buffer = new StringBuilder(); + for (String statement : statements) { + buffer.append(statement); + buffer.append("\n"); + } + return buffer.toString(); + } + + public ScriptEngine getScriptEngine() { + return new PyScriptEngine(this); + } + + public List<String> getMimeTypes() { + return Collections.EMPTY_LIST; + } + + public List<String> getNames() { + return Collections.unmodifiableList(Arrays.asList("python", "jython")); + } + +} Deleted: trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,101 +0,0 @@ -package org.python.jsr223; - -import java.util.List; -import javax.script.Bindings; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import org.python.core.Py; -import org.python.core.PyList; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.PyType; -import org.python.expose.ExposedType; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedMethod; - -@ExposedType(name = "scope", isBaseType = false) -public final class PyScriptEngineScope extends PyObject { - public static final PyType TYPE = PyType.fromClass(PyScriptEngineScope.class); - - private final ScriptContext context; - private final ScriptEngine engine; - - PyScriptEngineScope(ScriptEngine engine, ScriptContext context) { - this.context = context; - this.engine = engine; - } - - @ExposedGet(name = "context") - public PyObject pyGetContext() { - return Py.java2py(context); - } - - @ExposedGet(name = "engine") - public PyObject pyGetEngine() { - return Py.java2py(engine); - } - - @ExposedMethod - public PyObject scope_keys() { - PyList members = new PyList(); - synchronized (context) { - List<Integer> scopes = context.getScopes(); - for (int scope : scopes) { - Bindings bindings = context.getBindings(scope); - if (bindings == null) - continue; - for (String key : bindings.keySet()) - members.append(new PyString(key)); - } - } - members.sort(); - return members; - } - - // Not necessary for functionality; present to satisfy __builtin__.PyMapping_check - @ExposedMethod - public PyObject __getitem__(PyObject key) { - return super.__getitem__(key); - } - - public PyObject __finditem__(PyObject key) { - return __finditem__(key.asString()); - } - - public PyObject __finditem__(String key) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - return null; - return Py.java2py(context.getAttribute(key, scope)); - } - } - - @ExposedMethod - public void __setitem__(PyObject key, PyObject value) { - __setitem__(key.asString(), value); - } - - public void __setitem__(String key, PyObject value) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - scope = ScriptContext.ENGINE_SCOPE; - context.setAttribute(key, value.__tojava__(Object.class), scope); - } - } - - @ExposedMethod - public void __delitem__(PyObject key) { - __delitem__(key.asString()); - } - - public void __delitem__(String key) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - throw Py.KeyError(key); - context.removeAttribute(key, scope); - } - } -} Copied: trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java (from rev 6565, branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java) =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java (rev 0) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,101 @@ +package org.python.jsr223; + +import java.util.List; +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import org.python.core.Py; +import org.python.core.PyList; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyType; +import org.python.expose.ExposedType; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; + +@ExposedType(name = "scope", isBaseType = false) +public final class PyScriptEngineScope extends PyObject { + public static final PyType TYPE = PyType.fromClass(PyScriptEngineScope.class); + + private final ScriptContext context; + private final ScriptEngine engine; + + PyScriptEngineScope(ScriptEngine engine, ScriptContext context) { + this.context = context; + this.engine = engine; + } + + @ExposedGet(name = "context") + public PyObject pyGetContext() { + return Py.java2py(context); + } + + @ExposedGet(name = "engine") + public PyObject pyGetEngine() { + return Py.java2py(engine); + } + + @ExposedMethod + public PyObject scope_keys() { + PyList members = new PyList(); + synchronized (context) { + List<Integer> scopes = context.getScopes(); + for (int scope : scopes) { + Bindings bindings = context.getBindings(scope); + if (bindings == null) + continue; + for (String key : bindings.keySet()) + members.append(new PyString(key)); + } + } + members.sort(); + return members; + } + + // Not necessary for functionality; present to satisfy __builtin__.PyMapping_check + @ExposedMethod + public PyObject __getitem__(PyObject key) { + return super.__getitem__(key); + } + + public PyObject __finditem__(PyObject key) { + return __finditem__(key.asString()); + } + + public PyObject __finditem__(String key) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + return null; + return Py.java2py(context.getAttribute(key, scope)); + } + } + + @ExposedMethod + public void __setitem__(PyObject key, PyObject value) { + __setitem__(key.asString(), value); + } + + public void __setitem__(String key, PyObject value) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + scope = ScriptContext.ENGINE_SCOPE; + context.setAttribute(key, value.__tojava__(Object.class), scope); + } + } + + @ExposedMethod + public void __delitem__(PyObject key) { + __delitem__(key.asString()); + } + + public void __delitem__(String key) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + throw Py.KeyError(key); + context.removeAttribute(key, scope); + } + } +} Modified: trunk/jython/src/org/python/util/PythonInterpreter.java =================================================================== --- trunk/jython/src/org/python/util/PythonInterpreter.java 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/src/org/python/util/PythonInterpreter.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,10 +1,17 @@ package org.python.util; +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; import java.util.Properties; +import org.python.antlr.base.mod; import org.python.core.CompileMode; import org.python.core.CompilerFlags; +import org.python.core.ParserFacade; import org.python.core.Py; +import org.python.core.PyCode; import org.python.core.PyException; import org.python.core.PyFile; import org.python.core.PyFileWriter; @@ -12,6 +19,7 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyStringMap; +import org.python.core.PySyntaxError; import org.python.core.PySystemState; import org.python.core.__builtin__; @@ -131,6 +139,14 @@ } /** + * Evaluate a Python code object and return the result + */ + public PyObject eval(PyObject code) { + setState(); + return __builtin__.eval(code, locals, locals); + } + + /** * Execute a string of Python source in the local namespace */ public void exec(String s) { @@ -167,6 +183,29 @@ Py.flushLine(); } + /** + * Compile a string of Python source as either an expression (if possible) or module. + * + * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish + * between scripts which return values and those which do not, nor do they make the + * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) + */ + public PyCode compile(String script) { + return compile(script, "<script>"); + } + public PyCode compile(Reader reader) { + return compile(reader, "<script>"); + } + public PyCode compile(String script, String filename) { + return compile(new StringReader(script), filename); + } + public PyCode compile(Reader reader, String filename) { + mod node = ParserFacade.parseExpressionOrModule(reader, filename, cflags); + setState(); + return Py.compile_flags(node, filename, CompileMode.eval, cflags); + } + + public PyObject getLocals() { return locals; } Deleted: trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,156 +0,0 @@ -package org.python.jsr223; - -import java.io.IOException; -import java.io.StringReader; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleScriptContext; -import junit.framework.TestCase; -import org.python.core.PyString; - -public class ScriptEngineTest extends TestCase { - - public void testEvalString() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - assertNull(pythonEngine.eval("x = 5")); - assertEquals(Integer.valueOf(5), pythonEngine.eval("x")); - } - - public void testSyntaxError() { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - try { - pythonEngine.eval("5q"); - } catch (ScriptException e) { - assertEquals(e.getColumnNumber(), 1); - assertEquals(e.getLineNumber(), 1); - assertTrue(e.getMessage().startsWith("SyntaxError: ")); - return; - } - assertTrue("Expected a ScriptException", false); - } - - public void testPythonException() { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - try { - pythonEngine.eval("pass\ndel undefined"); - } catch (ScriptException e) { - assertEquals(e.getLineNumber(), 2); - assertTrue(e.getMessage().startsWith("NameError: ")); - return; - } - assertTrue("Expected a ScriptException", false); - } - - public void testScriptFilename() { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - SimpleScriptContext scriptContext = new SimpleScriptContext(); - scriptContext.setAttribute(ScriptEngine.FILENAME, "sample.py", ScriptContext.ENGINE_SCOPE); - try { - pythonEngine.eval("foo", scriptContext); - } catch (ScriptException e) { - assertEquals("sample.py", e.getFileName()); - return; - } - assertTrue("Expected a ScriptException", false); - } - - public void testCompileEvalString() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - CompiledScript five = ((Compilable)pythonEngine).compile("5"); - assertEquals(Integer.valueOf(5), five.eval()); - } - - public void testEvalReader() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - assertNull(pythonEngine.eval(new StringReader("x = 5"))); - assertEquals(Integer.valueOf(5), pythonEngine.eval(new StringReader("x"))); - } - - public void testCompileEvalReader() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - CompiledScript five = ((Compilable)pythonEngine).compile(new StringReader("5")); - assertEquals(Integer.valueOf(5), five.eval()); - } - - public void testBindings() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - pythonEngine.put("a", 42); - assertEquals(Integer.valueOf(42), pythonEngine.eval("a")); - assertNull(pythonEngine.eval("x = 5")); - assertEquals(Integer.valueOf(5), pythonEngine.get("x")); - assertNull(pythonEngine.eval("del x")); - assertNull(pythonEngine.get("x")); - } - - public void testInvoke() throws ScriptException, NoSuchMethodException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - Invocable invocableEngine = (Invocable)pythonEngine; - - assertNull(pythonEngine.eval("def f(x): return abs(x)")); - assertEquals(Integer.valueOf(5), invocableEngine.invokeFunction("f", Integer.valueOf(-5))); - assertEquals("spam", invocableEngine.invokeMethod(new PyString(" spam "), "strip")); - assertEquals("spam", invocableEngine.invokeMethod(" spam ", "strip")); - } - - public void testInvokeFunctionNoSuchMethod() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); - - try { - invocableEngine.invokeFunction("undefined"); - } catch (NoSuchMethodException e) { - return; - } - assertTrue("Expected a NoSuchMethodException", false); - } - - public void testInvokeMethodNoSuchMethod() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); - - try { - invocableEngine.invokeMethod("eggs", "undefined"); - } catch (NoSuchMethodException e) { - return; - } - assertTrue("Expected a NoSuchMethodException", false); - } - - public void testGetInterface() throws ScriptException, IOException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - Invocable invocableEngine = (Invocable)pythonEngine; - - assertNull(pythonEngine.eval("def read(cb): return 1")); - Readable readable = invocableEngine.getInterface(Readable.class); - assertEquals(1, readable.read(null)); - - assertNull(pythonEngine.eval( - "class C(object):\n" + - " def read(self, cb): return 2\n" + - "c = C()")); - readable = invocableEngine.getInterface(pythonEngine.get("c"), Readable.class); - assertEquals(2, readable.read(null)); - } -} Copied: trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java (from rev 6565, branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java) =================================================================== --- trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java (rev 0) +++ trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,156 @@ +package org.python.jsr223; + +import java.io.IOException; +import java.io.StringReader; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.script.SimpleScriptContext; +import junit.framework.TestCase; +import org.python.core.PyString; + +public class ScriptEngineTest extends TestCase { + + public void testEvalString() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + assertNull(pythonEngine.eval("x = 5")); + assertEquals(Integer.valueOf(5), pythonEngine.eval("x")); + } + + public void testSyntaxError() { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + try { + pythonEngine.eval("5q"); + } catch (ScriptException e) { + assertEquals(e.getColumnNumber(), 1); + assertEquals(e.getLineNumber(), 1); + assertTrue(e.getMessage().startsWith("SyntaxError: ")); + return; + } + assertTrue("Expected a ScriptException", false); + } + + public void testPythonException() { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + try { + pythonEngine.eval("pass\ndel undefined"); + } catch (ScriptException e) { + assertEquals(e.getLineNumber(), 2); + assertTrue(e.getMessage().startsWith("NameError: ")); + return; + } + assertTrue("Expected a ScriptException", false); + } + + public void testScriptFilename() { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + SimpleScriptContext scriptContext = new SimpleScriptContext(); + scriptContext.setAttribute(ScriptEngine.FILENAME, "sample.py", ScriptContext.ENGINE_SCOPE); + try { + pythonEngine.eval("foo", scriptContext); + } catch (ScriptException e) { + assertEquals("sample.py", e.getFileName()); + return; + } + assertTrue("Expected a ScriptException", false); + } + + public void testCompileEvalString() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + CompiledScript five = ((Compilable)pythonEngine).compile("5"); + assertEquals(Integer.valueOf(5), five.eval()); + } + + public void testEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + assertNull(pythonEngine.eval(new StringReader("x = 5"))); + assertEquals(Integer.valueOf(5), pythonEngine.eval(new StringReader("x"))); + } + + public void testCompileEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + CompiledScript five = ((Compilable)pythonEngine).compile(new StringReader("5")); + assertEquals(Integer.valueOf(5), five.eval()); + } + + public void testBindings() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + pythonEngine.put("a", 42); + assertEquals(Integer.valueOf(42), pythonEngine.eval("a")); + assertNull(pythonEngine.eval("x = 5")); + assertEquals(Integer.valueOf(5), pythonEngine.get("x")); + assertNull(pythonEngine.eval("del x")); + assertNull(pythonEngine.get("x")); + } + + public void testInvoke() throws ScriptException, NoSuchMethodException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + Invocable invocableEngine = (Invocable)pythonEngine; + + assertNull(pythonEngine.eval("def f(x): return abs(x)")); + assertEquals(Integer.valueOf(5), invocableEngine.invokeFunction("f", Integer.valueOf(-5))); + assertEquals("spam", invocableEngine.invokeMethod(new PyString(" spam "), "strip")); + assertEquals("spam", invocableEngine.invokeMethod(" spam ", "strip")); + } + + public void testInvokeFunctionNoSuchMethod() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); + + try { + invocableEngine.invokeFunction("undefined"); + } catch (NoSuchMethodException e) { + return; + } + assertTrue("Expected a NoSuchMethodException", false); + } + + public void testInvokeMethodNoSuchMethod() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); + + try { + invocableEngine.invokeMethod("eggs", "undefined"); + } catch (NoSuchMethodException e) { + return; + } + assertTrue("Expected a NoSuchMethodException", false); + } + + public void testGetInterface() throws ScriptException, IOException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + Invocable invocableEngine = (Invocable)pythonEngine; + + assertNull(pythonEngine.eval("def read(cb): return 1")); + Readable readable = invocableEngine.getInterface(Readable.class); + assertEquals(1, readable.read(null)); + + assertNull(pythonEngine.eval( + "class C(object):\n" + + " def read(self, cb): return 2\n" + + "c = C()")); + readable = invocableEngine.getInterface(pythonEngine.get("c"), Readable.class); + assertEquals(2, readable.read(null)); + } +} Property changes on: trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java ___________________________________________________________________ Modified: svn:mergeinfo - + /branches/jsr223/tests/java/org/python/tests/RedundantInterfaceDeclarations.java:6285-6565 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-23 03:27:00
|
Revision: 6566 http://jython.svn.sourceforge.net/jython/?rev=6566&view=rev Author: nriley Date: 2009-07-23 03:26:56 +0000 (Thu, 23 Jul 2009) Log Message: ----------- svnmerge property for JSR 223 branch Property Changed: ---------------- trunk/jython/ Property changes on: trunk/jython ___________________________________________________________________ Modified: svnmerge-integrated - /branches/pbcvm:1-6045 + /branches/jsr223:1-6284 /branches/pbcvm:1-6045 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-23 03:12:53
|
Revision: 6565 http://jython.svn.sourceforge.net/jython/?rev=6565&view=rev Author: nriley Date: 2009-07-23 03:12:52 +0000 (Thu, 23 Jul 2009) Log Message: ----------- JSR 223: Invocable implementation. Modified Paths: -------------- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java Modified: branches/jsr223/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 03:12:10 UTC (rev 6564) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 03:12:52 UTC (rev 6565) @@ -21,10 +21,12 @@ private final PythonInterpreter interp; private final ScriptEngineFactory factory; + private final PyModule module; PyScriptEngine(ScriptEngineFactory factory) { this.factory = factory; interp = new PythonInterpreter(new PyScriptEngineScope(this, context)); + module = (PyModule)Py.getSystemState().modules.__finditem__("__main__"); } public Object eval(String script, ScriptContext context) throws ScriptException { @@ -85,10 +87,9 @@ public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { try { - if (thiz instanceof PyObject) { - return ((PyObject) thiz).invoke(name, java2py(args)).__tojava__(Object.class); - } - throw new NoSuchMethodException(name); + if (!(thiz instanceof PyObject)) + thiz = Py.java2py(thiz); + return ((PyObject) thiz).invoke(name, java2py(args)).__tojava__(Object.class); } catch (PyException pye) { return throwInvokeException(pye, name); } @@ -96,30 +97,37 @@ public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { try { - return interp.get(name).__call__(java2py(args)).__tojava__(Object.class); + PyObject function = interp.get(name); + if (function == null) + throw new NoSuchMethodException(name); + return function.__call__(java2py(args)).__tojava__(Object.class); } catch (PyException pye) { return throwInvokeException(pye, name); } } public <T> T getInterface(Class<T> clazz) { - return getInterface(null, clazz); + return getInterface(module, clazz); } - public <T> T getInterface(Object thiz, Class<T> clazz) { + public <T> T getInterface(Object obj, Class<T> clazz) { + if (obj == null) + throw new IllegalArgumentException("object expected"); + if (clazz == null || !clazz.isInterface()) + throw new IllegalArgumentException("interface expected"); + final Object thiz = Py.java2py(obj); return (T) Proxy.newProxyInstance( - clazz.getClassLoader(), - new Class[] { clazz }, - new InvocationHandler() { - - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - try { - return ((PyObject) proxy).invoke(method.getName(), java2py(args)).__tojava__(Object.class); - } catch (PyException pye) { - return throwInvokeException(pye, method.getName()); + clazz.getClassLoader(), + new Class[] { clazz }, + new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try { + return ((PyObject) thiz).invoke(method.getName(), java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, method.getName()); + } } - } - }); + }); } private static Object throwInvokeException(PyException pye, String methodName) Modified: branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 03:12:10 UTC (rev 6564) +++ branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 03:12:52 UTC (rev 6565) @@ -1,14 +1,17 @@ package org.python.jsr223; +import java.io.IOException; import java.io.StringReader; import javax.script.Compilable; import javax.script.CompiledScript; +import javax.script.Invocable; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleScriptContext; import junit.framework.TestCase; +import org.python.core.PyString; public class ScriptEngineTest extends TestCase { @@ -98,4 +101,56 @@ assertNull(pythonEngine.eval("del x")); assertNull(pythonEngine.get("x")); } + + public void testInvoke() throws ScriptException, NoSuchMethodException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + Invocable invocableEngine = (Invocable)pythonEngine; + + assertNull(pythonEngine.eval("def f(x): return abs(x)")); + assertEquals(Integer.valueOf(5), invocableEngine.invokeFunction("f", Integer.valueOf(-5))); + assertEquals("spam", invocableEngine.invokeMethod(new PyString(" spam "), "strip")); + assertEquals("spam", invocableEngine.invokeMethod(" spam ", "strip")); + } + + public void testInvokeFunctionNoSuchMethod() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); + + try { + invocableEngine.invokeFunction("undefined"); + } catch (NoSuchMethodException e) { + return; + } + assertTrue("Expected a NoSuchMethodException", false); + } + + public void testInvokeMethodNoSuchMethod() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); + + try { + invocableEngine.invokeMethod("eggs", "undefined"); + } catch (NoSuchMethodException e) { + return; + } + assertTrue("Expected a NoSuchMethodException", false); + } + + public void testGetInterface() throws ScriptException, IOException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + Invocable invocableEngine = (Invocable)pythonEngine; + + assertNull(pythonEngine.eval("def read(cb): return 1")); + Readable readable = invocableEngine.getInterface(Readable.class); + assertEquals(1, readable.read(null)); + + assertNull(pythonEngine.eval( + "class C(object):\n" + + " def read(self, cb): return 2\n" + + "c = C()")); + readable = invocableEngine.getInterface(pythonEngine.get("c"), Readable.class); + assertEquals(2, readable.read(null)); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-23 03:12:14
|
Revision: 6564 http://jython.svn.sourceforge.net/jython/?rev=6564&view=rev Author: nriley Date: 2009-07-23 03:12:10 +0000 (Thu, 23 Jul 2009) Log Message: ----------- JSR 223: getInterface support; clean up and factor exception transformation. Modified Paths: -------------- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java Modified: branches/jsr223/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 23:52:19 UTC (rev 6563) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 03:12:10 UTC (rev 6564) @@ -1,7 +1,10 @@ package org.python.jsr223; +import java.lang.reflect.Method; import org.python.core.*; import java.io.Reader; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; import javax.script.AbstractScriptEngine; import javax.script.Bindings; import javax.script.Compilable; @@ -31,8 +34,8 @@ private Object eval(PyCode code) throws ScriptException { try { return interp.eval(code).__tojava__(Object.class); - } catch (PyException e) { - throw scriptException(e); + } catch (PyException pye) { + throw scriptException(pye); } } @@ -63,8 +66,8 @@ return interp.compile(script); else return interp.compile(script, filename); - } catch (PyException e) { - throw scriptException(e); + } catch (PyException pye) { + throw scriptException(pye); } } @@ -75,8 +78,8 @@ return interp.compile(reader); else return interp.compile(reader, filename); - } catch (PyException e) { - throw scriptException(e); + } catch (PyException pye) { + throw scriptException(pye); } } @@ -87,10 +90,7 @@ } throw new NoSuchMethodException(name); } catch (PyException pye) { - if (Py.matchException(pye, Py.AttributeError)) { - throw new NoSuchMethodException(name); - } - throw new ScriptException(pye); + return throwInvokeException(pye, name); } } @@ -98,29 +98,46 @@ try { return interp.get(name).__call__(java2py(args)).__tojava__(Object.class); } catch (PyException pye) { - if (Py.matchException(pye, Py.AttributeError)) { - throw new NoSuchMethodException(name); - } - throw new ScriptException(pye); + return throwInvokeException(pye, name); } } public <T> T getInterface(Class<T> clazz) { - throw new UnsupportedOperationException("Not supported yet."); + return getInterface(null, clazz); } public <T> T getInterface(Object thiz, Class<T> clazz) { - throw new UnsupportedOperationException("Not supported yet."); + return (T) Proxy.newProxyInstance( + clazz.getClassLoader(), + new Class[] { clazz }, + new InvocationHandler() { + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try { + return ((PyObject) proxy).invoke(method.getName(), java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, method.getName()); + } + } + }); } - private static ScriptException scriptException(PyException e) { + private static Object throwInvokeException(PyException pye, String methodName) + throws ScriptException, NoSuchMethodException { + if (Py.matchException(pye, Py.AttributeError)) { + throw new NoSuchMethodException(methodName); + } + throw scriptException(pye); + } + + private static ScriptException scriptException(PyException pye) { ScriptException se = null; try { - e.normalize(); + pye.normalize(); - PyObject type = e.type; - PyObject value = e.value; - PyTraceback tb = e.traceback; + PyObject type = pye.type; + PyObject value = pye.value; + PyTraceback tb = pye.traceback; if (__builtin__.isinstance(value, Py.SyntaxError)) { PyObject filename = value.__findattr__("filename"); @@ -147,10 +164,10 @@ } else { se = new ScriptException(Py.formatException(type, value)); } - se.initCause(e); + se.initCause(pye); return se; } catch (Exception ee) { - se = new ScriptException(e); + se = new ScriptException(pye); } return se; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-22 23:52:22
|
Revision: 6563 http://jython.svn.sourceforge.net/jython/?rev=6563&view=rev Author: nriley Date: 2009-07-22 23:52:19 +0000 (Wed, 22 Jul 2009) Log Message: ----------- JSR 223: bindings support. Modified Paths: -------------- branches/jsr223/CoreExposed.includes branches/jsr223/src/org/python/jsr223/PyScriptEngine.java branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java Added Paths: ----------- branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java Modified: branches/jsr223/CoreExposed.includes =================================================================== --- branches/jsr223/CoreExposed.includes 2009-07-22 23:52:08 UTC (rev 6562) +++ branches/jsr223/CoreExposed.includes 2009-07-22 23:52:19 UTC (rev 6563) @@ -41,6 +41,7 @@ org/python/core/PyType.class org/python/core/PyUnicode.class org/python/core/PyXRange.class +org/python/jsr223/PyScriptEngineScope.class org/python/modules/_codecs$EncodingMap.class org/python/modules/_csv/PyDialect.class org/python/modules/_csv/PyReader.class Modified: branches/jsr223/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 23:52:08 UTC (rev 6562) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 23:52:19 UTC (rev 6563) @@ -11,6 +11,7 @@ import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import javax.script.ScriptException; +import javax.script.SimpleBindings; import org.python.util.PythonInterpreter; public class PyScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { @@ -20,7 +21,7 @@ PyScriptEngine(ScriptEngineFactory factory) { this.factory = factory; - interp = new PythonInterpreter(); + interp = new PythonInterpreter(new PyScriptEngineScope(this, context)); } public Object eval(String script, ScriptContext context) throws ScriptException { @@ -40,7 +41,7 @@ } public Bindings createBindings() { - throw new UnsupportedOperationException("Not supported yet."); + return new SimpleBindings(); } public ScriptEngineFactory getFactory() { Added: branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java (rev 0) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java 2009-07-22 23:52:19 UTC (rev 6563) @@ -0,0 +1,101 @@ +package org.python.jsr223; + +import java.util.List; +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import org.python.core.Py; +import org.python.core.PyList; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyType; +import org.python.expose.ExposedType; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; + +@ExposedType(name = "scope", isBaseType = false) +public final class PyScriptEngineScope extends PyObject { + public static final PyType TYPE = PyType.fromClass(PyScriptEngineScope.class); + + private final ScriptContext context; + private final ScriptEngine engine; + + PyScriptEngineScope(ScriptEngine engine, ScriptContext context) { + this.context = context; + this.engine = engine; + } + + @ExposedGet(name = "context") + public PyObject pyGetContext() { + return Py.java2py(context); + } + + @ExposedGet(name = "engine") + public PyObject pyGetEngine() { + return Py.java2py(engine); + } + + @ExposedMethod + public PyObject scope_keys() { + PyList members = new PyList(); + synchronized (context) { + List<Integer> scopes = context.getScopes(); + for (int scope : scopes) { + Bindings bindings = context.getBindings(scope); + if (bindings == null) + continue; + for (String key : bindings.keySet()) + members.append(new PyString(key)); + } + } + members.sort(); + return members; + } + + // Not necessary for functionality; present to satisfy __builtin__.PyMapping_check + @ExposedMethod + public PyObject __getitem__(PyObject key) { + return super.__getitem__(key); + } + + public PyObject __finditem__(PyObject key) { + return __finditem__(key.asString()); + } + + public PyObject __finditem__(String key) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + return null; + return Py.java2py(context.getAttribute(key, scope)); + } + } + + @ExposedMethod + public void __setitem__(PyObject key, PyObject value) { + __setitem__(key.asString(), value); + } + + public void __setitem__(String key, PyObject value) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + scope = ScriptContext.ENGINE_SCOPE; + context.setAttribute(key, value.__tojava__(Object.class), scope); + } + } + + @ExposedMethod + public void __delitem__(PyObject key) { + __delitem__(key.asString()); + } + + public void __delitem__(String key) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + throw Py.KeyError(key); + context.removeAttribute(key, scope); + } + } +} Modified: branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-22 23:52:08 UTC (rev 6562) +++ branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-22 23:52:19 UTC (rev 6563) @@ -86,4 +86,16 @@ CompiledScript five = ((Compilable)pythonEngine).compile(new StringReader("5")); assertEquals(Integer.valueOf(5), five.eval()); } + + public void testBindings() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + pythonEngine.put("a", 42); + assertEquals(Integer.valueOf(42), pythonEngine.eval("a")); + assertNull(pythonEngine.eval("x = 5")); + assertEquals(Integer.valueOf(5), pythonEngine.get("x")); + assertNull(pythonEngine.eval("del x")); + assertNull(pythonEngine.get("x")); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-22 23:52:11
|
Revision: 6562 http://jython.svn.sourceforge.net/jython/?rev=6562&view=rev Author: nriley Date: 2009-07-22 23:52:08 +0000 (Wed, 22 Jul 2009) Log Message: ----------- JSR 223: standardize argument naming. Modified Paths: -------------- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java Modified: branches/jsr223/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 23:52:00 UTC (rev 6561) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 23:52:08 UTC (rev 6562) @@ -104,11 +104,11 @@ } } - public <T> T getInterface(Class<T> clasz) { + public <T> T getInterface(Class<T> clazz) { throw new UnsupportedOperationException("Not supported yet."); } - public <T> T getInterface(Object thiz, Class<T> clasz) { + public <T> T getInterface(Object thiz, Class<T> clazz) { throw new UnsupportedOperationException("Not supported yet."); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-22 23:52:04
|
Revision: 6561 http://jython.svn.sourceforge.net/jython/?rev=6561&view=rev Author: nriley Date: 2009-07-22 23:52:00 +0000 (Wed, 22 Jul 2009) Log Message: ----------- JSR 223: set PySystemState for separate compile/execute. Modified Paths: -------------- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java branches/jsr223/src/org/python/util/PythonInterpreter.java Modified: branches/jsr223/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 23:51:47 UTC (rev 6560) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 23:52:00 UTC (rev 6561) @@ -164,9 +164,11 @@ private class PyCompiledScript extends CompiledScript { private PyCode code; + private PySystemState systemState; PyCompiledScript(PyCode code) { this.code = code; + this.systemState = Py.getSystemState(); } public ScriptEngine getEngine() { @@ -175,6 +177,7 @@ public Object eval(ScriptContext ctx) throws ScriptException { // can't read filename from context at this point + Py.setSystemState(systemState); return PyScriptEngine.this.eval(code); } } Modified: branches/jsr223/src/org/python/util/PythonInterpreter.java =================================================================== --- branches/jsr223/src/org/python/util/PythonInterpreter.java 2009-07-22 23:51:47 UTC (rev 6560) +++ branches/jsr223/src/org/python/util/PythonInterpreter.java 2009-07-22 23:52:00 UTC (rev 6561) @@ -199,6 +199,7 @@ } public PyCode compile(Reader reader, String filename) { mod node = ParserFacade.parseExpressionOrModule(reader, filename, cflags); + setState(); return Py.compile_flags(node, filename, CompileMode.eval, cflags); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-22 23:51:50
|
Revision: 6560 http://jython.svn.sourceforge.net/jython/?rev=6560&view=rev Author: nriley Date: 2009-07-22 23:51:47 +0000 (Wed, 22 Jul 2009) Log Message: ----------- JSR 223: fix comments in ParserFacade. Modified Paths: -------------- branches/jsr223/src/org/python/core/ParserFacade.java Modified: branches/jsr223/src/org/python/core/ParserFacade.java =================================================================== --- branches/jsr223/src/org/python/core/ParserFacade.java 2009-07-22 21:15:39 UTC (rev 6559) +++ branches/jsr223/src/org/python/core/ParserFacade.java 2009-07-22 23:51:47 UTC (rev 6560) @@ -109,7 +109,7 @@ } /** - * Parse a string of Python source as either an expression (if possible) or module. + * Parse Python source as either an expression (if possible) or module. * * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish * between scripts which return values and those which do not, nor do they make the This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-22 21:15:46
|
Revision: 6559 http://jython.svn.sourceforge.net/jython/?rev=6559&view=rev Author: nriley Date: 2009-07-22 21:15:39 +0000 (Wed, 22 Jul 2009) Log Message: ----------- JSR 223: support for compile and eval with Readers. Modified Paths: -------------- branches/jsr223/src/org/python/core/ParserFacade.java branches/jsr223/src/org/python/jsr223/PyScriptEngine.java branches/jsr223/src/org/python/util/PythonInterpreter.java branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java Modified: branches/jsr223/src/org/python/core/ParserFacade.java =================================================================== --- branches/jsr223/src/org/python/core/ParserFacade.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/src/org/python/core/ParserFacade.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -10,6 +10,7 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; +import java.io.StringReader; import java.io.Writer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; @@ -108,6 +109,34 @@ } /** + * Parse a string of Python source as either an expression (if possible) or module. + * + * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish + * between scripts which return values and those which do not, nor do they make the + * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) + */ + public static mod parseExpressionOrModule(Reader reader, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + // first, try parsing as an expression + return parse(bufReader, CompileMode.eval, filename, cflags ); + } catch (Throwable t) { + try { + // then, try parsing as a module + bufReader.reset(); + return parse(bufReader, CompileMode.exec, filename, cflags); + } catch (Throwable tt) { + throw fixParseError(bufReader, tt, filename); + } + } finally { + close(bufReader); + } + } + + /** * Internal parser entry point. * * Users of this method should call fixParseError on any Throwable thrown @@ -130,6 +159,21 @@ } } + public static mod parse(Reader reader, + CompileMode kind, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + return parse(bufReader, kind, filename, cflags ); + } catch (Throwable t) { + throw fixParseError(bufReader, t, filename); + } finally { + close(bufReader); + } + } + public static mod parse(InputStream stream, CompileMode kind, String filename, @@ -223,6 +267,13 @@ } } + private static ExpectedEncodingBufferedReader prepBufReader(Reader reader, + CompilerFlags cflags, + String filename) + throws IOException { + return new ExpectedEncodingBufferedReader(new BufferedReader(reader), null); + } + private static ExpectedEncodingBufferedReader prepBufReader(InputStream input, CompilerFlags cflags, String filename, @@ -290,20 +341,10 @@ CompilerFlags cflags, String filename) throws IOException { - byte[] stringBytes; - if (cflags.source_is_utf8) { - // Passed unicode, re-encode the String to raw bytes - // NOTE: This could be more efficient if we duplicate - // prepBufReader/adjustForBOM/readEncoding to work on Readers, instead of - // encoding - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Writer w = new OutputStreamWriter(out, "utf-8"); - w.write(string); - w.close(); - stringBytes = out.toByteArray(); - } else { - stringBytes = StringUtil.toBytes(string); - } + if (cflags.source_is_utf8) + return prepBufReader(new StringReader(string), cflags, filename); + + byte[] stringBytes = StringUtil.toBytes(string); return prepBufReader(new ByteArrayInputStream(stringBytes), cflags, filename, true, false); } Modified: branches/jsr223/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -35,10 +35,8 @@ } } - // it would be nice if we supported a Reader interface in Py.compileFlags, instead of having - // to create a string here public Object eval(Reader reader, ScriptContext context) throws ScriptException { - throw new UnsupportedOperationException("Not supported yet."); + return eval(compileScript(reader, context)); } public Bindings createBindings() { @@ -53,21 +51,33 @@ return new PyCompiledScript(compileScript(script, context)); } - public CompiledScript compile(Reader script) throws ScriptException { - throw new UnsupportedOperationException("Not supported yet."); + public CompiledScript compile(Reader reader) throws ScriptException { + return new PyCompiledScript(compileScript(reader, context)); } private PyCode compileScript(String script, ScriptContext context) throws ScriptException { try { String filename = (String) context.getAttribute(ScriptEngine.FILENAME); if (filename == null) - return interp.compileExpressionOrModule(script); + return interp.compile(script); else - return interp.compileExpressionOrModule(script, filename); + return interp.compile(script, filename); } catch (PyException e) { throw scriptException(e); } } + + private PyCode compileScript(Reader reader, ScriptContext context) throws ScriptException { + try { + String filename = (String) context.getAttribute(ScriptEngine.FILENAME); + if (filename == null) + return interp.compile(reader); + else + return interp.compile(reader, filename); + } catch (PyException e) { + throw scriptException(e); + } + } public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { try { Modified: branches/jsr223/src/org/python/util/PythonInterpreter.java =================================================================== --- branches/jsr223/src/org/python/util/PythonInterpreter.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/src/org/python/util/PythonInterpreter.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -1,5 +1,9 @@ package org.python.util; +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; import java.util.Properties; import org.python.antlr.base.mod; @@ -184,23 +188,17 @@ * between scripts which return values and those which do not, nor do they make the * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) */ - public PyCode compileExpressionOrModule(String script) { - return compileExpressionOrModule(script, "<script>"); + public PyCode compile(String script) { + return compile(script, "<script>"); } - - public PyCode compileExpressionOrModule(String script, String filename) { - mod node; - try { - // first, try parsing as an expression - node = ParserFacade.parse(script, CompileMode.eval, filename, cflags); - } catch (PySyntaxError e) { - try { - // then, try parsing as a module - node = ParserFacade.parse(script, CompileMode.exec, filename, cflags); - } catch (PySyntaxError ee) { - throw ee; - } - } + public PyCode compile(Reader reader) { + return compile(reader, "<script>"); + } + public PyCode compile(String script, String filename) { + return compile(new StringReader(script), filename); + } + public PyCode compile(Reader reader, String filename) { + mod node = ParserFacade.parseExpressionOrModule(reader, filename, cflags); return Py.compile_flags(node, filename, CompileMode.eval, cflags); } Modified: branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-22 02:18:24 UTC (rev 6558) +++ branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-22 21:15:39 UTC (rev 6559) @@ -1,5 +1,6 @@ package org.python.jsr223; +import java.io.StringReader; import javax.script.Compilable; import javax.script.CompiledScript; import javax.script.ScriptContext; @@ -69,4 +70,20 @@ CompiledScript five = ((Compilable)pythonEngine).compile("5"); assertEquals(Integer.valueOf(5), five.eval()); } + + public void testEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + assertNull(pythonEngine.eval(new StringReader("x = 5"))); + assertEquals(Integer.valueOf(5), pythonEngine.eval(new StringReader("x"))); + } + + public void testCompileEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + CompiledScript five = ((Compilable)pythonEngine).compile(new StringReader("5")); + assertEquals(Integer.valueOf(5), five.eval()); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-22 02:18:45
|
Revision: 6558 http://jython.svn.sourceforge.net/jython/?rev=6558&view=rev Author: pjenvey Date: 2009-07-22 02:18:24 +0000 (Wed, 22 Jul 2009) Log Message: ----------- better repr Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/PyConnection.java trunk/jython/src/com/ziclix/python/sql/PyCursor.java trunk/jython/src/com/ziclix/python/sql/PyStatement.java Modified: trunk/jython/src/com/ziclix/python/sql/PyConnection.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2009-07-21 23:06:14 UTC (rev 6557) +++ trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2009-07-22 02:18:24 UTC (rev 6558) @@ -118,12 +118,15 @@ * * @return string representation of the object. */ + @Override public String toString() { try { - return "<PyConnection user='" + this.connection.getMetaData().getUserName() + "', url='" + this.connection.getMetaData().getURL() + "'>"; + return String.format("<PyConnection object at %s user='%s', url='%s'>", Py.idstr(this), + connection.getMetaData().getUserName(), + connection.getMetaData().getURL()); } catch (SQLException e) { - return "<PyConnection at " + hashCode() + ">"; + return String.format("<PyConnection object at %s", Py.idstr(this)); } } Modified: trunk/jython/src/com/ziclix/python/sql/PyCursor.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-21 23:06:14 UTC (rev 6557) +++ trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-22 02:18:24 UTC (rev 6558) @@ -166,7 +166,7 @@ */ @Override public String toString() { - return "<PyCursor object instance at " + Py.id(this) + ">"; + return String.format("<PyCursor object at %s>", Py.idstr(this)); } /** Modified: trunk/jython/src/com/ziclix/python/sql/PyStatement.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyStatement.java 2009-07-21 23:06:14 UTC (rev 6557) +++ trunk/jython/src/com/ziclix/python/sql/PyStatement.java 2009-07-22 02:18:24 UTC (rev 6558) @@ -130,20 +130,10 @@ return super.__str__(); } - /** - * Method __repr__ - * - * @return PyString - */ + @Override public PyString __repr__() { - - // care is taken not to display a rounded second value - StringBuffer buf = new StringBuffer("<PyStatement object for ["); - - buf.append(__str__().toString()); - buf.append("] at ").append(Py.id(this)).append(">"); - - return Py.newString(buf.toString()); + return Py.newString(String.format("<PyStatement object at %s for [%s]", Py.idstr(this), + __str__())); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-07-21 23:06:22
|
Revision: 6557 http://jython.svn.sourceforge.net/jython/?rev=6557&view=rev Author: amak Date: 2009-07-21 23:06:14 +0000 (Tue, 21 Jul 2009) Log Message: ----------- 1. Fixed a bug where send in UDP sockets whereby a send() on a connected UDP socket raised an NPE. 2. Added tests for same for both timeout and non-timeout code paths. 3. Dropped the "finishConnect" method for UDP sockets: DatagramChannels and DatagramSockts don't have finishConnect() methods, since UDP "connections" are not like TCP stateful connections: UDP connections are more akin to address filters, and cannot be "finished". Modified Paths: -------------- trunk/jython/Lib/socket.py trunk/jython/Lib/test/test_socket.py Modified: trunk/jython/Lib/socket.py =================================================================== --- trunk/jython/Lib/socket.py 2009-07-21 21:53:56 UTC (rev 6556) +++ trunk/jython/Lib/socket.py 2009-07-21 23:06:14 UTC (rev 6557) @@ -429,9 +429,6 @@ def connect(self, host, port): self.jchannel.connect(java.net.InetSocketAddress(host, port)) - def finish_connect(self): - return self.jchannel.finishConnect() - def disconnect(self): """ Disconnect the datagram socket. @@ -449,16 +446,19 @@ def _do_send_net(self, byte_array, socket_address, flags): # Need two separate implementations because the java.nio APIs do not support timeouts num_bytes = len(byte_array) - if socket_address: - packet = java.net.DatagramPacket(byte_array, num_bytes, socket_address) - else: + if self.jsocket.isConnected() and socket_address is None: packet = java.net.DatagramPacket(byte_array, num_bytes) + else: + packet = java.net.DatagramPacket(byte_array, num_bytes, socket_address) self.jsocket.send(packet) return num_bytes def _do_send_nio(self, byte_array, socket_address, flags): - byte_buf = java.nio.ByteBuffer.wrap(byte_array) - bytes_sent = self.jchannel.send(byte_buf, socket_address) + byte_buf = java.nio.ByteBuffer.wrap(byte_array) + if self.jchannel.isConnected() and socket_address is None: + bytes_sent = self.jchannel.write(byte_buf) + else: + bytes_sent = self.jchannel.send(byte_buf, socket_address) return bytes_sent def sendto(self, byte_array, host, port, flags): @@ -993,11 +993,7 @@ def connect_ex(self, addr): if not self.sock_impl: self._do_connect(addr) - if self.sock_impl.finish_connect(): - if self.mode == MODE_NONBLOCKING: - return errno.EISCONN - return 0 - return errno.EINPROGRESS + return 0 def sendto(self, data, p1, p2=None): try: Modified: trunk/jython/Lib/test/test_socket.py =================================================================== --- trunk/jython/Lib/test/test_socket.py 2009-07-21 21:53:56 UTC (rev 6556) +++ trunk/jython/Lib/test/test_socket.py 2009-07-21 23:06:14 UTC (rev 6557) @@ -857,6 +857,28 @@ self.cli.settimeout(10) self.cli.sendto(MSG, 0, (self.HOST, self.PORT)) + def testSendAndRecv(self): + # Testing send() and recv() over connect'ed UDP + msg = self.serv.recv(len(MSG)) + self.assertEqual(msg, MSG) + + def _testSendAndRecv(self): + self.cli.connect( (self.HOST, self.PORT) ) + self.cli.send(MSG, 0) + + def testSendAndRecvTimeoutMode(self): + # Need to test again in timeout mode, which follows + # a different code path + self.serv.settimeout(10) + # Testing send() and recv() over connect'ed UDP + msg = self.serv.recv(len(MSG)) + self.assertEqual(msg, MSG) + + def _testSendAndRecvTimeoutMode(self): + self.cli.connect( (self.HOST, self.PORT) ) + self.cli.settimeout(10) + self.cli.send(MSG, 0) + def testRecvFrom(self): # Testing recvfrom() over UDP msg, addr = self.serv.recvfrom(len(MSG)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-07-21 21:54:02
|
Revision: 6556 http://jython.svn.sourceforge.net/jython/?rev=6556&view=rev Author: thobes Date: 2009-07-21 21:53:56 +0000 (Tue, 21 Jul 2009) Log Message: ----------- Fix for a problem I discovered with the thread state being stored on yield in generators. This could have lead to faulty behaviour if the next resumption of the generator is from another thread or memory leaks if the generator is kept around longer than the lifetime of the thread. This fix does not have ideal memory footprint, one slot in the stored stack content array is left empty (where the thread state should have been), but it works, such minor memory optimizations can be saved for later. Modified Paths: -------------- trunk/jython/src/org/python/compiler/CodeCompiler.java Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-21 20:55:55 UTC (rev 6555) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-21 21:53:56 UTC (rev 6556) @@ -5,6 +5,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.ListIterator; import java.util.Map; import java.util.Stack; import java.util.Vector; @@ -635,15 +636,23 @@ code.iconst(stack.size()); code.anewarray("java/lang/Object"); code.astore(array); - for (int i = 0; i < stack.size(); i++) { - code.aload(array); - // Stack: |- ... value array - code.swap(); - code.iconst(i); - code.swap(); - // Stack: |- ... array index value - code.aastore(); - // Stack: |- ... + ListIterator<String> content = stack.listIterator(stack.size()); + for (int i = 0; content.hasPrevious(); i++) { + String signature = content.previous(); + if ("org/python/core/ThreadState".equals(signature)) { + // Stack: ... threadstate + code.pop(); + // Stack: ... + } else { + code.aload(array); + // Stack: |- ... value array + code.swap(); + code.iconst(i++); + code.swap(); + // Stack: |- ... array index value + code.aastore(); + // Stack: |- ... + } } return array; } else { @@ -655,12 +664,16 @@ if (stack.size() > 0) { int i = stack.size() -1; for (String signature : stack) { - code.aload(array); - // Stack: |- ... array - code.iconst(i--); - code.aaload(); - // Stack: |- ... value - code.checkcast(signature); + if ("org/python/core/ThreadState".equals(signature)) { + loadThreadState(); + } else { + code.aload(array); + // Stack: |- ... array + code.iconst(i--); + code.aaload(); + // Stack: |- ... value + code.checkcast(signature); + } } code.freeLocal(array); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-07-21 20:55:58
|
Revision: 6555 http://jython.svn.sourceforge.net/jython/?rev=6555&view=rev Author: thobes Date: 2009-07-21 20:55:55 +0000 (Tue, 21 Jul 2009) Log Message: ----------- Fix for issue 1407. Modified Paths: -------------- trunk/jython/src/org/python/compiler/CodeCompiler.java Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-21 02:48:53 UTC (rev 6554) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-21 20:55:55 UTC (rev 6555) @@ -657,7 +657,7 @@ for (String signature : stack) { code.aload(array); // Stack: |- ... array - code.iconst(i); + code.iconst(i--); code.aaload(); // Stack: |- ... value code.checkcast(signature); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-21 02:48:54
|
Revision: 6554 http://jython.svn.sourceforge.net/jython/?rev=6554&view=rev Author: pjenvey Date: 2009-07-21 02:48:53 +0000 (Tue, 21 Jul 2009) Log Message: ----------- accept unicode statements and return unicode for cursor description's name Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/Fetch.java trunk/jython/src/com/ziclix/python/sql/PyConnection.java trunk/jython/src/com/ziclix/python/sql/PyCursor.java Modified: trunk/jython/src/com/ziclix/python/sql/Fetch.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/Fetch.java 2009-07-21 01:00:16 UTC (rev 6553) +++ trunk/jython/src/com/ziclix/python/sql/Fetch.java 2009-07-21 02:48:53 UTC (rev 6554) @@ -259,7 +259,7 @@ for (int i = 1; i <= meta.getColumnCount(); i++) { PyObject[] a = new PyObject[7]; - a[0] = Py.newString(meta.getColumnLabel(i)); + a[0] = Py.newUnicode(meta.getColumnLabel(i)); a[1] = Py.newInteger(meta.getColumnType(i)); a[2] = Py.newInteger(meta.getColumnDisplaySize(i)); a[3] = Py.None; Modified: trunk/jython/src/com/ziclix/python/sql/PyConnection.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2009-07-21 01:00:16 UTC (rev 6553) +++ trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2009-07-21 02:48:53 UTC (rev 6554) @@ -14,6 +14,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; + import org.python.core.ClassDictInit; import org.python.core.Py; import org.python.core.PyBuiltinMethodSet; @@ -22,6 +23,8 @@ import org.python.core.PyList; import org.python.core.PyObject; import org.python.core.PyString; +import org.python.core.PyUnicode; + import com.ziclix.python.sql.util.PyArgParser; /** @@ -339,7 +342,6 @@ * @return the native form of this statement */ public PyObject nativesql(PyObject nativeSQL) { - if (closed) { throw zxJDBC.makeException(zxJDBC.ProgrammingError, "connection is closed"); } @@ -349,6 +351,9 @@ } try { + if (nativeSQL instanceof PyUnicode) { + return Py.newUnicode(this.connection.nativeSQL(nativeSQL.toString())); + } return Py.newString(this.connection.nativeSQL(nativeSQL.__str__().toString())); } catch (SQLException e) { throw zxJDBC.makeException(e); Modified: trunk/jython/src/com/ziclix/python/sql/PyCursor.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-21 01:00:16 UTC (rev 6553) +++ trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-21 02:48:53 UTC (rev 6554) @@ -23,6 +23,7 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyTuple; +import org.python.core.PyUnicode; import com.ziclix.python.sql.util.PyArgParser; @@ -382,7 +383,8 @@ stmt = (PyStatement)sql; } else { Statement sqlStatement = null; - String sqlString = sql.__str__().toString(); + String sqlString = + sql instanceof PyUnicode ? sql.toString() : sql.__str__().toString(); if (sqlString.trim().length() == 0) { return null; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-21 01:00:36
|
Revision: 6553 http://jython.svn.sourceforge.net/jython/?rev=6553&view=rev Author: pjenvey Date: 2009-07-21 01:00:16 +0000 (Tue, 21 Jul 2009) Log Message: ----------- ensure all DBAPI cursor functions throw a "cursor is closed" exception when appropriate Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/PyCursor.java Modified: trunk/jython/src/com/ziclix/python/sql/PyCursor.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-21 00:56:33 UTC (rev 6552) +++ trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-21 01:00:16 UTC (rev 6553) @@ -634,6 +634,7 @@ * @return a single sequence from the result set, or None when no more data is available */ public PyObject fetchone() { + ensureOpen(); return this.fetch.fetchone(); } @@ -649,6 +650,7 @@ * no more data is available */ public PyObject fetchall() { + ensureOpen(); return this.fetch.fetchall(); } @@ -676,6 +678,7 @@ * no more data is available */ public PyObject fetchmany(int size) { + ensureOpen(); return this.fetch.fetchmany(size); } @@ -685,6 +688,7 @@ * @return true if more sets exist, else None */ public PyObject nextset() { + ensureOpen(); return this.fetch.nextset(); } @@ -728,6 +732,7 @@ * */ public void scroll(int value, String mode) { + ensureOpen(); this.fetch.scroll(value, mode); } @@ -763,9 +768,7 @@ * */ protected void clear() { - if (closed) { - throw zxJDBC.makeException(zxJDBC.ProgrammingError, "cursor is closed"); - } + ensureOpen(); this.warnings = Py.None; this.lastrowid = Py.None; @@ -858,6 +861,15 @@ } return false; } + + /** + * Throw a ProgrammingError if the cursor has been closed. + */ + private void ensureOpen() { + if (closed) { + throw zxJDBC.makeException(zxJDBC.ProgrammingError, "cursor is closed"); + } + } } class CursorFunc extends PyBuiltinMethodSet { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-21 00:56:50
|
Revision: 6552 http://jython.svn.sourceforge.net/jython/?rev=6552&view=rev Author: pjenvey Date: 2009-07-21 00:56:33 +0000 (Tue, 21 Jul 2009) Log Message: ----------- coding standards: 4 space indents, remove redundant parens, whitespace Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/PyCursor.java Modified: trunk/jython/src/com/ziclix/python/sql/PyCursor.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-20 17:35:01 UTC (rev 6551) +++ trunk/jython/src/com/ziclix/python/sql/PyCursor.java 2009-07-21 00:56:33 UTC (rev 6552) @@ -1,4 +1,3 @@ - /* * Jython Database Specification API 2.0 * @@ -14,6 +13,7 @@ import java.sql.SQLWarning; import java.sql.Statement; import java.util.List; + import org.python.core.ClassDictInit; import org.python.core.Py; import org.python.core.PyBuiltinMethodSet; @@ -23,6 +23,7 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyTuple; + import com.ziclix.python.sql.util.PyArgParser; /** @@ -35,956 +36,957 @@ */ public class PyCursor extends PyObject implements ClassDictInit, WarningListener { - /** Field fetch */ - protected Fetch fetch; + /** Field fetch */ + protected Fetch fetch; - /** Field closed */ - private boolean closed; + /** Field closed */ + private boolean closed; - /** Field arraysize */ - protected int arraysize; + /** Field arraysize */ + protected int arraysize; - /** Field softspace */ - protected int softspace; + /** Field softspace */ + protected int softspace; - /** Field rsType */ - protected PyObject rsType; + /** Field rsType */ + protected PyObject rsType; - /** Field rsConcur */ - protected PyObject rsConcur; + /** Field rsConcur */ + protected PyObject rsConcur; - /** Field warnings */ - protected PyObject warnings; + /** Field warnings */ + protected PyObject warnings; - /** Field warnings */ - protected PyObject lastrowid; + /** Field warnings */ + protected PyObject lastrowid; - /** Field updatecount */ - protected PyObject updatecount; + /** Field updatecount */ + protected PyObject updatecount; - /** Field dynamicFetch */ - protected boolean dynamicFetch; + /** Field dynamicFetch */ + protected boolean dynamicFetch; - /** Field connection */ - protected PyConnection connection; + /** Field connection */ + protected PyConnection connection; - /** Field datahandler */ - protected DataHandler datahandler; + /** Field datahandler */ + protected DataHandler datahandler; - /** Field statement */ - protected PyStatement statement; + /** Field statement */ + protected PyStatement statement; - // they are stateless instances, so we only need to instantiate it once - private static final DataHandler DATAHANDLER = DataHandler.getSystemDataHandler(); + // they are stateless instances, so we only need to instantiate it once + private static final DataHandler DATAHANDLER = DataHandler.getSystemDataHandler(); - /** - * Create the cursor with a static fetch. - * - * @param connection - */ - PyCursor(PyConnection connection) { - this(connection, false); - } + /** + * Create the cursor with a static fetch. + * + * @param connection + */ + PyCursor(PyConnection connection) { + this(connection, false); + } - /** - * Create the cursor, optionally choosing the type of fetch (static or dynamic). - * If dynamicFetch is true, then use a dynamic fetch. - * - * @param connection - * @param dynamicFetch - */ - PyCursor(PyConnection connection, boolean dynamicFetch) { + /** + * Create the cursor, optionally choosing the type of fetch (static or dynamic). + * If dynamicFetch is true, then use a dynamic fetch. + * + * @param connection + * @param dynamicFetch + */ + PyCursor(PyConnection connection, boolean dynamicFetch) { + this.arraysize = 1; + this.softspace = 0; + this.closed = false; + this.rsType = Py.None; + this.rsConcur = Py.None; + this.connection = connection; + this.datahandler = DATAHANDLER; + this.dynamicFetch = dynamicFetch; - this.arraysize = 1; - this.softspace = 0; - this.closed = false; - this.rsType = Py.None; - this.rsConcur = Py.None; - this.connection = connection; - this.datahandler = DATAHANDLER; - this.dynamicFetch = dynamicFetch; + // constructs the appropriate Fetch among other things + this.clear(); + } - // constructs the appropriate Fetch among other things - this.clear(); - } + /** + * Create the cursor, optionally choosing the type of fetch (static or dynamic). + * If dynamicFetch is true, then use a dynamic fetch. + * rsType and rsConcur are used to create the Statement if both are non-None + * + * @param connection + * @param dynamicFetch + * @param rsType + * @param rsConcur + */ + PyCursor(PyConnection connection, boolean dynamicFetch, PyObject rsType, PyObject rsConcur) { + this(connection, dynamicFetch); + this.rsType = rsType; + this.rsConcur = rsConcur; + } - /** - * Create the cursor, optionally choosing the type of fetch (static or dynamic). - * If dynamicFetch is true, then use a dynamic fetch. - * rsType and rsConcur are used to create the Statement if both are non-None - * - * @param connection - * @param dynamicFetch - * @param rsType - * @param rsConcur - */ - PyCursor(PyConnection connection, boolean dynamicFetch, PyObject rsType, PyObject rsConcur) { + /** Field __methods__ */ + protected static PyList __methods__; - this(connection, dynamicFetch); + /** Field __members__ */ + protected static PyList __members__; - this.rsType = rsType; - this.rsConcur = rsConcur; - } + static { + PyObject[] m = new PyObject[9]; - /** Field __methods__ */ - protected static PyList __methods__; + m[0] = new PyString("close"); + m[1] = new PyString("execute"); + m[2] = new PyString("executemany"); + m[3] = new PyString("fetchone"); + m[4] = new PyString("fetchall"); + m[5] = new PyString("fetchmany"); + m[6] = new PyString("callproc"); + m[7] = new PyString("next"); + m[8] = new PyString("write"); + __methods__ = new PyList(m); + m = new PyObject[11]; + m[0] = new PyString("arraysize"); + m[1] = new PyString("rowcount"); + m[2] = new PyString("rownumber"); + m[3] = new PyString("description"); + m[4] = new PyString("datahandler"); + m[5] = new PyString("warnings"); + m[6] = new PyString("lastrowid"); + m[7] = new PyString("updatecount"); + m[8] = new PyString("softspace"); + m[9] = new PyString("closed"); + m[10] = new PyString("connection"); + __members__ = new PyList(m); + } - /** Field __members__ */ - protected static PyList __members__; - - static { - PyObject[] m = new PyObject[9]; - - m[0] = new PyString("close"); - m[1] = new PyString("execute"); - m[2] = new PyString("executemany"); - m[3] = new PyString("fetchone"); - m[4] = new PyString("fetchall"); - m[5] = new PyString("fetchmany"); - m[6] = new PyString("callproc"); - m[7] = new PyString("next"); - m[8] = new PyString("write"); - __methods__ = new PyList(m); - m = new PyObject[11]; - m[0] = new PyString("arraysize"); - m[1] = new PyString("rowcount"); - m[2] = new PyString("rownumber"); - m[3] = new PyString("description"); - m[4] = new PyString("datahandler"); - m[5] = new PyString("warnings"); - m[6] = new PyString("lastrowid"); - m[7] = new PyString("updatecount"); - m[8] = new PyString("softspace"); - m[9] = new PyString("closed"); - m[10] = new PyString("connection"); - __members__ = new PyList(m); - } - - /** - * String representation of the object. - * - * @return a string representation of the object. - */ - public String toString() { - return "<PyCursor object instance at " + Py.id(this) + ">"; - } - - /** - * Sets the attribute name to value. - * - * @param name - * @param value - */ - public void __setattr__(String name, PyObject value) { - - if ("arraysize".equals(name)) { - this.arraysize = value.asInt(); - } else if ("softspace".equals(name)) { - this.softspace = value.asInt(); - } else if ("datahandler".equals(name)) { - this.datahandler = (DataHandler)value.__tojava__(DataHandler.class); - } else { - super.__setattr__(name, value); + /** + * String representation of the object. + * + * @return a string representation of the object. + */ + @Override + public String toString() { + return "<PyCursor object instance at " + Py.id(this) + ">"; } - } - /** - * Gets the value of the attribute name. - * - * @param name - * @return the attribute for the given name - */ - public PyObject __findattr_ex__(String name) { - - if ("arraysize".equals(name)) { - return Py.newInteger(arraysize); - } else if ("softspace".equals(name)) { - return Py.newInteger(softspace); - } else if ("__methods__".equals(name)) { - return __methods__; - } else if ("__members__".equals(name)) { - return __members__; - } else if ("description".equals(name)) { - return this.fetch.description; - } else if ("rowcount".equals(name)) { - return Py.newInteger(this.fetch.rowcount); - } else if ("rownumber".equals(name)) { - int rn = this.fetch.rownumber; - return (rn < 0) ? Py.None : Py.newInteger(rn); - } else if ("warnings".equals(name)) { - return warnings; - } else if ("lastrowid".equals(name)) { - return lastrowid; - } else if ("updatecount".equals(name)) { - return updatecount; - } else if ("datahandler".equals(name)) { - return Py.java2py(this.datahandler); - } else if ("dynamic".equals(name)) { - return this.dynamicFetch ? Py.One : Py.Zero; - } else if ("connection".equals(name)) { - return this.connection; - } else if ("closed".equals(name)) { - return Py.newBoolean(closed); - } else if ("callproc".equals(name)) { - try { - // dynamically decide on the the attribute based on the driver - if (!getMetaData().supportsStoredProcedures()) { - return null; + /** + * Sets the attribute name to value. + * + * @param name + * @param value + */ + @Override + public void __setattr__(String name, PyObject value) { + if ("arraysize".equals(name)) { + this.arraysize = value.asInt(); + } else if ("softspace".equals(name)) { + this.softspace = value.asInt(); + } else if ("datahandler".equals(name)) { + this.datahandler = (DataHandler)value.__tojava__(DataHandler.class); + } else { + super.__setattr__(name, value); } - } catch (Throwable t) {} } - return super.__findattr_ex__(name); - } + /** + * Gets the value of the attribute name. + * + * @param name + * @return the attribute for the given name + */ + @Override + public PyObject __findattr_ex__(String name) { + if ("arraysize".equals(name)) { + return Py.newInteger(arraysize); + } else if ("softspace".equals(name)) { + return Py.newInteger(softspace); + } else if ("__methods__".equals(name)) { + return __methods__; + } else if ("__members__".equals(name)) { + return __members__; + } else if ("description".equals(name)) { + return this.fetch.description; + } else if ("rowcount".equals(name)) { + return Py.newInteger(this.fetch.rowcount); + } else if ("rownumber".equals(name)) { + int rn = this.fetch.rownumber; + return (rn < 0) ? Py.None : Py.newInteger(rn); + } else if ("warnings".equals(name)) { + return warnings; + } else if ("lastrowid".equals(name)) { + return lastrowid; + } else if ("updatecount".equals(name)) { + return updatecount; + } else if ("datahandler".equals(name)) { + return Py.java2py(this.datahandler); + } else if ("dynamic".equals(name)) { + return this.dynamicFetch ? Py.One : Py.Zero; + } else if ("connection".equals(name)) { + return this.connection; + } else if ("closed".equals(name)) { + return Py.newBoolean(closed); + } else if ("callproc".equals(name)) { + try { + // dynamically decide on the the attribute based on the driver + if (!getMetaData().supportsStoredProcedures()) { + return null; + } + } catch (Throwable t) {} + } - /** - * Initializes the object's namespace. - * - * @param dict - */ - static public void classDictInit(PyObject dict) { - - dict.__setitem__("__version__", Py.newString("$Revision$").__getslice__(Py.newInteger(11), Py.newInteger(-2), null)); - dict.__setitem__("fetchmany", new CursorFunc("fetchmany", 0, 0, 1, "fetch specified number of rows")); - dict.__setitem__("close", new CursorFunc("close", 1, 0, "close the cursor")); - dict.__setitem__("fetchall", new CursorFunc("fetchall", 2, 0, "fetch all results")); - dict.__setitem__("fetchone", new CursorFunc("fetchone", 3, 0, "fetch the next result")); - dict.__setitem__("nextset", new CursorFunc("nextset", 4, 0, "return next set or None")); - dict.__setitem__("execute", new CursorFunc("execute", 5, 1, 4, "execute the sql expression")); - dict.__setitem__("setinputsizes", new CursorFunc("setinputsizes", 6, 1, "not implemented")); - dict.__setitem__("setoutputsize", new CursorFunc("setoutputsize", 7, 1, 2, "not implemented")); - dict.__setitem__("callproc", new CursorFunc("callproc", 8, 1, 4, "executes a stored procedure")); - dict.__setitem__("executemany", new CursorFunc("executemany", 9, 1, 3, "execute sql with the parameter list")); - dict.__setitem__("scroll", new CursorFunc("scroll", 10, 1, 2, "scroll the cursor in the result set to a new position according to mode")); - dict.__setitem__("write", new CursorFunc("write", 11, 1, "execute the sql written to this file-like object")); - dict.__setitem__("prepare", new CursorFunc("prepare", 12, 1, "prepare the sql statement for later execution")); - - // hide from python - dict.__setitem__("classDictInit", null); - dict.__setitem__("toString", null); - dict.__setitem__("getDataHandler", null); - dict.__setitem__("warning", null); - dict.__setitem__("fetch", null); - dict.__setitem__("statement", null); - dict.__setitem__("dynamicFetch", null); - dict.__setitem__("getPyClass", null); - dict.__setitem__("rsConcur", null); - dict.__setitem__("rsType", null); - } - - /** - * Delete the cursor. - * - */ - public void __del__() { - close(); - } - - /** - * Close the cursor now (rather than whenever __del__ is called). - * The cursor will be unusable from this point forward; an Error - * (or subclass) exception will be raised if any operation is - * attempted with the cursor. - * - */ - public void close() { - - try { - this.clear(); - this.connection.remove(this); - } finally { - this.closed = true; + return super.__findattr_ex__(name); } - } - /** - * Returns an iteratable object. - * - * @return PyObject - * - * @since Jython 2.2, DB API 2.0+ - */ - public PyObject __iter__() { - return this; - } + /** + * Initializes the object's namespace. + * + * @param dict + */ + static public void classDictInit(PyObject dict) { + PyObject version = + Py.newString("$Revision$").__getslice__(Py.newInteger(11), + Py.newInteger(-2)); + dict.__setitem__("__version__", version); + dict.__setitem__("fetchmany", new CursorFunc("fetchmany", 0, 0, 1, "fetch specified number of rows")); + dict.__setitem__("close", new CursorFunc("close", 1, 0, "close the cursor")); + dict.__setitem__("fetchall", new CursorFunc("fetchall", 2, 0, "fetch all results")); + dict.__setitem__("fetchone", new CursorFunc("fetchone", 3, 0, "fetch the next result")); + dict.__setitem__("nextset", new CursorFunc("nextset", 4, 0, "return next set or None")); + dict.__setitem__("execute", new CursorFunc("execute", 5, 1, 4, "execute the sql expression")); + dict.__setitem__("setinputsizes", new CursorFunc("setinputsizes", 6, 1, "not implemented")); + dict.__setitem__("setoutputsize", new CursorFunc("setoutputsize", 7, 1, 2, "not implemented")); + dict.__setitem__("callproc", new CursorFunc("callproc", 8, 1, 4, "executes a stored procedure")); + dict.__setitem__("executemany", new CursorFunc("executemany", 9, 1, 3, "execute sql with the parameter list")); + dict.__setitem__("scroll", new CursorFunc("scroll", 10, 1, 2, "scroll the cursor in the result set to a new position according to mode")); + dict.__setitem__("write", new CursorFunc("write", 11, 1, "execute the sql written to this file-like object")); + dict.__setitem__("prepare", new CursorFunc("prepare", 12, 1, "prepare the sql statement for later execution")); - /** - * Returns the next row from the currently executing SQL statement - * using the same semantics as .fetchone(). A StopIteration - * exception is raised when the result set is exhausted for Python - * versions 2.2 and later. - * - * @return PyObject - * - * @since Jython 2.2, DB API 2.0+ - */ - public PyObject next() { - PyObject row = __iternext__(); - if (row == null) { - throw Py.StopIteration(""); + // hide from python + dict.__setitem__("classDictInit", null); + dict.__setitem__("toString", null); + dict.__setitem__("getDataHandler", null); + dict.__setitem__("warning", null); + dict.__setitem__("fetch", null); + dict.__setitem__("statement", null); + dict.__setitem__("dynamicFetch", null); + dict.__setitem__("getPyClass", null); + dict.__setitem__("rsConcur", null); + dict.__setitem__("rsType", null); } - return row; - } - /** - * Return the next element of the sequence that this is an iterator - * for. Returns null when the end of the sequence is reached. - * - * @since Jython 2.2 - * - * @return PyObject - */ - public PyObject __iternext__() { - PyObject row = fetchone(); - return row.__nonzero__() ? row : null; - } - - /** - * Return ths DatabaseMetaData for the current connection. - * - * @return DatabaseMetaData - * - * @throws SQLException - */ - protected DatabaseMetaData getMetaData() throws SQLException { - return this.connection.connection.getMetaData(); - } - - /** - * Return the currently bound DataHandler. - * - * @return DataHandler - */ - public DataHandler getDataHandler() { - return this.datahandler; - } - - /** - * Prepare a statement ready for executing. - * - * @param sql the sql to execute or a prepared statement - * @param maxRows max number of rows to be returned - * @param prepared if true, prepare the statement, otherwise create a normal statement - * - * @return PyStatement - */ - private PyStatement prepareStatement(PyObject sql, PyObject maxRows, boolean prepared) { - - PyStatement stmt = null; - - if (sql == Py.None) { - return null; + /** + * Delete the cursor. + * + */ + public void __del__() { + close(); } - try { - if (sql instanceof PyStatement) { - stmt = (PyStatement)sql; - } else { - Statement sqlStatement = null; - String sqlString = sql.__str__().toString(); - - if (sqlString.trim().length() == 0) { - return null; + /** + * Close the cursor now (rather than whenever __del__ is called). + * The cursor will be unusable from this point forward; an Error + * (or subclass) exception will be raised if any operation is + * attempted with the cursor. + * + */ + public void close() { + try { + this.clear(); + this.connection.remove(this); + } finally { + this.closed = true; } + } - boolean normal = ((this.rsType == Py.None) && (this.rsConcur == Py.None)); + /** + * Returns an iteratable object. + * + * @return PyObject + * + * @since Jython 2.2, DB API 2.0+ + */ + @Override + public PyObject __iter__() { + return this; + } - if (normal) { - if (prepared) { - sqlStatement = this.connection.connection.prepareStatement(sqlString); - } else { - sqlStatement = this.connection.connection.createStatement(); - } - } else { - int t = this.rsType.asInt(); - int c = this.rsConcur.asInt(); - - if (prepared) { - sqlStatement = this.connection.connection.prepareStatement(sqlString, t, c); - } else { - sqlStatement = this.connection.connection.createStatement(t, c); - } + /** + * Returns the next row from the currently executing SQL statement + * using the same semantics as .fetchone(). A StopIteration + * exception is raised when the result set is exhausted for Python + * versions 2.2 and later. + * + * @return PyObject + * + * @since Jython 2.2, DB API 2.0+ + */ + public PyObject next() { + PyObject row = __iternext__(); + if (row == null) { + throw Py.StopIteration(""); } + return row; + } - int style = prepared ? PyStatement.STATEMENT_PREPARED : PyStatement.STATEMENT_STATIC; + /** + * Return the next element of the sequence that this is an iterator + * for. Returns null when the end of the sequence is reached. + * + * @since Jython 2.2 + * + * @return PyObject + */ + @Override + public PyObject __iternext__() { + PyObject row = fetchone(); + return row.__nonzero__() ? row : null; + } - stmt = new PyStatement(sqlStatement, sqlString, style); - } + /** + * Return ths DatabaseMetaData for the current connection. + * + * @return DatabaseMetaData + * + * @throws SQLException + */ + protected DatabaseMetaData getMetaData() throws SQLException { + return this.connection.connection.getMetaData(); + } - if (maxRows != Py.None) { - stmt.statement.setMaxRows(maxRows.asInt()); - } - } catch (AbstractMethodError e) { - throw zxJDBC.makeException(zxJDBC.NotSupportedError, zxJDBC.getString("nodynamiccursors")); - } catch (PyException e) { - throw e; - } catch (Throwable e) { - throw zxJDBC.makeException(e); + /** + * Return the currently bound DataHandler. + * + * @return DataHandler + */ + public DataHandler getDataHandler() { + return this.datahandler; } - return stmt; - } + /** + * Prepare a statement ready for executing. + * + * @param sql the sql to execute or a prepared statement + * @param maxRows max number of rows to be returned + * @param prepared if true, prepare the statement, otherwise create a normal statement + * + * @return PyStatement + */ + private PyStatement prepareStatement(PyObject sql, PyObject maxRows, boolean prepared) { + PyStatement stmt = null; - /** - * This method is optional since not all databases provide stored procedures. - * - * Call a stored database procedure with the given name. The sequence of parameters - * must contain one entry for each argument that the procedure expects. The result of - * the call is returned as modified copy of the input sequence. Input parameters are - * left untouched, output and input/output parameters replaced with possibly new values. - * - * The procedure may also provide a result set as output. This must then be made available - * through the standard fetchXXX() methods. - * - * @param name - * @param params - * @param bindings - * @param maxRows - */ - public void callproc(PyObject name, final PyObject params, PyObject bindings, PyObject maxRows) { + if (sql == Py.None) { + return null; + } - this.clear(); + try { + if (sql instanceof PyStatement) { + stmt = (PyStatement)sql; + } else { + Statement sqlStatement = null; + String sqlString = sql.__str__().toString(); - try { - if (getMetaData().supportsStoredProcedures()) { - if (isSeqSeq(params)) { - throw zxJDBC.makeException(zxJDBC.NotSupportedError, "sequence of sequences is not supported"); - } + if (sqlString.trim().length() == 0) { + return null; + } - final Procedure procedure = datahandler.getProcedure(this, name); - Statement stmt = procedure.prepareCall(this.rsType, this.rsConcur); + boolean normal = (this.rsType == Py.None && this.rsConcur == Py.None); - if (maxRows != Py.None) { - stmt.setMaxRows(maxRows.asInt()); - } + if (normal) { + if (prepared) { + sqlStatement = this.connection.connection.prepareStatement(sqlString); + } else { + sqlStatement = this.connection.connection.createStatement(); + } + } else { + int t = this.rsType.asInt(); + int c = this.rsConcur.asInt(); - // get the bindings per the stored proc spec - PyDictionary callableBindings = new PyDictionary(); + if (prepared) { + sqlStatement = this.connection.connection.prepareStatement(sqlString, t, + c); + } else { + sqlStatement = this.connection.connection.createStatement(t, c); + } + } - procedure.normalizeInput(params, callableBindings); + int style = prepared + ? PyStatement.STATEMENT_PREPARED : PyStatement.STATEMENT_STATIC; - // overwrite with any user specific bindings - if (bindings instanceof PyDictionary) { - callableBindings.update(bindings); + stmt = new PyStatement(sqlStatement, sqlString, style); + } + + if (maxRows != Py.None) { + stmt.statement.setMaxRows(maxRows.asInt()); + } + } catch (AbstractMethodError e) { + throw zxJDBC.makeException(zxJDBC.NotSupportedError, + zxJDBC.getString("nodynamiccursors")); + } catch (PyException e) { + throw e; + } catch (Throwable e) { + throw zxJDBC.makeException(e); } - this.statement = new PyStatement(stmt, procedure); - - this.execute(params, callableBindings); - } else { - throw zxJDBC.makeException(zxJDBC.NotSupportedError, zxJDBC.getString("noStoredProc")); - } - } catch (PyException e) { - throw e; - } catch (Throwable e) { - throw zxJDBC.makeException(e); - } finally { - if (this.statement != null) { - - // close what we opened - this.statement.close(); - } + return stmt; } - } - /** - * Prepare a database operation (query or command) and then execute it against all - * parameter sequences or mappings found in the sequence seq_of_parameters. - * Modules are free to implement this method using multiple calls to the execute() - * method or by using array operations to have the database process the sequence as - * a whole in one call. - * - * The same comments as for execute() also apply accordingly to this method. - * - * Return values are not defined. - * - * @param sql - * @param params - * @param bindings - * @param maxRows - */ - public void executemany(PyObject sql, PyObject params, PyObject bindings, PyObject maxRows) { - if (isSeq(params) && params.__len__() == 0) { - //executemany with an empty params tuple is a no-op - return; - } - execute(sql, params, bindings, maxRows); - } + /** + * This method is optional since not all databases provide stored procedures. + * + * Call a stored database procedure with the given name. The sequence of parameters + * must contain one entry for each argument that the procedure expects. The result of + * the call is returned as modified copy of the input sequence. Input parameters are + * left untouched, output and input/output parameters replaced with possibly new values. + * + * The procedure may also provide a result set as output. This must then be made available + * through the standard fetchXXX() methods. + * + * @param name + * @param params + * @param bindings + * @param maxRows + */ + public void callproc(PyObject name, final PyObject params, PyObject bindings, + PyObject maxRows) { + this.clear(); - /** - * Prepare and execute a database operation (query or command). - * Parameters may be provided as sequence or mapping and will - * be bound to variables in the operation. Variables are specified - * in a database-specific notation (see the module's paramstyle - * attribute for details). - * - * A reference to the operation will be retained by the cursor. - * If the same operation object is passed in again, then the cursor - * can optimize its behavior. This is most effective for algorithms - * where the same operation is used, but different parameters are - * bound to it (many times). - * - * For maximum efficiency when reusing an operation, it is best to - * use the setinputsizes() method to specify the parameter types and - * sizes ahead of time. It is legal for a parameter to not match the - * predefined information; the implementation should compensate, possibly - * with a loss of efficiency. - * - * The parameters may also be specified as list of tuples to e.g. insert - * multiple rows in a single operation, but this kind of usage is - * deprecated: executemany() should be used instead. - * - * Return values are not defined. - * - * @param sql sql string or prepared statement - * @param params params for a prepared statement - * @param bindings dictionary of (param index : SQLType binding) - * @param maxRows integer value of max rows - */ - public void execute(final PyObject sql, PyObject params, PyObject bindings, PyObject maxRows) { - int rowIndex = -1; - this.clear(); + try { + if (getMetaData().supportsStoredProcedures()) { + if (isSeqSeq(params)) { + throw zxJDBC.makeException(zxJDBC.NotSupportedError, + "sequence of sequences is not supported"); + } - boolean hasParams = hasParams(params); - PyStatement stmt = this.prepareStatement(sql, maxRows, hasParams); + final Procedure procedure = datahandler.getProcedure(this, name); + Statement stmt = procedure.prepareCall(this.rsType, this.rsConcur); - if (stmt == null) { - return; - } + if (maxRows != Py.None) { + stmt.setMaxRows(maxRows.asInt()); + } - this.statement = stmt; + // get the bindings per the stored proc spec + PyDictionary callableBindings = new PyDictionary(); - try { - synchronized (this.statement) { - if (hasParams) { + procedure.normalizeInput(params, callableBindings); - // if we have a sequence of sequences, let's run through them and finish - if (isSeqSeq(params)) { + // overwrite with any user specific bindings + if (bindings instanceof PyDictionary) { + callableBindings.update(bindings); + } - // [(3, 4)] or [(3, 4), (5, 6)] - rowIndex = 0; - for (int i = 0, len = params.__len__(); i < len; i++) { - PyObject param = params.__getitem__(i); + this.statement = new PyStatement(stmt, procedure); - this.execute(param, bindings); - rowIndex++; + this.execute(params, callableBindings); + } else { + throw zxJDBC.makeException(zxJDBC.NotSupportedError, + zxJDBC.getString("noStoredProc")); } - } else { - this.execute(params, bindings); - } - } else { - - // execute the sql string straight up - this.execute(Py.None, Py.None); + } catch (PyException e) { + throw e; + } catch (Throwable e) { + throw zxJDBC.makeException(e); + } finally { + if (this.statement != null) { + // close what we opened + this.statement.close(); + } } - } - } catch (PyException e) { - throw e; - } catch (Throwable e) { - throw zxJDBC.makeException(zxJDBC.Error, e, rowIndex); - } finally { - if (this.statement != null) { + } - // only close static, single-use statements - if (!(sql instanceof PyStatement) && (!this.dynamicFetch)) { - this.statement.close(); + /** + * Prepare a database operation (query or command) and then execute it against all + * parameter sequences or mappings found in the sequence seq_of_parameters. + * Modules are free to implement this method using multiple calls to the execute() + * method or by using array operations to have the database process the sequence as + * a whole in one call. + * + * The same comments as for execute() also apply accordingly to this method. + * + * Return values are not defined. + * + * @param sql + * @param params + * @param bindings + * @param maxRows + */ + public void executemany(PyObject sql, PyObject params, PyObject bindings, PyObject maxRows) { + if (isSeq(params) && params.__len__() == 0) { + //executemany with an empty params tuple is a no-op + return; } - } + execute(sql, params, bindings, maxRows); } - } - /** - * Execute the current sql statement. Some generic functionality such - * as updating the lastrowid and updatecount occur as well. - */ - protected void execute(PyObject params, PyObject bindings) { + /** + * Prepare and execute a database operation (query or command). + * Parameters may be provided as sequence or mapping and will + * be bound to variables in the operation. Variables are specified + * in a database-specific notation (see the module's paramstyle + * attribute for details). + * + * A reference to the operation will be retained by the cursor. + * If the same operation object is passed in again, then the cursor + * can optimize its behavior. This is most effective for algorithms + * where the same operation is used, but different parameters are + * bound to it (many times). + * + * For maximum efficiency when reusing an operation, it is best to + * use the setinputsizes() method to specify the parameter types and + * sizes ahead of time. It is legal for a parameter to not match the + * predefined information; the implementation should compensate, possibly + * with a loss of efficiency. + * + * The parameters may also be specified as list of tuples to e.g. insert + * multiple rows in a single operation, but this kind of usage is + * deprecated: executemany() should be used instead. + * + * Return values are not defined. + * + * @param sql sql string or prepared statement + * @param params params for a prepared statement + * @param bindings dictionary of (param index : SQLType binding) + * @param maxRows integer value of max rows + */ + public void execute(final PyObject sql, PyObject params, PyObject bindings, PyObject maxRows) { + int rowIndex = -1; + this.clear(); - try { - Statement stmt = this.statement.statement; + boolean hasParams = hasParams(params); + PyStatement stmt = this.prepareStatement(sql, maxRows, hasParams); - this.datahandler.preExecute(stmt); + if (stmt == null) { + return; + } - // this performs the SQL execution and fetch per the Statement type - this.statement.execute(this, params, bindings); + this.statement = stmt; - this.lastrowid = this.datahandler.getRowId(stmt); + try { + synchronized (this.statement) { + if (hasParams) { - int uc = stmt.getUpdateCount(); + // if we have a sequence of sequences, let's run through them and finish + if (isSeqSeq(params)) { - this.updatecount = (uc < 0) ? Py.None : Py.newInteger(uc); + // [(3, 4)] or [(3, 4), (5, 6)] + rowIndex = 0; + for (int i = 0, len = params.__len__(); i < len; i++) { + PyObject param = params.__getitem__(i); - warning(new WarningEvent(this, stmt.getWarnings())); - this.datahandler.postExecute(stmt); - } catch (PyException e) { - throw e; - } catch (Throwable e) { - throw zxJDBC.makeException(e); + this.execute(param, bindings); + rowIndex++; + } + } else { + this.execute(params, bindings); + } + } else { + // execute the sql string straight up + this.execute(Py.None, Py.None); + } + } + } catch (PyException e) { + throw e; + } catch (Throwable e) { + throw zxJDBC.makeException(zxJDBC.Error, e, rowIndex); + } finally { + if (this.statement != null) { + // only close static, single-use statements + if (!(sql instanceof PyStatement) && !this.dynamicFetch) { + this.statement.close(); + } + } + } } - } - /** - * Fetch the next row of a query result set, returning a single sequence, - * or None when no more data is available. - * - * An Error (or subclass) exception is raised if the previous call to - * executeXXX() did not produce any result set or no call was issued yet. - * - * @return a single sequence from the result set, or None when no more data is available - */ - public PyObject fetchone() { - return this.fetch.fetchone(); - } + /** + * Execute the current sql statement. Some generic functionality such + * as updating the lastrowid and updatecount occur as well. + */ + protected void execute(PyObject params, PyObject bindings) { + try { + Statement stmt = this.statement.statement; - /** - * Fetch all (remaining) rows of a query result, returning them as a sequence - * of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute - * can affect the performance of this operation. - * - * An Error (or subclass) exception is raised if the previous call to executeXXX() - * did not produce any result set or no call was issued yet. - * - * @return a sequence of sequences from the result set, or an empty sequence when - * no more data is available - */ - public PyObject fetchall() { - return this.fetch.fetchall(); - } + this.datahandler.preExecute(stmt); - /** - * Fetch the next set of rows of a query result, returning a sequence of - * sequences (e.g. a list of tuples). An empty sequence is returned when - * no more rows are available. - * - * The number of rows to fetch per call is specified by the parameter. If - * it is not given, the cursor's arraysize determines the number of rows - * to be fetched. The method should try to fetch as many rows as indicated - * by the size parameter. If this is not possible due to the specified number - * of rows not being available, fewer rows may be returned. - * - * An Error (or subclass) exception is raised if the previous call to executeXXX() - * did not produce any result set or no call was issued yet. - * - * Note there are performance considerations involved with the size parameter. - * For optimal performance, it is usually best to use the arraysize attribute. - * If the size parameter is used, then it is best for it to retain the same value - * from one fetchmany() call to the next. - * - * @param size - * @return a sequence of sequences from the result set, or an empty sequence when - * no more data is available - */ - public PyObject fetchmany(int size) { - return this.fetch.fetchmany(size); - } + // this performs the SQL execution and fetch per the Statement type + this.statement.execute(this, params, bindings); - /** - * Move the result pointer to the next set if available. - * - * @return true if more sets exist, else None - */ - public PyObject nextset() { - return this.fetch.nextset(); - } + this.lastrowid = this.datahandler.getRowId(stmt); - /** - * Prepare a sql statement for later execution. - * - * @param sql The sql string to be prepared. - * - * @return A prepared statement usable with .executeXXX() - */ - public PyStatement prepare(PyObject sql) { + int uc = stmt.getUpdateCount(); - PyStatement s = this.prepareStatement(sql, Py.None, true); + this.updatecount = uc < 0 ? Py.None : Py.newInteger(uc); - // add to the set of statements which are leaving our control - this.connection.add(s); + warning(new WarningEvent(this, stmt.getWarnings())); + this.datahandler.postExecute(stmt); + } catch (PyException e) { + throw e; + } catch (Throwable e) { + throw zxJDBC.makeException(e); + } + } - return s; - } + /** + * Fetch the next row of a query result set, returning a single sequence, + * or None when no more data is available. + * + * An Error (or subclass) exception is raised if the previous call to + * executeXXX() did not produce any result set or no call was issued yet. + * + * @return a single sequence from the result set, or None when no more data is available + */ + public PyObject fetchone() { + return this.fetch.fetchone(); + } - /** - * Scroll the cursor in the result set to a new position according - * to mode. - * - * If mode is 'relative' (default), value is taken as offset to - * the current position in the result set, if set to 'absolute', - * value states an absolute target position. - * - * An IndexError should be raised in case a scroll operation would - * leave the result set. In this case, the cursor position is left - * undefined (ideal would be to not move the cursor at all). - * - * Note: This method should use native scrollable cursors, if - * available, or revert to an emulation for forward-only - * scrollable cursors. The method may raise NotSupportedErrors to - * signal that a specific operation is not supported by the - * database (e.g. backward scrolling). - * - * - * @param value - * @param mode - * - */ - public void scroll(int value, String mode) { - this.fetch.scroll(value, mode); - } + /** + * Fetch all (remaining) rows of a query result, returning them as a sequence + * of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute + * can affect the performance of this operation. + * + * An Error (or subclass) exception is raised if the previous call to executeXXX() + * did not produce any result set or no call was issued yet. + * + * @return a sequence of sequences from the result set, or an empty sequence when + * no more data is available + */ + public PyObject fetchall() { + return this.fetch.fetchall(); + } - /** - * Adds a warning to the tuple and will follow the chain as necessary. - * - * @param event - */ - public void warning(WarningEvent event) { + /** + * Fetch the next set of rows of a query result, returning a sequence of + * sequences (e.g. a list of tuples). An empty sequence is returned when + * no more rows are available. + * + * The number of rows to fetch per call is specified by the parameter. If + * it is not given, the cursor's arraysize determines the number of rows + * to be fetched. The method should try to fetch as many rows as indicated + * by the size parameter. If this is not possible due to the specified number + * of rows not being available, fewer rows may be returned. + * + * An Error (or subclass) exception is raised if the previous call to executeXXX() + * did not produce any result set or no call was issued yet. + * + * Note there are performance considerations involved with the size parameter. + * For optimal performance, it is usually best to use the arraysize attribute. + * If the size parameter is used, then it is best for it to retain the same value + * from one fetchmany() call to the next. + * + * @param size + * @return a sequence of sequences from the result set, or an empty sequence when + * no more data is available + */ + public PyObject fetchmany(int size) { + return this.fetch.fetchmany(size); + } - if (this.warnings == Py.None) { - this.warnings = new PyList(); + /** + * Move the result pointer to the next set if available. + * + * @return true if more sets exist, else None + */ + public PyObject nextset() { + return this.fetch.nextset(); } - SQLWarning warning = event.getWarning(); - while(warning != null) { + /** + * Prepare a sql statement for later execution. + * + * @param sql The sql string to be prepared. + * + * @return A prepared statement usable with .executeXXX() + */ + public PyStatement prepare(PyObject sql) { + PyStatement s = this.prepareStatement(sql, Py.None, true); - PyObject[] warn = new PyObject[] { - // there are three parts: (reason, state, vendorCode) - Py.java2py(warning.getMessage()), - Py.java2py(warning.getSQLState()), - Py.newInteger(warning.getErrorCode()) - }; + // add to the set of statements which are leaving our control + this.connection.add(s); - // add the warning to the list - ((PyList)this.warnings).append(new PyTuple(warn)); - - warning = warning.getNextWarning(); + return s; } - } - /** - * Resets the cursor state. This includes flushing the warnings - * and any previous results. - * - */ - protected void clear() { - - if (closed) { - throw zxJDBC.makeException(zxJDBC.ProgrammingError, "cursor is closed"); + /** + * Scroll the cursor in the result set to a new position according + * to mode. + * + * If mode is 'relative' (default), value is taken as offset to + * the current position in the result set, if set to 'absolute', + * value states an absolute target position. + * + * An IndexError should be raised in case a scroll operation would + * leave the result set. In this case, the cursor position is left + * undefined (ideal would be to not move the cursor at all). + * + * Note: This method should use native scrollable cursors, if + * available, or revert to an emulation for forward-only + * scrollable cursors. The method may raise NotSupportedErrors to + * signal that a specific operation is not supported by the + * database (e.g. backward scrolling). + * + * + * @param value + * @param mode + * + */ + public void scroll(int value, String mode) { + this.fetch.scroll(value, mode); } - this.warnings = Py.None; - this.lastrowid = Py.None; - this.updatecount = Py.newInteger(-1); + /** + * Adds a warning to the tuple and will follow the chain as necessary. + * + * @param event + */ + public void warning(WarningEvent event) { + if (this.warnings == Py.None) { + this.warnings = new PyList(); + } - try { - this.fetch.close(); - } catch (Throwable e) {} - finally { - this.fetch = Fetch.newFetch(this.datahandler, this.dynamicFetch); + SQLWarning warning = event.getWarning(); + while (warning != null) { + PyObject[] warn = new PyObject[] { + // there are three parts: (reason, state, vendorCode) + Py.java2py(warning.getMessage()), + Py.java2py(warning.getSQLState()), + Py.newInteger(warning.getErrorCode()) + }; - this.fetch.addWarningListener(this); - } + // add the warning to the list + ((PyList)this.warnings).append(new PyTuple(warn)); - if (this.statement != null) { - - // we can't close a dynamic fetch statement until everything has been - // consumed so the only time we can clean up is now - // but if this is a previously prepared statement we don't want to close - // it underneath someone; we can check this by looking in the set - try { - if (this.dynamicFetch && (!this.connection.contains(this.statement))) { - this.statement.close(); + warning = warning.getNextWarning(); } - } finally { - this.statement = null; - } } - } - /** - * Method isSeq - * - * @param object - * - * @return true for any PyList, PyTuple or java.util.List - * - */ - public static boolean isSeq(PyObject object) { + /** + * Resets the cursor state. This includes flushing the warnings + * and any previous results. + * + */ + protected void clear() { + if (closed) { + throw zxJDBC.makeException(zxJDBC.ProgrammingError, "cursor is closed"); + } - if ((object == null) || (object == Py.None)) { - return false; - } + this.warnings = Py.None; + this.lastrowid = Py.None; + this.updatecount = Py.newInteger(-1); - if (object.__tojava__(List.class) != Py.NoConversion) { - return true; + try { + this.fetch.close(); + } catch (Throwable e) { + // ok + } finally { + this.fetch = Fetch.newFetch(this.datahandler, this.dynamicFetch); + this.fetch.addWarningListener(this); + } + + if (this.statement != null) { + // we can't close a dynamic fetch statement until everything has been + // consumed so the only time we can clean up is now + // but if this is a previously prepared statement we don't want to close + // it underneath someone; we can check this by looking in the set + try { + if (this.dynamicFetch && !this.connection.contains(this.statement)) { + this.statement.close(); + } + } finally { + this.statement = null; + } + } } - // originally checked for __getitem__ and __len__, but this is true for PyString - // and we don't want to insert one character at a time - return (object instanceof PyList) || (object instanceof PyTuple); - } + /** + * Method isSeq + * + * @param object + * + * @return true for any PyList, PyTuple or java.util.List + * + */ + public static boolean isSeq(PyObject object) { + if (object == null || object == Py.None) { + return false; + } - /** - * Method hasParams - * - * @param params - * - * @return boolean - * - */ - public static boolean hasParams(PyObject params) { - if(Py.None == params) { - return false; - } + if (object.__tojava__(List.class) != Py.NoConversion) { + return true; + } - boolean isSeq = isSeq(params); - // the optional argument better be a sequence - if (!isSeq) { - throw zxJDBC.makeException(zxJDBC.ProgrammingError, zxJDBC.getString("optionalSecond")); + // originally checked for __getitem__ and __len__, but this is true for PyString + // and we don't want to insert one character at a time + return object instanceof PyList || object instanceof PyTuple; } - return params.__len__() > 0; - } - /** - * Method isSeqSeq - * - * @param object - * - * @return true is a sequence of sequences - * - */ - public static boolean isSeqSeq(PyObject object) { + /** + * Method hasParams + * + * @param params + * + * @return boolean + * + */ + public static boolean hasParams(PyObject params) { + if (Py.None == params) { + return false; + } - if (isSeq(object) && (object.__len__() > 0)) { - for (int i = 0; i < object.__len__(); i++) { - if (!isSeq(object.__finditem__(i))) { - return false; + boolean isSeq = isSeq(params); + // the optional argument better be a sequence + if (!isSeq) { + throw zxJDBC.makeException(zxJDBC.ProgrammingError, + zxJDBC.getString("optionalSecond")); } - } - return true; + return params.__len__() > 0; } - return false; - } + + /** + * Method isSeqSeq + * + * @param object + * + * @return true is a sequence of sequences + * + */ + public static boolean isSeqSeq(PyObject object) { + if (isSeq(object) && (object.__len__() > 0)) { + for (int i = 0; i < object.__len__(); i++) { + if (!isSeq(object.__finditem__(i))) { + return false; + } + } + return true; + } + return false; + } } class CursorFunc extends PyBuiltinMethodSet { - CursorFunc(String name, int index, int argcount, String doc) { - this(name, index, argcount, argcount, doc); - } - CursorFunc(String name, int index, int minargs, int maxargs, String doc) { - super(name, index, minargs, maxargs, doc, PyCursor.class); - } - public PyObject __call__() { - PyCursor cursor = (PyCursor)__self__; - switch (index) { - case 0 : - return cursor.fetchmany(cursor.arraysize); - case 1 : - cursor.close(); - return Py.None; - case 2 : - return cursor.fetchall(); - case 3 : - return cursor.fetchone(); - case 4 : - return cursor.nextset(); - default : - throw info.unexpectedCall(0, false); + CursorFunc(String name, int index, int argcount, String doc) { + this(name, index, argcount, argcount, doc); } - } - public PyObject __call__(PyObject arg) { - PyCursor cursor = (PyCursor)__self__; - switch (index) { - case 0 : - return cursor.fetchmany(arg.asInt()); - case 5 : - cursor.execute(arg, Py.None, Py.None, Py.None); - return Py.None; - case 6 : - case 7 : - return Py.None; - case 8 : - cursor.callproc(arg, Py.None, Py.None, Py.None); - return Py.None; - case 9 : - cursor.executemany(arg, Py.None, Py.None, Py.None); - return Py.None; - case 10 : - cursor.scroll(arg.asInt(), "relative"); - return Py.None; - case 11 : - cursor.execute(arg, Py.None, Py.None, Py.None); - return Py.None; - case 12 : - return cursor.prepare(arg); - default : - throw info.unexpectedCall(1, false); + CursorFunc(String name, int index, int minargs, int maxargs, String doc) { + super(name, index, minargs, maxargs, doc, PyCursor.class); } - } - public PyObject __call__(PyObject arga, PyObject argb) { - PyCursor cursor = (PyCursor)__self__; - switch (index) { - case 5 : - cursor.execute(arga, argb, Py.None, Py.None); - return Py.None; - case 7 : - return Py.None; - case 8 : - cursor.callproc(arga, argb, Py.None, Py.None); - return Py.None; - case 9 : - cursor.executemany(arga, argb, Py.None, Py.None); - return Py.None; - case 10 : - cursor.scroll(arga.asInt(), argb.toString()); - return Py.None; - default : - throw info.unexpectedCall(2, false); + @Override + public PyObject __call__() { + PyCursor cursor = (PyCursor)__self__; + switch (index) { + case 0 : + return cursor.fetchmany(cursor.arraysize); + case 1 : + cursor.close(); + return Py.None; + case 2 : + return cursor.fetchall(); + case 3 : + return cursor.fetchone(); + case 4 : + return cursor.nextset(); + default : + throw info.unexpectedCall(0, false); + } } - } - public PyObject __call__(PyObject arga, PyObject argb, PyObject argc) { - PyCursor cursor = (PyCursor)__self__; - switch (index) { - case 5 : - cursor.execute(arga, argb, argc, Py.None); - return Py.None; - case 8 : - cursor.callproc(arga, argb, argc, Py.None); - return Py.None; - case 9 : - cursor.executemany(arga, argb, argc, Py.None); - return Py.None; - default : - throw info.unexpectedCall(3, false); + @Override + public PyObject __call__(PyObject arg) { + PyCursor cursor = (PyCursor)__self__; + switch (index) { + case 0 : + return cursor.fetchmany(arg.asInt()); + case 5 : + cursor.execute(arg, Py.None, Py.None, Py.None); + return Py.None; + case 6 : + case 7 : + return Py.None; + case 8 : + cursor.callproc(arg, Py.None, Py.None, Py.None); + return Py.None; + case 9 : + cursor.executemany(arg, Py.None, Py.None, Py.None); + return Py.None; + case 10 : + cursor.scroll(arg.asInt(), "relative"); + return Py.None; + case 11 : + cursor.execute(arg, Py.None, Py.None, Py.None); + return Py.None; + case 12 : + return cursor.prepare(arg); + default : + throw info.unexpectedCall(1, false); + } } - } - public PyObject __call__(PyObject[] args, String[] keywords) { + @Override + public PyObject __call__(PyObject arga, PyObject argb) { + PyCursor cursor = (PyCursor)__self__; + switch (index) { + case 5 : + cursor.execute(arga, argb, Py.None, Py.None); + return Py.None; + case 7 : + return Py.None; + case 8 : + cursor.callproc(arga, argb, Py.None, Py.None); + return Py.None; + case 9 : + cursor.executemany(arga, argb, Py.None, Py.None); + return Py.None; + case 10 : + cursor.scroll(arga.asInt(), argb.toString()); + return Py.None; + default : + throw info.unexpectedCall(2, false); + } + } - PyCursor cursor = (PyCursor)__self__; - PyArgParser parser = new PyArgParser(args, keywords); - PyObject sql = parser.arg(0); - PyObject params = parser.kw("params", Py.None); - PyObject bindings = parser.kw("bindings", P... [truncated message content] |
From: <nr...@us...> - 2009-07-20 17:35:16
|
Revision: 6551 http://jython.svn.sourceforge.net/jython/?rev=6551&view=rev Author: nriley Date: 2009-07-20 17:35:01 +0000 (Mon, 20 Jul 2009) Log Message: ----------- JSR 223: test Python exceptions as well as syntax errors. Modified Paths: -------------- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java Modified: branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-20 09:41:42 UTC (rev 6550) +++ branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-20 17:35:01 UTC (rev 6551) @@ -34,6 +34,20 @@ assertTrue("Expected a ScriptException", false); } + public void testPythonException() { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + try { + pythonEngine.eval("pass\ndel undefined"); + } catch (ScriptException e) { + assertEquals(e.getLineNumber(), 2); + assertTrue(e.getMessage().startsWith("NameError: ")); + return; + } + assertTrue("Expected a ScriptException", false); + } + public void testScriptFilename() { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine pythonEngine = manager.getEngineByName("python"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-07-20 09:41:47
|
Revision: 6550 http://jython.svn.sourceforge.net/jython/?rev=6550&view=rev Author: thobes Date: 2009-07-20 09:41:42 +0000 (Mon, 20 Jul 2009) Log Message: ----------- Fix for problem with compiling coroutines, yield was not allowed in the iterator expression of for-nodes. Example of failing code: def err(): for x in (yield): pass Fixed by deferring the allocation of the registers for storing the iter until after the iter expression is evaluated. Modified Paths: -------------- trunk/jython/src/org/python/compiler/CodeCompiler.java Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-20 04:13:32 UTC (rev 6549) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-20 09:41:42 UTC (rev 6550) @@ -1089,14 +1089,14 @@ Label start_loop = new Label(); Label next_loop = new Label(); - int iter_tmp = code.getLocal("org/python/core/PyObject"); - int expr_tmp = code.getLocal("org/python/core/PyObject"); - setline(node); //parse the list visit(node.getInternalIter()); + int iter_tmp = code.getLocal("org/python/core/PyObject"); + int expr_tmp = code.getLocal("org/python/core/PyObject"); + //set up the loop iterator code.invokevirtual("org/python/core/PyObject", "__iter__", "()Lorg/python/core/PyObject;"); code.astore(iter_tmp); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-20 04:13:36
|
Revision: 6549 http://jython.svn.sourceforge.net/jython/?rev=6549&view=rev Author: fwierzbicki Date: 2009-07-20 04:13:32 +0000 (Mon, 20 Jul 2009) Log Message: ----------- whitespace (tabs->spaces) Modified Paths: -------------- trunk/jython/src/org/python/compiler/Code.java Modified: trunk/jython/src/org/python/compiler/Code.java =================================================================== --- trunk/jython/src/org/python/compiler/Code.java 2009-07-19 08:15:53 UTC (rev 6548) +++ trunk/jython/src/org/python/compiler/Code.java 2009-07-20 04:13:32 UTC (rev 6549) @@ -21,12 +21,12 @@ //XXX: I'd really like to get sig and access out of here since MethodVistitor // should already have this information. public Code(MethodVisitor mv, String sig, int access) { - this.mv = mv; - this.sig = sig; - nlocals = -sigSize(sig, false); - if ((access & ACC_STATIC) != ACC_STATIC) nlocals = nlocals+1; - argcount = nlocals; - locals = new String[nlocals+128]; + this.mv = mv; + this.sig = sig; + nlocals = -sigSize(sig, false); + if ((access & ACC_STATIC) != ACC_STATIC) nlocals = nlocals+1; + argcount = nlocals; + locals = new String[nlocals+128]; } public int getLocal(String type) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-07-19 08:15:59
|
Revision: 6548 http://jython.svn.sourceforge.net/jython/?rev=6548&view=rev Author: cgroves Date: 2009-07-19 08:15:53 +0000 (Sun, 19 Jul 2009) Log Message: ----------- Add an ant task to compile proxies This works by naively importing the modules with the proxy output directory set to the destination configured in the ant task. Eventually it's going to need to work with our Lib directory to generate proxies for all of our Java subclasses, but it currently fails miserably on various modules that aren't expecting to be straight-up imported. Modified Paths: -------------- trunk/jython/src/org/python/core/PyJavaType.java trunk/jython/src/org/python/core/PyType.java trunk/jython/src/org/python/expose/generate/ExposeTask.java trunk/jython/src/org/python/util/GlobMatchingTask.java trunk/jython/src/org/python/util/JycompileAntTask.java Added Paths: ----------- trunk/jython/src/org/python/util/CompileProxiesTask.java trunk/jython/src/org/python/util/FileNameMatchingTask.java Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2009-07-19 06:49:49 UTC (rev 6547) +++ trunk/jython/src/org/python/core/PyJavaType.java 2009-07-19 08:15:53 UTC (rev 6548) @@ -186,7 +186,7 @@ underlying_class = forClass; computeLinearMro(baseClass); } else { - needsInners.add(this); + needsInners.add(this); javaProxy = forClass; objtype = PyType.fromClassSkippingInners(Class.class, needsInners); // Wrapped Java types fill in their mro first using all of their interfaces then their Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-07-19 06:49:49 UTC (rev 6547) +++ trunk/jython/src/org/python/core/PyType.java 2009-07-19 08:15:53 UTC (rev 6548) @@ -1051,8 +1051,9 @@ PyObject dict = element.fastGetDict(); if (dict != null) { PyObject obj = dict.__finditem__(name); - if (obj != null) + if (obj != null) { return obj; + } } } return null; Modified: trunk/jython/src/org/python/expose/generate/ExposeTask.java =================================================================== --- trunk/jython/src/org/python/expose/generate/ExposeTask.java 2009-07-19 06:49:49 UTC (rev 6547) +++ trunk/jython/src/org/python/expose/generate/ExposeTask.java 2009-07-19 08:15:53 UTC (rev 6548) @@ -8,8 +8,8 @@ import org.apache.tools.ant.BuildException; import org.objectweb.asm.ClassWriter; +import org.python.core.Options; import org.python.core.Py; -import org.python.core.Options; import org.python.util.GlobMatchingTask; public class ExposeTask extends GlobMatchingTask { Added: trunk/jython/src/org/python/util/CompileProxiesTask.java =================================================================== --- trunk/jython/src/org/python/util/CompileProxiesTask.java (rev 0) +++ trunk/jython/src/org/python/util/CompileProxiesTask.java 2009-07-19 08:15:53 UTC (rev 6548) @@ -0,0 +1,68 @@ +package org.python.util; + +import java.io.File; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import org.apache.tools.ant.BuildException; +import org.python.core.Py; +import org.python.core.PySystemState; + +/** + * Compiles the Java proxies for Python classes in the Python modules in a given directory tree to + * another directory. + */ +public class CompileProxiesTask extends JycompileAntTask { + + @Override + public void process(Set<File> toCompile) throws BuildException { + // Run our superclass' compile first to check that everything has valid syntax before + // attempting to import it and to keep the imports from generating class files in the source + // directory + super.process(toCompile); + Properties props = new Properties(); + props.setProperty(PySystemState.PYTHON_CACHEDIR_SKIP, "true"); + PySystemState.initialize(props, null); + PySystemState sys = Py.getSystemState(); + // Part 2 of not spewing compilation in the source directory: import our compiled files + sys.path.insert(0, Py.newString(destDir.getAbsolutePath())); + sys.javaproxy_dir = destDir.getAbsolutePath(); + PythonInterpreter interp = new PythonInterpreter(); + for (String module : compiledModuleNames) { + try { + interp.exec("import " + module); + } catch (RuntimeException t) { + // We didn't get to import any of these files, so their compiled form can't hang + // around or we won't pick them up as needing compilation next time. + for (File f : compiledModuleFiles) { + f.delete(); + } + throw t; + } + // This module was successfully imported, so its compiled file can hang around + compiledModuleFiles.remove(0); + } + } + + @Override + protected void compile(File src, File compiled, String moduleName) { + try { + super.compile(src, compiled, moduleName); + } catch (BuildException ex) { + // This depends on the modtime of the source being newer than that of the compiled file + // to decide to do the import in process, so even though these files compiled properly, + // they need to be deleted to allow them to be imported in process next time around. + for (File f : compiledModuleFiles) { + f.delete(); + } + throw ex; + } + compiledModuleNames.add(moduleName); + compiledModuleFiles.add(compiled); + } + + private List<String> compiledModuleNames = Generic.list(); + + private List<File> compiledModuleFiles = Generic.list(); +} Added: trunk/jython/src/org/python/util/FileNameMatchingTask.java =================================================================== --- trunk/jython/src/org/python/util/FileNameMatchingTask.java (rev 0) +++ trunk/jython/src/org/python/util/FileNameMatchingTask.java 2009-07-19 08:15:53 UTC (rev 6548) @@ -0,0 +1,95 @@ +package org.python.util; + +import java.io.File; +import java.util.Set; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.taskdefs.MatchingTask; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.FileNameMapper; +import org.apache.tools.ant.util.SourceFileScanner; + +public abstract class FileNameMatchingTask extends MatchingTask { + + private Path src; + + protected File destDir; + + private Set<File> toProcess = Generic.set(); + + /** + * Set the source directories to find the class files to be exposed. + */ + public void setSrcdir(Path srcDir) { + if (src == null) { + src = srcDir; + } else { + src.append(srcDir); + } + } + + /** + * Gets the source dirs to find the class files to be exposed. + */ + public Path getSrcdir() { + return src; + } + + /** + * Set the destination directory into which the Java source files should be compiled. + * + * @param destDir + * the destination director + */ + public void setDestdir(File destDir) { + this.destDir = destDir; + } + + /** + * Gets the destination directory into which the java source files should be compiled. + * + * @return the destination directory + */ + public File getDestdir() { + return destDir; + } + + @Override + public void execute() throws BuildException { + checkParameters(); + toProcess.clear(); + for (String srcEntry : src.list()) { + File srcDir = getProject().resolveFile(srcEntry); + if (!srcDir.exists()) { + throw new BuildException("srcdir '" + srcDir.getPath() + "' does not exist!", + getLocation()); + } + String[] files = getDirectoryScanner(srcDir).getIncludedFiles(); + scanDir(srcDir, destDir != null ? destDir : srcDir, files); + } + process(toProcess); + } + + protected abstract void process(Set<File> matches); + + protected abstract FileNameMapper createMapper(); + + protected void scanDir(File srcDir, File destDir, String[] files) { + SourceFileScanner sfs = new SourceFileScanner(this); + for (File file : sfs.restrictAsFiles(files, srcDir, destDir, createMapper())) { + toProcess.add(file); + } + } + /** + * Check that all required attributes have been set and nothing silly has been entered. + */ + protected void checkParameters() throws BuildException { + if (src == null || src.size() == 0) { + throw new BuildException("srcdir attribute must be set!", getLocation()); + } + if (destDir != null && !destDir.isDirectory()) { + throw new BuildException("destination directory '" + destDir + "' does not exist " + + "or is not a directory", getLocation()); + } + } +} \ No newline at end of file Modified: trunk/jython/src/org/python/util/GlobMatchingTask.java =================================================================== --- trunk/jython/src/org/python/util/GlobMatchingTask.java 2009-07-19 06:49:49 UTC (rev 6547) +++ trunk/jython/src/org/python/util/GlobMatchingTask.java 2009-07-19 08:15:53 UTC (rev 6548) @@ -1,101 +1,19 @@ package org.python.util; -import java.io.File; -import java.util.Set; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.taskdefs.MatchingTask; -import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.FileNameMapper; import org.apache.tools.ant.util.GlobPatternMapper; -import org.apache.tools.ant.util.SourceFileScanner; -public abstract class GlobMatchingTask extends MatchingTask { +public abstract class GlobMatchingTask extends FileNameMatchingTask { - private Path src; - - protected File destDir; - - private Set<File> toExpose = Generic.set(); - - /** - * Set the source directories to find the class files to be exposed. - */ - public void setSrcdir(Path srcDir) { - if (src == null) { - src = srcDir; - } else { - src.append(srcDir); - } - } - - /** - * Gets the source dirs to find the class files to be exposed. - */ - public Path getSrcdir() { - return src; - } - - /** - * Set the destination directory into which the Java source files should be compiled. - * - * @param destDir - * the destination director - */ - public void setDestdir(File destDir) { - this.destDir = destDir; - } - - /** - * Gets the destination directory into which the java source files should be compiled. - * - * @return the destination directory - */ - public File getDestdir() { - return destDir; - } - @Override - public void execute() throws BuildException { - checkParameters(); - toExpose.clear(); - for (String srcEntry : src.list()) { - File srcDir = getProject().resolveFile(srcEntry); - if (!srcDir.exists()) { - throw new BuildException("srcdir '" + srcDir.getPath() + "' does not exist!", - getLocation()); - } - String[] files = getDirectoryScanner(srcDir).getIncludedFiles(); - scanDir(srcDir, destDir != null ? destDir : srcDir, files); - } - process(toExpose); + protected FileNameMapper createMapper() { + FileNameMapper mapper = new GlobPatternMapper(); + mapper.setFrom(getFrom()); + mapper.setTo(getTo()); + return mapper; } - protected abstract void process(Set<File> matches); - protected abstract String getFrom(); protected abstract String getTo(); - - protected void scanDir(File srcDir, File destDir, String[] files) { - GlobPatternMapper m = new GlobPatternMapper(); - m.setFrom(getFrom()); - m.setTo(getTo()); - SourceFileScanner sfs = new SourceFileScanner(this); - for (File file : sfs.restrictAsFiles(files, srcDir, destDir, m)) { - toExpose.add(file); - } - } - - /** - * Check that all required attributes have been set and nothing silly has been entered. - */ - protected void checkParameters() throws BuildException { - if (src == null || src.size() == 0) { - throw new BuildException("srcdir attribute must be set!", getLocation()); - } - if (destDir != null && !destDir.isDirectory()) { - throw new BuildException("destination directory '" + destDir + "' does not exist " - + "or is not a directory", getLocation()); - } - } -} \ No newline at end of file +} Modified: trunk/jython/src/org/python/util/JycompileAntTask.java =================================================================== --- trunk/jython/src/org/python/util/JycompileAntTask.java 2009-07-19 06:49:49 UTC (rev 6547) +++ trunk/jython/src/org/python/util/JycompileAntTask.java 2009-07-19 08:15:53 UTC (rev 6548) @@ -59,10 +59,12 @@ imp.cacheCompiledSource(src.getAbsolutePath(), compiled.getAbsolutePath(), bytes); } + @Override protected String getFrom() { return "*.py"; } + @Override protected String getTo() { return "*$py.class"; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-07-19 06:49:52
|
Revision: 6547 http://jython.svn.sourceforge.net/jython/?rev=6547&view=rev Author: cgroves Date: 2009-07-19 06:49:49 +0000 (Sun, 19 Jul 2009) Log Message: ----------- Move version-init into init as it wasn't used separately, and add a fileset to the jarring to shut up ant's spurious warning about no files being included Modified Paths: -------------- trunk/jython/build.xml Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-07-19 06:23:03 UTC (rev 6546) +++ trunk/jython/build.xml 2009-07-19 06:49:49 UTC (rev 6547) @@ -113,7 +113,38 @@ </uptodate> </target> - <target name="init" depends="version-init"> + <target name="init"> + <property file="${user.home}/ant.properties" /> + <property file="${basedir}/ant.properties" /> + + <property name="PY_RELEASE_LEVEL_ALPHA" value="10"/> <!-- 0xA --> + <property name="PY_RELEASE_LEVEL_BETA" value="11"/> <!-- 0xB --> + <property name="PY_RELEASE_LEVEL_GAMMA" value="12"/> <!-- 0xC --> + <property name="PY_RELEASE_LEVEL_FINAL" value="15"/> <!-- 0xF --> + <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> + + <!-- The current version info --> + <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_FINAL}"/> + <property name="jython.release_serial" value="0"/> + + <condition property="do.snapshot.build"> + <isset property="snapshot.revision" /> + </condition> + <!-- Switch to a snapshot release_level when appropriate --> + <condition property="jython.real_release_level" value="${PY_RELEASE_LEVEL_SNAPSHOT}" else="${jython.release_level}"> + <isset property="do.snapshot.build" /> + </condition> + <condition property="os.family.unix"> + <os family="unix"/> + </condition> + <condition property="os.family.windows"> + <os family="windows"/> + </condition> <property name="build.compiler" value="modern" /> <property name="jdk.target.version" value="1.5" /> <property name="jdk.source.version" value="1.5" /> @@ -177,40 +208,6 @@ <property name="jython.deploy.jar" value="jython.jar" /> </target> - <target name="version-init"> - <property file="${user.home}/ant.properties" /> - <property file="${basedir}/ant.properties" /> - - <property name="PY_RELEASE_LEVEL_ALPHA" value="10"/> <!-- 0xA --> - <property name="PY_RELEASE_LEVEL_BETA" value="11"/> <!-- 0xB --> - <property name="PY_RELEASE_LEVEL_GAMMA" value="12"/> <!-- 0xC --> - <property name="PY_RELEASE_LEVEL_FINAL" value="15"/> <!-- 0xF --> - <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> - - <!-- The current version info --> - <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_FINAL}"/> - <property name="jython.release_serial" value="0"/> - - <condition property="do.snapshot.build"> - <isset property="snapshot.revision" /> - </condition> - <!-- Switch to a snapshot release_level when appropriate --> - <condition property="jython.real_release_level" value="${PY_RELEASE_LEVEL_SNAPSHOT}" else="${jython.release_level}"> - <isset property="do.snapshot.build" /> - </condition> - <condition property="os.family.unix"> - <os family="unix"/> - </condition> - <condition property="os.family.windows"> - <os family="windows"/> - </condition> - </target> - <target name="full-preinit"> <property file="${user.home}/ant.properties" /> <property file="${basedir}/ant.properties" /> @@ -593,9 +590,13 @@ <fileset dir="${compile.dir}" includes="org/python/tests/Callbacker*"/> </jar> <jar destfile="${dist.dir}/${jython.dev.jar}" duplicate="fail"> + <!-- If only nameunion is used, ant issues a spurious warning about no files being + included. Use a fileset for version.properties just to shut that up. --> + <fileset dir="${compile.dir}" includes="org/python/version.properties"/> <nameunion> <fileset dir="${exposed.dir}"/> - <fileset dir="${compile.dir}" excludes="org/python/expose/generate/**"/> + <fileset dir="${compile.dir}" + excludes="org/python/expose/generate/**,org/python/version.properties"/> </nameunion> <manifest> <attribute name="Main-Class" value="org.python.util.jython" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-07-19 06:23:06
|
Revision: 6546 http://jython.svn.sourceforge.net/jython/?rev=6546&view=rev Author: cgroves Date: 2009-07-19 06:23:03 +0000 (Sun, 19 Jul 2009) Log Message: ----------- Eclipse needs jna now Modified Paths: -------------- trunk/jython/.classpath Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-07-19 06:16:59 UTC (rev 6545) +++ trunk/jython/.classpath 2009-07-19 06:23:03 UTC (rev 6546) @@ -20,6 +20,7 @@ <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="lib" path="extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar"/> + <classpathentry kind="lib" path="extlibs/jna.jar"/> <classpathentry kind="output" path="bugtests/classes"/> </classpath> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-07-19 06:17:03
|
Revision: 6545 http://jython.svn.sourceforge.net/jython/?rev=6545&view=rev Author: cgroves Date: 2009-07-19 06:16:59 +0000 (Sun, 19 Jul 2009) Log Message: ----------- Properties are fixed once they're set, so there's no need to set them conditionally. Don't force an overwrite on the registry file in dev builds. Modified Paths: -------------- trunk/jython/build.xml Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-07-19 05:35:22 UTC (rev 6544) +++ trunk/jython/build.xml 2009-07-19 06:16:59 UTC (rev 6545) @@ -367,11 +367,7 @@ <!-- skip-brand can be set in ant.properties or as a system property to keep from updating the version.properties file and making the jar on every developer build. --> <target name="brand-version" depends="init, svnversion" unless="skip-brand"> - <condition property="build.svn.revision" value=""> - <not> - <isset property="build.svn.revision"/> - </not> - </condition> + <property name="build.svn.revision" value=""/> <tstamp> <format property="build.date" pattern="MMM d yyyy" offset="0"/> <format property="build.time" pattern="HH:mm:ss" offset="0"/> @@ -719,7 +715,7 @@ </chmod> <!-- copy the registry --> - <copy todir="${dist.dir}" file="${jython.base.dir}/registry" preservelastmodified="true" overwrite="true" /> + <copy todir="${dist.dir}" file="${jython.base.dir}/registry" preservelastmodified="true"/> </target> <target name="copy-cpythonlib"> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-19 05:35:39
|
Revision: 6544 http://jython.svn.sourceforge.net/jython/?rev=6544&view=rev Author: pjenvey Date: 2009-07-19 05:35:22 +0000 (Sun, 19 Jul 2009) Log Message: ----------- have the dbapi Binary type convert strs to byte arrays Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/zxJDBC.java Modified: trunk/jython/src/com/ziclix/python/sql/zxJDBC.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/zxJDBC.java 2009-07-19 05:33:37 UTC (rev 6543) +++ trunk/jython/src/com/ziclix/python/sql/zxJDBC.java 2009-07-19 05:35:22 UTC (rev 6544) @@ -11,6 +11,7 @@ import org.python.core.ClassDictInit; import org.python.core.Options; import org.python.core.Py; +import org.python.core.PyArray; import org.python.core.PyBuiltinFunctionSet; import org.python.core.PyDictionary; import org.python.core.PyException; @@ -455,6 +456,9 @@ ticks = ((Number) arg.__tojava__(Number.class)).longValue(); return zxJDBC.datefactory.TimestampFromTicks(ticks); case 7: + if (arg instanceof PyString) { + arg = PyArray.TYPE.__call__(Py.newString("b"), arg); + } return arg; default : throw info.unexpectedCall(1, false); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-19 05:34:05
|
Revision: 6543 http://jython.svn.sourceforge.net/jython/?rev=6543&view=rev Author: pjenvey Date: 2009-07-19 05:33:37 +0000 (Sun, 19 Jul 2009) Log Message: ----------- cleanup/coding standards Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/zxJDBC.java Modified: trunk/jython/src/com/ziclix/python/sql/zxJDBC.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/zxJDBC.java 2009-07-17 15:47:45 UTC (rev 6542) +++ trunk/jython/src/com/ziclix/python/sql/zxJDBC.java 2009-07-19 05:33:37 UTC (rev 6543) @@ -12,7 +12,6 @@ import org.python.core.Options; import org.python.core.Py; import org.python.core.PyBuiltinFunctionSet; -import org.python.core.PyClass; import org.python.core.PyDictionary; import org.python.core.PyException; import org.python.core.PyInteger; @@ -20,10 +19,13 @@ import org.python.core.PyString; import org.python.core.PyStringMap; +import java.io.CharArrayWriter; +import java.io.PrintWriter; import java.lang.reflect.Field; import java.sql.SQLException; import java.text.MessageFormat; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; import java.util.MissingResourceException; import java.util.Properties; @@ -105,7 +107,8 @@ static { try { - resourceBundle = ResourceBundle.getBundle("com.ziclix.python.sql.resource.zxJDBCMessages"); + resourceBundle = + ResourceBundle.getBundle("com.ziclix.python.sql.resource.zxJDBCMessages"); } catch (MissingResourceException e) { throw new RuntimeException("missing zxjdbc resource bundle"); } @@ -117,18 +120,34 @@ * @param dict */ public static void classDictInit(PyObject dict) { + PyObject version = + Py.newString("$Revision$").__getslice__(Py.newInteger(11), + Py.newInteger(-2)); dict.__setitem__("apilevel", new PyString("2.0")); dict.__setitem__("threadsafety", new PyInteger(1)); dict.__setitem__("paramstyle", new PyString("qmark")); - dict.__setitem__("__version__", Py.newString("$Revision$").__getslice__(Py.newInteger(11), Py.newInteger(-2), null)); - dict.__setitem__("Date", new zxJDBCFunc("Date", 1, 3, 3, "construct a Date from year, month, day")); - dict.__setitem__("Time", new zxJDBCFunc("Time", 2, 3, 3, "construct a Date from hour, minute, second")); - dict.__setitem__("Timestamp", new zxJDBCFunc("Timestamp", 3, 6, 6, "construct a Timestamp from year, month, day, hour, minute, second")); - dict.__setitem__("DateFromTicks", new zxJDBCFunc("DateFromTicks", 4, 1, 1, "construct a Date from seconds since the epoch")); - dict.__setitem__("TimeFromTicks", new zxJDBCFunc("TimeFromTicks", 5, 1, 1, "construct a Time from seconds since the epoch")); - dict.__setitem__("TimestampFromTicks", new zxJDBCFunc("TimestampFromTicks", 6, 1, 1, "construct a Timestamp from seconds since the epoch")); - dict.__setitem__("Binary", new zxJDBCFunc("Binary", 7, 1, 1, "construct an object capable of holding binary data")); + dict.__setitem__("__version__", version); + dict.__setitem__("Date", new zxJDBCFunc("Date", 1, 3, 3, + "construct a Date from year, month, day")); + dict.__setitem__("Time", new zxJDBCFunc("Time", 2, 3, 3, + "construct a Date from hour, minute, second")); + dict.__setitem__("Timestamp", + new zxJDBCFunc("Timestamp", 3, 6, 6, + "construct a Timestamp from year, month, day, hour, " + + "minute, second")); + dict.__setitem__("DateFromTicks", + new zxJDBCFunc("DateFromTicks", 4, 1, 1, + "construct a Date from seconds since the epoch")); + dict.__setitem__("TimeFromTicks", + new zxJDBCFunc("TimeFromTicks", 5, 1, 1, + "construct a Time from seconds since the epoch")); + dict.__setitem__("TimestampFromTicks", + new zxJDBCFunc("TimestampFromTicks", 6, 1, 1, + "construct a Timestamp from seconds since the epoch")); + dict.__setitem__("Binary", + new zxJDBCFunc("Binary", 7, 1, 1, + "construct an object capable of holding binary data")); zxJDBC._addSqlTypes(dict); zxJDBC._addConnectors(dict); zxJDBC._buildExceptions(dict); @@ -155,20 +174,17 @@ * @throws PyException */ protected static void _addSqlTypes(PyObject dict) throws PyException { - PyDictionary sqltype = new PyDictionary(); dict.__setitem__("sqltype", sqltype); try { - Class c = Class.forName("java.sql.Types"); + Class<?> c = Class.forName("java.sql.Types"); Field[] fields = c.getFields(); - for (int i = 0; i < fields.length; i++) { - Field f = fields[i]; + for (Field f : fields) { PyString name = Py.newString(f.getName()); PyObject value = new DBApiType(f.getInt(c)); - dict.__setitem__(name, value); sqltype.__setitem__(value, name); } @@ -176,11 +192,9 @@ c = Class.forName("java.sql.ResultSet"); fields = c.getFields(); - for (int i = 0; i < fields.length; i++) { - Field f = fields[i]; + for (Field f : fields) { PyString name = Py.newString(f.getName()); PyObject value = Py.newInteger(f.getInt(c)); - dict.__setitem__(name, value); } } catch (Throwable t) { @@ -191,8 +205,6 @@ dict.__setitem__("NUMBER", dict.__getitem__(Py.newString("NUMERIC"))); dict.__setitem__("STRING", dict.__getitem__(Py.newString("VARCHAR"))); dict.__setitem__("DATETIME", dict.__getitem__(Py.newString("TIMESTAMP"))); - - return; } /** @@ -202,7 +214,6 @@ * @throws PyException */ protected static void _addConnectors(PyObject dict) throws PyException { - PyObject connector = Py.None; Properties props = new Properties(); @@ -210,7 +221,7 @@ props.put("lookup", "com.ziclix.python.sql.connect.Lookup"); props.put("connectx", "com.ziclix.python.sql.connect.Connectx"); - java.util.Enumeration names = props.propertyNames(); + Enumeration<?> names = props.propertyNames(); while (names.hasMoreElements()) { String name = ((String) names.nextElement()).trim(); @@ -219,13 +230,13 @@ try { connector = (PyObject) Class.forName(className).newInstance(); dict.__setitem__(name, connector); - Py.writeComment("zxJDBC", "loaded connector [" + className + "] as [" + name + "]"); + Py.writeComment("zxJDBC", "loaded connector [" + className + "] as [" + name + + "]"); } catch (Throwable t) { - Py.writeComment("zxJDBC", "failed to load connector [" + name + "] using class [" + className + "]"); + Py.writeComment("zxJDBC", "failed to load connector [" + name + + "] using class [" + className + "]"); } } - - return; } /** @@ -234,7 +245,6 @@ * @param dict */ protected static void _buildExceptions(PyObject dict) { - Error = buildClass("Error", Py.StandardError); Warning = buildClass("Warning", Py.StandardError); InterfaceError = buildClass("InterfaceError", Error); @@ -259,20 +269,20 @@ */ public static String getString(String key) { int i = 0; - List lines = null; + List<String> lines = null; String resource = null; while (true) { try { resource = resourceBundle.getString(key + "." + (i++)); if (lines == null) { - lines = new ArrayList(); + lines = new ArrayList<String>(); } lines.add(resource); } catch (MissingResourceException e) { break; } } - if ((lines == null) || (lines.size() == 0)) { + if (lines == null || lines.size() == 0) { try { resource = resourceBundle.getString(key); } catch (MissingResourceException e) { @@ -321,7 +331,7 @@ * @return PyException */ public static PyException makeException(PyObject type, String msg) { - return Py.makeException(type, Py.newString((msg == null) ? "" : msg)); + return Py.makeException(type, msg == null ? Py.EmptyString : Py.newString(msg)); } /** @@ -339,7 +349,8 @@ // contains most of the SQLSTATES codes. // Otherwise, the state is not following the standard. if (state != null && state.length() == 5) { - if (state.startsWith("23")) { //Class 23 => Integrity Constraint Violation + if (state.startsWith("23")) { + // Class 23 => Integrity Constraint Violation type = IntegrityError; } else if (state.equals("40002")) { // 40002 => TRANSACTION INTEGRITY CONSTRAINT VIOLATION @@ -366,13 +377,13 @@ * * @param type * @param t - * @param rowIndex Row index where the error has happened. Useful for diagnosing. + * @param rowIndex Row index where the error has happened. Useful for diagnosing. * @return PyException */ public static PyException makeException(PyObject type, Throwable t, int rowIndex) { if (Options.showJavaExceptions) { - java.io.CharArrayWriter buf = new java.io.CharArrayWriter(); - java.io.PrintWriter writer = new java.io.PrintWriter(buf); + CharArrayWriter buf = new CharArrayWriter(); + PrintWriter writer = new PrintWriter(buf); writer.println("Java Traceback:"); if (t instanceof PyException) { ((PyException) t).super__printStackTrace(writer); @@ -393,7 +404,7 @@ if (sqlException.getSQLState() != null) { buffer.append(", [SQLState: " + sqlException.getSQLState() + "]"); } - if(rowIndex >= 0) { + if (rowIndex >= 0) { buffer.append(", [Row number: " + rowIndex + "]"); } sqlException = sqlException.getNextException(); @@ -430,6 +441,7 @@ super(name, index, minargs, maxargs, doc); } + @Override public PyObject __call__(PyObject arg) { long ticks; switch (index) { @@ -449,6 +461,7 @@ } } + @Override public PyObject __call__(PyObject arga, PyObject argb, PyObject argc) { switch (index) { case 1: @@ -466,6 +479,7 @@ } } + @Override public PyObject fancyCall(PyObject[] args) { switch (index) { case 3: @@ -481,4 +495,3 @@ } } } - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |