Skip to content

Commit

Permalink
Expose rich comparision methods on Java classes implementing Comparable
Browse files Browse the repository at this point in the history
  • Loading branch information
groves committed Jan 22, 2009
1 parent 3a577fa commit e42e8ff
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
38 changes: 36 additions & 2 deletions Lib/test/test_java_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

from test import test_support

from java.lang import (ExceptionInInitializerError, String, Runnable, System, Runtime, Math, Byte)
from java.lang import (ClassCastException, ExceptionInInitializerError, String, Runnable, System,
Runtime, Math, Byte)
from java.math import BigDecimal, BigInteger
from java.io import (FileInputStream, FileNotFoundException, FileOutputStream, FileWriter,
from java.io import (File, FileInputStream, FileNotFoundException, FileOutputStream, FileWriter,
OutputStreamWriter, UnsupportedEncodingException)
from java.util import ArrayList, Date, HashMap, Hashtable, StringTokenizer, Vector

Expand Down Expand Up @@ -350,6 +351,39 @@ class X(Runnable):
for i in v:
pass

def test_comparable_delegation(self):
first_file = File("a")
first_date = Date(100)
for a, b, c in [(first_file, File("b"), File("c")), (first_date, Date(1000), Date())]:
self.assertTrue(a.compareTo(b) < 0)
self.assertEquals(-1, cmp(a, b))
self.assertTrue(a.compareTo(c) < 0)
self.assertEquals(-1, cmp(a, c))
self.assertEquals(0, a.compareTo(a))
self.assertEquals(0, cmp(a, a))
self.assertTrue(b.compareTo(a) > 0)
self.assertEquals(1, cmp(b, a))
self.assertTrue(c.compareTo(b) > 0)
self.assertEquals(1, cmp(c, b))
self.assertTrue(a < b)
self.assertTrue(a <= a)
self.assertTrue(b > a)
self.assertTrue(c >= a)
self.assertTrue(a != b)
l = [b, c, a]
self.assertEquals(a, min(l))
self.assertEquals(c, max(l))
l.sort()
self.assertEquals([a, b, c], l)
# Check that we fall back to the default comparison(class name) instead of using compareTo
# on non-Comparable types
self.assertRaises(ClassCastException, first_file.compareTo, first_date)
self.assertEquals(-1, cmp(first_file, first_date))
self.assertTrue(first_file < first_date)
self.assertTrue(first_file <= first_date)
self.assertTrue(first_date > first_file)
self.assertTrue(first_date >= first_file)

class SecurityManagerTest(unittest.TestCase):
def test_nonexistent_import_with_security(self):
policy = test_support.findfile("python_home.policy")
Expand Down
53 changes: 53 additions & 0 deletions src/org/python/core/PyJavaType.java
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,14 @@ public PyObject __call__(PyObject o) {
return proxy.equals(oAsJava) ? Py.True : Py.False;
}
});
addMethod(new PyBuiltinMethodNarrow("__ne__", 1) {
@Override
public PyObject __call__(PyObject o) {
Object proxy = self.getJavaProxy();
Object oAsJava = o.__tojava__(proxy.getClass());
return !proxy.equals(oAsJava) ? Py.True : Py.False;
}
});
addMethod(new PyBuiltinMethodNarrow("__hash__") {
@Override
public PyObject __call__() {
Expand All @@ -415,6 +423,32 @@ public PyObject __call__() {
}
});
}
if(forClass == Comparable.class) {
addMethod(new ComparableMethod("__lt__", 1) {
@Override
protected boolean getResult(int comparison) {
return comparison < 0;
}
});
addMethod(new ComparableMethod("__le__", 1) {
@Override
protected boolean getResult(int comparison) {
return comparison <= 0;
}
});
addMethod(new ComparableMethod("__gt__", 1) {
@Override
protected boolean getResult(int comparison) {
return comparison > 0;
}
});
addMethod(new ComparableMethod("__ge__", 1) {
@Override
protected boolean getResult(int comparison) {
return comparison >= 0;
}
});
}
}

/**
Expand Down Expand Up @@ -559,6 +593,25 @@ protected Map<Object, Object> asMap(){
}
}

private static abstract class ComparableMethod extends PyBuiltinMethodNarrow {
protected ComparableMethod(String name, int numArgs) {
super(name, numArgs);
}
@Override
public PyObject __call__(PyObject arg) {
Object asjava = arg.__tojava__(Object.class);
int compare;
try {
compare = ((Comparable<Object>)self.getJavaProxy()).compareTo(asjava);
} catch(ClassCastException classCast) {
return Py.NotImplemented;
}
return getResult(compare) ? Py.True : Py.False;
}

protected abstract boolean getResult(int comparison);
}

private static Map<Class<?>, PyBuiltinMethod[]> getCollectionProxies() {
if (collectionProxies == null) {
collectionProxies = Generic.map();
Expand Down

0 comments on commit e42e8ff

Please sign in to comment.