Skip to content
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

Compiled methods are completed as 'builtins' #2031

Open
zerocewl opened this issue Nov 1, 2024 · 3 comments
Open

Compiled methods are completed as 'builtins' #2031

zerocewl opened this issue Nov 1, 2024 · 3 comments

Comments

@zerocewl
Copy link
Contributor

zerocewl commented Nov 1, 2024

First things first: Thx for creating and maintaining jedi!

I have an issue with completing compiled files, created with cython but only with methods / functions inside classes. If i try to complete these methods they are shown as builtins and not as function, in fact all infos like docstring are missing too.

To reproduce the issue i used a simple python class (the static function is only to show, that this one works):

class MyClass:

   def my_function(self):
      print('hello from function2')
   
   @staticmethod
   def my_function_static():
      print('hello from static function')

Following the simple hello world example from Cython i created the so file / compiled with

python setup.py build_ext --inplace

After this i tried to create the completion with the minimal changed jedi example:

import jedi
source='''
import helloworld
helloworld.MyClass().my_func'''
script = jedi.Script(source, path='example.py')
completions = script.complete(3, len('helloworld.MyClass().my_func'))

But the completion from the first entry returns module_nameas builtins.

I also create a small pytest to assert the completion, but only with the already created compiled file:

def test_jedi_class_completion():
    source='''
import helloworld
helloworld.MyClass().my_func'''
    script = jedi.Script(source, path='example.py')
    completions = script.complete(3, len('helloworld.MyClass().my_func'))
    assert completions[0].module_name == 'helloworld'
    assert completions[0].type == 'function'
    assert completions[0].description == 'def my_function'

I tried to debug inference/compiled and only found a very rough workaround by setting the is_get_descriptor in access.py#L335 to False. So maybe the return value from

attr, is_get_descriptor = getattr_static(self._obj, name) is not as expected for this case?

Here is a screenshot from the pytest, showing the wrong content for the completion.

image

Note: Static functions inside classes works as expected.

I used python 3.11.10 on arm mac (the issue is on windows reproducible too).

❯ pip list
Package    Version
---------- -------
Cython     3.0.11
jedi       0.19.1
parso      0.8.4
pip        24.2
setuptools 74.1.2
@davidhalter
Copy link
Owner

The problem is probably that the attribute on helloworld.MyClass.my_func' might just be an alias to abs or whatever builtin function. I'm not sure we have the information on the object (on classes we do). We could probably change the default there. But this is all highly complicated, because for a lot of these things we are talking about heuristics.

@zerocewl
Copy link
Contributor Author

zerocewl commented Nov 1, 2024

hm that sounds not very promising =)

There is no easy solution where we can adapt the criterion if the node is a class function? For other functions the completion is working fine...

I only found during debugging in getattr_static that at some point a __get__ is checked and found for the function, but i don't know why this should be the check.

@zerocewl
Copy link
Contributor Author

zerocewl commented Nov 4, 2024

Another nasty workaround could be the change of /jedi/inference/compiled/access.py#L354 by adding a check like type(attr).__name__ != "cython_function_or_method":

if is_get_descriptor and type(attr) not in ALLOWED_DESCRIPTOR_ACCESS and type(attr).__name__ != "cython_function_or_method":

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants