pythonic-emacs / anaconda-mode

Code navigation, documentation lookup and completion for Python.
GNU General Public License v3.0
710 stars 87 forks source link

Handle the case when jedi of an older version is installed globally #327

Closed valignatev closed 6 years ago

valignatev commented 6 years ago

Hi! There's a case when jedi is installed globally, and it's of a lesser version than required by anaconda. It might happen quite often provided people using global installation of ipython, for example. In this case, import jedi won't fail, and assertion for jedi version will always fail as well. This little pull request handles this case and also reloads jedi if needed after importing of an older version.

What do you think?

proofit404 commented 6 years ago

Hi, thanks for the contribution!

I have several questions:

  1. importlib.reload survived several renames. Does it present on this name under all supported python versions?
  2. Does jedi go through reloading correctly?
  3. Maybe it is simpler to ensure installation directories are present and stays at the beginning of sys.path?

What do you think?

Regards, Artem.

valignatev commented 6 years ago

Hey, thanks for the fast response!

  1. My bad, should use imp for python2.7
  2. I wonder how to check this with 100% confidence. Besides jedi.__version__ we might also check jedi.utils. version_info I guess
  3. This will work after initial installation of anaconda-mode, but upon the very first install (or reinstall) older global jedi might already be installed, it'll be imported and assertion will fail (basically, this happened to me after I upgraded anaconda-mode)
proofit404 commented 6 years ago

I meant check installation directory exists before trying to import jedi. And if it missed add it to the missing dependencies.

valignatev commented 6 years ago

This is a great idea actually. Yeah, I'll try to do this and fix my PR accordingly.

valignatev commented 6 years ago

I did the upfront checking for installation folders. There's a nested loop here now, but I think it won't harm since we're talking about 6 iterations in the worst case, and it's quite readable to me. I also kept try/except ImportError part just in case installation process fails somehow.

What do you think?

proofit404 commented 6 years ago

Thanks! I think this should work.

bet4it commented 5 years ago

It seems that if python-shell-interpreter was set to ipython3, which depends on jedi and will load it when starts, the sys.path won't work when import jedi again.

According to python's documentation, the modules loaded before will be put into sys.modules as a cache, and if we want to import a module, python will first check whether it is in the cache, and load it directly if it is found. So if we install a old version of jedi and it is loaded by ipython first, the jedi imported by anaconda-mode will still be the old version, even if we have installed the newer version correctly in local directory and set sys.path to it, which will cause the assert to fail.

It seems that there are no simple and universal ways to load a module directly from a specific directory.

I'm curious that if the API of jedi doesn't change in recent versions, why should we force users to use the latest version or jedi?