diff --git a/tests/installers.sh b/tests/installers.sh index f2b89d4..2ad17cb 100755 --- a/tests/installers.sh +++ b/tests/installers.sh @@ -214,6 +214,26 @@ HOME="$pyenv_env_home" XDG_CONFIG_HOME="$pyenv_env_xdg" \ zsh -lc '[[ "$(command -v python3)" == "$HOME/.pyenv/shims/python3" ]]' || fail "pyenv Python is not restored in login zsh after the system profile" +# Interactive initialization runs once while repeated sourcing restores PATH. +mkdir -p "$pyenv_env_home/.pyenv/bin" +cat >"$pyenv_env_home/.pyenv/bin/pyenv" <<'PYENV' +#!/bin/sh +printf '%s\n' "$*" >> "$PYENV_ROOT/init-calls" +printf '%s\n' 'pyenv() { command pyenv "$@"; }' +PYENV +chmod +x "$pyenv_env_home/.pyenv/bin/pyenv" +HOME="$pyenv_env_home" PYENV_ROOT="$pyenv_env_home/.pyenv" PATH=/usr/bin:/bin \ + zsh -dfic ' + source "$1" + (( $+functions[pyenv] )) || exit 1 + path=(/usr/bin /bin) + source "$1" + [[ $(command -v python3) == "$PYENV_ROOT/shims/python3" ]] + ' zsh "$ROOT/zsh/pyenv.zsh" || + fail "interactive pyenv initialization did not preserve its function and Python PATH" +printf '%s\n' 'init - --no-rehash zsh' | cmp -s - "$pyenv_env_home/.pyenv/init-calls" || + fail "pyenv initialization must run once without a startup rehash" + # A later easyzsh migration must not move the login hook before the system profile. HOME="$pyenv_env_home" bash "$ROOT/deploy.sh" --home "$pyenv_env_home" --migrate-zprofile >/dev/null grep -Fqx "$pyenv_login_hook" "$pyenv_env_home/.zprofile" || diff --git a/zsh/pyenv.zsh b/zsh/pyenv.zsh index e282e79..d721231 100644 --- a/zsh/pyenv.zsh +++ b/zsh/pyenv.zsh @@ -3,6 +3,8 @@ export PYENV_ROOT="${PYENV_ROOT:-$HOME/.pyenv}" [[ -d "$PYENV_ROOT/bin" ]] && path=("$PYENV_ROOT/bin" ${path:#$PYENV_ROOT/bin}) [[ -d "$PYENV_ROOT/shims" ]] && path=("$PYENV_ROOT/shims" ${path:#$PYENV_ROOT/shims}) export PATH -if [[ -o interactive ]] && command -v pyenv &> /dev/null; then - eval "$(pyenv init - zsh)" +# Login profiles can reapply PATH without repeating shell integration. +# Run `pyenv rehash` after installing entry points through `python -m pip`. +if [[ -o interactive ]] && (( ! $+functions[pyenv] )) && command -v pyenv &> /dev/null; then + eval "$(pyenv init - --no-rehash zsh)" fi