pyenv-virtualenv icon indicating copy to clipboard operation
pyenv-virtualenv copied to clipboard

.python-version activation doesn't set $VIRTUAL_ENV

Open Tsubashi opened this issue 5 years ago • 8 comments

Perhaps I am missing something, but when I use a .python-version file to activate virtual environments, the $VIRTUAL_ENV variable isn't set. Using pyenv activate, however, does set it. For example, suppose I have a folder /projects/my_project with a .python-version file containing my_venv. When I cd into that folder, I can see that pyenv has properly detected the file and switched to using my_venv by running pyenv versions:

me@my_system$ pyenv versions
  system
  3.8.2
* my_venv (set by /projects/my_project/.python-version)

My shell's prompt (which checks for ${VIRTUAL_ENV}) has not updated, and sure enough, running echo ${VIRTUAL_ENV} produces a blank line. If I run pyenv activate my_venv, though, it all works as expected: pyenv picks it up and echo ${VIRTUAL_ENV} returns /Users/me/.pyenv/versions/3.8.2/env/my_venv

Given the verbiage in the README ("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") I expected VIRTUAL_ENV to be set as it is via pyenv activate

Tsubashi avatar Apr 09 '20 16:04 Tsubashi

For me this discovery came because I was trying to avoid the message about prompt changing being deprecated by adding the checks into my .bashrc file. I originally checked for the VIRTUAL_ENV variable, but found that it wouldn't actually match what pyenv was doing.

For anyone else in the same boat, here is the work-around I am currently using:

if type "pyenv" > /dev/null 2>&1; then
    local PYENV_VERSION_NAME=$(pyenv version-name)
    if [[ ${PYENV_VERSION_NAME} != "system" ]]; then
        PS1="(${PYENV_VERSION_NAME}) ${PS1}"
    fi
fi

Obviously, it makes a few assumptions:

  • Your default python is system
  • You don't want to see the marker when using the system python
  • You only use pyenv to manage virtualenvs

Tsubashi avatar Apr 09 '20 16:04 Tsubashi

This issue also interferes with pipenv, which expects this env variable to be set, in order to use existing virtual environment. Otherwise, pipenv keeps creating a new virtual environment (that is its default behaviour)

darkfishy avatar May 12 '20 03:05 darkfishy

I am not sure how helpful this is but if you keep only one line in your .python-version, the one with the virtualenv name, and delete any other (python version numbers), then it automatically sets $VIRTUAL_ENV.

behaghel avatar Dec 27 '20 15:12 behaghel

I know this issue has been opened a long time ago. But it used to work perfectly for me, and now it seems like the $VIRTUAL_ENV variable is not set anymore? I am using fish as my shell, maybe it matters?

dcupif avatar May 05 '22 09:05 dcupif

I am not sure how helpful this is but if you keep only one line in your .python-version, the one with the virtualenv name, and delete any other (python version numbers), then it automatically sets $VIRTUAL_ENV.

Nope, I can't confirm this. VIRTUAL_ENV does not get set anymore, independently from the number of entries in .python-version

simonmeggle avatar Jul 08 '22 13:07 simonmeggle

I am coming from this issue at python-poetry and wanted to find out why Poetry installs dependencies as if there were no active venv at all.

OS: Monterey 12.2, ARM64E Shell: zsh

To reproduce the coherence with the missing VIRTUAL_ENV variable I have written a small script.

Just uncomment (activate) the line

export VIRTUAL_ENV=$(pyenv virtualenv-prefix)/envs/$PYENV_VENV_NAME 

and Poetry will behave as expected and install the dependencies in the current active venv (e.g. set by .python_version).

OK example which shows that Poetry is able to install the robotframework package into the venv:

❯ bash pyenv-poetry-test.sh create
❯ PWD = /Users/simon/Documents/01_Development/06_Minimalbeispiele
❯ Versions:
❯   pyenv: pyenv 2.3.2
❯   poetry: Poetry (version 1.2.0b2)
❯   pyenv global: system
❯ ---
❯ Tidying up
❯ Removing project
❯ Executing: rm -rf project
❯ Deleting pyenv-venv project
❯ Executing: pyenv virtualenv-delete -f project
-----
❯ Creating and entering project
❯ pyenv - create project: 'pyenv virtualenv 3.8.13 project'
Looking in links: /var/folders/pw/jgxh06cn3gs4_j7qqc31xn0w0000gn/T/tmp6j4htdzc
Requirement already satisfied: setuptools in /Users/simon/.pyenv/versions/3.8.13/envs/project/lib/python3.8/site-packages (56.0.0)
Requirement already satisfied: pip in /Users/simon/.pyenv/versions/3.8.13/envs/project/lib/python3.8/site-packages (22.0.4)
❯ pyenv - set local version: 'pyenv local project'
❯ pyenv - show local version: 'pyenv local'
project
❯ poetry - config:
cache-dir = "/Users/simon/Library/Caches/pypoetry"
experimental.new-installer = true
experimental.system-git-client = false
installer.max-workers = null
installer.no-binary = null
installer.parallel = true
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/simon/Library/Caches/pypoetry/virtualenvs
virtualenvs.prefer-active-python = false
virtualenvs.prompt = "{project_name}-py{python_version}"
❯ poetry - initialization: 'poetry init -n --name=project --python='^3.8' --dependency=robotframework'
Using version ^5.0.1 for robotframework
❯ poetry - install in pyenv: 'pyenv exec poetry install'
Using virtualenv: /Users/simon/.pyenv/versions/3.8.13/envs/project
Updating dependencies
Resolving dependencies...
   1: fact: project is 0.1.0
   1: derived: project
   1: fact: project depends on robotframework (^5.0.1)
   1: selecting project (0.1.0)
   1: derived: robotframework (>=5.0.1,<6.0.0)
   1: selecting robotframework (5.0.1)
   1: Version solving took 0.020 seconds.
   1: Tried 1 solutions.

Writing lock file

Finding the necessary packages for the current system

Package operations: 1 install, 0 updates, 0 removals

  • Installing robotframework (5.0.1)
❯ Pip list:
Package        Version
-------------- -------
pip            22.0.4
robotframework 5.0.1
setuptools     56.0.0

Now the same, but without setting the VIRTUAL_ENV var:

    # ### WITHOUT THIS VARIABLE, POETRY WON'T USE THE VIRTUALENV VERSION SET FOR THIS FOLDER ###
    # (it will prepare the venv in the "poetry way")
    # export VIRTUAL_ENV=$(pyenv virtualenv-prefix)/envs/$PYENV_VENV_NAME

NOK example - watch the marked lines!

❯ bash pyenv-poetry-test.sh create
❯ PWD = /Users/simon/Documents/01_Development/06_Minimalbeispiele
❯ Versions:
❯   pyenv: pyenv 2.3.2
❯   poetry: Poetry (version 1.2.0b2)
❯   pyenv global: system
❯ ---
❯ Tidying up
❯ Removing project
❯ Executing: rm -rf project
❯ Deleting pyenv-venv project
❯ Executing: pyenv virtualenv-delete -f project
-----
❯ Creating and entering project
❯ pyenv - create project: 'pyenv virtualenv 3.8.13 project'
Looking in links: /var/folders/pw/jgxh06cn3gs4_j7qqc31xn0w0000gn/T/tmpjn51tc7x
Requirement already satisfied: setuptools in /Users/simon/.pyenv/versions/3.8.13/envs/project/lib/python3.8/site-packages (56.0.0)
Requirement already satisfied: pip in /Users/simon/.pyenv/versions/3.8.13/envs/project/lib/python3.8/site-packages (22.0.4)
❯ pyenv - set local version: 'pyenv local project'
❯ pyenv - show local version: 'pyenv local'
project
❯ poetry - config:
cache-dir = "/Users/simon/Library/Caches/pypoetry"
experimental.new-installer = true
experimental.system-git-client = false
installer.max-workers = null
installer.no-binary = null
installer.parallel = true
virtualenvs.create = true
virtualenvs.in-project = null
virtualenvs.options.always-copy = false
virtualenvs.options.no-pip = false
virtualenvs.options.no-setuptools = false
virtualenvs.options.system-site-packages = false
virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/simon/Library/Caches/pypoetry/virtualenvs
virtualenvs.prefer-active-python = false
virtualenvs.prompt = "{project_name}-py{python_version}"
❯ poetry - initialization: 'poetry init -n --name=project --python='^3.8' --dependency=robotframework'
Using version ^5.0.1 for robotframework
❯ poetry - install in pyenv: 'pyenv exec poetry install'
Creating virtualenv project-snjECpG8-py3.9 in /Users/simon/Library/Caches/pypoetry/virtualenvs   #  ---<<<< ! < ! < ! < ! < ! < ! < !
Using virtualenv: /Users/simon/Library/Caches/pypoetry/virtualenvs/project-snjECpG8-py3.9   #  ---<<<< ! < ! < ! < ! < ! < ! < !
Updating dependencies
Resolving dependencies...
   1: fact: project is 0.1.0
   1: derived: project
   1: fact: project depends on robotframework (^5.0.1)
   1: selecting project (0.1.0)
   1: derived: robotframework (>=5.0.1,<6.0.0)
   1: selecting robotframework (5.0.1)
   1: Version solving took 0.031 seconds.
   1: Tried 1 solutions.

Writing lock file

Finding the necessary packages for the current system

Package operations: 1 install, 0 updates, 0 removals

  • Installing robotframework (5.0.1)
❯ Pip list:   #  lists the modules of the desired venv, but robotframework is missing (installed in Poetry's venv)---<<<< ! < ! < ! < ! < ! < ! < !
Package    Version
---------- -------
pip        22.0.4
setuptools 56.0.0
 #  ---<<<< ! < ! < ! < ! < ! < ! < !

simonmeggle avatar Jul 08 '22 13:07 simonmeggle

I was running into this issue, I was just able to resolve it by following the instructions in the README about enabling automatic activation of virtualenvs (step 2 under Installing as a pyenv plugin)

nint8835 avatar Oct 20 '22 13:10 nint8835

@simonmeggle are you maybe using the precmd/precwd workaround from #259? I've noticed that that workaround unfortunately leads to VIRTUAL_ENV not being set correctly

hassec avatar Sep 10 '23 21:09 hassec