jorgenschaefer / elpy

Emacs Python Development Environment
GNU General Public License v3.0
1.9k stars 262 forks source link

Auto-completion #1085

Open schatimo opened 7 years ago

schatimo commented 7 years ago

Hi Jorgen, thanks for providing elpy for emacs! I am currently dealing with the issue of using completion at point for an object. For instance, creating matrix = numpy.zeros((3,3)). Then I want to access the object matrix by typing matrix. - but then I do not get auto-completion in editing buffer. But when going for the Python shell in emacs, I get auto-completion (by hitting TAB). How can I get auto-completion work in editing buffer and not only in shell buffer?

Many thanks in advance! Timo

rbbernardino commented 7 years ago

Hello there!

I'm having exactly the same issue, it does auto-complete for packages and variables' identifiers, but it doesn't work for a "dot" after a variable.

However, if I type the first letter, it will work!! So @schatimo, as a workaround while we wait for an answer, just type the first letter of what you're looking for.


To clearly demonstrate the issue, if I do

import pandas as pd
ndata = pd.

Suggestions for pd. will pop up, as you can see here: ScreenShot of package dot completion

Now, if I do:

ndata = pd.read_csv("info-nabuco.csv")
ndata.

No completion will pop, nothing will happen. If I do company-complete it'll return "no completion found". As you can see here: ScreenShot of error

However, if I type at least the first letter of some elegible candidate, it'll complete perfectly! Check here: Object dot completion with one of more letter


I hope someone can give us some instructions on how to debug and find out what's wrong...


I've checked if the correct backend, elpy-company-backend (which is) and all the python packages installed (with elpy-setup, which is also fine).

Thank you very much for your attention! Best Regards, Rodrigo

gopar commented 7 years ago

Hey, have you guys tried looking into company-minimum-prefix-length? I have the following in my config

(setq company-minimum-prefix-length 1) ;;default is 3 I believe
rbbernardino commented 7 years ago

@gopar, that variable just set the minimum for automatic completion, if I call "company-complete" it will complete even with it set to 3 and only one character typed. Anyway, I tried and with no success...

jorgenschaefer commented 7 years ago

How can I get auto-completion work in editing buffer and not only in shell buffer?

The Python buffer actually has all the modules your code is using loaded and mapped to the names your code is using them as. This is somewhat inefficient and even dangerous to do in general (think if Elpy would automatically and constantly evaluate all your Python code all the time – not sensible!). Instead, the backends Elpy uses (Jedi and Rope) parse the Python and try to guess what the name might refer to. As Python is a highly dynamic language, this is not easy to get 100% correct. As such, Jedi and Rope go for a best effort approach. Which can fail. Especially for modules implemented in C, like most of numpy/scipy.

Nicholas-Autio-Mitchell commented 7 years ago

@jorgenschaefer - thank you for your explanation regarding when Elpy's autocomplete using Rope/Jedi can fail.

Does this mean, if I have imported a module (and so it is already loaded in the shell), then Elpy should be able to autcomplete for that module? I am facing a weird situation in which that does work for some packages, e.g. Numpy, and is not working for others, e.g. spaCy. Both of these libraries contain C code deep down, so I don't know what the problem is for spacy.

If I run the following:

import numpy as np
import spacy

np. <press-tab>

... I get the expected autocomplete options for Numpy. Now if I do the same for spacy:

spacy. <press-tab>

I get the message:

No completion found

If I try the same for spacy within the interpreter, I get the completions as expected. I have checked that spacy is indeed being loaded from the site-packages of the current interpreter and looked for any config within Elpy that might allow to specify this folder in the hope it nudges (in my case Jedi) in the right direction, without luck. I am assuming here, that the location is important (i.e. site-packages) and not where the package came from, e.g. conda-installed versus pip-installed.

Is this a known limitation? If so, what decides if it works for a package or not? A quick test for comparison in Microsoft's new Visual Studio Code on Linux does manage to get the auto-completions for spacy within the file, using the same python interpreter etc.

If there are any system vars or info I can provide to help, let me know :smile:

jorgenschaefer commented 7 years ago

Does this mean, if I have imported a module (and so it is already loaded in the shell), then Elpy should be able to autcomplete for that module?

Whether a module is loaded in the shell is irrelevant to whether Rope or Jedi can find completions inside of that module.

If so, what decides if it works for a package or not?

The algorithm used by Rope or Jedi decides whether it works or not. :-)

A quick test for comparison in Microsoft's new Visual Studio Code on Linux does manage to get the auto-completions for spacy within the file, using the same python interpreter etc.

Yeah, Microsoft Visual Studio Code does not use Jedi or Rope (at least to my knowledge), and Elpy does not use Microsoft Visual Studio Code. :-D

Nicholas-Autio-Mitchell commented 7 years ago

Haha :laughing: of course I know VS Code is something completely different... it just does a much better job out of the box than Jedi it seems.

Do you have any pointers (links to old posts) that will help configure Jedi with Elpy? I can't figure out why some modules are found and others not. Sometimes it works for a module and then it doesn't in a different file. All using the same environment though, so I can't figure out the cause of the inconsistency.

I am also getting the timeout message fairly often. Sometimes not though. I can only think that Jedi is not finding module installed in Python3, as it is based on Python2 (according to the config). It says in their documentation that this isn't important.

guilherme-salome commented 5 years ago

I may have the same problem. Autocompletion is failing with numpy, it can autocomplete numpy but not a numpy.ndarray instance (Cannot complete at point):

screen shot 2019-02-15 at 9 48 28 am

Another related issue: When using code-blocks in org-mode to write python (similar to jupyter notebook), the completion works in some cases, but is not persistent across multiple code blocks sharing the same session.

For example, if I write a code block, import pandas and create a new data frame, then auto completion works:

screenshot 2019-02-15 09 43 24

However, if I create a new code block (after executing the previous), sharing the same session, then autocompletion does not work anymore:

screen shot 2019-02-15 at 9 46 53 am
galaunay commented 5 years ago

Numpy completion

Elpy relies on jedi for completion. In the case you are describing, Jedi does not seem to be able to provide completion, as you can see here:

import jedi

source = """ import numpy as np
x = np.array([1, 2, 3])
x.
"""
script = jedi.Script(source, line=3, column=2)
print(script.completions())

Jedi should be able to manage such a simple script, you should report upstream to jedi.

Org-babel support

Unfortunately, there is no way for Elpy to know if there is other blocks in the same session. You may get what you want using poly-org but I am afraid it will not be perfect either...

kourosh2 commented 4 years ago

Hi,

I am having exact same problem as @schatimo and @Salompas; Tab autocomplete works for imported modules but not for instances. For example, autocomplete works for test = np.array(),

Screen Shot 2020-09-25 at 1 51 56 PM

But not for test. And if I do M-x Elpy-company-backend, I get “cannot complete at a point”.

Screen Shot 2020-09-25 at 1 53 36 PM

Has anyone have a solution/workaround for this?

Thanks, Kourosh

galaunay commented 4 years ago

It seems to work with some numpy objects, like np.ndarray()... But not np.array().

However, it remains an issue with Jedi. I encourage you to report to their repo.