Issues with pyenv-virtualenv: Python and PIP not changed when activating / deactivating virtual environment
Asked Answered
N

2

11

I installed pyenv-virtualenv using Linuxbrew (Homebrew 2.2.5) on my Ubuntu 16.04 VPS. The pyenv version is: 1.2.16. Now when I do a test like this:

pyenv install 3.8.1
pyenv virtualenv 3.8.1 test
cd /.pyenv/versions/3.8.1/envs/test
pyenv local 3.8.1

Then entering / leaving the /.pyenv/versions/3.8.1/envs/test doesn't activate deactivate the virtual environment and I don't see (test) username:~ in my shell. I also created a /home/users/test directory and .python-version there but still entering / leaving directory does nothing.

Accordingn to the documentation:

If eval "$(pyenv virtualenv-init -)" is configured in your shell, pyenv-virtualenv will automatically activate/deactivate virtualenvs on entering/leaving directories which contain a .python-version file that contains the name of a valid virtual environment as shown in the output of pyenv virtualenvs (e.g., venv34 or 3.4.3/envs/venv34 in example above) . .python-version files are used by pyenv to denote local Python versions and can be created and deleted with the pyenv local command.


So first question is: Why this doesn't work? Why the virtual environment is not activated / deactivated automatically at entering / leaving a directory containing a .python-version file?

Also when I activate virtualenv by hand pyenv activate test and then check the Python version, it prints the system Python version and not the one from environment: Python 3.8.1:

python --version
Python 3.7.6

I can get the right Python version only by directly referring to virtualenv shims Python like this:

which python
/home/andre/.pyenv/shims/python
/home/andre/.pyenv/shims/python --version
Python 3.8.1

The behaviour is the same whenever the virtualenv "test" is activated or not. I would expect that after activating "test" the command python --version returns Python 3.8.1

So second question: why pip and python are not switched when activating / deactivating the virtual environment ?

Are these pyenv bugs? Or am I doing something wrong?

Nostril answered 13/2, 2020 at 16:37 Comment(0)
N
11

It turns out that in order to automatically activate / deactivate a venv when entering / leaving a directory the .python-version file in there must contain the venv name and not the Python version associated with that venv

So executing: pyenv local 3.8.1 creates a .python-version file which only includes the Python version 3.8.1. Then entering / leaving a directory containing .python-version file will set / unset the Python version specified in that file but will not activate / deactivate any venv.

To create a .python-version file that will do both: activate a virtual environment and set Python version the command should look like: pyenv local test where test is a venv created with: pyenv virtualenv 3.8.1 test.

So changing 3.8.1 to test in the .python-version fixed the problem. After I done this the venv was activated / deactivated when entering / leaving directory containing .python-version.

But still the Python version did not change to the one associated with the venv (in this case 3.8.1)

Then I found out that I had two lines in my .profile that was causing this problem:

alias python=/home/linuxbrew/.linuxbrew/bin/python3
alias pip=/home/linuxbrew/.linuxbrew/bin/pip3

After removing these lines everything works as expected.

If still having any problems make sure you have these lines in your .profile or .bash_profile, whichever one you are using:

export PATH="$HOME/.pyenv/bin:$PATH"

eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

if command -v pyenv 1>/dev/null 2>&1; then
  export PYENV_ROOT="$HOME/.pyenv"
  export PATH="$PYENV_ROOT/bin:$PATH"
  eval "$(pyenv init --path)"
  eval "$(pyenv init -)"
fi

Nostril answered 31/5, 2020 at 1:25 Comment(3)
How did you come up with this solution? Is it experimental or you have found some nice source of information about pyenv internals elswhere? I mean pyenv is great but official docs are somewhat obscure about low-level details.Kym
For the first issue I was asking a little bit around... I think it's confusing for many people as .python-version suggests it contains the Python version but in fact it must contain the virtual environment name (what is actually clearly stated in the docs, but still I made this mistake...) The second issue was caused by myself.Nostril
THANK YOU! I would have never figured this out because pyenv local --help returns Usage: pyenv local <version> <version2> <..>. That is so very deceiving.Trinitrophenol
R
9

I also had similar problem. The solution was to change the entries I put in my ~/.bashrc. I went on to export the variable export PYENV_ROOT="$HOME/.pyenv" and added the line eval "$(pyenv init --path)".

Run the command below in full and it will add the necessary entries to the ~/.bashrc of the user you are using.

read -r -d '' FILE_CONTENT << 'HEREDOC'
BEGIN

# >>>>>>
# pyenv configurations.

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)" # This only sets up the path stuff.
eval "$(pyenv init -)" # This makes pyenv work in the shell.
eval "$(pyenv virtualenv-init -)" # Enabling virtualenv so it works natively.
# <<<<<<

END
HEREDOC
echo -n "${FILE_CONTENT:6:-3}" | tee -a ~/.bashrc

NOTE: Tested on Manjaro (Linux, Arch based).

Thanks! =D

[Ref(s).: https://github.com/pyenv/pyenv-installer , https://github.com/pyenv/pyenv , https://realpython.com/intro-to-pyenv/ , https://github.com/pyenv/pyenv-virtualenv/issues/390#issuecomment-852599456 , https://www.giters.com/pyenv/pyenv-virtualenv/issues/407 ]

Roussel answered 15/1, 2022 at 3:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.