gciatto / dummy-kt-jpype

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dummy project for assessing Kotlin-Python interoperability via JPype

Problem (Hypothesis)

Kotlin-generated nested anonymous objects do not work as expected.

Consider the following Java code creating a lazy int range generator

package dummy.kt.jpype;

import java.util.Iterator;

public class IterablesJava {
    public static Iterable<Integer> intRange(int min, int max) {
        return new Iterable<Integer>() {
            @Override
            public Iterator<Integer> iterator() {
                return new Iterator<Integer>() {
                    private int x = min;

                    @Override
                    public boolean hasNext() {
                        return x < max;
                    }

                    @Override
                    public Integer next() {
                        return x++;
                    }
                };
            }
        };
    }
}

and its Kotlin equivalent:

// file named Iterables.kt => Java class is named IterablesKt
package dummy.kt.jpype

fun intRange(min: Int, max: Int): Iterable<Int> =
    object : Iterable<Int> {
        override fun iterator(): Iterator<Int> =
            object : Iterator<Int> {
                private var x = min

                override fun hasNext(): Boolean = x < max

                override fun next(): Int = x++
            }
    }

Then, the following Python script using both intRange methods from Python:

import jpype
import jpype.imports

import jpype
import jpype.imports

# starting jvm

from dummy.kt.jpype import IterablesJava, IterablesKt

iterable = IterablesJava.intRange(1, 10) # works (calling the Java version)
iterator = iterable.iterator() # works
print(iterator.next()) # 1

iterable = IterablesKt.intRange(1, 10) # works (calling the Python version)
iterator = iterable.iterator() # AttributeError: 'java.lang.Object$Anonymous' object has no attribute 'iterator'
print(iterator.next()) # not executed

fails when executing the Kotlin version of intRange.

By inspecting the code, I'd say that JPype is struggling in correctly managing nested anonymous objects when the corresponding code is generated by Kotlin.

By inspecting the bytecode, I also note that the object returned by iterable.iterator() should not be of type java.lang.Object$Anonymous -- as reported by the exception message --, but rather IterablesKt$intRange$1$iterator$1 (I guess).

How to reproduce

  1. Re-compile the JVM code by ./gradlew shadowJar

    • This should create a fat jar containing both the Java- and Kotlin-based implementations of intRange in build/libs
      • First run make take a while since Gradle and dependencies should be downloaded
  2. Restore Python dependencies via pip install -r requirements.txt

  3. Run the main.py script via python main.py

About


Languages

Language:Kotlin 64.0%Language:Java 20.3%Language:Python 15.7%