Compare commits

...

9 Commits

Author SHA1 Message Date
Anup Das
cf6f3c3200
fix(rehash): prevent terminal hang caused by stale or sandbox-blocked lock file (#3469)
* reduce stale lock TTL to 2 min, check for stale lock before acquiring and each time -- to hold up new shell sessions for as little as possible

---------

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-06-04 22:36:11 +03:00
Ivan Pozdeev
45180928d3
2.7.1 2026-06-03 09:09:54 +03:00
native-api
c12fd3ae6b
realpath.c: fix obsolete syntax warning (#3468) 2026-06-03 08:42:53 +03:00
Ayush
455d1a31db
init: add --install for shell setup (#3454) 2026-06-03 01:13:07 +03:00
pyenv-bot[bot]
efc77132f7
Add CPython 3.15.0b2 (#3467)
Co-authored-by: native-api <2670332+native-api@users.noreply.github.com>
2026-06-03 00:55:40 +03:00
native-api
c425c9ec3a
Update URLs for PyPy nightly; Remove pypy3.5 and pypy3.7 nightly (#3466)
pypy3.5-c-jit-latest and pypy3.7-c-jit-latest are no longer available
2026-06-02 13:16:51 +03:00
native-api
95ddd7d479
Support 3.9 EOL Pip URL, consolidate tests (#3465) 2026-06-02 10:29:59 +03:00
Ivan Pozdeev
29057a6c69
2.6.32 2026-05-31 06:20:35 +03:00
native-api
23eb9a9ee3
Merge pull request #3463 from native-api/3.14_openssl_4_r2
3.14.0-5: Support building against OpenSSL 4
2026-05-31 05:59:43 +03:00
17 changed files with 430 additions and 246 deletions

View File

@ -1,5 +1,26 @@
# Version History
## Release v2.7.1
* Support 3.9 EOL Pip URL, consolidate tests by @native-api in https://github.com/pyenv/pyenv/pull/3465
* Update URLs for PyPy nightly; Remove pypy3.5 and pypy3.7 nightly by @native-api in https://github.com/pyenv/pyenv/pull/3466
* Add CPython 3.15.0b2 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3467
* init: add --install for shell setup by @macayu17 in https://github.com/pyenv/pyenv/pull/3454
* realpath.c: fix obsolete syntax warning by @native-api in https://github.com/pyenv/pyenv/pull/3468
## Release v2.6.32
* Add miniconda3 26.3.2-2, miniforge3 26.3.2-0, 26.3.2-1 by @native-api in https://github.com/pyenv/pyenv/pull/3445
* miniforge3 26.1, 26.3, add_miniforge: exclude .pkg installers by @native-api in https://github.com/pyenv/pyenv/pull/3446
* miniforge 26, CI: switch check to 3.13 by @native-api in https://github.com/pyenv/pyenv/pull/3447
* 2.7, 3.4: force C99 standard; 2.7.14-18: force OpenSSL 1 formula by @native-api in https://github.com/pyenv/pyenv/pull/3448
* rehash: detect and remove a stale lockfile by @native-api in https://github.com/pyenv/pyenv/pull/3450
* Add GraalPy 25.0.3 by @msimacek in https://github.com/pyenv/pyenv/pull/3452
* 3.11.0+: Use the `--with-openssl-rpath' Configure option when possible by @native-api in https://github.com/pyenv/pyenv/pull/3458
* python_build: Make `verify_python` verify `pythonX.Y' suffix by @native-api in https://github.com/pyenv/pyenv/pull/3459
* Add micropython 1.22.0 to 1.28.0; add downstream patches to fix compilation errors by @native-api in https://github.com/pyenv/pyenv/pull/3460
* Fix linking against a keg_only Homebrew OpenSSL when a a non-keg_only one is also installed by @native-api in https://github.com/pyenv/pyenv/pull/3462
* Add missing CPython 3.14.2t by @native-api in https://github.com/pyenv/pyenv/pull/3464
* 3.14.0-5: Support building against OpenSSL 4 by @native-api in https://github.com/pyenv/pyenv/pull/3463
## Release v2.6.31
* CI: add_cpython: Support prereleases for non-initial CPython releases by @native-api in https://github.com/pyenv/pyenv/pull/3443
* Add CPython 3.14.5 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3444

View File

@ -393,11 +393,15 @@ List existing pyenv shims.
Configure the shell environment for pyenv
Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--no-rehash] [<shell>])"
pyenv init --install [<shell>]
pyenv init --detect-shell [<shell>]
- Initialize shims directory, print PYENV_SHELL variable, completions path
and shell function
--path Print shims path
--install Configure detected shell startup files
--no-push-path Do not push shim to the start of PATH if they're already there
--detect-shell Print shell startup files detected for the current shell
--no-rehash Add no rehash command to output
## `pyenv completions`

View File

@ -179,6 +179,24 @@ which does install native Windows Python versions.
The below setup should work for the vast majority of users for common use cases.
See [Advanced configuration](#advanced-configuration) for details and more configuration options.
If `pyenv` is already on `PATH`, you can configure the relevant shell startup
files automatically:
```sh
pyenv init --install
```
If `pyenv` is not on `PATH` yet, run the same command through the `pyenv`
executable in your chosen installation directory.
This uses the same shell detection as `pyenv init`. If a startup file already
contains Pyenv-related configuration, the command refuses to edit it; review the
file manually and run `pyenv init <shell>` to see the suggested setup.
For Bash, avoid the automatic `--install` path if your `BASH_ENV` points to
`.bashrc`; use the manual Bash instructions below so the `eval "$(pyenv init - bash)"`
line only goes in your login startup file.
#### Bash
<details>

View File

@ -12,7 +12,7 @@
set -e
[ -n "$PYENV_DEBUG" ] && set -x
version="2.6.31"
version="2.7.1"
git_revision=""
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then

View File

@ -1,6 +1,8 @@
#!/usr/bin/env bash
# Summary: Configure the shell environment for pyenv
# Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--detect-shell] [--no-rehash] [<shell>])"
# Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--no-rehash] [<shell>])"
# pyenv init --install [<shell>]
# pyenv init --detect-shell [<shell>]
set -e
[ -n "$PYENV_DEBUG" ] && set -x
@ -9,6 +11,7 @@ set -e
if [ "$1" = "--complete" ]; then
echo -
echo --path
echo --install
echo --no-push-path
echo --no-rehash
echo --detect-shell
@ -30,6 +33,9 @@ while [ "$#" -gt 0 ]; do
--path)
mode="path"
;;
--install)
mode="install"
;;
--detect-shell)
mode="detect-shell"
;;
@ -81,21 +87,23 @@ function main() {
exit 0
;;
"detect-shell")
detect_profile 1
detect_profile
print_detect_shell
exit 0
;;
"install")
install_shell_startup_files
exit 0
;;
esac
# should never get here
exit 2
}
function detect_profile() {
local detect_for_detect_shell="$1"
case "$shell" in
bash )
if [ -e '~/.bash_profile' ]; then
if [ -e "${HOME}/.bash_profile" ]; then
profile='~/.bash_profile'
else
profile='~/.profile'
@ -103,6 +111,10 @@ function detect_profile() {
profile_explain="~/.bash_profile if it exists, otherwise ~/.profile"
rc='~/.bashrc'
;;
fish )
profile='~/.config/fish/config.fish'
rc='~/.config/fish/config.fish'
;;
pwsh )
profile='~/.config/powershell/profile.ps1'
rc='~/.config/powershell/profile.ps1'
@ -121,13 +133,10 @@ function detect_profile() {
rc='~/.profile'
;;
* )
if [ -n "$detect_for_detect_shell" ]; then
profile=
rc=
else
profile='your shell'\''s login startup file'
rc='your shell'\''s interactive startup file'
fi
profile=
rc=
profile_explain='your shell'\''s login startup file'
rc_explain='your shell'\''s interactive startup file'
;;
esac
}
@ -146,38 +155,32 @@ function help_() {
echo "# Add pyenv executable to PATH by running"
echo "# the following interactively:"
echo
echo 'set -Ux PYENV_ROOT $HOME/.pyenv'
echo 'set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths'
print_fish_user_path_setup
echo
echo "# Load pyenv automatically by appending"
echo "# the following to ~/.config/fish/config.fish:"
echo
echo 'pyenv init - fish | source'
print_fish_shell_setup
echo
;;
pwsh )
echo '# Load pyenv automatically by appending'
echo "# the following to $profile :"
echo
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"'
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {'
echo ' $Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }'
echo 'iex ((pyenv init -) -join "`n")'
print_pwsh_shell_setup
;;
* )
echo '# Load pyenv automatically by appending'
echo -n "# the following to "
if [ "$profile" == "$rc" ]; then
echo "$profile :"
if [[ "$profile" == "$rc" && -z $rc_explain ]]; then
echo "${profile_explain:-$profile} :"
else
echo
echo "# ${profile_explain:-$profile} (for login shells)"
echo "# and $rc (for interactive shells) :"
echo "# and ${rc_explain:-$rc} (for interactive shells) :"
fi
echo
echo 'export PYENV_ROOT="$HOME/.pyenv"'
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"'
echo 'eval "$(pyenv init - '$shell')"'
print_posix_shell_setup
;;
esac
echo
@ -186,6 +189,154 @@ function help_() {
} >&2
}
function print_posix_shell_setup() {
echo 'export PYENV_ROOT="$HOME/.pyenv"'
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"'
echo 'eval "$(pyenv init - '$shell')"'
}
function print_fish_shell_setup() {
echo 'pyenv init - fish | source'
}
function print_fish_user_path_setup() {
echo 'set -Ux PYENV_ROOT $HOME/.pyenv'
echo 'if functions -q fish_add_path'
echo ' test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin'
echo 'else'
echo ' test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths'
echo 'end'
}
function print_pwsh_shell_setup() {
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"'
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {'
echo ' $Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }'
echo 'iex ((pyenv init -) -join "`n")'
}
function expand_home_path() {
local path="$1"
printf '%s\n' "${path/#\~/$HOME}"
}
function install_shell_startup_files() {
if [[ -z $HOME ]]; then
echo "pyenv: HOME must be set to configure shell startup files" >&2
return 1
fi
detect_profile
local files=()
local lines=()
local profile_path rc_path setup
case "$shell" in
bash | zsh | ksh | ksh93 | mksh )
rc_path="$(expand_home_path "$rc")"
profile_path="$(expand_home_path "$profile")"
setup="$(print_posix_shell_setup)"
files=("$rc_path")
lines=("$setup")
if [[ $profile_path != "$rc_path" ]]; then
files+=("$profile_path")
lines+=("$setup")
fi
;;
fish )
rc_path="$(expand_home_path "$rc")"
files=("$rc_path")
lines=("$(print_fish_shell_setup)")
;;
pwsh )
rc_path="$(expand_home_path "$rc")"
files=("$rc_path")
lines=("$(print_pwsh_shell_setup)")
;;
* )
echo "pyenv: cannot automatically configure startup files for $shell" >&2
return 1
;;
esac
local index
for ((index = 0; index < ${#files[@]}; index++)); do
check_startup_file "${files[$index]}" || return 1
done
if [[ $shell == fish ]]; then
install_fish_user_paths || return 1
fi
for ((index = 0; index < ${#files[@]}; index++)); do
append_lines "${files[$index]}" "${lines[$index]}"
done
}
function check_startup_file() {
local file="$1"
local grep_status
if [[ ! -e $file ]]; then
return 0
fi
if [[ ! -f $file || ! -r $file ]]; then
echo "pyenv: failed to inspect $file" >&2
return 1
fi
if grep -Fi pyenv "$file" >/dev/null; then
echo "pyenv: cannot automatically apply changes to $file: it appears to already contain Pyenv-related code." >&2
echo "pyenv: review the file's contents and apply changes manually if necessary." >&2
echo "pyenv: run \`pyenv init $shell\` to see the suggested setup." >&2
return 1
else
grep_status=$?
if [[ $grep_status == 1 ]]; then
return 0
fi
echo "pyenv: failed to inspect $file" >&2
return "$grep_status"
fi
}
function install_fish_user_paths() {
local fish_setup
if ! command -v fish >/dev/null; then
echo "pyenv: fish is not available to configure fish universal variables" >&2
return 1
fi
fish_setup="$(print_fish_user_path_setup)"
if ! fish -c "$fish_setup"; then
echo "pyenv: failed to configure fish universal variables" >&2
return 1
fi
}
function append_lines() {
local file="$1"
local lines="$2"
local dir last_char
dir="${file%/*}"
if [[ $dir != "$file" ]]; then
mkdir -p "$dir"
fi
if [[ -s $file ]]; then
last_char="$(tail -c 1 "$file")" || return 1
if [[ -n $last_char ]]; then
echo >> "$file"
fi
fi
printf '%s\n' "$lines" >> "$file"
}
function init_dirs() {
mkdir -p "${PYENV_ROOT}/"{shims,versions}
}

View File

@ -13,15 +13,29 @@ mkdir -p "$SHIM_PATH"
declare last_acquire_error
acquire_lock() {
# Ensure only one instance of pyenv-rehash is running at a time by
# setting the shell's `noclobber` option and attempting to write to
# the prototype shim file.
local ret
# An old lock file is presumed stale. We assume no healthy rehash takes this long.
# The time is picked very small so that a killed rehash holds up new shell sessions
# for as little as possible
find "$PROTOTYPE_SHIM_PATH" -mmin +2 -exec rm -f {} \; 2>/dev/null || true
set -o noclobber
# Assuming an old lockfile is stale
# Unknown why this happens for some users but this at least unblocks them
last_acquire_error="$( { ( echo -n > "$PROTOTYPE_SHIM_PATH"; ) 2>&1 1>&3 3>&1-; } 3>&1)" \
|| { find "$PROTOTYPE_SHIM_PATH" -mmin +10 -exec rm -f {} \; ; ret=1; }
&& trap release_lock EXIT \
|| {
# Linux Landlock and MacOS Seatbelt sandbox subsystems return false information in access(),
# making -w "$SHIM_PATH" not catch the fact that the shims dir is not writable in this case.
# Bash doesn't provide access to errno to check for non-EEXIST error code in `echo >'.
# So check for writablity by trying to write to a different file,
# in a way that taxes the usual use case as little as possible.
if [[ -z $tested_for_other_write_errors ]]; then
( t="$(TMPDIR="$SHIM_PATH" mktemp)" && rm "$t" ) \
&& tested_for_other_write_errors=1 \
|| { echo "pyenv: cannot rehash: $SHIM_PATH isn't writable" >&2
set +o noclobber
exit 1; }
fi
ret=1
}
set +o noclobber
[[ -z "${ret}" ]]
}
@ -32,6 +46,7 @@ remove_prototype_shim() {
release_lock() {
remove_prototype_shim
trap - EXIT
}
if [ ! -w "$SHIM_PATH" ]; then
@ -45,22 +60,8 @@ PYENV_REHASH_TIMEOUT=${PYENV_REHASH_TIMEOUT:-60}
while (( SECONDS <= start + PYENV_REHASH_TIMEOUT )); do
if acquire_lock; then
acquired=1
# If we were able to obtain a lock, register a trap to clean up the
# prototype shim when the process exits.
trap release_lock EXIT
break
else
#Landlock sandbox subsystem in the Linux kernel returns false information in access() as of 6.14.0,
# making -w "$SHIM_PATH" not catch the fact that the shims dir is not writable in this case.
#Bash doesn't provide access to errno to check for non-EEXIST error code in acquire_lock.
#So check for writablity by trying to write to a different file,
# in a way that taxes the usual use case as little as possible.
if [[ -z $tested_for_other_write_errors ]]; then
( t="$(TMPDIR="$SHIM_PATH" mktemp)" && rm "$t" ) && tested_for_other_write_errors=1 ||
{ echo "pyenv: cannot rehash: $SHIM_PATH isn't writable" >&2; break; }
fi
# POSIX sleep(1) doesn't provide subsecond precision, but many others do
sleep 0.1 2>/dev/null || sleep 1
fi

View File

@ -14,7 +14,7 @@
# -g/--debug Build a debug version
#
PYTHON_BUILD_VERSION="2.6.31"
PYTHON_BUILD_VERSION="2.7.1"
OLDIFS="$IFS"
@ -2678,7 +2678,7 @@ if [ -z "${GET_PIP_URL}" ]; then
2.6 | 2.6.* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/2.6/get-pip.py"
;;
2.7 | 2.7.* | pypy2.7 | pypy2.7-* )
2.7 | 2.7.* | pypy2.7 | pypy2.7-* | pypy-c-jit-* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/2.7/get-pip.py"
;;
3.2 | 3.2.* )
@ -2702,6 +2702,9 @@ if [ -z "${GET_PIP_URL}" ]; then
3.8 | 3.8.* | pypy3.8 | pypy3.8-* | pyston* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.8/get-pip.py"
;;
3.9 | 3.9.* | pypy3.9 | pypy3.9-* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.9/get-pip.py"
;;
* )
GET_PIP_URL="https://bootstrap.pypa.io/get-pip.py"
;;

View File

@ -1,11 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.2" "https://github.com/openssl/openssl/releases/download/openssl-3.6.2/openssl-3.6.2.tar.gz#aaf51a1fe064384f811daeaeb4ec4dce7340ec8bd893027eee676af31e83a04f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.15.0b1" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0b1.tar.xz#d4d52ccfa1d727ef5235fbb7d70fa1dbacf10b8b3760db622875da05acbe437c" standard verify_py315 copy_python_gdb ensurepip
else
install_package "Python-3.15.0b1" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0b1.tgz#9b41271890067875db7f0f5cb2fdcb944b90c473f272a18a13b93c059d84c68e" standard verify_py315 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,11 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-4.0.0" "https://github.com/openssl/openssl/releases/download/openssl-4.0.0/openssl-4.0.0.tar.gz#c32cf49a959c4f345f9606982dd36e7d28f7c58b19c2e25d75624d2b3d2f79ac" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.15.0b2" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0b2.tar.xz#d14f474ab679e90bc734b02ff58447b6ec99a821af61d6ff0c1da0f86e341a71" standard verify_py315 copy_python_gdb ensurepip
else
install_package "Python-3.15.0b2" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0b2.tgz#781f4bcdef48d1d38b335fdc7a156b4e5fe9738b14456121f949257ff5cce77c" standard verify_py315 copy_python_gdb ensurepip
fi

View File

@ -1,30 +1,21 @@
case "$(pypy_architecture 2>/dev/null || true)" in
"linux" )
install_nightly_package "pypy-c-jit-latest-linux" "http://buildbot.pypy.org/nightly/trunk/pypy-c-jit-latest-linux.tar.bz2" "pypy-c-jit-*-linux" "pypy" verify_py27 ensurepip
;;
"linux-armel" )
install_nightly_package "pypy-c-jit-latest-linux-armel" "http://buildbot.pypy.org/nightly/trunk/pypy-c-jit-latest-linux-armel.tar.bz2" "pypy-c-jit-*-linux-armel" "pypy" verify_py27 ensurepip
;;
"linux-armhf" )
if [[ "$(cat /etc/issue 2>/dev/null || true)" == "Raspbian"* ]]; then
install_nightly_package "pypy-c-jit-latest-linux-armhf-raspbian" "http://buildbot.pypy.org/nightly/trunk/pypy-c-jit-latest-linux-armhf-raspbian.tar.bz2" "pypy-c-jit-*-linux-armhf-raspbian" "pypy" verify_py27 ensurepip
else
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of PyPy is not available for $(pypy_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
fi
install_nightly_package "pypy-c-jit-latest-linux" "https://buildbot.pypy.org/nightly/main/pypy-c-jit-latest-linux.tar.bz2" "pypy-c-jit-*-linux" "pypy" verify_py27 ensurepip_lt21
;;
"linux64" )
install_nightly_package "pypy-c-jit-latest-linux64" "http://buildbot.pypy.org/nightly/trunk/pypy-c-jit-latest-linux64.tar.bz2" "pypy-c-jit-*-linux64" "pypy" verify_py27 ensurepip
install_nightly_package "pypy-c-jit-latest-linux64" "https://buildbot.pypy.org/nightly/main/pypy-c-jit-latest-linux64.tar.bz2" "pypy-c-jit-*-linux64" "pypy" verify_py27 ensurepip_lt21
;;
"linux-aarch64" )
install_nightly_package "pypy-c-jit-latest-aarch64" "https://buildbot.pypy.org/nightly/main/pypy-c-jit-latest-aarch64.tar.bz2" "pypy-c-jit-*-aarch64" "pypy" verify_py27 ensurepip_lt21
;;
"osarm64" )
install_nightly_package "pypy-c-jit-latest-macos_arm64" "https://buildbot.pypy.org/nightly/main/pypy-c-jit-latest-macos_arm64.tar.bz2" "pypy-c-jit-*-macos_arm64" "pypy" verify_py27 ensurepip_lt21
;;
"osx64" )
install_nightly_package "pypy-c-jit-latest-osx64" "http://buildbot.pypy.org/nightly/trunk/pypy-c-jit-latest-osx64.tar.bz2" "pypy-c-jit-*-osx64" "pypy" verify_py27 ensurepip
install_nightly_package "pypy-c-jit-latest-macos_x86_64" "https://buildbot.pypy.org/nightly/main/pypy-c-jit-latest-macos_x86_64.tar.bz2" "pypy-c-jit-*-macos_x86_64" "pypy" verify_py27 ensurepip_lt21
;;
"win32" )
install_zip "pypy-c-jit-latest-win32" "http://buildbot.pypy.org/nightly/trunk/pypy-c-jit-latest-win32.zip" "pypy" verify_py27 ensurepip
install_zip "pypy-c-jit-latest-win32" "https://buildbot.pypy.org/nightly/main/pypy-c-jit-latest-win32.zip" "pypy" verify_py27 ensurepip_lt21
;;
* )
{ echo

View File

@ -1,49 +0,0 @@
echo
colorize 1 "WARNING"
echo ": This may eat your kittens/ affect timespace in alternate dimensions/"
echo "cause you to complain more. Nightly builds are meant for testing only."
echo
echo "To report bugs/regressions, please see:"
echo
echo "http://doc.pypy.org/en/latest/faq.html#how-should-i-report-a-bug"
echo
case "$(pypy_architecture 2>/dev/null || true)" in
"linux" )
install_nightly_package "pypy-c-jit-latest-linux" "http://buildbot.pypy.org/nightly/py3.5/pypy-c-jit-latest-linux.tar.bz2" "pypy-c-jit-*-linux" "pypy" verify_py27 ensurepip
;;
"linux-armel" )
install_nightly_package "pypy-c-jit-latest-linux-armel" "http://buildbot.pypy.org/nightly/py3.5/pypy-c-jit-latest-linux-armel.tar.bz2" "pypy-c-jit-*-linux-armel" "pypy" verify_py27 ensurepip
;;
"linux-armhf" )
if [[ "$(cat /etc/issue 2>/dev/null || true)" == "Raspbian"* ]]; then
install_nightly_package "pypy-c-jit-latest-linux-armhf-raspbian" "http://buildbot.pypy.org/nightly/py3.5/pypy-c-jit-latest-linux-armhf-raspbian.tar.bz2" "pypy-c-jit-*-linux-armhf-raspbian" "pypy" verify_py27 ensurepip
else
{ echo
colorize 1 "ERROR"
echo ": The latest nightly build of PyPy 3.5 is not available for $(pypy_architecture 2>/dev/null || true),"
echo "Please check http://buildbot.pypy.org/nightly/py3.5/ for previous builds."
echo
} >&2
exit 1
fi
;;
"linux64" )
install_nightly_package "pypy3.5-c-jit-latest-linux64" "http://buildbot.pypy.org/nightly/py3.5/pypy-c-jit-latest-linux64.tar.bz2" "pypy-c-jit-*-linux64" "pypy" verify_py35 ensurepip
;;
"osx64" )
install_nightly_package "pypy-c-jit-latest-osx64" "http://buildbot.pypy.org/nightly/py3.5/pypy-c-jit-latest-osx64.tar.bz2" "pypy-c-jit-*-osx64" "pypy" verify_py27 ensurepip
;;
"win32" )
install_zip "pypy-c-jit-latest-win32" "http://buildbot.pypy.org/nightly/py3.5/pypy-c-jit-latest-win32.zip" "pypy" verify_py27 ensurepip
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The latest nightly build of PyPy 3.5 is not available for $(pypy_architecture 2>/dev/null || true),"
echo "Please check http://buildbot.pypy.org/nightly/py3.5/ for previous builds."
echo
} >&2
exit 1
;;
esac

View File

@ -1,39 +0,0 @@
echo
colorize 1 "WARNING"
echo ": This may eat your kittens/ affect timespace in alternate dimensions/"
echo "cause you to complain more. Nightly builds are meant for testing only."
echo "Current pypy py3.7 development status:"
echo
echo "https://foss.heptapod.net/pypy/pypy/-/wikis/py3.7%20status"
echo
echo "for the latest status updates. To report bugs/regressions, please see:"
echo
echo "https://doc.pypy.org/en/latest/faq.html#how-should-i-report-a-bug"
echo
case "$(pypy_architecture 2>/dev/null || true)" in
"linux" )
install_nightly_package "pypy-c-jit-latest-linux" "https://buildbot.pypy.org/nightly/py3.7/pypy-c-jit-latest-linux.tar.bz2" "pypy-c-jit-*-linux" "pypy" verify_py27 ensurepip
;;
"linux64" )
install_nightly_package "pypy3.7-c-jit-latest-linux64" "https://buildbot.pypy.org/nightly/py3.7/pypy-c-jit-latest-linux64.tar.bz2" "pypy-c-jit-*-linux64" "pypy" verify_py35 ensurepip
;;
"linux-aarch64" )
install_nightly_package "pypy3.7-c-jit-latest-aarch64" "https://buildbot.pypy.org/nightly/py3.7/pypy-c-jit-latest-aarch64.tar.bz2" "pypy-c-jit-*-aarch64" "pypy" verify_py35 ensurepip
;;
"osx64" )
install_nightly_package "pypy-c-jit-latest-osx64" "https://buildbot.pypy.org/nightly/py3.7/pypy-c-jit-latest-osx64.tar.bz2" "pypy-c-jit-*-osx64" "pypy" verify_py27 ensurepip
;;
"win32" )
install_zip "pypy-c-jit-latest-win32" "https://buildbot.pypy.org/nightly/py3.7/pypy-c-jit-latest-win32.zip" "pypy" verify_py27 ensurepip
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The latest nightly build of PyPy 3.7 is not available for $(pypy_architecture 2>/dev/null || true),"
echo "Please check https://buildbot.pypy.org/nightly/py3.7/ for previous builds."
echo
} >&2
exit 1
;;
esac

View File

@ -388,82 +388,39 @@ OUT
assert_success
}
@test "use the custom GET_PIP_URL for 2.6 versions" {
run_inline_definition_with_name --name=2.6 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/2.6/get-pip.py"
assert_success
}
@test "use custom GET_PIP_URLs" {
@test "use the custom GET_PIP_URL for 2.7 versions" {
run_inline_definition_with_name --name=2.7 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/2.7/get-pip.py"
assert_success
}
declare -a name_subdir=(\
2.6
2.7
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
@test "use the custom GET_PIP_URL for 3.2 versions" {
run_inline_definition_with_name --name=3.2 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/3.2/get-pip.py"
assert_success
}
"pypy2.7-7.3.12 2.7"
"pypy-c-jit-latest-linux 2.7"
"pypy3.5-7.0.0 3.5"
"pypy3.6-7.3.3 3.6"
"pypy3.7-7.3.3 3.7"
"pypy3.8-7.3.8 3.8"
"pypy3.9-7.3.16 3.9"
@test "use the custom GET_PIP_URL for 3.3 versions" {
run_inline_definition_with_name --name=3.3 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/3.3/get-pip.py"
assert_success
}
"pyston-2.3.5 3.8"
)
@test "use the custom GET_PIP_URL for 3.4 versions" {
run_inline_definition_with_name --name=3.4 <<OUT
echo "\${GET_PIP_URL}"
for item_s in "${name_subdir[@]}"; do
item=($item_s)
name="${item[0]}"
subdir="${item[1]:-$name}"
run_inline_definition_with_name --name="$name" <<OUT
echo "\${DEFINITION_PATH##*/}:\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/3.4/get-pip.py"
assert_success
}
@test "use the custom GET_PIP_URL for 3.5 versions" {
run_inline_definition_with_name --name=3.5 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/3.5/get-pip.py"
assert_success
}
@test "use the custom GET_PIP_URL for 3.6 versions" {
run_inline_definition_with_name --name=3.6 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/3.6/get-pip.py"
assert_success
}
@test "use the custom GET_PIP_URL for pypy2.7 versions" {
run_inline_definition_with_name --name=pypy2.7-7.3.12 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/2.7/get-pip.py"
assert_success
}
@test "use the custom GET_PIP_URL for pypy3.5 versions" {
run_inline_definition_with_name --name=pypy3.5-7.0.0 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/3.5/get-pip.py"
assert_success
}
@test "use the custom GET_PIP_URL for pypy3.6 versions" {
run_inline_definition_with_name --name=pypy3.6-7.3.3 <<OUT
echo "\${GET_PIP_URL}"
OUT
assert_output "https://bootstrap.pypa.io/pip/3.6/get-pip.py"
assert_success
assert_output "$name:https://bootstrap.pypa.io/pip/$subdir/get-pip.py"
assert_success
done
}

View File

@ -2,8 +2,7 @@
#include <stdlib.h>
#include <stdio.h>
int realpath_builtin(list)
WORD_LIST *list;
int realpath_builtin(WORD_LIST *list)
{
int es;
char *realbuf, *p;

View File

@ -79,6 +79,134 @@ OUT
assert_line "PYENV_SHELL_DETECT=bash"
}
@test "shell detection for fish startup file" {
run pyenv-init --detect-shell fish
assert_success
assert_line "PYENV_SHELL_DETECT=fish"
assert_line "PYENV_PROFILE_DETECT=~/.config/fish/config.fish"
assert_line "PYENV_RC_DETECT=~/.config/fish/config.fish"
}
@test "completion includes install option" {
run pyenv-init --complete
assert_success
assert_line "--install"
}
@test "install setup for detected shell startup files" {
mkdir -p "$HOME"
run pyenv-init --install
assert_success
expected_setup=$'export PYENV_ROOT="$HOME/.pyenv"\n[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"\neval "$(pyenv init - bash)"'
assert_equal "$expected_setup" "$(cat "$HOME/.bashrc")"
assert_equal "$expected_setup" "$(cat "$HOME/.profile")"
}
@test "install setup for bash uses existing bash_profile" {
mkdir -p "$HOME"
touch "$HOME/.bash_profile"
run pyenv-init --install bash
assert_success
expected_setup=$'export PYENV_ROOT="$HOME/.pyenv"\n[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"\neval "$(pyenv init - bash)"'
assert_equal "$expected_setup" "$(cat "$HOME/.bashrc")"
assert_equal "$expected_setup" "$(cat "$HOME/.bash_profile")"
assert [ ! -e "$HOME/.profile" ]
}
@test "install setup for zsh startup files" {
mkdir -p "$HOME"
run pyenv-init --install zsh
assert_success
expected_setup=$'export PYENV_ROOT="$HOME/.pyenv"\n[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"\neval "$(pyenv init - zsh)"'
assert_equal "$expected_setup" "$(cat "$HOME/.zshrc")"
assert_equal "$expected_setup" "$(cat "$HOME/.zprofile")"
}
@test "install setup for fish startup file" {
mkdir -p "$HOME"
create_stub fish <<OUT
printf '%s\n' "\$2" > "$PYENV_TEST_DIR/fish-script"
OUT
run pyenv-init --install fish
assert_success
expected_fish_script=$'set -Ux PYENV_ROOT $HOME/.pyenv\nif functions -q fish_add_path\n test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin\nelse\n test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths\nend'
expected_setup='pyenv init - fish | source'
assert_equal "$expected_fish_script" "$(cat "$PYENV_TEST_DIR/fish-script")"
assert_equal "$expected_setup" "$(cat "$HOME/.config/fish/config.fish")"
}
@test "install setup for pwsh startup file" {
mkdir -p "$HOME"
run pyenv-init --install pwsh
assert_success
expected_setup=$'$Env:PYENV_ROOT="$Env:HOME/.pyenv"\nif (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {\n $Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }\niex ((pyenv init -) -join "`n")'
assert_equal "$expected_setup" "$(cat "$HOME/.config/powershell/profile.ps1")"
}
@test "install refuses to modify files with pyenv-related code" {
mkdir -p "$HOME"
echo 'eval "$(pyenv init -)"' > "$HOME/.bashrc"
run pyenv-init --install bash
assert_failure
assert_line "pyenv: cannot automatically apply changes to $HOME/.bashrc: it appears to already contain Pyenv-related code."
assert_line "pyenv: review the file's contents and apply changes manually if necessary."
assert_line "pyenv: run \`pyenv init bash\` to see the suggested setup."
assert_equal 'eval "$(pyenv init -)"' "$(cat "$HOME/.bashrc")"
assert [ ! -e "$HOME/.profile" ]
}
@test "install treats PYENV_ROOT as pyenv-related code" {
mkdir -p "$HOME"
echo 'export PYENV_ROOT="$HOME/tools/python-env"' > "$HOME/.bashrc"
run pyenv-init --install bash
assert_failure
assert_line "pyenv: cannot automatically apply changes to $HOME/.bashrc: it appears to already contain Pyenv-related code."
}
@test "install refuses unreadable startup file without partial writes" {
mkdir -p "$HOME/.bashrc"
run pyenv-init --install bash
assert_failure
assert_line "pyenv: failed to inspect $HOME/.bashrc"
assert [ ! -e "$HOME/.profile" ]
}
@test "install setup keeps fish block intact when generic lines already exist" {
mkdir -p "$HOME/.config/fish"
create_stub fish <<OUT
exit 0
OUT
echo "end" > "$HOME/.config/fish/config.fish"
run pyenv-init --install fish
assert_success
expected_setup=$'end\npyenv init - fish | source'
assert_equal "$expected_setup" "$(cat "$HOME/.config/fish/config.fish")"
}
@test "install setup fails gracefully for unsupported shell" {
mkdir -p "$HOME"
run pyenv-init --install nu
assert_failure "pyenv: cannot automatically configure startup files for nu"
}
@test "option to skip rehash" {
run pyenv-init - --no-rehash
assert_success

View File

@ -38,18 +38,17 @@ pyenv: cannot rehash: couldn't acquire lock ${PYENV_ROOT}/shims/.pyenv-shim for
assert_success
}
@test "stale lockfile is removed" {
@test "removes stale lockfile" {
mkdir -p "${PYENV_ROOT}/shims"
#GNU and BSD `date` support generating relative dates via different syntax
# but BusyBox `date` used in Bash Docker images doesn't
# A portable code to set mtime to "N minutes ago" is long and unwieldy,
# see https://unix.stackexchange.com/questions/806015/portably-set-a-files-time-to-n-minutes-ago
# Using a fixed timestamp far in the past is infinitely simpler and good enough for the test
touch -t 200001010000.00 "${PYENV_ROOT}/shims/.pyenv-shim"
run pyenv-rehash
assert_success ""
assert [ ! -e "${PYENV_ROOT}/shims/.pyenv-shim" ]
}
@test "creates shims" {
create_alt_executable_in_version "2.7" "python"
create_alt_executable_in_version "2.7" "fab"