[Jython-checkins] jython: Enable mixing Python and Java types in the bases of a class when
jim.baker
jython-checkins at python.org
Fri Jan 10 05:08:23 CET 2014
http://hg.python.org/jython/rev/b4ae9e2893c8
changeset: 7175:b4ae9e2893c8
user: Jim Baker <jim.baker at rackspace.com>
date: Thu Jan 09 21:08:56 2014 -0700
summary:
Enable mixing Python and Java types in the bases of a class when
using a metaclass.
files:
Lib/test/test_java_subclasses.py | 46 +++++++++++++++++++-
src/org/python/core/PyType.java | 12 +++++
2 files changed, 57 insertions(+), 1 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
@@ -8,6 +8,7 @@
from java.lang import (Boolean, Class, ClassLoader, Comparable,Integer, Object, Runnable, String,
Thread, ThreadGroup)
from java.util import Date, Hashtable, Vector
+from java.util.concurrent import Callable, Executors
from java.awt import Color, Component, Dimension, Rectangle
from javax.swing import ComboBoxModel, ListModel
@@ -331,13 +332,56 @@
self.assertEquals(len(called), 1)
+class MetaClass(type):
+ def __new__(meta, name, bases, d):
+
+ # Insert the method to be called from Java
+ def call(self):
+ return self.x
+
+ d["call"] = call
+ d["foo"] = 99
+ return super(MetaClass, meta).__new__(meta, name, bases, d)
+
+
+class MetaBase(object):
+ __metaclass__ = MetaClass
+
+
+class MetaClassTest(unittest.TestCase):
+
+ def test_java_with_metaclass_base(self):
+ """Java classes can be mixed with Python bases using metaclasses"""
+
+ # Permute mixin order
+ class Bar(MetaBase, Callable):
+ def __init__(self, x):
+ self.x = x
+
+ class Baz(Callable, MetaBase):
+ def __init__(self, x):
+ self.x = x
+
+ # Go through {bar|baz}.call indirectly through a Java path,
+ # just to ensure this mixin provided by the metaclass is available
+ pool = Executors.newSingleThreadExecutor()
+ bar = Bar(42)
+ self.assertEqual(bar.foo, 99)
+ self.assertEqual(42, pool.submit(bar).get())
+ baz = Baz(47)
+ self.assertEqual(baz.foo, 99)
+ self.assertEqual(47, pool.submit(baz).get())
+ pool.shutdown()
+
+
def test_main():
test_support.run_unittest(InterfaceTest,
TableModelTest,
AutoSuperTest,
PythonSubclassesTest,
AbstractOnSyspathTest,
- ContextClassloaderTest)
+ ContextClassloaderTest,
+ MetaClassTest)
if __name__ == '__main__':
diff --git a/src/org/python/core/PyType.java b/src/org/python/core/PyType.java
--- a/src/org/python/core/PyType.java
+++ b/src/org/python/core/PyType.java
@@ -1119,6 +1119,10 @@
return best;
}
+ private static boolean isJavaRootClass(PyType type) {
+ return type instanceof PyJavaType && type.fastGetName().equals("java.lang.Class");
+ }
+
/**
* Finds the most derived subtype of initialMetatype in the types
* of bases, or initialMetatype if it is already the most derived.
@@ -1130,11 +1134,19 @@
*/
private static PyType findMostDerivedMetatype(PyObject[] bases_list, PyType initialMetatype) {
PyType winner = initialMetatype;
+ if (isJavaRootClass(winner)) { // consider this root class to be equivalent to type
+ winner = PyType.TYPE;
+ }
+
for (PyObject base : bases_list) {
if (base instanceof PyClass) {
continue;
}
PyType curtype = base.getType();
+ if (isJavaRootClass(curtype)) {
+ curtype = PyType.TYPE;
+ }
+
if (winner.isSubType(curtype)) {
continue;
}
--
Repository URL: http://hg.python.org/jython
More information about the Jython-checkins
mailing list