pyenv initialization in .bash_profile vs. .bashrc (after release 2.0.0) - bash

With the recent release of pyenv 2.0.0, the documentation currently recommends the following configuration for a bash shell:
# inside ~/.bash_profile
eval "$(pyenv init --path)"
# inside ~/.bashrc
eval "$(pyenv init -)"
If I'm not allowed to edit .bashrc on my system (for reasons completely unrelated to pyenv), what would be the drawbacks of just putting both inside my profile, like this:
# inside ~/.bash_profile
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
I've been using it like this for a few hours, and I haven't noticed any issues (on MacOS, with a Homebrew installation of pyenv, and Python 3.6/3.7/3.8 virtual environments created with venv). I'm trying to understand what might be the drawbacks of configuring my system this way, and why the documentation makes such a big deal about using both .bash_profile and .bashrc.
Will configuring pyenv in this way cause problems for me in the future?

Bash only runs ~/.bash_profile when you start a login shell. When you start a new shell by typing bash or exec bash, its runs only ~/.bashrc. However, you can work around this easily by always starting new shells with bash -l or exec bash -l, which will make the new shell a login shell.
To find out whether it makes a difference whether you don't run eval "$(pyenv init -)" in non-login shells, let's have a look at what pyenv init - really does:
$ pyenv init -
export PYENV_SHELL=bash
source '/usr/local/Cellar/pyenv/2.0.0/libexec/../completions/pyenv.bash'
command pyenv rehash 2>/dev/null
pyenv() {
local command
command="${1:-}"
if [ "$#" -gt 0 ]; then
shift
fi
case "$command" in
rehash|shell)
eval "$(pyenv "sh-$command" "$#")"
;;
*)
command pyenv "$command" "$#"
;;
esac
}
Since export PYENV_SHELL=bash puts $PYENV_SHELL into the environment, it will get imported for your non-login shells, too. So, that doesn't make any difference.
As for the rest, it looks like the main thing you're missing out on is command line completion for pyenv. Other than that, there's just some special wrapping for pyenv shell and pyenv rehash.
So, as long as you don't use tab completion for pyenv nor use the commands pyenv shell and pyenv rehash in your non-login shells, then it should make no difference. But even if you do want to use those there, you can simply start the shell with bash -l or just run eval "$(pyenv init -)" manually.

Related

How to set path correctly from RBENV shims on Mac M1 with zsh

I'm having trouble setting up the rbenv paths
I follow the instructions as specified here: rbenv installation page
I run the command on a zsh terminal:
rbenv init
The terminal gives me the instruction to run
eval "$(rbenv init - zsh)"
I then close the restart the terminal and check to see if all is configured correctly by running:
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash
and I get the following failure:
Checking for rbenv shims in PATH: not found
If I try open the fils .zshrc I find only the following path written to it
export PATH="/opt/homebrew/opt/libpq/bin:$PATH"
but no shims. Can I add the shims manually? I don't know what it should look like? Or is there any reason the command eval "$(rbenv init - zsh)" is not working properly?
Got it working: I need to run echo 'eval "$(rbenv init -)"' >> ~/.zshrc

pyenv: failed to activate virtualenv - settings not read from .profile at login

This is a known topic, almost similar to this one.
However - why am I having the pyenv settings passed in ok from .profile at login only up to the virtualenv string.
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
eval "$(pyenv virtualenv-init -)"
After login, the above portion is read (pyenv is active in terminal) but not virtualenv. Manual activation of the venv produces the well-known error message.
$pyenv activate venv_name
Failed to activate virtualenv.
Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.
I can solve this by explicitly sourcing .profile - then it works fine.
But why would .profile not be read or interpreted at once at login?
Modifying .bashrc takes no effect. Seems like it's not being read. But .profile is.
Global python is system (2.7).
Take care
Try pyenv init --path instead of pyenv init - and again putting it in bashrc.

conda activate on Travis CI

I am using conda 4.6.8 to test a python package in a conda env on Travis CI. I want to replace my old source activate ENVNAME line with the new conda activate ENVNAME command in my Travis CI configuration. If I run this on Travis:
>>> conda update -n base conda
>>> conda init
no change /home/travis/miniconda/condabin/conda
no change /home/travis/miniconda/bin/conda
no change /home/travis/miniconda/bin/conda-env
no change /home/travis/miniconda/bin/activate
no change /home/travis/miniconda/bin/deactivate
no change /home/travis/miniconda/etc/profile.d/conda.sh
no change /home/travis/miniconda/etc/fish/conf.d/conda.fish
no change /home/travis/miniconda/shell/condabin/Conda.psm1
no change /home/travis/miniconda/shell/condabin/conda-hook.ps1
no change /home/travis/miniconda/lib/python3.7/site-packages/xonsh/conda.xsh
no change /home/travis/miniconda/etc/profile.d/conda.csh
modified /home/travis/.bashrc
==> For changes to take effect, close and re-open your current shell. <==
How can I "close and re-open" my shell on Travis? Because otherwise I cannot activate my conda environment:
>>> conda create -n TEST package_names
>>> conda activate TEST
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run
$ conda init <SHELL_NAME>
Currently supported shells are:
- bash
- fish
- tcsh
- xonsh
- zsh
- powershell
See 'conda init --help' for more information and options.
IMPORTANT: You may need to close and restart your shell after running 'conda init'.
The command "conda activate TEST" failed and exited with 1 during .
Your build has been stopped.
Not sure it is currently supported as the official doc still uses source in travis.yml.
What does conda init do?
This new command should harmonize the way users setup their shells to be able to call conda activate.
Actually, if you run conda init --dry-run --verbose you will see that it tries to source conda.sh from your ~/.bashrc (assuming you're running Bash, from info mentioned in your question).
And conda.sh will define a conda() function that will catch a few commands among which activate and deactivate and dispatch to $CONDA_EXE:
conda() {
if [ "$#" -lt 1 ]; then
"$CONDA_EXE"
else
\local cmd="$1"
shift
case "$cmd" in
activate|deactivate)
__conda_activate "$cmd" "$#"
;;
install|update|upgrade|remove|uninstall)
"$CONDA_EXE" "$cmd" "$#" && __conda_reactivate
;;
*) "$CONDA_EXE" "$cmd" "$#" ;;
esac
fi
}
So unless this function is defined in your local shell, you won't be able to call conda activate.
Hint on a solution? (not tested for Travis CI)
The only hint I can suggest is to try source $(conda info --root)/etc/profile.d/conda.sh and then conda activate. This should do roughly the same as conda init assuming you are using Bourne shell derivatives.
For csh there is $(conda info --root)/etc/profile.d/conda.csh, and for fish there is $(conda info --root)/etc/fish/conf.d/conda.fish
Note: although not tested for Travis CI, this solution works for me from bash. Of course, the conda executable should be found in PATH for conda info --root to work properly.

Failed to activate virtualenv via shellscript

I'm trying to activate my pyenv-virtualenv environment through very simple bash script like this.
set -e
pyenv activate myenv
But I can't activate my env with below error:
Failed to activate virtualenv.
Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.
I can activate it in command line, so I think it's due to my shell environment.
I use fish shell, but it's launched after $PATH settings read in bash shell.
I show you my settings.
.bash_profile:
export LANG="ja_JP.UTF-8"
export XDG_CONFIG_HOME="$HOME/.config"
export PATH="/sbin"
export PATH="/usr/sbin:$PATH"
export PATH="/bin:$PATH"
export PATH="/usr/bin:$PATH"
export PATH="/usr/local/bin:$PATH"
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
exec fish
And my config.fish:
status --is-interactive; and source (pyenv init -|psub)
status --is-interactive; and source (pyenv virtualenv-init -|psub)
What's wrong?
I'm using:
OS: OS X 10.13.5
fish: v2.7.1
pyenv: v1.2.5
pyenv-virtualenv: v1.1.3
I believe the cause is that you are initializing PyEnv in the Fish shell environment but then calling PyEnv in the Bash shell environment (via your Bash script). To solve this problem, you could try either of the following potential solutions:
Initialize PyEnv in your Bash environment (in addition to your Fish environment)
Write your script in Fish instead of Bash
Since PyEnv seems so have better support for Bash than Fish, let's focus on option #1. Step 3 of the PyEnv installation guide suggests the following command for adding PyEnv initialization to your ~/.bash_profile:
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bash_profile
After running that command, I suspect your script will function as you expect. If it does not, you could try adding the same PyEnv initialization snippet (that you just added to your ~/.bash_profile) to the top of your Bash script.

What's "which pyenv > /dev/null" mean?

Everyone write if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi into .bashrc etc after installation of pyenv.
I know if I didn't excute eval "$(pyenv init -)", python's version would not change.
Why do I need to write if which pyenv > /dev/null?
What's it mean? What would happen without it?
Thanks.
It is used to check if pyenv is found, but suppress the output of the which command.
Without it, the output of which would print to the console, every time .bashrc is sourced.

Resources