coc-python icon indicating copy to clipboard operation
coc-python copied to clipboard

Wrong python interpreter by default

Open mikepqr opened this issue 5 years ago • 29 comments

According to the README

Select your preferred Python interpreter/version/environment using the Select Interpreter command. By default we use the one that's on your path.

I take this to mean the default should match the output of which python. But it doesn't.

e.g. on my machine

$ which python
/Users/mike/.ves/default/bin/python

and then in vim after :CocCommand python.setInterpreter I get:

Select pythonPath, current: /usr/local/bin/python3:
1. /usr/bin/python
2. /Users/mike/.pyenv/versions/2.7.13/bin/python
3. /usr/local/bin/python
4. /Users/mike/.pyenv/versions/3.5.3/bin/python
5. /Users/mike/.pyenv/versions/3.6.1/bin/python
6. /Users/mike/.pyenv/shims/python
7. /Users/mike/.pyenv/versions/3.6.3/bin/python
8. /Users/mike/.pyenv/versions/3.7.0a3/bin/python
9. /Users/mike/.ves/default/bin/python
10. /Users/mike/.pyenv/versions/3.7.0/bin/python
11. /usr/local/bin/python3

The value I'm expecting to be the default is the 9th on the list and the order of these items seeems to be random.

How do I fix this? Or is this the intended behavior?

mikepqr avatar Jun 28 '19 03:06 mikepqr

Or is this the intended behavior?

Yes, it is, you have to choose right interpreter for your project once, the logic for auto select python interpreter is quite complex. It chooses higher python version by default https://github.com/neoclide/coc-python/tree/master/src/interpreter/autoSelection, check out :h coc-status for statusline integration.

chemzqm avatar Jun 28 '19 03:06 chemzqm

Is there a reason why you don't just choose the first one on my $PATH?

(And can I suggest you update the README, because I can't see any other way of interpreting "By default we use the one that's on your path"?)

mikepqr avatar Jun 28 '19 03:06 mikepqr

Is there a reason why you don't just choose the first one on my $PATH?

It's logic from vscode-python, just fixed the doc.

chemzqm avatar Jun 28 '19 03:06 chemzqm

I can't read TS/JS, so I don't understand the logic, but I would imagine it makes some sense for a GUI app, where environment is weird.

But for vim, which is (usually) a CLI program, there is no better guess that the first python in $PATH. I'd urge you to consider changing it for coc-python to this very simple rule.

But if it's the intended behavior feel free to close this.

(One more thing about the README "Select Interpreter command" should presumably be "setInterpreter command".)

mikepqr avatar Jun 28 '19 04:06 mikepqr

There could be multiple python in $PAH, like python and python3, we still not sure which one should be used. vim can be use in both gui and tui environment, so I tend to keep this logic.

chemzqm avatar Jun 28 '19 04:06 chemzqm

I also agree that using the interpreter as in which python as a default one makes a lot of sense. Currently it seems that we can have only one global interpreter, no multiple workspaces (a limitation; related to #20).

That being said, is there any programmatic way (e.g. vimscript) to configure python path? :CocCommand python.setInterpreter works only with user input, but it would be great to have a way to configure it automatically.

wookayin avatar Jun 30 '19 21:06 wookayin

My vote is for two new mutually exclusive settings "python.usePathInterpreter" and "python.defaultInterpreter".

If usePathInterpreter is true then the first python in $PATH is used. If defaultInterpreter is the path of a python interpeter then that is used.

But if usePathInterpreter is false (the default) and defaultInterpreter is undefined (also the default), coc-python falls back to the vscode-python algorithm.

mikepqr avatar Jun 30 '19 23:06 mikepqr

"python.defaultInterpreter" is not needed, use "python.pythonPath" configuration.

chemzqm avatar Jun 30 '19 23:06 chemzqm

Ah. OK then. My vote is for python.usePathInterpreter.

mikepqr avatar Jun 30 '19 23:06 mikepqr

(and renaming either python.setInterpreter or python.pythonPath to make it more obvious that they are related)

mikepqr avatar Jun 30 '19 23:06 mikepqr

python.usePathInterpreter is not easy to implement, PR welcome.

chemzqm avatar Jun 30 '19 23:06 chemzqm

I have .python-version in project root folder, which has the virtualenv python version, which is the one for which python. I don't understand why it's not picked by default.

oblitum avatar Aug 27 '19 15:08 oblitum

My current workaround:

  call coc#config('python', {
  \   'jediEnabled': v:false,
  \   'pythonPath': split(execute('!which python'), '\n')[-1]
  \ })

But I've found it to present several issues. On a virtualenv, I miss builtins like print, and it affects the python version when outside a virtualenv.

oblitum avatar Aug 27 '19 15:08 oblitum

@chemzqm maybe coc-python should ignore, or at least have a setting to ignore ~ as root path? It's causing MPLS to loop CPU.

oblitum avatar Aug 27 '19 16:08 oblitum

I wanted to summarize things for those new to coc and coc-python and stumbled here by google search (like me). Please correct me if this is wrong.

@chemzqm recently wrote a memo system to store the selected python interpreter. That means, you may be able to simply set the python interpreter for a file/project and it will be remembered. To set up initially:

:CocCommand python.setInterpreter

Then select the correct interpreter for your project.

As @chemzqm indicated here, a more direct (but non-programmatic) way to deal with this issue is to add pythonPath to your config on a per-project basis:

  1. Get the python path you want to use. For a project using pyenv and a .python-version file:

    pyenv which python

  2. In your .vim/coc-settings.json file at your project root, add a python.pythonPath line as shown below:

    {
        "python.linting.pylintEnabled": false,
        "python.linting.flake8Enabled": true,
        "python.linting.enabled": true,
        "python.pythonPath": "/home/jtprince/.pyenv/versions/plotformer-3.7.4/bin/python"
    }
    

Also see the workaround by @oblitum here

jtprince avatar Oct 03 '19 22:10 jtprince

Another workaround would be to place a dummy Python interpreter. "python.pythonPath":"/home/jason/python", /home/jason/python:

#!/bin/bash
python "$@"

jasonkena avatar Nov 09 '19 07:11 jasonkena

I wanted to summarize things for those new to coc and coc-python and stumbled here by google search (like me). Please correct me if this is wrong.

@chemzqm recently wrote a memo system to store the selected python interpreter. That means, you may be able to simply set the python interpreter for a file/project and it will be remembered. To set up initially:

:CocCommand python.setInterpreter

Then select the correct interpreter for your project.

As @chemzqm indicated here, a more direct (but non-programmatic) way to deal with this issue is to add pythonPath to your config on a per-project basis:

  1. Get the python path you want to use. For a project using pyenv and a .python-version file: pyenv which python

  2. In your .vim/coc-settings.json file at your project root, add a python.pythonPath line as shown below:

    {
      "python.linting.pylintEnabled": false,
      "python.linting.flake8Enabled": true,
      "python.linting.enabled": true,
      "python.pythonPath": "/home/jtprince/.pyenv/versions/plotformer-3.7.4/bin/python"
    }
    

Also see the workaround by @oblitum here

If you set python.pythonPath, python.setInterpreter will be failed. My coc-python version is 1.2.6

TimKingNF avatar Nov 11 '19 08:11 TimKingNF

@chemzqm I am finding the current behaviour hard to reason about:

  • Each time a start a new vim session I have to do CocCommand python.setInterpreter and choose the python from the virtual env. It also seems that that setting is not cached anywhere -- I would have at least expected the memo system to cache it per folder -- is there a reason the memo system only has a global cache rather than storing something in .vim/

In addition something about the default behaviour is selecting my global python over the currently active virtualenv (perhaps because global is Py 3.8, but virtualenv is only 3.7) -- this behaviour is massively confusing to me as a linux user. which python, which python3 all show the virtualenv, so that is what I would expect it to use.

Would you accept a PR to reorder/change the detection to favour active virtual env more?

ashb avatar Feb 12 '20 11:02 ashb

@ashb there must be something wrong with your setup because there's actually a memo system, and at least for me it works, it has been even mentioned in this thread already. The only issue everyone is hitting is no automatic env detection on first use.

oblitum avatar Feb 12 '20 16:02 oblitum

More than willing to believe something is wrong, but I don't even know where to start. The log files are... verbose. When should this memo system come in to play?

So for you are you saying that once you run setInterpreter it saves it, even if you close and open vim, and if you have mutliple vims in different folders?

Also this is for vim -- the equivalent of Vimscript exepath('python') should be the top hit ;)

ashb avatar Feb 12 '20 17:02 ashb

It comes into play from start, when it sets some python executable by default, which may not be the one you want, then you set the one you want, and coc.nvim updates it on ~/.config/coc/memos.json, so next time you start [n]vim on a the same directory, it will pick the last one saved for that dir.

oblitum avatar Feb 12 '20 18:02 oblitum

Thanks @oblitum In trying to reproduce this I deleted my memos file and now can't reproduce it.

(I have questions about the amount of duplication in the memos file, but that's a separate issue)

Back to the original question at hand: I (and I guess most people here) would prefer the default option is exepath('python') equivalent. Perhaps a new provider/method, and either making that the default, or a config option to let users change the order of the discovery methods. How does that sound @chemzqm ?

ashb avatar Feb 12 '20 19:02 ashb

I believe exepath('python') is not useful and not what MPLS/jedi may expect. For example, it doesn't matter what pyenv virtualenv I'm in, echo exepath('python') always gives ~/.pyenv/shims/python, which is the pyenv wrapper, and not meaningful about the actual location of the virtualenv (for example, ~/.pyenv/versions/miniconda3-latest/envs/tacotron2/bin/python).

oblitum avatar Feb 12 '20 20:02 oblitum

And actually the same thing happens for a previous snippet I've shared.

oblitum avatar Feb 12 '20 20:02 oblitum

Too many possible ways of creating venvs in python I guess. (I'm using virtualenvwrapper with my venvs in ~/.virtualenvs/)

ashb avatar Feb 12 '20 21:02 ashb

My workaround with conda:

Add the following to init.vim/.vimrc:

if $CONDA_PREFIX == ""
  let s:current_python_path=$CONDA_PYTHON_EXE
else
  let s:current_python_path=$CONDA_PREFIX.'/bin/python'
endif
call coc#config('python', {'pythonPath': s:current_python_path})

znculee avatar Apr 22 '20 01:04 znculee

Hmm, I'm also not sure this is the desired behaviour. coc-python now picks a conda environment as default interpreter, because it's a higher version than my system python.

I would prefer to only use conda interpreters if they're actually activated.

lrvdijk avatar Apr 24 '20 18:04 lrvdijk

This is a complex matter to pin down, hence personally I'm just ok with setting it once per workspace.

oblitum avatar Apr 24 '20 18:04 oblitum

If you use pyenv and pyenv_virtualenv you can also just use the following in init.vim/.vimrc:

call coc#config('python', {'pythonPath': $PYENV_VIRTUAL_ENV})

carlosrojas avatar Jul 28 '20 04:07 carlosrojas