coc-python
coc-python copied to clipboard
Wrong python interpreter by default
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?
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.
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"?)
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.
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".)
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.
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.
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.
"python.defaultInterpreter" is not needed, use "python.pythonPath" configuration.
Ah. OK then. My vote is for python.usePathInterpreter.
(and renaming either python.setInterpreter or python.pythonPath to make it more obvious that they are related)
python.usePathInterpreter is not easy to implement, PR welcome.
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.
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.
@chemzqm maybe coc-python should ignore, or at least have a setting to ignore ~ as root path? It's causing MPLS to loop CPU.
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:
-
Get the python path you want to use. For a project using pyenv and a
.python-versionfile:pyenv which python -
In your
.vim/coc-settings.jsonfile at your project root, add apython.pythonPathline 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
Another workaround would be to place a dummy Python interpreter.
"python.pythonPath":"/home/jason/python",
/home/jason/python:
#!/bin/bash
python "$@"
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.setInterpreterThen 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:
Get the python path you want to use. For a project using pyenv and a
.python-versionfile:pyenv which pythonIn your
.vim/coc-settings.jsonfile at your project root, add apython.pythonPathline 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
@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.setInterpreterand 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 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.
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 ;)
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.
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 ?
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).
And actually the same thing happens for a previous snippet I've shared.
Too many possible ways of creating venvs in python I guess. (I'm using virtualenvwrapper with my venvs in ~/.virtualenvs/)
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})
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.
This is a complex matter to pin down, hence personally I'm just ok with setting it once per workspace.
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})