pyenv/libexec/pyenv-which
Daniel Hahler 44c20af80e Optimize pyenv-which: implement remove_from_path in Bash
This greatly improves the performance of `pyenv virtualenvwrapper_lazy`,
which happens to call pyenv-which a lot.

For profiling I've initially used:

    % zmodload zsh/zprof
    % eval "$(pyenv init -)"
    % pyenv virtualenvwrapper_lazy

    Before:
    % zprof|grep -E '(pyenv|virtualenv)'
     1)    1         754,07   754,07   58,95%    751,50   751,50   58,75%  pyenv
    21)    1           2,57     2,57    0,20%      2,57     2,57    0,20%  virtualenvwrapper_setup_lazy_loader
     1)    1         754,07   754,07   58,95%    751,50   751,50   58,75%  pyenv
           1/1         2,57     2,57    0,20%      2,57     2,57             virtualenvwrapper_setup_lazy_loader [21]
           1/1         2,57     2,57    0,20%      2,57     2,57             pyenv [1]
    21)    1           2,57     2,57    0,20%      2,57     2,57    0,20%  virtualenvwrapper_setup_lazy_loader

    After:
    % zprof|grep -E '(pyenv|virtualenv)'
     1)    1         383,30   383,30   27,97%    380,88   380,88   27,79%  pyenv
    31)    1           2,42     2,42    0,18%      2,42     2,42    0,18%  virtualenvwrapper_setup_lazy_loader
     1)    1         383,30   383,30   27,97%    380,88   380,88   27,79%  pyenv
           1/1         2,42     2,42    0,18%      2,42     2,42             virtualenvwrapper_setup_lazy_loader [31]
           1/1         2,42     2,42    0,18%      2,42     2,42             pyenv [1]
    31)    1           2,42     2,42    0,18%      2,42     2,42    0,18%  virtualenvwrapper_setup_lazy_loader

Fixes https://github.com/yyuu/pyenv-virtualenvwrapper/issues/13
2014-03-13 19:21:32 +01:00

66 lines
1.4 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Summary: Display the full path to an executable
#
# Usage: pyenv which <command>
#
# Displays the full path to the executable that pyenv will invoke when
# you run the given command.
set -e
[ -n "$PYENV_DEBUG" ] && set -x
# Provide pyenv completions
if [ "$1" = "--complete" ]; then
exec pyenv shims --short
fi
OLDIFS="$IFS"
IFS=: versions=($(pyenv-version-name))
IFS=: PYENV_VERSION="${versions[*]}"
IFS="$OLDIFS"
PYENV_COMMAND="$1"
if [ -z "$PYENV_COMMAND" ]; then
pyenv-help --usage which >&2
exit 1
fi
for version in "${versions[@]}"; do
if [ "$version" = "system" ]; then
# Remove shims from PATH:
_path=":$PATH:"
_remove="${PYENV_ROOT}/shims"
_path="${_path//:$_remove:/:}"
PYENV_COMMAND_PATH="$(PATH=$_path command -v "$PYENV_COMMAND" || true)"
else
PYENV_COMMAND_PATH="${PYENV_ROOT}/versions/${version}/bin/${PYENV_COMMAND}"
fi
if [ -x "$PYENV_COMMAND_PATH" ]; then
break
fi
done
OLDIFS="$IFS"
IFS=$'\n' scripts=(`pyenv-hooks which`)
IFS="$OLDIFS"
for script in "${scripts[@]}"; do
source "$script"
done
if [ -x "$PYENV_COMMAND_PATH" ]; then
echo "$PYENV_COMMAND_PATH"
else
echo "pyenv: $PYENV_COMMAND: command not found" >&2
versions="$(pyenv-whence "$PYENV_COMMAND" || true)"
if [ -n "$versions" ]; then
{ echo
echo "The \`$1' command exists in these Python versions:"
echo "$versions" | sed 's/^/ /g'
echo
} >&2
fi
exit 127
fi