From: <cg...@us...> - 2009-01-04 08:41:20
|
Revision: 5839 http://jython.svn.sourceforge.net/jython/?rev=5839&view=rev Author: cgroves Date: 2009-01-04 08:41:16 +0000 (Sun, 04 Jan 2009) Log Message: ----------- Fixing test288 involved making proxy class method lookup go through __findattr__ on PyObject instead of doing its specialized lookup through the object's dict and type. This means wrapped Java instance method lookup is going through PyObjectDerived's __findattr_ex__ which has a scary comment about its slowness. I'm a little worried this will hurt Java performance, but I'm still holding off on optimizing any of the newstyle java stuff. test278 - Moved to test_java_integration test280 - Tested by test_scope test281,286,289 - Testing jythonc; deleted test282 - Moved to test_class_jy test284 - Tested by test_java_visibility test285 - Moved to test_java_integration test287 - Already disabled, deleted test288 - Moved to test_java_integration test290 - Tested by test_pickle test291 - Tested by test_import_jy Modified Paths: -------------- trunk/jython/Lib/test/test_class_jy.py trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/compiler/ProxyMaker.java trunk/jython/src/org/python/core/PyReflectedFunction.java trunk/jython/src/org/python/core/ReflectedArgs.java trunk/jython/tests/java/org/python/tests/Callbacker.java Added Paths: ----------- trunk/jython/tests/java/org/python/tests/BeanImplementation.java trunk/jython/tests/java/org/python/tests/BeanInterface.java Removed Paths: ------------- trunk/jython/bugtests/test278.py trunk/jython/bugtests/test278p/ trunk/jython/bugtests/test280.py trunk/jython/bugtests/test280c.py trunk/jython/bugtests/test281.py trunk/jython/bugtests/test281c.py trunk/jython/bugtests/test282.py trunk/jython/bugtests/test284.py trunk/jython/bugtests/test284j1.java trunk/jython/bugtests/test284j2.java trunk/jython/bugtests/test285.py trunk/jython/bugtests/test286.py trunk/jython/bugtests/test286c.py trunk/jython/bugtests/test287.py trunk/jython/bugtests/test288.py trunk/jython/bugtests/test289.py trunk/jython/bugtests/test289c.py Modified: trunk/jython/Lib/test/test_class_jy.py =================================================================== --- trunk/jython/Lib/test/test_class_jy.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/Lib/test/test_class_jy.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -177,6 +177,12 @@ # conflict class D(B, C): pass + + def test_getitem_exceptions(self): + class A: + def __getitem__(self, key): + raise IndexError, "Fraid not" + self.assertRaises(IndexError, A().__getitem__, 'b') class ClassNamelessModuleTestCase(unittest.TestCase): Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/Lib/test/test_java_integration.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -2,18 +2,24 @@ import unittest import sys import re + +from test import test_support -from test import test_support -from java.awt import Dimension, Color, Component, Rectangle -from java.util import ArrayList, HashMap, Hashtable, StringTokenizer, Vector -from java.io import FileOutputStream, FileWriter, OutputStreamWriter - -from java.lang import (Boolean, Class, ClassLoader, ExceptionInInitializerError, Integer, Object, String, - Runnable, Thread, ThreadGroup, System, Runtime, Math, Byte) +from java.lang import (Boolean, Class, ClassLoader, ExceptionInInitializerError, Integer, Object, + String, Runnable, Thread, ThreadGroup, System, Runtime, Math, Byte) +from java.math import BigDecimal +from java.io import (FileInputStream, FileNotFoundException, FileOutputStream, FileWriter, + OutputStreamWriter, UnsupportedEncodingException) +from java.util import ArrayList, Date, HashMap, Hashtable, StringTokenizer, Vector + +from java.awt import Dimension, Color, Component, Container, Rectangle +from java.awt.event import ComponentEvent from javax.swing.table import AbstractTableModel from javax.swing.tree import TreePath -from java.math import BigDecimal +from org.python.core.util import FileUtil +from org.python.tests import BeanImplementation, Callbacker, Listenable +from javatests import MethodInvokationTest """ public abstract class Abstract { public Abstract() { @@ -114,7 +120,6 @@ self.assertRaises(TypeError, Component) def test_str_doesnt_coerce_to_int(self): - from java.util import Date self.assertRaises(TypeError, Date, '99-01-01', 1, 1) def test_Class_newInstance_works_on_proxies(self): @@ -128,9 +133,6 @@ def test_multiple_listeners(self): '''Check that multiple BEP can be assigned to a single cast listener''' - from org.python.tests import Listenable - from java.awt.event import ComponentEvent - from java.awt import Container m = Listenable() called = [] def f(evt, called=called): @@ -143,6 +145,11 @@ self.assertEquals(1, len(called)) m.fireComponentHidden(ComponentEvent(Container(), 0)) self.assertEquals(2, len(called)) + + def test_bean_interface(self): + b = BeanImplementation() + self.assertEquals("name", b.getName()) + self.assertEquals("name", b.name) class ExtendJavaTest(unittest.TestCase): def test_override_tostring(self): @@ -159,6 +166,36 @@ except TypeError: pass + def test_multilevel_override(self): + class SubDate(Date): + def toString(self): + s = Date.toString(self) + return 'SubDate -> Date' + + class SubSubDate(SubDate): + def toString(self): + return 'SubSubDate -> ' + SubDate.toString(self) + self.assertEquals("SubDate -> Date", SubDate().toString()) + self.assertEquals("SubSubDate -> SubDate -> Date", SubSubDate().toString()) + + def test_passthrough(self): + class CallbackPassthrough(Callbacker.Callback): + def __init__(self, worker): + self.worker = worker + + def __getattribute__(self, name): + if name == 'call': + return getattr(self.worker, name) + return object.__getattribute__(self, name) + + collector = Callbacker.CollectingCallback() + c = CallbackPassthrough(collector) + Callbacker.callNoArg(c) + self.assertEquals("call()", collector.calls[0]) + c.call(7) + self.assertEquals("call(7)", collector.calls[1]) + + class SysIntegrationTest(unittest.TestCase): def setUp(self): self.orig_stdout = sys.stdout @@ -204,16 +241,13 @@ class IOTest(unittest.TestCase): def test_io_errors(self): "Check that IOException isn't mangled into an IOError" - from java.io import UnsupportedEncodingException self.assertRaises(UnsupportedEncodingException, OutputStreamWriter, System.out, "garbage") self.assertRaises(IOError, OutputStreamWriter, System.out, "garbage") def test_fileio_error(self): - from java.io import FileInputStream, FileNotFoundException self.assertRaises(FileNotFoundException, FileInputStream, "garbage") def test_unsupported_tell(self): - from org.python.core.util import FileUtil fp = FileUtil.wrap(System.out) self.assertRaises(IOError, fp.tell) @@ -436,10 +470,8 @@ self.assertEquals(expectedClass, model.getColumnClass(i)) class BigDecimalTest(unittest.TestCase): - def test_coerced_bigdecimal(self): from javatests import BigDecimalTest - x = BigDecimal("123.4321") y = BigDecimalTest().asBigDecimal() @@ -449,8 +481,6 @@ class MethodInvTest(unittest.TestCase): def test_method_invokation(self): - from javatests import MethodInvokationTest - bar = MethodInvokationTest.foo1(Byte(10)) self.assertEquals(bar, "foo1 with byte arg: 10", "Wrong method called") @@ -458,7 +488,6 @@ class InterfaceTest(unittest.TestCase): def test_override(self): - from java.lang import String class Foo(Runnable): def run(self): pass def toString(self): return "Foo!!!" @@ -469,7 +498,6 @@ self.assertEquals(s, "Foo!!!", "toString not overridden in interface") def test_java_calling_python_interface_implementation(self): - from org.python.tests import Callbacker called = [] class PyCallback(Callbacker.Callback): def call(self, extraarg=None): Deleted: trunk/jython/bugtests/test278.py =================================================================== --- trunk/jython/bugtests/test278.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test278.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,17 +0,0 @@ - - -""" - -""" - -import support - -support.compileJava("test278p/bug.java", classpath=".") - -from test278p import bug -b=bug() -assert b.getName() == "name" -assert b.name== "name" - - -#raise support.TestError("" + `x`) Deleted: trunk/jython/bugtests/test280.py =================================================================== --- trunk/jython/bugtests/test280.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test280.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,12 +0,0 @@ -""" - -""" - -import support - -try: - import test280c -except UnboundLocalError: - pass -else: - raise support.TestError("Should raise UnboundLocalError") Deleted: trunk/jython/bugtests/test280c.py =================================================================== --- trunk/jython/bugtests/test280c.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test280c.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,6 +0,0 @@ - -x = 1 -def f(): - print x - x = 2 -f() \ No newline at end of file Deleted: trunk/jython/bugtests/test281.py =================================================================== --- trunk/jython/bugtests/test281.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test281.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,10 +0,0 @@ -""" - -""" - -import support - -support.compileJPythonc("test281c.py", core=1, jar="test281c.jar", output="test281.err") -support.runJava("test281c", classpath="test281c.jar") - -#raise support.TestError("" + `x`) Deleted: trunk/jython/bugtests/test281c.py =================================================================== --- trunk/jython/bugtests/test281c.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test281c.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,16 +0,0 @@ -""" - -""" - -import support - - -if __name__ == "__main__": - try: - raise "me" - except: - pass - else: - raise support.TestError("Should not happen") - - Deleted: trunk/jython/bugtests/test282.py =================================================================== --- trunk/jython/bugtests/test282.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test282.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,16 +0,0 @@ -""" - -""" - -import support - -class A: - def __getitem__(self, key): - raise IndexError, "hello" - -try: - A()['b'] -except IndexError: - pass -else: - raise support.TestError("Should raise IndexError") Deleted: trunk/jython/bugtests/test284.py =================================================================== --- trunk/jython/bugtests/test284.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test284.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,12 +0,0 @@ - -import support - -support.compileJava("test284j2.java", classpath=".") - -import test284j1 - -assert test284j1().foo() == 'test284j1.foo' - -import test284j2 - -assert test284j2().foo() == 'test284j2.foo' Deleted: trunk/jython/bugtests/test284j1.java =================================================================== --- trunk/jython/bugtests/test284j1.java 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test284j1.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,6 +0,0 @@ - -public class test284j1 { - public String foo() { - return "test284j1.foo"; - } -} \ No newline at end of file Deleted: trunk/jython/bugtests/test284j2.java =================================================================== --- trunk/jython/bugtests/test284j2.java 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test284j2.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,6 +0,0 @@ - -public class test284j2 extends test284j1 { - public String foo() { - return "test284j2.foo"; - } -} \ No newline at end of file Deleted: trunk/jython/bugtests/test285.py =================================================================== --- trunk/jython/bugtests/test285.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test285.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,17 +0,0 @@ -""" -Test multilevel overriding of java methods. -""" - -from java.util import Date - -class SubDate(Date): - def toString(self): - s = Date.toString(self) - return 'SubDate -> Date' - -class SubSubDate(SubDate): - def toString(self): - return 'SubSubDate -> ' + SubDate.toString(self) - -assert SubDate().toString() == 'SubDate -> Date' -assert SubSubDate().toString() == 'SubSubDate -> SubDate -> Date' Deleted: trunk/jython/bugtests/test286.py =================================================================== --- trunk/jython/bugtests/test286.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test286.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,8 +0,0 @@ -""" - -""" - -import support - -support.compileJPythonc("test286c.py", output="test286.err") -support.runJava("test286c", classpath="jpywork") Deleted: trunk/jython/bugtests/test286c.py =================================================================== --- trunk/jython/bugtests/test286c.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test286c.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,17 +0,0 @@ -""" -Test multilevel overriding of java methods in jythonc. -""" - -from java.util import Date - -class SubDate(Date): - def toString(self): - s = Date.toString(self) - return 'SubDate -> Date' - -class SubSubDate(SubDate): - def toString(self): - return 'SubSubDate -> ' + SubDate.toString(self) - -assert SubDate().toString() == 'SubDate -> Date' -assert SubSubDate().toString() == 'SubSubDate -> SubDate -> Date' Deleted: trunk/jython/bugtests/test287.py =================================================================== --- trunk/jython/bugtests/test287.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test287.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,22 +0,0 @@ -""" - -""" - -import support - -raise support.TestWarning("mixing base classes between Jython and Java is not supported") - -import java.util -import org.python.core -class LX(org.python.core.PyList,java.util.List): - pass - -l = LX() - -try: - l.add('x') -except AttributeError: - pass -else: - raise support.TestError("expected an AttributeError") - Deleted: trunk/jython/bugtests/test288.py =================================================================== --- trunk/jython/bugtests/test288.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test288.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,46 +0,0 @@ -""" - -""" - -import support - -support.compileJava("classes/test288j.java") - -import test288j, test288i - - -class t: - def __init__(self, s): - self.s = s - - def __getattr__(self, name): - return getattr(self.s, name) - -class u(test288i): - def __init__(self, s): - self.s = s - - def get(self, i=None): - if i: - return self.s.get(i) - else: - return self.s.get() - -class v(test288i): - def __init__(self, s): - self.s = s - - def __getattr__(self, name): - return getattr(self.s, name) - -def main(): - y = v(test288j()) - y.get() - y.get(2) - y.get() - y.get(0) - -if __name__ == '__main__': - main() - -#raise support.TestError("" + `x`) Deleted: trunk/jython/bugtests/test289.py =================================================================== --- trunk/jython/bugtests/test289.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test289.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,10 +0,0 @@ -""" - -""" - -import support - -support.compileJava("classes/test288j.java") - -support.compileJPythonc("test289c.py", output="test289.err") -support.runJava("test289c", classpath="jpywork", pass_jython_home=1) Deleted: trunk/jython/bugtests/test289c.py =================================================================== --- trunk/jython/bugtests/test289c.py 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/bugtests/test289c.py 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,45 +0,0 @@ -""" - -""" - -import support - - -import test288j, test288i - - -class t: - def __init__(self, s): - self.s = s - - def __getattr__(self, name): - return getattr(self.s, name) - -class u(test288i): - def __init__(self, s): - self.s = s - - def get(self, i=None): - if i: - return self.s.get(i) - else: - return self.s.get() - -class v(test288i): - def __init__(self, s): - self.s = s - - def __getattr__(self, name): - return getattr(self.s, name) - -def main(): - y = v(test288j()) - y.get() - y.get(2) - y.get() - y.get(0) - -if __name__ == '__main__': - main() - -#raise support.TestError("" + `x`) Modified: trunk/jython/src/org/python/compiler/ProxyMaker.java =================================================================== --- trunk/jython/src/org/python/compiler/ProxyMaker.java 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/src/org/python/compiler/ProxyMaker.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -12,9 +12,10 @@ import java.util.Set; import org.python.core.Py; -import org.python.core.PyJavaType; +import org.python.core.PyMethod; import org.python.core.PyObject; import org.python.core.PyProxy; +import org.python.core.PyReflectedFunction; import org.python.objectweb.asm.Label; import org.python.objectweb.asm.Opcodes; import org.python.util.Generic; @@ -66,22 +67,21 @@ proxy.__initProxy__(new Object[0]); o = proxy._getPyInstance(); } - PyObject ret = null; - if (o.getDict() != null) { - ret = o.getDict().__finditem__(name); - } - if (ret == null) { - PyObject[] definedOn = new PyObject[1]; - PyObject typeDefined = o.getType().lookup_where(name, definedOn); - if (!(definedOn[0] instanceof PyJavaType)) { - ret = typeDefined; + PyObject ret = o.__findattr__(name); + if (ret instanceof PyMethod) { + PyMethod meth = ((PyMethod)ret); + if (meth.im_func instanceof PyReflectedFunction) { + PyReflectedFunction func = (PyReflectedFunction)meth.im_func; + if (func.nargs > 0 && proxy.getClass() == func.argslist[0].declaringClass) { + // This function is the default return for the proxy type if the Python instance + // hasn't returned something of its own from __findattr__, so do the standard + // Java call on this + return null; + } } } - if (ret == null) { - return null; - } Py.setSystemState(proxy._getPySystemState()); - return ret.__get__(o, null); + return ret; } Class<?> superclass; Modified: trunk/jython/src/org/python/core/PyReflectedFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyReflectedFunction.java 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/src/org/python/core/PyReflectedFunction.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -145,22 +145,31 @@ public PyObject __call__(PyObject self, PyObject[] args, String[] keywords) { ReflectedCallData callData = new ReflectedCallData(); - Object method = null; - ReflectedArgs[] argsl = argslist; - int n = nargs; - for (int i = 0; i < n; i++) { - ReflectedArgs rargs = argsl[i]; + ReflectedArgs match = null; + for (int i = 0; i < nargs && match == null; i++) { // System.err.println(rargs.toString()); - if (rargs.matches(self, args, keywords, callData)) { - method = rargs.data; - break; + if (argslist[i].matches(self, args, keywords, callData)) { + match = argslist[i]; } } - if (method == null) { + if (match == null) { throwError(callData.errArg, args.length, self != null, keywords.length != 0); } Object cself = callData.self; - Method m = (Method)method; + Method m = (Method)match.data; + + // If this is a direct call to a Java class instance method with a PyProxy instance as the + // arg, use the super__ version to actually route this through the method on the class. + if (self == null && cself != null && cself instanceof PyProxy + && !__name__.startsWith("super__") + && match.declaringClass != cself.getClass()) { + String mname = ("super__" + __name__); + try { + m = cself.getClass().getMethod(mname, m.getParameterTypes()); + } catch (Exception e) { + throw Py.JavaError(e); + } + } Object o; try { o = m.invoke(cself, callData.getArgsArray()); @@ -247,7 +256,7 @@ } } - private static String niceName(Class arg) { + private static String niceName(Class<?> arg) { if (arg == String.class || arg == PyString.class) { return "String"; } @@ -260,11 +269,10 @@ protected void throwBadArgError(int errArg, int nArgs, boolean self) { Set<Class<?>> argTypes = Generic.set(); for (int i = 0; i < nargs; i++) { - // if (!args.isStatic && !self) { len = len-1; } // This check works almost all the time. - // I'm still a little worried about non-static methods - // called with an explict self... - if (argslist[i].args.length == nArgs) { + // I'm still a little worried about non-static methods called with an explicit self... + if (argslist[i].args.length == nArgs || + (!argslist[i].isStatic && !self && argslist[i].args.length == nArgs - 1)) { if (errArg == ReflectedCallData.UNABLE_TO_CONVERT_SELF) { argTypes.add(argslist[i].declaringClass); } else { Modified: trunk/jython/src/org/python/core/ReflectedArgs.java =================================================================== --- trunk/jython/src/org/python/core/ReflectedArgs.java 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/src/org/python/core/ReflectedArgs.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,7 +1,7 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; -class ReflectedArgs { +public class ReflectedArgs { public Class[] args; public Object data; @@ -258,10 +258,9 @@ } public String toString() { - String s = "" + this.declaringClass + ", " + this.isStatic + ", " + this.flags + ", " - + this.data + "\n"; + String s = declaringClass + ", " + isStatic + ", " + flags + ", " + data + "\n"; s = s + "\t("; - for (Class arg : this.args) { + for (Class<?> arg : args) { s += arg.getName() + ", "; } s += ")"; Added: trunk/jython/tests/java/org/python/tests/BeanImplementation.java =================================================================== --- trunk/jython/tests/java/org/python/tests/BeanImplementation.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/BeanImplementation.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -0,0 +1,9 @@ +package org.python.tests; + + +public class BeanImplementation implements BeanInterface { + + public String getName() { + return "name"; + } +} Added: trunk/jython/tests/java/org/python/tests/BeanInterface.java =================================================================== --- trunk/jython/tests/java/org/python/tests/BeanInterface.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/BeanInterface.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -0,0 +1,6 @@ +package org.python.tests; + + +public interface BeanInterface { + String getName(); +} Modified: trunk/jython/tests/java/org/python/tests/Callbacker.java =================================================================== --- trunk/jython/tests/java/org/python/tests/Callbacker.java 2009-01-04 05:48:09 UTC (rev 5838) +++ trunk/jython/tests/java/org/python/tests/Callbacker.java 2009-01-04 08:41:16 UTC (rev 5839) @@ -1,5 +1,9 @@ package org.python.tests; +import java.util.List; + +import org.python.util.Generic; + public class Callbacker { public interface Callback { @@ -9,6 +13,19 @@ public void call(long oneArg); } + public static class CollectingCallback implements Callback { + + public List<String> calls = Generic.list(); + + public void call() { + calls.add("call()"); + } + + public void call(long oneArg) { + calls.add("call(" + oneArg + ")"); + } + } + public static void callNoArg(Callback c) { c.call(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |