Skip to content

Is there a way to set environment variables for each version? #263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
RobRoseKnows opened this issue May 12, 2018 · 5 comments
Closed

Is there a way to set environment variables for each version? #263

RobRoseKnows opened this issue May 12, 2018 · 5 comments

Comments

@RobRoseKnows
Copy link

I'd like to be able to set environment variables specific to each virtualenv created by pyenv when I enter a directory. I found Issue #55 that seems to mention this and says it's not currently supported, but it's also from 2014, so I was wondering if anything has changed since then.

I tried adding export statements to ~/.pyenv/versions/3.6.5/envs/my-env/bin/activate (where my-env is a local 3.6.5 virtualenv set in the .python-version file) but they didn't get set. I'm planning on trying direnv as suggested in issue #55, but I was wondering if pyenv now has native support for this, or if such support is planned in the future.

@bossjones
Copy link

Came across this post in another git issue earlier today ... it has some code that is specific to miniconda, but it seems it could work in any situation. pyenv.d hook scripts: #178 (comment) ( Hope that helps @RobRoseKnows ) !

@native-api
Copy link
Member

native-api commented Dec 24, 2024

Pyenv-Virtualenv doesn't actually source the activate/deactivate scripts (but it does source scripts from conda activate.d/deactivate.d and profile.d).

It's possible to execute arbitrary code with an after_activate hook:

$PYENV_ROOT/plugins/<your_plugin_name>/etc/pyenv.d/activate/<your_hook_name.sh>:

your_fn_name() {
  if [[ $venv == "foo" ]]; then
    export magic_word="xyzzy"
  fi
}

after_activate your_fn_name

This script will be sourced at

for script in "${scripts[@]}"; do source "$script"; done
and the hook evald at
for hook in "${after_hooks[@]}"; do eval "$hook"; done
.

@skerain
Copy link

skerain commented Mar 7, 2025

@native-api Sorry, but this is not working. After a git pull, I placed a script in the directory .pyenv/plugins/pyenv-virtualenv/etc/pyenv.d/activate/after_configure_pypi.bash. The content of my script is as follows:

configure_pypi() {
  export SOMETHING="its-a-thing"
}
after_activate configure_pypi

When I replace the last line with the direct execution of the function, a source after_configure_pypi.bash works (SOMETHING is correctly created).

When I activate my virtual environment, no SOMETHING in my environment variables.

What did I not understand ?

@native-api
Copy link
Member

native-api commented Mar 8, 2025

Sorry. I was writing from memory. The example above would work if activate was a regular subcommand. But it's an in-shell subcommand (implemented in pyenv-sh-activate and run by the pyenv shell function; there is also a regular activate subcommand but all it does is print an error message) -- because it needs to make changes to the active shell.

In-shell subcommands (and their hooks) need to print commands to execute in the user's shell rather than execute them directly.

I've tested the following code to work:

~/.pyenv/plugins/venv-envvars/etc/pyenv.d/activate/set-envvars.bash:

set_venv_envvars() {
    echo 'export magic_word="xyzzy"'
}

after_activate set_venv_envvars

Now:

$ pyenv activate test
(test) $ set | grep magic
magic_word=xyzzy

Note that you'll probably also need a similar deactivate hook to unset any of the envvars you set -- otherwise, they'd stick after deactivation which you probably don't want.

@skerain
Copy link

skerain commented Mar 11, 2025

Thank you for taking the time to respond to me, it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants