[Jython-checkins] jython: Detail why NotImplemented when calling abstract Java methods

jim.baker jython-checkins at python.org
Thu Oct 1 20:17:57 CEST 2015


https://hg.python.org/jython/rev/62f6901dc1ee
changeset:   7737:62f6901dc1ee
user:        Jim Baker <jim.baker at rackspace.com>
date:        Thu Oct 01 13:15:43 2015 -0500
summary:
  Detail why NotImplemented when calling abstract Java methods

Now provides the class of the object, the specific method that is
NotImplemented, and the Java class or interface that defines the
abstract method.

Example: NotImplementedError: 'ResponseMock' object does not implement
abstract method 'getStatus' from 'javax.servlet.http.HttpServletResponse'

Fixes http://bugs.jython.org/issue2407

files:
  Lib/test/test_java_subclasses.py              |   6 +++-
  src/org/python/compiler/ProxyCodeHelpers.java |  12 ++++++++++
  src/org/python/compiler/ProxyMaker.java       |  10 +++++---
  3 files changed, 22 insertions(+), 6 deletions(-)


diff --git a/Lib/test/test_java_subclasses.py b/Lib/test/test_java_subclasses.py
--- a/Lib/test/test_java_subclasses.py
+++ b/Lib/test/test_java_subclasses.py
@@ -404,7 +404,8 @@
         # 3.x
         c = C()
         self.assertEqual(c.size(), 47)
-        with self.assertRaisesRegexp(NotImplementedError, r"^$"):
+        msg = r"^'C' object does not implement abstract method 'get' from 'java.util.AbstractList'$"
+        with self.assertRaisesRegexp(NotImplementedError, msg):
             C().get(42)
 
     def test_concrete_method(self):
@@ -435,7 +436,8 @@
         class C(Callable):
             pass
         
-        with self.assertRaisesRegexp(NotImplementedError, r"^$"):
+        msg = r"^'C' object does not implement abstract method 'call' from 'java.util.concurrent.Callable'$"
+        with self.assertRaisesRegexp(NotImplementedError, msg):
             C().call()
 
 
diff --git a/src/org/python/compiler/ProxyCodeHelpers.java b/src/org/python/compiler/ProxyCodeHelpers.java
--- a/src/org/python/compiler/ProxyCodeHelpers.java
+++ b/src/org/python/compiler/ProxyCodeHelpers.java
@@ -8,6 +8,7 @@
 
 import org.objectweb.asm.Type;
 import org.python.core.Py;
+import org.python.core.PyException;
 import org.python.core.PyMethod;
 import org.python.core.PyObject;
 import org.python.core.PyProxy;
@@ -85,6 +86,17 @@
         return ret;
     }
 
+    public static PyException notImplementedAbstractMethod(
+            PyProxy proxy, String name, String superClass) {
+        PyObject o = proxy._getPyInstance();
+        String msg = String.format(
+                "'%.200s' object does not implement abstract method '%.200s' from '%.200s'",
+                o.getType().fastGetName(),
+                name,
+                superClass);
+        return Py.NotImplementedError(msg);
+    }
+
     public static String mapClass(Class<?> c) {
         String name = c.getName();
         int index = name.indexOf(".");
diff --git a/src/org/python/compiler/ProxyMaker.java b/src/org/python/compiler/ProxyMaker.java
--- a/src/org/python/compiler/ProxyMaker.java
+++ b/src/org/python/compiler/ProxyMaker.java
@@ -388,10 +388,12 @@
             code.pop();
 
             // throw an exception if we cannot load a Python method for this abstract method
-            // note that the unreachable return is simply to simplify bytecode gen
-            code.ldc("");
-            code.invokestatic(p(Py.class), "NotImplementedError",
-                    sig(PyException.class, String.class));
+            // note that the unreachable return is simply present to simplify bytecode gen
+            code.aload(0);
+            code.ldc(pyName);
+            code.ldc(declaringClass.getName());
+            code.invokestatic("org/python/compiler/ProxyCodeHelpers", "notImplementedAbstractMethod",
+                    makeSig($pyExc, $pyProxy, $str, $str));
             code.checkcast(p(Throwable.class));
             code.athrow();
 

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list