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

Support virtualenvwrapper with / without pyenv virtualenv-init or virtualenvwrapper plugins #2023

Merged
merged 1 commit into from
Oct 27, 2022

Conversation

jeffwidman
Copy link
Collaborator

@jeffwidman jeffwidman commented Oct 26, 2022

The desired logic is:

For the pyenv plugins virtualenv-init and virtualenvwrapper:

  1. If either plugin is present, activate it
  2. If virtualenvwrapper plugin is not present, then fallback to standard virtualenvwrapper.
  3. If virtualenvwrapper plugin is present, then don't fallback to
    standard virtualenvwrapper, regardless of whether virtualenv-init is present.

Previously, if the virtualenv command was present but pyenv was
missing, then the fallback wouldn't be hit. This bug was introduced by
#1981 which ensured that
the pyenv virtualenvwrapper plugin was activated if present,
regardless of the presence of the virtualenv-init plugin.

As an optimization, the check for the pyenv plugins are skipped if
pyenv itself isn't found.

Since we only want to fallback if the pyenv virtualenvwrapper plugin
is missing, but that's buried within the pyenv logic and we also need
to handle when pyenv itself is missing, this switches to using a flag
variable.

I also renamed the virtualenv_sources var to
virtualenvwrapper_sources as virtualenv is distinct from
virtualenvwrapper, so using one name for a var that is really about
the other is confusing.

Looking at git blame, there's a lot of prior art here around trying
to support all the permutations of pyenv and various plugins:

So we need to be extremely careful to continue to support all these permutations.

Fix #2022

@jeffwidman jeffwidman force-pushed the make-virtualenvwrapper-work-without-pyenv branch from a97c139 to 2b7d12a Compare October 26, 2022 06:07
@jeffwidman jeffwidman changed the title Support virtualenvwrapper with / without pyenv and with / without virtualenv-init plugin Support virtualenvwrapper with / without pyenv virtualenv-init or virtualenvwrapper plugins Oct 26, 2022
@jeffwidman jeffwidman force-pushed the make-virtualenvwrapper-work-without-pyenv branch 5 times, most recently from 7230970 to 155b667 Compare October 26, 2022 06:43
if (( $pyenv_plugins[(i)virtualenvwrapper(_lazy|)] <= $#pyenv_plugins )); then
pyenv "$pyenv_plugins[(R)virtualenvwrapper(_lazy|)]"
$pyenv_virtualenvwrapper_plugin_found=true
fi
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only change in this block is indenting within the pyenv check + setting the pyenv_virtualenvwrapper_plugin_found var.

@jeffwidman jeffwidman marked this pull request as ready for review October 26, 2022 06:46
@jeffwidman jeffwidman marked this pull request as draft October 26, 2022 06:51
…or `virtualenvwrapper` plugins

The desired logic is:

For the `pyenv` plugins `virtualenv-init` and `virtualenvwrapper`:
1. If either plugin is present, activate it
2. If `virtualenvwrapper` plugin is not present, then
   [fallback to standard
   `virtualenvwrapper`](#1414 (comment)).
3. If `virtualenvwrapper` plugin is present, then [don't fallback to
   standard `virtualenvwrapper`, regardless of whether `virtualenv-init`
   is
   present](#1981 (comment)).

Previously, if the `virtualenv` command was present but `pyenv` was
missing, then the fallback wouldn't be hit. This bug was introduced by
#1981 which ensured that
the `pyenv` `virtualenvwrapper` plugin was activated if present,
regardless of the presence of the `virtualenv-init` plugin.

As an optimization, the check for the `pyenv` plugins are skipped if
`pyenv` itself isn't found.

Since we only want to fallback if the `pyenv` `virtualenvwrapper` plugin
is missing, but that's buried within the `pyenv` logic and we also need
to handle when `pyenv` itself is missing, this switches to using a flag
variable.

I also renamed the `virtualenv_sources` var to
`virtualenvwrapper_sources` as `virtualenv` is distinct from
`virtualenvwrapper`, so using one name for a var that is really about
the other is confusing.

Looking at `git blame`, there's a _lot_ of prior art here around trying
to support all the permutations of `pyenv` and various plugins:
* #1413
* #1414
* #1433
* #1434

So we need to be extremely careful to continue to support all these
permutations.

Fix #2022
@jeffwidman jeffwidman force-pushed the make-virtualenvwrapper-work-without-pyenv branch from 155b667 to 4ced4a6 Compare October 26, 2022 06:58
)
if (( $#virtualenvwrapper_sources )); then
source "$virtualenvwrapper_sources[1]"
fi
Copy link
Collaborator Author

@jeffwidman jeffwidman Oct 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only change in this block of logic is the rename of virtenv_sources to virtualenvwrapper_sources

@@ -116,38 +116,42 @@ if (( $+VIRTUALENVWRAPPER_VIRTUALENV || $+commands[virtualenv] )) \
# look for plugins of interest. Scanning shell '$path' isn't enough as they
# can exist in 'pyenv' synthesized paths (e.g., '~/.pyenv/plugins') instead.
local -a pyenv_plugins
local pyenv_virtualenvwrapper_plugin_found
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing revealed this line isn't necessary... but I was unclear if it's more idiomatic to declare the var since otherwise it's only set deep in nested if, but then tested at a higher level of scope.

Also unclear if when declaring it's best to declare it as a local or not... I don't understand why pyenv_plugins is declared as a local but virtenv_sources isn't...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think pyenv_plugins is declared locally so we can specify that it's an array. It seems reasonable to also declare pyenv_virtualenvwrapper_plugin_found up here.

@jeffwidman jeffwidman marked this pull request as ready for review October 26, 2022 07:03
@jeffwidman
Copy link
Collaborator Author

@zbirenbaum @diraol @zachwhaley since you were all involved in prior PR's around this section of code logic, can you take this for a test drive to ensure I'm not accidentally breaking something in your use cases with this.

Also @indrajitr / @belak I'd appreciate some sanity check reviews.

Copy link
Collaborator

@belak belak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this change - I think it's a more formalized version of the logic we wanted in the first place and starts removing some of the magic/inconsistencies.

It's way easier to say "pyenv's virtualenv plugin will be used when available, otherwise we fall back to the plain virtualenvwrapper".

@@ -116,38 +116,42 @@ if (( $+VIRTUALENVWRAPPER_VIRTUALENV || $+commands[virtualenv] )) \
# look for plugins of interest. Scanning shell '$path' isn't enough as they
# can exist in 'pyenv' synthesized paths (e.g., '~/.pyenv/plugins') instead.
local -a pyenv_plugins
local pyenv_virtualenvwrapper_plugin_found
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think pyenv_plugins is declared locally so we can specify that it's an array. It seems reasonable to also declare pyenv_virtualenvwrapper_plugin_found up here.

@zbirenbaum
Copy link
Collaborator

I like this too. My change was a quick one to prevent people from getting locked out of their systems since that’s a really bad bug to have. This is a better formalization.

@jeffwidman
Copy link
Collaborator Author

Thanks all!

I'm going to merge given the positive reception. If we find further bugs/unhandled edge cases, I'm happy to take another look.

@jeffwidman jeffwidman merged commit e3a9583 into master Oct 27, 2022
@jeffwidman jeffwidman deleted the make-virtualenvwrapper-work-without-pyenv branch October 27, 2022 06:46
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

Successfully merging this pull request may close these issues.

virtualenvwrapper broke after d840f0fc7bb9e604fedef40eff4ed53f4c3c60f6
3 participants