Currently a POC to demonstrate the feasibility of generating type hints from Java classes to be used by MyPy and other Python type checkers.
Next steps:
-
Add support for generics from the full type signature of the method, instead of using Any (especially noticeable for container types like
HashMap
below). -
Callable
, etc, take parameters. Get these out of Java. -
Union constructor/method overloading as used by Java so that only one
__init__
method, etc is generated -
Test against MyPy 2.7 support
-
Test against Jython 3.x code (necessary for full support of Python type functionality). Obviously this would be be best with a working Jython 3.x implemengtation, however since such code is, with a couple of exceptions, always legal Python 3.x code, this can be done using MyPy's existing static analysis support.
-
Obvious engineering improvements, again this is currently just a quick POC to show feasibility!
To run, you need to ensure the ASM 7.2 library jar is on your
CLASSPATH; this can also be readily done if you are using a dev build of
Jython, which doesn't move the org.objectweb.asm
namespace into org.python
.
Example:
$ jython jstubgen-poc.py java.util.HashMap
class HashMap(java.util.AbstractMap, java.util.Map, java.lang.Cloneable, java.io.Serializable):
def __init__(self, initialCapacity: int, loadFactor: float) -> None: ...
def __init__(self, initialCapacity: int) -> None: ...
def __init__(self) -> None: ...
def __init__(self, m: Map) -> None: ...
def size(self) -> int: ...
def isEmpty(self) -> bool: ...
def get(self, key: Any) -> Any: ...
def containsKey(self, key: Any) -> bool: ...
def put(self, key: Any, value: Any) -> Any: ...
def putAll(self, m: Map) -> None: ...
def remove(self, key: Any) -> Any: ...
def clear(self) -> None: ...
def containsValue(self, value: Any) -> bool: ...
def keySet(self) -> Set: ...
def values(self) -> Collection: ...
def entrySet(self) -> Set: ...
def getOrDefault(self, key: Any, defaultValue: Any) -> Any: ...
def putIfAbsent(self, key: Any, value: Any) -> Any: ...
def remove(self, key: Any, value: Any) -> bool: ...
def replace(self, key: Any, oldValue: Any, newValue: Any) -> bool: ...
def replace(self, key: Any, value: Any) -> Any: ...
def computeIfAbsent(self, key: Any, mappingFunction: Callable) -> Any: ...
def computeIfPresent(self, key: Any, remappingFunction: Callable) -> Any: ...
def compute(self, key: Any, remappingFunction: Callable) -> Any: ...
def merge(self, key: Any, value: Any, remappingFunction: Callable) -> Any: ...
def forEach(self, action: Callable) -> None: ...
def replaceAll(self, function: Callable) -> None: ...
def clone(self) -> Any: ...