Skip to content
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

Python module failing to run pyenv virtualenv-init #1428

Closed
zachwhaley opened this issue Aug 16, 2017 · 16 comments
Closed

Python module failing to run pyenv virtualenv-init #1428

zachwhaley opened this issue Aug 16, 2017 · 16 comments

Comments

@zachwhaley
Copy link
Contributor

zachwhaley commented Aug 16, 2017

Description

It seems like the Python module is incorrectly using the commands array, by trying to find a command named pyenv-virtualenv-init, causing the module to not find and run pyenv virtualenv-init.
Line in question: https://github.com/sorin-ionescu/prezto/blob/master/modules/python/init.zsh#L96

But looking at the code history, the Python module has been using this since April of 2017 1050a0a, so I feel like I must be doing something wrong.

I have pyenv installed with the virtualenv plugin, but when I run $+commands[pyenv-virtualenv-init] in my shell I get 0

Expected behavior

virtualenv is loaded via pyenv

Actual behavior

virtualenv is not loaded, and an error is printed on shell open

/home/zwhaley/.zprezto/modules/python/init.zsh:source:109: no such file or directory: 

Steps to Reproduce

  1. Enable Python module zstyle ':prezto:module:python:virtualenv' auto-switch 'yes'
  2. Open shell

Versions

  • Prezto commit: dbf96d2
  • ZSH version: zsh 5.3.1 (x86_64-redhat-linux-gnu)
  • OS information: Fedora release 26 (Twenty Six) x86_64
@gpanders
Copy link
Contributor

gpanders commented Aug 16, 2017

Additionally, if one installs pyenv and pyenv-virtualenv via Homebrew, the condition (( $+VIRTUALENVWRAPPER_VIRTUALENV || $+commands[virtualenv] )) in the if-check will return false, since neither the environment variable or the command is defined. This prevents the execution from even reaching the if (( $+commands[pyenv-virtualenv-init] )); then line.

I think the first if-check condition should be changed to

(( $+VIRTUALENVWRAPPER_VIRTUALENV || $+commands[virtualenv] || $+commands[pyenv-virtualenv-init] ))

@zachwhaley
Copy link
Contributor Author

Doing some more diving, and it seems like there is a pyenv-virtualenv-init executable in $(pyenv root)/plugins/pyenv-virtualenv/bin/. Is this something Prezto is supposed to add to my path for me?

@gpanders
Copy link
Contributor

@zachwhaley How did you install pyenv-virtualenv?

@zachwhaley
Copy link
Contributor Author

@gpanders I believe I installed it using pyenv-installer

@gpanders
Copy link
Contributor

@zachwhaley I removed my last comment. I just looked through the pyenv source and found this line:

for plugin_bin in "${PYENV_ROOT}/plugins/"*/bin; do
    PATH="${plugin_bin}:${PATH}"
done

So if the pyenv-virtualenv-init executable is truly in your $(pyenv root)/plugins/pyenv-virtualenv/bin/ directory as you claim, it should be added to your path automatically with the execution of eval $(pyenv init -). It seems like something else is afoot here.

@zachwhaley
Copy link
Contributor Author

@gpanders Good question. I'll look into this and get back to y'all.

@zachwhaley
Copy link
Contributor Author

So running eval "$(pyenv init -)" does not add any plugin bin paths to my shell session's PATH, but instead adds to the sub-shell session that is run when pyenv is called.

pyenv init - itself just prints out some shell commands that we then eval, which is what is actually added to my shell session. And from the looks of it, the only thing that is added to the user's path is $HOME/.pyenv/shims

So I do think your original comment was correct. Prezto can't rely on the plugin executables being in the user's PATH.

SO link 🙂

@belak
Copy link
Collaborator

belak commented Aug 17, 2017

If we can't rely on pyenv being in the path, how can we find it?

virtualenvwrapper is reasonable because it has a few possible names it can be called (some of which are in the PATH and some which aren't)... but people don't generally install it to some random location. Are there common locations the pyenv commands are installed which we could check (allowing an override for completely different paths)?

I personally don't currently use pyenv... I stick to just virtualenvwrapper... but I would be happy to review any pull requests which attempt to solve this.

@gpanders
Copy link
Contributor

gpanders commented Aug 17, 2017

@belak pyenv is on the path, but pyenv-virtualenv-init is not for certain installation methods (i.e. using Github to clone the project, which is what one would do on Ubuntu).

The command pyenv virtualenv-init - is valid (notice the space between pyenv and virtualenv-init. This is a different command) and is what needs to be executed, so we could just call that and check the return code for a zero value; however, I don't know what the performance impact is of executing that function simply for an if condition. I'll bet there is a more elegant way.

@diraol
Copy link
Contributor

diraol commented Aug 17, 2017

@zachwhaley did you experienced this problem with pyenv virtualenvwrapper?
https://github.com/pyenv/pyenv-virtualenvwrapper/issues/19

or something similar to it?

@zachwhaley
Copy link
Contributor Author

If you want to avoid calling a command that doesn't exist, you could use the pyenv commands command to list the available commands and grep for virtualenv-init

e.g.

if pyenv commands | command grep -q virtualenv-init; then
    $(pyenv virtualenv-init -)
fi

@zachwhaley
Copy link
Contributor Author

@diraol I don't have virtualenvwrapper installed, which is why the fallback in python/init.zsh doesn't work for me.

@gpanders
Copy link
Contributor

@zachwhaley That looks like it should work to me. Do you want to test it and write a PR?

@zachwhaley
Copy link
Contributor Author

@gpanders Sure!

@indrajitr
Copy link
Collaborator

indrajitr commented Aug 17, 2017

Okay, catching up on this one. Apologies for delayed response.

If you want to avoid calling a command that doesn't exist, you could use the pyenv commands command to list the available commands and grep for virtualenv-init

e.g.

if pyenv commands | command grep -q virtualenv-init; then
    $(pyenv virtualenv-init -)
fi

Based on source, it seems to be doing regular $PATH scanning.

But seems like this worked for @gpanders, so I am wondering how this is getting treated different from $+commands[pyenv-virtualenv-init].


Edit: Is it possible that $HOME/.pyenv/shims has been prepended to the $PATH as a result of a pyenv init - in ~/.zshrc?

@gpanders
Copy link
Contributor

gpanders commented Aug 17, 2017

@indrajitr The reason it worked for me is because I was on a Mac and installed the pyenv-virtualenv package from Homebrew. This package places an executable pyenv-virtualenv-init in /usr/local/bin, which is on the user's path, so the $+commands[pyenv-virtualenv-init] returns true.

However, when installing pyenv-virtualenv on Ubuntu using either the pyenv-installer or simply Git cloning into ~/.pyenv/plugins, there is no pyenv-virtualenv-init on the path. @zachwhaley's grep solution works in either case, so I think that is the way to go.

Edit: There does seem to be some confusion here regarding the difference between pyenv-virtualenv-init and pyenv virtualenv-init. One has a dash, the other a space. The former is what prezto is currently checking for on the path, while the latter is the actual command to be executed.

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

5 participants