jorgenschaefer / pyvenv

Python virtual environment interface for Emacs
363 stars 57 forks source link

postactivate not run? #40

Open jluttine opened 8 years ago

jluttine commented 8 years ago

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 in postactivate. However, these variables are not available after running pyvenv-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?

jluttine commented 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.

jluttine commented 8 years ago

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.

jorgenschaefer commented 8 years ago

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?

jluttine commented 8 years ago

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.

jorgenschaefer commented 8 years ago

What's the value of M-: (pyvenv-hook-dir)?

jluttine commented 8 years ago

Not a valid command and no such variable found... I wonder if this is something wrong in how Spacemacs configures pyvenv..

jorgenschaefer commented 8 years ago

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. :-/

diegolascasas commented 8 years ago

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)

jorgenschaefer commented 8 years ago

Strange and stranger … do you export those environment variables? If not, could you try to do so?

diegolascasas commented 8 years ago

Thanks for the quick reply (:

Yes, they are all exported.

jorgenschaefer commented 8 years ago

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?

diegolascasas commented 8 years ago
# 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.

jorgenschaefer commented 8 years ago

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.

diegolascasas commented 8 years ago

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.

jorgenschaefer commented 8 years ago

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?

jluttine commented 8 years ago

This sounds like it could be my problem too. I'm setting up virtualenvwrapper in ~/.bash_profile as source virtualenvwrapper.sh.

jorgenschaefer commented 8 years ago

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.

jefftrull commented 6 years ago

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.

jorgenschaefer commented 5 years ago

I have no idea what might be causing this I'm afraid. If you find out, please let me know!

jefftrull commented 5 years ago

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)

jorgenschaefer commented 5 years ago

Sorry for the late reply. Yes, I can reproduce this. I do not know how to fix it. :-(

jefftrull commented 5 years ago

Ah OK, thanks for the explanation. Let's keep this open, shall we? Maybe someone will get a brainwave.