-
-
Notifications
You must be signed in to change notification settings - Fork 508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jedi does not fetch annotations for dynamically generated class methods on JPype #1347
Comments
Looking deeper it appears the my methods are not triggering PEP0484 anywhere. Thus my attempts to supply |
I just did a new release. However How do your annotations typically look like? |
Thanks for the reply. The system is currently pretty simple. I have implemented a property on my methods (PyJPMethod) that calls a short piece of Python code the first time which uses Java reflection to create a dictionary. The dictionary currently just contains
It would be hard to make that into a string though as the dynamic class does not have any presence in Python as far as a path. It may live inside in multiple JVMs in which case there may be many instances with the same name (one for each JVM). It will always be a regular Python class with a standard The descriptors are sufficient to pass functionlike for the purposes of inspect. Thus I can provide an alternative API if required. The ideal API would be to call Relevant sections of code for This code shows the properties that are generated for the Java method.
Here is the code that generates the
The class also returns a docstring, but it is napolean style with customizations for Java. Having multiple overloads strung onto one class is really not something Python documentation can do, so I had to improvise to make it possible for it to get render in autodoc. I attempted to get jedi to pick it up by adding my classes to the safe list for probing in jedi.extension.compiled. The docstring was parsed, but there is nothing for it as the return type is bogus and the style is not supported. Jedi didn't look call Here is a short example to help make it more clear.
Gives...
|
Today's your lucky day :) I quickly fixed it. It doesn't work for the 3.8 case, where I'm not even sure how to do that anyway, but your case should work. Please test and have fun! |
Thanks for the quick turnaround. I assume that I need to add these lines to my module to activate it.
Or is there a different mechanism required? |
I guess, yes :) It is a known problem. #1299 will be the ticket to probably do something like |
I am not sure that one would want to force allowing unsafe gettr everywhere. This solution would have the downside that since other packages such as IPython are deciding how to call Script, the problem would propagate to having to contact every maintainer and ask them to enable an unsafe option to use my module. My types are derived from the python types thus they pass
as opposed to something like
Barring the serious meta programming I am doing, there aren't too many compiled objects that would be trying to derive from Python base types. And anyone doing that is likely trying to pretend to be safe. |
Yes it was intentional. The only way this is safe is if you actually check the exact types. I think it was ok to catch your case as "insecure".
That's true, but they could also offer this as configuration. That's at least what people want (AFAIK). Or we could create a |
I am just worried about that case of having to document 8 different ways to set up the tab completion on IPython, PyCharm, Spyder, vim, Jupyter, Bob's Discount Python Front, etc... It would be a nightmare given I don't use all those packages (with the exception of Bob's). Things like If the user wants to use a module like JPype that is adding new basic types via extension, and the documentation says "this will configure Jedi to accept Java types as Python native which is potentially unsafe. YOU HAVE BEEN WARNED." then they likely have already consented to calling potentially unsafe things for those limited set of classes. But then as I am trying to be as safe as I can (while using Java), there isn't really any user code that should be on that path unless they monkey patch my internal classes at which point they really didn't want safety. Having a master switch called on jedi that activates all unsafe operations (including for things other than JPype) would seem like inviting even more errors as it would mean some untested third party class gets trusted. If you want, I can push the annotations to be pure caches, but that would be a performance hit as the annotations are only for use when editing. Alternatively I can force the user to import a module with the hacks ie. "import jpype.jedi" but I find not enough people actually read the docs for that to be very effective. I should also note that my tracing indicates that Jedi entered my code at least once on an untrusted class. Not one that I added to the trusted list, but something that I was emulating that ended up being accepted and called. It was the meta class for the created class types. |
I recently thought a lot about this stuff again and realized that it's probably pretty pointless to protect the user with these kind of measures. It is more of a safety thing. This means that subclasses of functions should be returned normally, but subclasses of properties should be "dealt" with. The way how we deal with properties now is different, see #1299. For Interpreter completions they just get executed, for Script calls not. I figured this is ok for now and I'll wait for feedback. Hope you are ok with this. I'm pretty sure your use cases will now be covered. |
Thanks for the info. I will check it out when I have the chance. |
I am attempting get tab completion to work for the JPype module under IPython. JPype is a bridge between Java and Python. As part of the process it generates dynamic classes and methods which have no presence in terms of a Python file. The classes and methods implement the relevant Python APIs such as
__doc__
and__annotations__
. But no matter what I do I just get garbage outputs. Tracing down through as best I can it appears that Jedi is trying to open the source files rather than calling inspect to get type hints or even asking for the__doc__
, in an effort to avoid calling Python code. The problem is there is absolutely no way to get type hints for dynamic classes produced by a CPython extension like JPype.Can you please point me to some documentation on how to inform Jedi where the type hints are located? Or perhaps give me a some way to mark my objects as being safe to probe?
The text was updated successfully, but these errors were encountered: