From 2294c2d514b642339de811d6616da7bbf3a9262e Mon Sep 17 00:00:00 2001 From: Craig Macdonald Date: Tue, 21 Apr 2020 21:04:56 +0100 Subject: [PATCH] remove "holds"; more test cases; detect lambda in signature scoring --- jnius/jnius_conversion.pxi | 8 ++------ jnius/jnius_export_class.pxi | 5 +---- jnius/jnius_utils.pxi | 5 +++++ tests/test_lambdas.py | 31 +++++++++++++++++++++++++++++-- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/jnius/jnius_conversion.pxi b/jnius/jnius_conversion.pxi index 5919209..09b5f42 100644 --- a/jnius/jnius_conversion.pxi +++ b/jnius/jnius_conversion.pxi @@ -29,14 +29,13 @@ cdef void release_args(JNIEnv *j_env, tuple definition_args, jvalue *j_args, arg pass j_env[0].DeleteLocalRef(j_env, j_args[index].l) -cdef list populate_args(JNIEnv *j_env, tuple definition_args, jvalue *j_args, args): +cdef void populate_args(JNIEnv *j_env, tuple definition_args, jvalue *j_args, args): # do the conversion from a Python object to Java from a Java definition cdef JavaClassStorage jcs cdef JavaObject jo cdef JavaClass jc cdef PythonJavaClass pc cdef int index - holds=[] for index, argtype in enumerate(definition_args): py_arg = args[index] @@ -108,13 +107,11 @@ cdef list populate_args(JNIEnv *j_env, tuple definition_args, jvalue *j_args, ar j_args[index].l = convert_pyarray_to_java(j_env, argtype, py_arg) # lambda or function - elif callable(py_arg) and argtype == "Ljava/util/function/Function;": + elif callable(py_arg): # we need to make a java object in python py_arg = convert_python_callable_to_jobject(argtype, py_arg) - # we need to keep that python object around - holds.append(py_arg) # TODO: this line should not be needed to prevent py_arg from being GCd activeLambdaJavaProxies.add(py_arg) @@ -154,7 +151,6 @@ cdef list populate_args(JNIEnv *j_env, tuple definition_args, jvalue *j_args, ar '{0!r}'.format(py_arg)) j_args[index].l = convert_pyarray_to_java( j_env, argtype[1:], py_arg) - return holds cdef convert_jobject_to_python(JNIEnv *j_env, definition, jobject j_object): diff --git a/jnius/jnius_export_class.pxi b/jnius/jnius_export_class.pxi index e13aa4c..8cd87fc 100644 --- a/jnius/jnius_export_class.pxi +++ b/jnius/jnius_export_class.pxi @@ -850,14 +850,11 @@ cdef class JavaMethod(object): try: # convert python argument if necessary - # holds is a list of objects that need to be kept around for - # the lifetime of the call - holds = None if len(args): j_args = malloc(sizeof(jvalue) * d_args_len) if j_args == NULL: raise MemoryError('Unable to allocate memory for java args') - holds = populate_args(j_env, self.definition_args, j_args, args) + populate_args(j_env, self.definition_args, j_args, args) try: # do the call diff --git a/jnius/jnius_utils.pxi b/jnius/jnius_utils.pxi index 55cbc25..09a4bb0 100644 --- a/jnius/jnius_utils.pxi +++ b/jnius/jnius_utils.pxi @@ -360,6 +360,11 @@ cdef int calculate_score(sign_args, args, is_varargs=False) except *: score += 1 continue + # its a function or lambda, we can pass that as an object + if callable(arg): + score += 1 + continue + # native type? not accepted return -1 diff --git a/tests/test_lambdas.py b/tests/test_lambdas.py index d2eecd3..1a1da61 100644 --- a/tests/test_lambdas.py +++ b/tests/test_lambdas.py @@ -4,14 +4,34 @@ from jnius import autoclass, JavaException class TestLambdas(unittest.TestCase): + def testCallable(self): + callFn = lambda: "done" + executor = autoclass("java.util.concurrent.Executors").newFixedThreadPool(1) + future = executor.submit(callFn) + print(type(future)) + self.assertEqual("done", future.get()) + executor.shutdownNow() + + def testComparator(self): + numbers = autoclass('java.util.ArrayList')() + Collections = autoclass('java.util.Collections') + numbers.add(1) + numbers.add(3) + revSort = lambda i, j: j - i + Collections.sort(numbers, revSort) + self.assertEqual(numbers[0], 3) + self.assertEqual(numbers[1], 1) + def testJavaUtilFunction(self): - Arrays = autoclass("java.util.Arrays") Collectors = autoclass("java.util.stream.Collectors") - #J: List numbers = Arrays.asList(1, 2, 3); numbers = autoclass('java.util.ArrayList')() numbers.add(1) numbers.add(2) numbers.add(3) + + def squareFn(i): + return i * i + #J: List squares = numbers.stream().map( i -> i*i).collect(Collectors.toList()); squares = numbers.stream().map(lambda i : i * i).collect(Collectors.toList()) @@ -20,6 +40,13 @@ class TestLambdas(unittest.TestCase): self.assertEqual(squares[0], 1) self.assertEqual(squares[1], 4) self.assertEqual(squares[2], 9) + + squares = numbers.stream().map(squareFn).collect(Collectors.toList()) + + self.assertEqual(len(squares), len(numbers)) + self.assertEqual(squares[0], 1) + self.assertEqual(squares[1], 4) + self.assertEqual(squares[2], 9) if __name__ == '__main__':