Open jluttine opened 8 years ago
I'm seeing this as follows: I use Spacemacs and Python layer. I activate my virtual environment with pyvenv (pyvenv-workon
). I then launch a Python shell and send the current buffer to it (python-shell-send-buffer
). But it complains that some environment variables aren't defined although they are defined in postactivate
script of the virtual environment. Everything works outside Emacs. I'm not sure if this is an issue in the Emacs Python shell instead.
Just a note: If I look at the list of environment variables with shell-copy-environment-variable
, I can see variables like VIRTUAL_ENV
etc which are defined by workon
but not the environment variables defined in postactivate
. So it seems that postactivate
isn't run at all.
Hello and thank you for the report! Pyvenv should detect changes to the environment in your postactivate script and adjust Emacs' environment accordingly. Processes already started will not see the changed environment, but if your Python shell is new, it should see the changes.
You can try M-: (getenv "VARIABLE")
to see the value Emacs sees itself to make sure the variable is indeed not set.
If it is not set, do add some code to your postactivate
script that prints some message. Pyvenv should pop up a window with the output after you activate the relevant virtualenv. Does this work?
Those variables are not available with getenv
after activating the environment with pyvenv-workon
. I added echo HELLO
to postactivate
but I can't see that message printing anywhere in Emacs. As a workaround, I define the environment variables with setenv
in .dir-locals.el
of the relevant project.
What's the value of M-: (pyvenv-hook-dir)
?
Not a valid command and no such variable found... I wonder if this is something wrong in how Spacemacs configures pyvenv..
I do not know how to run an elisp expression in spacemacs I am afraid. I would like to know what the return value of that function is - it might be that your setup is missing some variable pyvenv needs. :-/
I am also having this problem. I use (vanilla) emacs 24.5.1.
My postactivate script exports some environment variables, but they are not defined after pyvenv-workon
using M-: (getenv "NAME")
. If I write a command in it such as echo hello!
, it is not displayed in a buffer, regardless if I put it in the "global" postactivate or on the project-specific postactivate.
The variables are defined if I call workon from the terminal.
M-: (pyvenv-hook-dir)
returns my virtualenv dir (~/.virtualenvs
)
Strange and stranger … do you export
those environment variables? If not, could you try to do so?
Thanks for the quick reply (:
Yes, they are all exported.
Ok. Let's do this step by step.
Could you run the following code, inside your virtualenv:
$VIRTUALENVWRAPPER_PYTHON -c "from virtualenvwrapper.hook_loader import main; main()" --script foo.txt post_activate
( . foo.txt ; env )
Does this show the environment variables? What are the contents of foo.txt
?
# post_activate
# project
#
# Change to the project directory, as long as we haven't been told not to.
#
[ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME" -a "$VIRTUALENVWRAPPER_PROJECT_CD" = 1 ] && virtualenvwrapper_cd "$(cat "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME")"
# user_scripts
#
# Run user-provided scripts
#
[ -f "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate" ] && source "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate"
[ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate" ] && source "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate"
It does show the environment variables.
Also, I normally run emacs on the window system (installed from homebrew -- OS X). I noticed that if I run it from the command line I get the variables that are defined in the global postactivate (but not in the local)
Moreover, a number of variables are not defined in the window system and are in the shell after I run pyenv-workon
: all VIRTUALENVWRAPPER_*
, PROJECT_HOME
, WORKON_HOME
.
There's a long-standing bug/mis-feature in OS X that it does not export the same environment variables in the GUI, and thus GUI-launched applications, than it does in a shell. There are some discussions on how to fix this online, including a package that sets environment variables from a shell in OS X.
You might be missing VIRTUALENVWRAPPER_ENV_BIN_DIR
, I suppose. That would break virtualenv-specific hooks.
Thanks for the pointer! I changed the way I initialize Emacs.app and now it is loading my shell environment.
Even so, as you said, VIRTUALENVWRAPPER_ENV_BIN_DIR
was missing.
It turns out it is not exported by virtualenvwrapper.sh
(it is kept local, so it is still defined after the script is sourced). I changed my .zshrc to export it after sourcing the script, and now everything seems to work.
Hm. That would mean that your shell-file-name
, when invoked to run a script, does not set up virtualenvwrapper. Is that the case? Where do you set up virtualenvwrapper?
This sounds like it could be my problem too. I'm setting up virtualenvwrapper in ~/.bash_profile
as source virtualenvwrapper.sh
.
virtualenvwrapper suggests sourcing the .sh file in .bashrc
, not .bash_profile
… you might already have problems in a subshell this way. Hm.
I guess pyvenv should export some of the virtualenvwrapper variables just to be sure … At least these, it seems:
VIRTUALENVWRAPPER_PROJECT_FILENAME=.project
VIRTUALENVWRAPPER_HOOK_DIR=$WORKON_HOME
VIRTUALENVWRAPPER_ENV_BIN_DIR=bin
Or maybe just source VIRTUALENVWRAPPER_SCRIPT
, although that might not be set, either. Hrm.
I'm running into this problem as well :( On Linux, though. I tried doing manual setenv on VIRTUALENVWRAPPER_WORKON_CD, VIRTUALENVWRAPPER_HOOK_DIR, VIRTUALENVWRAPPER_SCRIPT, and VIRTUALENVWRAPPER_PROJECT_FILENAME
as well as starting Emacs from a shell where these were already set, but in no case did my desired environment variable get set from the postactivate script.
As the other users reported, it works fine on the command line.
I have no idea what might be causing this I'm afraid. If you find out, please let me know!
Perhaps a test case would help. Create a new environment:
mkvirtualenv bar
Add an environment variable:
cat >> /path/to/Envs/bar/bin/postactivate
export TEST_ENV_VAR=NotWorking
Try it out in the shell:
% workon bar
% printenv | grep TEST_ENV_VAR
TEST_ENV_VAR=NotWorking
Now in emacs:
M-x pyvenv-workon
bar
M-x getenv
TEST_ENV_VAR
(no match)
Sorry for the late reply. Yes, I can reproduce this. I do not know how to fix it. :-(
Ah OK, thanks for the explanation. Let's keep this open, shall we? Maybe someone will get a brainwave.
I'm not quite sure about this but it seems to me that
postactivate
script of my virtualenvironment isn't run. I have created my venv with virtualenvwrapper and defined some environment variables inpostactivate
. However, these variables are not available after runningpyvenv-workon
although the virtual environment seems to be otherwise properly activated. Is this to be expected, is there a bug somewhere or am I doing something wrong?