Skip to content
This repository has been archived by the owner on Dec 24, 2020. It is now read-only.

Wrong python interpreter by default #55

Open
mikepqr opened this issue Jun 28, 2019 · 29 comments
Open

Wrong python interpreter by default #55

mikepqr opened this issue Jun 28, 2019 · 29 comments

Comments

@mikepqr
Copy link

mikepqr commented Jun 28, 2019

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?

@chemzqm
Copy link
Member

chemzqm commented Jun 28, 2019

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.

@mikepqr
Copy link
Author

mikepqr commented Jun 28, 2019

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"?)

@chemzqm
Copy link
Member

chemzqm commented Jun 28, 2019

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.

@mikepqr
Copy link
Author

mikepqr commented Jun 28, 2019

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".)

@chemzqm
Copy link
Member

chemzqm commented Jun 28, 2019

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.

@wookayin
Copy link

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.

@mikepqr
Copy link
Author

mikepqr commented Jun 30, 2019

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.

@chemzqm
Copy link
Member

chemzqm commented Jun 30, 2019

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

@mikepqr
Copy link
Author

mikepqr commented Jun 30, 2019

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

@mikepqr
Copy link
Author

mikepqr commented Jun 30, 2019

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

@chemzqm
Copy link
Member

chemzqm commented Jun 30, 2019

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

@oblitum
Copy link
Member

oblitum commented Aug 27, 2019

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
Copy link
Member

oblitum commented Aug 27, 2019

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
Copy link
Member

oblitum commented Aug 27, 2019

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

@jtprince
Copy link

jtprince commented Oct 3, 2019

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

@jasonkena
Copy link

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

#!/bin/bash
python "$@"

@TimKingNF
Copy link

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

@ashb
Copy link

ashb commented Feb 12, 2020

@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?

@oblitum
Copy link
Member

oblitum commented Feb 12, 2020

@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.

@ashb
Copy link

ashb commented Feb 12, 2020

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 ;)

@oblitum
Copy link
Member

oblitum commented Feb 12, 2020

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.

@ashb
Copy link

ashb commented Feb 12, 2020

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 ?

@oblitum
Copy link
Member

oblitum commented Feb 12, 2020

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
Copy link
Member

oblitum commented Feb 12, 2020

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

@ashb
Copy link

ashb commented Feb 12, 2020

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

@znculee
Copy link

znculee commented Apr 22, 2020

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})

@lrvdijk
Copy link

lrvdijk commented Apr 24, 2020

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.

@oblitum
Copy link
Member

oblitum commented Apr 24, 2020

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

@carlosrojas
Copy link

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})

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

No branches or pull requests