Hi, I updated my Homebrew install and I'm now getting an info message displayed whenever I'm changing into directories that have a .python-version file in them (I'm guessing? I'm not entirely sure on what triggers the behaviour).
It says:
pyenv-virtualenv: prompt changing will be removed from future release. configureexport PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.`
but it's not really clear to me from that message _how_ the prompt will change in the future and how that variable is supposed to work, i.e. what its expected behaviour is.
I added the var to my shell file just to try it out, and the resulting prompt is definitely _not_ what I want, as it seems to get stuck in a mode where it always displays the currently activated virtualenv, regardless of where I am in my file system.
Re: what's going to change:
Will only the active/deactive messages disappear? Or both that and the prompt prefix that displays the virtualenv's name, like so (myvirtualenv) mymachine:~$?
And a general question, not directly related to this issue: are you accepting PRs for improving documentation? Because I'd really like to add a bit of info to this repo's README that would've saved me lots of time trying to figure out a particular problem I had.
In pyenv-virtualenv prior to v20151222, there were some known issues related to management of $PATH and shell's prompt (#51, #69, #80).
To solve all those issues intrinsically, pyenv-virtualenv stopped using activate script generated by virtualenv, venv and conda env (#104). The virtual environments will be pick up via _shims_ just like other ordinary versions in pyenv (e.g. 2.7.11, 3.5.1, etc.). Because these virtual environments are just a pyenv version now, I don't like to do something special for them as much as possible. I added that deprecation warning and I will remove the prompt changing feature in _future_ releases (actually, the feature has already been removed for fish shell since it had known problem).
https://github.com/yyuu/pyenv-virtualenv/blob/v20151222/bin/pyenv-sh-activate#L221
Now you can see what virtual environment (or a version) is activated from the output of pyenv versions, like other non-virtual versions in pyenv. Any users can configure their shell to show the name of activated virtualenv in their prompt like before, but pyenv-virtualenv will stop doing it by default in future release.
Any contributions are always welcomed. We need more hands and eyes to improve things, especially for documentation since I am pretty bad at documentation :stuck_out_tongue:
I'm still not sure if I understand fully. (;
So, you won't remove the code for changing the prompt entirely (that's how the message read to me!), but the prompt change won't be _the default_ anymore and users will have to (re)enable it via their shell (with the PYENV_VIRTUALENV_DISABLE_PROMPTvariable)?
Is that it? And will that affect both the 'activate/deactivate' messages and the display of the virtualenv's name? (Meaning: does the variable cover both, or is it possible to only get the name displayed and not the activate/deactivate messages?)
Regarding the documentation: yeah, I'd especially like for it (any documentation, really!) to be as beginner-friendly as possible. (: So, not leaving out any info that might be helpful for people not (so) familiar with certain tools, or the lingo that comes with them.
I'd really love to see more programming beginners use Homebrew & pyenv (or chruby etc.) from the beginning as I believe it's generally a good idea not to mess with one's Mac system too much. But, for beginners, info on additional tools and how to use them can be quite overwhelming (and missing 'helper' messages can make navigation/usage of tools more difficult). So if I'm struggling with any of this, it must be n times harder for total beginners! And I'm afraid they're then more likely to just _not_ go through all the trouble of trying to figure out how to do things (better).
Anyway, cool, I'll change that one bit I was looking to change soon, and submit a PR!
I didn't say I won't remove it. It's just keep for now for compatibility between previous release.
Oh, so _are_ you planning to remove it altogether? That would be a pity. ): It's a really, really useful feature to have.
Btw. I thought about the issue some more, trying to figure out why I found the current instructions so confusing. I think it's because the variable says 'disable' for a function which will be disabled by default anyway!
People will have to 'disable' something that's already disabled, when really, they want to turn on something that's turned off by default. I.e. wouldn't it make more sense to name it PYENV_VIRTUALENV_ENABLE_PROMPT and have people set it to 0 in their shell config if they want to (re)enable the prompt?
I guess the PYENV_VIRTUALENV_DISABLE_PROMPT variable is just a temporary solution to let you test how it will be once the feature is removed. It will probably go away together with the feature.
Anyways, I also had a little trouble understanding the message (which is why I googled it). I wasn't aware that pyenv-virtualenv sets PS1 since I'm setting PS1 myself in my ~/.bashrc, and therefore export PYENV_VIRTUALENV_DISABLE_PROMPT=1 did nothing.
It's probably a good idea to either include information in the README on how users can set up their prompt themselves, or link to a guide somewhere else. In my setup, I'm using the $VIRTUAL_ENV variable, which I expect still will be available:
function updatePrompt {
# Styles
GREEN='\[\e[0;32m\]'
BLUE='\[\e[0;34m\]'
RESET='\[\e[0m\]'
# Base prompt: \W = working dir
PROMPT="\W"
# Current Git repo
if type "__git_ps1" > /dev/null 2>&1; then
PROMPT="$PROMPT$(__git_ps1 "${GREEN}(%s)${RESET}")"
fi
# Current virtualenv
if [[ $VIRTUAL_ENV != "" ]]; then
# Strip out the path and just leave the env name
PROMPT="$PROMPT${BLUE}{${VIRTUAL_ENV##*/}}${RESET}"
fi
PS1="$PROMPT\$ "
}
export -f updatePrompt
# Bash shell executes this function just before displaying the PS1 variable
export PROMPT_COMMAND='updatePrompt'
@danmichaelo I agree (a link to) instructions should be included as it cannot be assumed that everyone who'd like to use pyenv-virtualenv knows how to write shell functions.
As said before, for beginners it's tricky enough to work out how to get tools like pyenv(-virtualenv) running in the first place; if we want more folks to use cool tools (which I hope we all do!) we need to make sure they are accessible.
I'll see if I can find time to try out your function, thanks for posting the code!
@danmichaelo @kerstin newbie here, how can I use that shell function to have the prompt like virtualenv's? Thanks :D
@GandaG Copy and paste the code into a file named .bashrc (or .bash_profile) in your home folder should work. If you're not accustomed to these files, just google them.
@danmichaelo thanks! The prompt appeared after restarting so I guess I better not change anything (I have this bookmarked though)
@GandaG, you won't need that piece of code just yet, only once the prompt message is removed (in future versions). Though it might not actually be applicable anymore then. (; We'll see.
(I'll definitely want to keep the prompt change, so we might have to create our own workarounds in the future.)
@yyuu @kerstin @danmichaelo I'm sorry I came to this thread really late but, do you guys mean that pyenv activate/deactivate is no longer recommended and users should create .python-version and let pyenv handle virtualenv auto switching instead?
@athrunsun only virtualenv like prompt changing feature has been deprecated.
I don't have any plan to deprecate pyenv activate and pyenv deactivate. They should work as long as pyenv's PYENV_VERSION environment variable works.
@yyuu Thanks. It looks I can change to a specific virtualenv by pyenv shell as well, which is more convenient.
@yyuu Can you clarify your last message? What's the difference between the "virtualenv like prompt changing feature" and pyenv activate/deactivate? If the latter is being removed in a future version will there be any way to run different venvs within a single directory, say from a script? From what I understand using the .python-version auto switches using only one environment per directory
I found some typo in my last comment. At least I don't have any plan to deprecate activate/deactivate
I think the confusion is around what is meant by "prompt changing". To clarify, what is going to be removed is the bit where the PS1 is modified, correct? ie:
(my-cool-env) ~/Documents/projects/my-cool-proj $
That () bit at the beginning changing upon activating or deactivating a certain virtualenv. That will no longer happen in the future?
I believe the message has been taken to mean "you will not be able to activate or deactivate virtualenvs from the terminal in the future".
Am I correct in my understanding of what folks are possibly (mis)understanding?
@mmatlock-shr Yeah, my assumption was that the _visual indicator_ that one was in a directory with a virtualenv was going to disappear, i.e. that the (my-cool-env) bit in front of ~/Documents/projects/my-cool-proj $ would get removed.
Why not just keep it in, make it configurable but off by default?
Best of both worlds.
Having a prompt showing immediately that you're in a virtualenv is absolutely necessary and invaluable feature. I don't know how many times I've accidentally installed some stuff globally by using pip because I didn't pay enough attention to the prompt showing me that I hadn't activated virtualenv yet.
Any news on this ?
As @svenvarkel mentionned, it's absolutely necessary to have a way to know whether a virtual env is activated or not.
I'm very surprised that any env var is set by pyenv to indicate that a virtual env is being used in this shell.
Why not exporting a environment variable, like $VIRTUAL_ENV set by venv or virtualenv ?
I was looking for an answer.
I tried to play a little bit with this, isn't that enough for you? (That's fine with me)
export PS1='\n$(pyenv version-name)\n'$PS1
I was looking for an answer.
I tried to play a little bit with this, isn't that enough for you? (That's fine with me)
export PS1='\n$(pyenv version-name)\n'$PS1
Thanks for the tip! I just prefer use it as prefix, but I liked your version too
A slight change to @cglacet 's version makes the prompt look just like the default virtualenv behavior:
export PS1='($(pyenv version-name)) '$PS1
yields something like:
(myvenv) $
I like his idea; it is simple, non-hacky, and easy to undo.
Now its 2020 and the warning message is still there. I am glad to see that the functions
My suggestion would be
Thanks
In the mean time I added a simple function to .bashrc
function workon() {
pyenv activate "$@" 2> >(grep -v PYENV_VIRTUALENV_DISABLE_PROMPT)
}
Usage: workon VENV_NAME
Shout-out to virtualenvwrapper!
idk. if this is handy, but none of the other bash solutions quite replicate the default pyenv prompt behaviour in some way or another. I have put them together to do this which seems to work well. it hides the prompt if not in a virtualenv and revaluates with each new prompt - so it will change to be correct as you cd in and out of different envs and the system
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
export BASE_PROMPT=$PS1
function updatePrompt {
if [[ "$(pyenv version-name)" != "system" ]]; then
export PS1='($(pyenv version-name)) '$BASE_PROMPT
else
export PS1=$BASE_PROMPT
fi
}
export PROMPT_COMMAND='updatePrompt'
adding this or similar to the README could be a reasonable substitute for removing/disabling the behaviour. although I'm not sure if this would work in shells other than bash?
@LukeAI Thank you for providing the solution!
I had to make a few changes to make it work (I am using zsh).
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
export BASE_PROMPT=$PS1
function updatePrompt {
if [[ "$(pyenv version-name)" != "system" ]]; then
# the next line should be double quote; single quote would not work for me
export PS1="($(pyenv version-name)) "$BASE_PROMPT
else
export PS1=$BASE_PROMPT
fi
}
export PROMPT_COMMAND='updatePrompt'
precmd() { eval '$PROMPT_COMMAND' } # this line is necessary for zsh
In cases where you have multiple version specified in .python-version the prompt gets really long. Amending the commented lines below allowed me to just show the first version listed in the file:
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
# turn up deprecated pyenv prompt
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
# recreate old pyenv promptbehavior
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
export BASE_PROMPT=$PS1
function updatePrompt {
if [[ "$(pyenv version-name)" != "system" ]]; then
PYENV_VER=$(pyenv version-name) # capture version name in variable
export PS1="(${PYENV_VER%%:*}) "$BASE_PROMPT # grab text prior to first ':' character
else
export PS1=$BASE_PROMPT
fi
}
export PROMPT_COMMAND='updatePrompt'
So after of all, I don't need to concern that warning, right?
I have slightly modified @rmorshea 's script, for people who change the global environment from system:
export PYENV_VIRTUALENV_DISABLE_PROMPT=1
export BASE_PROMPT=$PS1
function updatePrompt {
PYENV_VER=$(pyenv version-name) # capture version name in variable
if [[ "${PYENV_VER}" != "$(pyenv global | paste -sd ':' -)" ]]; then # MODIFIED: "system" -> "$(pyenv global | paste -sd ':' -)"
export PS1="(${PYENV_VER%%:*}) "$BASE_PROMPT # grab text prior to first ':' character
else
export PS1=$BASE_PROMPT
fi
}
export PROMPT_COMMAND='updatePrompt'
| paste -sd ':' - is needed because pyenv global prints line-break separated virtualenv names.
Most helpful comment
Having a prompt showing immediately that you're in a virtualenv is absolutely necessary and invaluable feature. I don't know how many times I've accidentally installed some stuff globally by using pip because I didn't pay enough attention to the prompt showing me that I hadn't activated virtualenv yet.