jpype-project / jpype

JPype is cross language bridge to allow Python programs full access to Java class libraries.
http://www.jpype.org
Apache License 2.0
1.12k stars 183 forks source link

robustness of org.jpype.javadoc.JavadocExtractor? #1213

Open froh opened 2 months ago

froh commented 2 months ago

Hi,

I'm generating .py stubs for jpype itself, using mypy stubgen, like so:

import jpype
jpype.startJVM()
from mypy import stubgen
options = stubgen.parse_options("--inspect-mode --include-private --verbose -m _jpype".split())
stubgen.generate_stubs(options)

this tries to getattr(cls, "__doc__", None) where cls is <java class '_jpype._JArrayPrimitive'>:

> ...VENV/lib/python3.12/site-packages/mypy/stubgenc.py:784, in InspectionStubGenerator.generate_class_stub(self, class_name, cls, output)
    781 self.record_name(class_name)
    782 self.indent()
--> 784 class_info = ClassInfo(class_name, "", getattr(cls, "__doc__", None), cls)
    786 for attr, value in items:
    787     # use unevaluated descriptors when dealing with property inspection
    788     raw_value = raw_lookup.get(attr, value)

which, through an intricate c++ and java stack, then fails glamorously in _jclassDoc(cls), like so:

> ....VENV/lib/python3.12/site-packages/jpype/_jclass.py(166)_jclassDoc()
    164     if not hasattr(cls, "__javadoc__"):
    165         jde = JClass("org.jpype.javadoc.JavadocExtractor")()
--> 166         jd = jde.getDocumentation(cls)
    167         if jd is not None:
    168             setattr(cls, "__javadoc__", jd)
TypeError: No matching overloads found for org.jpype.javadoc.JavadocExtractor.getDocumentation(_jpype._JClass), options are:
        public static org.jpype.javadoc.Javadoc org.jpype.javadoc.JavadocExtractor.getDocumentation(java.lang.Class)

staring at the code I think the magic getattr(cls, '__doc__', None) should fail more gracefully, like, just return None, if there is neither python __doc__ nor _Java javadoc are available,

the stub generation also fails in the same way for these modules:

-m MODULE stubgen param cls failing getattr(cls, 'doc', None)
-m _jpype <java class '_jpype._JArrayPrimitive'>
-m jpype._jclass <java class 'JInterface'>
-m jpype._jexception <java class 'JException'>
-m jpype._jarray <java class 'JArray'>

please advise :-)

PS: an additional argument --ignore-errors leads to quite some useful output already, so this already gets some nice output:

import jpype
jpype.startJVM()
from mypy import stubgen
options = stubgen.parse_options("--inspect-mode --include-private --include-doc --verbose --ignore-errors -p jpype -p _jpype".split())
stubgen.generate_stubs(options)

requirements.txt:

jpype1
mypy