vscode-python: pyenv + virtualenv not working - use pyenv activate for all

Environment data

  • VS Code version: 1.30.2
  • Extension version (available under the Extensions sidebar): vscode-python 2018.12.1
  • OS and version: ubuntu 16.04LTS
  • Python version (& distribution if applicable, e.g. Anaconda): any pypy,cpython
  • Type of virtual environment used (N/A | venv | virtualenv | conda | …): pyenv
  • Relevant/affected Python packages and their versions: None

Expected behaviour

When choosing python interpreter it lists all versions under ~/.pyenv correctly (see png below), but the ones created with pyenv+virtualenv like pyenv virtualenv 3.7.2 mycoolapp which creates a venv environment under pyenv using python 3.7.2 with the name mycoolapp. This should be activated with: pyenv activate mycoolapp

The ones listed with venv VSC does: $ source /home/mortenb/.pyenv/versions/mycoolapp/bin/activate

The ones listed with pyenv (the ones created with pyenv install 3.7.2, that downloads, compile and install the specified python version): $pyenv shell 3.7.2 this works for base versions not for pyenv+virtualenv, but I recommend using pyenv activate for all

$ pyenv help activate
Usage: pyenv activate <virtualenv>
       pyenv activate --unset

Activate a Python virtualenv environment in current shell.
This acts almost as same as `pyenv shell`, but this invokes the `activate`
script in your shell.

<virtualenv> should be a string matching a Python version known to pyenv.

Example loading flask on python 3.6.2:

venv-vs-pyenv

VSC does when opening a terminal:

$ source /home/mortenb/.pyenv/versions/flask/bin/activate
$ which python
/home/mortenb/.pyenv/shims/python
$ python --version
Python 3.7.0

It is wrong version, if it had done this it would have been correct:

$ pyenv activate flask
pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.
(flask) mortenb@mortenb-home1:/dist/sensio/unity-selenium$ which python
/home/mortenb/.pyenv/shims/python
(flask) mortenb@mortenb-home1:/dist/sensio/unity-selenium$ python --version
Python 3.6.2

Pyenv is a terrific technology, we manage full python versioning control within docker containers by a single build parameter. This container tagged with version number we use as base container for all python projects within the company, it makes regression testing and upgrading a oneliner in jenkins:

https://gist.github.com/fenchu/14b8fe5a0c24942f845a35106c7b176a

So please continue supporting it 😃

Thanks

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 44
  • Comments: 34 (6 by maintainers)

Most upvoted comments

Adding "python.terminal.activateEnvironment": false to my settings resolved this issue for me.

If VSCode can’t properly activate the python versions installed by pyenv, it should not pretend to support them!

We are going through old issues and we noticed that no one from the team had replied to this issue. I want to apologize for the oversight and to let you know that the issue was reviewed by the team and triaged (as shown by the labels applied to this issue).

I’d also prefer VSCode to run “pyenv activate” rather than “pyenv shell”. I would welcome a configuration option that allows users the ability to select between the two commands.

@alexrjs, same issue on my Mac. I’m using pyenv with the out-of-the-box python3 venv library. I noticed …/bin/python3 within the venv folder was a symlink to ~/.pyenv/shims/python3. This was causing my issue when trying to point the interpreter path in VS Code to the virtual environment.

What fixed my situation was recreating the virtual environment by using python -m venv . --copies – I probably could have just replaced the python3 symlink in the existing virtual environment folder. I was then able to choose the interpreter I wanted without it going to the .pyenv path. I hope this helps.

@Spenhouet thanks for the apology; it’s really appreciated.

And I do understand the feeling that a 2 year old bug will never get fixed. But something in general to know about the extension is we are actually working towards rewriting the whole thing to fix all of these nagging issues and fix perf issues. The first thing we did that for is environment discovery which has (hopefully) become more reliable and extension activation is now over 80% faster while shrinking the size of the extension from it’s peak of 40MB to about 12MB.

So I do appreciate your patience with us while we go through this work to fix our fundamentals and we are planning to tackle the terminal situation as part of all of this work in 2022.

For me this works when I have only a single root but fails if I am using a multi-root workspace.

@Spenhouet please be careful of making assumptions about the ease/difficulty of doing something. While it might seem like a 10 minute fix to you, we have to research if the command has been available for long enough to rely on it (i.e. is it over a year old and available to all pyenv users?), how will it interact with anything else we do, make sure the tests pass, etc. So making the requested change will definitely take more than 10 minutes.

We are also actively working on moving away from sending commands to the terminal for activation so things like this won’t be a concern. We are working through conda right now and then we are going to directly tackle this general issue.

Finally, this is only the 22nd most upvoted issue in our repo. It isn’t even the most upvoted pyenv issue.

If you would like to submit a PR to change what command we send to the terminal and address the concerns I outlined above then we will definitely take a look at it.

@brettcannon Thanks. You are right.

Apparently, I was also way too fast to judge. I had quite some issues on my WSL instance. I completely reinstalled everything (including the WSL distro) and now the pyenv shell venv that VSCode is doing is actually working. I don’t know why it was not working before and why it is working now.

So my assumption that this is generally not working was wrong and only based on the issues my system had. Maybe others have similar issues.

It looked to me like it is generally not working and that there is an easy fix. Googled it and found this issue. Thought “great, it is already reported and probably somebody is already on it”. Then I did see that the issue is already 2 years old without any big movement. Most of the time this means “this will never be fixed”. Sadly this is the case with many software (independent of commercial or not). Lately this really gets to me since I’m spending big junks of my time applying work arounds to stuff that has nothing to do with my actual work. I want to apologize for my reaction.

The preference setting to disable auto-activation was sufficient for me.

I activate and deactivate virtual environments all the time. I often deactivate them if I want to delete them from disk and recreate them. I also might create two virtual environments, each with different versions of libraries installed, switch between them by activating and deactivating, and test code in each environment.

Seems that, when I added the setting to user settings, it didn’t register. Moved it to the remote settings and it worked 👍

@karrtikr Can you provide minimal steps to verify this?

Setting "python.terminal.activateEnvironment": false does not resolve anything for me. Then it does not even try anymore.

If I install any package via a VSCode prompt (e.g. linter, formatter, ipykernel, …) it opens a new terminal with the wrong environment. It then installs the packages in the wrong environment…

VS Code always tries to do:

pyenv shell venv

Which does not work. Instead it should do:

pyenv activate venv

@brettcannon This seems like a 10min. fix. Not sure why it takes 2 years to address this?

Here’s my dirty hack for this (after days of frustration with this):

modify ~/.zshrc

if (( ${+PYTHON_VENV} )); then
  source <path_to_venv>
fi

modify vscode settings.json

"terminal.integrated.env.osx": {
        "PYTHON_VENV": "<path_to_venv>"
    }

Hope this helps.

After I change the parameter to not activate when starting the terminal, when I install an extension, e.g., pylint, it does it by using a pyvsc-run-isolated.py script, which still causes the extension to NOT install in the selected pyenv environment. I’m not sure if that is the intended behaviour, but I found it a bit weird. Although, I’m not sure where I would really want extensions installed… I’m using vscode on windows but accessing a pyenv environment in WSL1.

So this seems to be primarily around pyenv discussion-wise, so not sure if best to mention it here or if it should be kinda separate issue but I use pyenv + pipenv. With pipenv you’d want VSCode to be using pipenv. Basically, I agree with taliesinb sentiment.

If VSCode can’t properly activate the python versions installed by pyenv, it should not pretend to support them!

…except I’d expand it a little to say that if it’s supporting a tool (pyenv,pipenv) then it should use it as it’s intended to be used, or provide a way for the user to tell VSCode what to do (if you want to get generic with it), otherwise it’s not much of a supported thing.

So if possible maybe have it do fallbacks? So try pipenv shell if that didn’t work try pyenv activate, then try source method? …for when opening terminal.