pyenv / pyenv-virtualenv

a pyenv plugin to manage virtualenv (a.k.a. python-virtualenv)
MIT License
6.18k stars 399 forks source link

Set CONDA_PROMPT_MODIFIER env var when activating conda environment #455

Open 0xdevalias opened 1 year ago

0xdevalias commented 1 year ago

Overview

When activating a conda environment manually (eg. conda activate textgen), the following CONDA_* env vars are set in my environment:

⇒ env | grep CONDA
CONDA_EXE=/Users/devalias/.pyenv/versions/miniconda3-latest/bin/conda
_CE_CONDA=
CONDA_PYTHON_EXE=/Users/devalias/.pyenv/versions/miniconda3-latest/bin/python
CONDA_SHLVL=1
CONDA_PROMPT_MODIFIER=(textgen)
CONDA_DEFAULT_ENV=textgen
CONDA_PREFIX=/Users/devalias/.pyenv/versions/miniconda3-latest/envs/textgen

Yet when I use pyenv/pyenv-virtualenv to activate the conda environment, the CONDA_* env vars are different:

⇒ env | grep CONDA
CONDA_EXE=/Users/devalias/.pyenv/versions/miniconda3-latest/bin/conda
_CE_CONDA=
CONDA_PYTHON_EXE=/Users/devalias/.pyenv/versions/miniconda3-latest/bin/python
CONDA_SHLVL=0
CONDA_DEFAULT_ENV=textgen
CONDA_PREFIX=/Users/devalias/.pyenv/versions/miniconda3-latest/envs/textgen

Diffing these it seems that CONDA_SHLVL changes from 0 to 1, and CONDA_PROMPT_MODIFIER isn't set:

CONDA_EXE=/Users/devalias/.pyenv/versions/miniconda3-latest/bin/conda
_CE_CONDA=
CONDA_PYTHON_EXE=/Users/devalias/.pyenv/versions/miniconda3-latest/bin/python
- CONDA_SHLVL=1
+ CONDA_SHLVL=0
- CONDA_PROMPT_MODIFIER=(textgen)
CONDA_DEFAULT_ENV=textgen
CONDA_PREFIX=/Users/devalias/.pyenv/versions/miniconda3-latest/envs/textgen

In the manually activated version, having CONDA_PROMPT_MODIFIER set tells my shell prompt to display the activated conda environment; yet the fact that this isn't set in the automatically activated environment makes it seem as though it isn't working properly, even though I can see that it is based on the activated python version/etc.

It looks like changes would probably have to be made in the following files to implement this, though i'm not 100% sure how easy/hard it would be, or if there are other deeper places I would need to be looking also:

Issue Template

Too many issues will kill our team's development velocity, drastically. Make sure you have checked all steps below.

Prerequisite

Description

native-api commented 1 year ago

Are those ennvars a part of a public API? Who says you can rely on them being set?

0xdevalias commented 1 year ago

@native-api I have no idea? I'm not deeply versed in either project. All I did was observe the lack of a shell prompt being set in the env auto activated by pyenv-virtualenv, and then look into why that seemed to be by diffing the 2 shell envs.

Edit:

It seems to be mentioned in the deepdives of 'what happens' here.. so.. I assume yes?

It's also indirectly referenced here, with the conda config setting to control how the prompt is defined (conda config --set env_prompt '({name})'):

0xdevalias commented 1 year ago

Looking at:

And:

I wonder if it might not even be better to just call conda shell.bash activate foo or similar directly, rather than manually setting the env vars (and having to keep them up to date)

When no conda env is active, and no env specified in the activate command:

⇒ conda shell.bash activate
PS1='(base) '
export PATH='/Users/devalias/.pyenv/versions/miniconda3-latest/bin:/Users/devalias/.pyenv/versions/miniconda3-latest/condabin:REDACTED'
export CONDA_PREFIX='/Users/devalias/.pyenv/versions/miniconda3-latest'
export CONDA_SHLVL='1'
export CONDA_DEFAULT_ENV='base'
export CONDA_PROMPT_MODIFIER='(base) '
export CONDA_EXE='/Users/devalias/.pyenv/versions/miniconda3-latest/bin/conda'
export _CE_M=''
export _CE_CONDA=''
export CONDA_PYTHON_EXE='/Users/devalias/.pyenv/versions/miniconda3-latest/bin/python'

When no conda env is active, and an non-existing env (eg. noexist) specified in the activate command:

⇒ conda shell.bash activate noexist

EnvironmentNameNotFound: Could not find conda environment: noexist
You can list all discoverable environments with `conda info --envs`.

When no conda env is active, and an existing env (eg. textgen) specified in the activate command:

⇒ conda shell.bash activate textgen
PS1='(textgen) '
export PATH='/Users/devalias/.pyenv/versions/miniconda3-latest/envs/textgen/bin:/Users/devalias/.pyenv/versions/anaconda3-2022.05/condabin:REDACTED
export CONDA_PREFIX='/Users/devalias/.pyenv/versions/miniconda3-latest/envs/textgen'
export CONDA_SHLVL='1'
export CONDA_DEFAULT_ENV='textgen'
export CONDA_PROMPT_MODIFIER='(textgen) '
export CONDA_EXE='/Users/devalias/.pyenv/versions/miniconda3-latest/bin/conda'
export _CE_M=''
export _CE_CONDA=''
export CONDA_PYTHON_EXE='/Users/devalias/.pyenv/versions/miniconda3-latest/bin/python'

When conda env is already active (eg. textgen), and an existing env (eg. textgen) specified in the activate command:

⇒ conda shell.bash activate textgen
PS1='(textgen) '
export PATH='/Users/devalias/.pyenv/versions/miniconda3-latest/envs/textgen/bin:/Users/devalias/.pyenv/versions/anaconda3-2022.05/condabin:REDACTED
export CONDA_SHLVL='1'
export CONDA_PROMPT_MODIFIER='(textgen) '

This is talked about in more detail here:

native-api commented 1 year ago

@native-api I have no idea? I'm not deeply versed in either project. All I did was observe the lack of a shell prompt being set in the env auto activated by pyenv-virtualenv, and then look into why that seemed to be by diffing the 2 shell envs.

So the real problem is the prompt not changing?

It should, unless you have PYENV_VIRTUALENV_DISABLE_PROMPT set.

0xdevalias commented 1 year ago

The 'real problem' is wanting to see consistent things happen whether I activate the conda environment manually using conda activate, or automatically using pyenv-virtualenv.

I would have expected pyenv-virtualenv to basically just be calling conda activate under the hood.

The observed symptom was the prompt not changing, which led me to discover the other env vars not being changed in the same way either.

Edit: For completeness, I did have PYENV_VIRTUALENV_DISABLE_PROMPT set; but IMO that doesn't change the underlying fact that I would have expected conda activate to be called by pyenv-virtualenv rather than just setting 1 env var it uses.