Compare commits

...

17 Commits

Author SHA1 Message Date
Ivan Pozdeev
b52a8e3f52 python-build scripts: Switch to jc release
They finally made a release with our fix
2026-06-19 08:36:53 +03:00
Ayush
f122a9d764
CI: add_version enhancements (#3475)
- Prevent OpenSSL from bumping across major versions
- Skip adding versions that already have pending PRs
- Copy/move patches when adding new releases in the same series
2026-06-14 21:46:48 +03:00
native-api
3323ba3ed9
README: clarify shell setup instructions using the new --install option 2026-06-12 15:34:14 +03:00
Ivan Pozdeev
b43c9e5d42 2.7.2 2026-06-10 23:16:50 +03:00
pyenv-bot[bot]
532b659ca2
Add CPython 3.13.14 (#3473)
---------

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-06-10 23:12:21 +03:00
pyenv-bot[bot]
7565df6eab
Add CPython 3.14.6 (#3472)
---------

Co-authored-by: native-api <2670332+native-api@users.noreply.github.com>
Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-06-10 23:11:56 +03:00
Ivan Pozdeev
e55613a267 CI: Don't trigger push checks on a pull request 2026-06-10 22:03:22 +03:00
Ivan Pozdeev
6c0c5cfa96 Fix verify_* calls in 3.6.x
Fixes #3470
2026-06-10 21:56:41 +03:00
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
35 changed files with 10590 additions and 378 deletions

View File

@ -1,5 +1,8 @@
name: macos_build name: macos_build
on: [pull_request, push] on:
push:
branches: [master]
pull_request: {}
permissions: permissions:
contents: read # to fetch code (actions/checkout) contents: read # to fetch code (actions/checkout)

View File

@ -1,5 +1,8 @@
name: pyenv_tests name: pyenv_tests
on: [pull_request, push] on:
push:
branches: [master]
pull_request: {}
permissions: permissions:
contents: read # to fetch code (actions/checkout) contents: read # to fetch code (actions/checkout)

View File

@ -1,5 +1,8 @@
name: ubuntu_build name: ubuntu_build
on: [pull_request, push] on:
push:
branches: [master]
pull_request: {}
permissions: permissions:
contents: read # to fetch code (actions/checkout) contents: read # to fetch code (actions/checkout)

View File

@ -1,5 +1,32 @@
# Version History # Version History
## Release v2.7.2
* fix(rehash): prevent terminal hang caused by stale or sandbox-blocked lock file by @anupddas in https://github.com/pyenv/pyenv/pull/3469
* 3.6.x: Fix verify_* calls by @native-api in https://github.com/pyenv/pyenv/commit/6c0c5cfa9619e4a7a90102d8bee6c771c4739836
* Add CPython 3.14.6 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3472
* Add CPython 3.13.14 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3473
## 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 ## 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 * 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 * 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 Configure the shell environment for pyenv
Usage: eval "$(pyenv init [-|--path] [--no-push-path] [--no-rehash] [<shell>])" 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 - Initialize shims directory, print PYENV_SHELL variable, completions path
and shell function and shell function
--path Print shims path --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 --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 --no-rehash Add no rehash command to output
## `pyenv completions` ## `pyenv completions`

237
README.md
View File

@ -69,6 +69,7 @@ This project was forked from [rbenv](https://github.com/rbenv/rbenv) and
* [Using Pyenv without shims](#using-pyenv-without-shims) * [Using Pyenv without shims](#using-pyenv-without-shims)
* [Running nested shells from Python-based programs](#running-nested-shells-from-python-based-programs) * [Running nested shells from Python-based programs](#running-nested-shells-from-python-based-programs)
* [Environment variables](#environment-variables) * [Environment variables](#environment-variables)
* [Manual shell setup](#manual-shell-setup)
* **[Development](#development)** * **[Development](#development)**
* [Contributing](#contributing) * [Contributing](#contributing)
* [Version History](#version-history) * [Version History](#version-history)
@ -177,115 +178,28 @@ which does install native Windows Python versions.
---- ----
The below setup should work for the vast majority of users for common use cases. 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. See [Advanced configuration](#advanced-configuration)
and specifically [Manual shell setup](#manual-shell-setup) for details and more configuration options.
#### Bash To add the suggested setup code to the startup files of the running shell,
<details> run `<path/to/pyenv> --install`.
Specifically:
Stock Bash startup files vary widely between distributions in which of them source * If you installed Pyenv with the installer script:
which, under what circumstances, in what order and what additional configuration they perform.
As such, the most reliable way to get Pyenv in all environments is to append Pyenv
configuration commands to both `.bashrc` (for interactive shells)
and the profile file that Bash would use (for login shells).
1. First, add the commands to `~/.bashrc` by running the following in your terminal: ```sh
~/.pyenv/bin/pyenv init --install
```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
```
2. Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well.
If you have none of these, create a `~/.profile` and add the commands there.
* to add to `~/.profile`:
``` bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
echo 'eval "$(pyenv init - bash)"' >> ~/.profile
```
* to add to `~/.bash_profile`:
```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init - bash)"' >> ~/.bash_profile
``` ```
**Bash warning**: There are some systems where the `BASH_ENV` variable is configured * If you installed Pyenv with Homebrew:
to point to `.bashrc`. On such systems, you should almost certainly put the
`eval "$(pyenv init - bash)"` line into `.bash_profile`, and **not** into `.bashrc`. Otherwise, you
may observe strange behaviour, such as `pyenv` getting into an infinite loop.
See [#264](https://github.com/pyenv/pyenv/issues/264) for details.
</details> ```sh
pyenv init --install
#### Zsh
<details>
Add Pyenv startup commands to `~/.zshrc` by running the following in your terminal:
```zsh
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc
``` ```
If you wish to get Pyenv in noninteractive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`. For Bash, avoid the automatic `--install` path if your `BASH_ENV` points to
</details> `.bashrc`; use the manual Bash instructions below so the `eval "$(pyenv init - bash)"`
line only goes in your login startup file.
#### Fish
<details>
1. If you have Fish 3.2.0 or newer, execute this interactively:
```fish
set -Ux PYENV_ROOT $HOME/.pyenv
test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin
```
2. Otherwise, execute the snippet below:
```fish
set -Ux PYENV_ROOT $HOME/.pyenv
test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths
```
3. Now, add this to `~/.config/fish/config.fish`:
```fish
pyenv init - fish | source
```
</details>
#### Nushell
<details>
Add the following lines to your `config.nu` to add Pyenv and its shims to your `PATH`.
Shell integration (completions and subcommands changing the shell's state)
isn't currently supported.
~~~ nu
$env.PYENV_ROOT = "~/.pyenv" | path expand
if (( $"($env.PYENV_ROOT)/bin" | path type ) == "dir") {
$env.PATH = $env.PATH | prepend $"($env.PYENV_ROOT)/bin" }
$env.PATH = $env.PATH | prepend $"(pyenv root)/shims"
~~~
</details>
#### Microsoft PowerShell
<details>
Add the commands to `$profile.CurrentUserAllHosts` by running the following in your terminal:
~~~ pwsh
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' >> $profile.CurrentUserAllHosts
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {
$Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }' >> $profile.CurrentUserAllHosts
echo 'iex ((pyenv init -) -join "`n")' >> $profile.CurrentUserAllHosts
~~~
</details>
### C. Restart your shell ### C. Restart your shell
---- ----
@ -797,6 +711,127 @@ name | default | description
See also [_Special environment variables_ in Python-Build's README](plugins/python-build/README.md#special-environment-variables) See also [_Special environment variables_ in Python-Build's README](plugins/python-build/README.md#special-environment-variables)
for environment variables that can be used to customize the build. for environment variables that can be used to customize the build.
### Manual shell setup
Below is the suggested shell setup added to shell startup files by `pyenv init --install`.
* To automatically install Pyenv for a shell different than the running shell, run
```sh
path/to/pyenv --install <shell executable name>
```
e.g. `~/.pyenv --install bash`.
#### Bash
<details>
Stock Bash startup files vary widely between distributions in which of them source
which, under what circumstances, in what order and what additional configuration they perform.
As such, the most reliable way to get Pyenv in all environments is to append Pyenv
configuration commands to both `.bashrc` (for interactive shells)
and the profile file that Bash would use (for login shells).
1. First, add the commands to `~/.bashrc` by running the following in your terminal:
```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc
```
2. Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well.
If you have none of these, create a `~/.profile` and add the commands there.
* to add to `~/.profile`:
``` bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
echo 'eval "$(pyenv init - bash)"' >> ~/.profile
```
* to add to `~/.bash_profile`:
```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init - bash)"' >> ~/.bash_profile
```
**Bash warning**: There are some systems where the `BASH_ENV` variable is configured
to point to `.bashrc`. On such systems, you should almost certainly put the
`eval "$(pyenv init - bash)"` line into `.bash_profile`, and **not** into `.bashrc`. Otherwise, you
may observe strange behaviour, such as `pyenv` getting into an infinite loop.
See [#264](https://github.com/pyenv/pyenv/issues/264) for details.
</details>
#### Zsh
<details>
Add Pyenv startup commands to `~/.zshrc` by running the following in your terminal:
```zsh
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc
```
If you wish to get Pyenv in noninteractive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`.
</details>
#### Fish
<details>
1. If you have Fish 3.2.0 or newer, execute this interactively:
```fish
set -Ux PYENV_ROOT $HOME/.pyenv
test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin
```
2. Otherwise, execute the snippet below:
```fish
set -Ux PYENV_ROOT $HOME/.pyenv
test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths
```
3. Now, add this to `~/.config/fish/config.fish`:
```fish
pyenv init - fish | source
```
</details>
#### Nushell
<details>
Add the following lines to your `config.nu` to add Pyenv and its shims to your `PATH`.
Shell integration (completions and subcommands changing the shell's state)
isn't currently supported.
~~~ nu
$env.PYENV_ROOT = "~/.pyenv" | path expand
if (( $"($env.PYENV_ROOT)/bin" | path type ) == "dir") {
$env.PATH = $env.PATH | prepend $"($env.PYENV_ROOT)/bin" }
$env.PATH = $env.PATH | prepend $"(pyenv root)/shims"
~~~
</details>
#### Microsoft PowerShell
<details>
Add the commands to `$profile.CurrentUserAllHosts` by running the following in your terminal:
~~~ pwsh
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' >> $profile.CurrentUserAllHosts
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {
$Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }' >> $profile.CurrentUserAllHosts
echo 'iex ((pyenv init -) -join "`n")' >> $profile.CurrentUserAllHosts
~~~
</details>
---- ----
## Development ## Development

View File

@ -12,7 +12,7 @@
set -e set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
version="2.6.31" version="2.7.2"
git_revision="" git_revision=""
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then 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 #!/usr/bin/env bash
# Summary: Configure the shell environment for pyenv # 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 set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
@ -9,6 +11,7 @@ set -e
if [ "$1" = "--complete" ]; then if [ "$1" = "--complete" ]; then
echo - echo -
echo --path echo --path
echo --install
echo --no-push-path echo --no-push-path
echo --no-rehash echo --no-rehash
echo --detect-shell echo --detect-shell
@ -30,6 +33,9 @@ while [ "$#" -gt 0 ]; do
--path) --path)
mode="path" mode="path"
;; ;;
--install)
mode="install"
;;
--detect-shell) --detect-shell)
mode="detect-shell" mode="detect-shell"
;; ;;
@ -81,21 +87,23 @@ function main() {
exit 0 exit 0
;; ;;
"detect-shell") "detect-shell")
detect_profile 1 detect_profile
print_detect_shell print_detect_shell
exit 0 exit 0
;; ;;
"install")
install_shell_startup_files
exit 0
;;
esac esac
# should never get here # should never get here
exit 2 exit 2
} }
function detect_profile() { function detect_profile() {
local detect_for_detect_shell="$1"
case "$shell" in case "$shell" in
bash ) bash )
if [ -e '~/.bash_profile' ]; then if [ -e "${HOME}/.bash_profile" ]; then
profile='~/.bash_profile' profile='~/.bash_profile'
else else
profile='~/.profile' profile='~/.profile'
@ -103,6 +111,10 @@ function detect_profile() {
profile_explain="~/.bash_profile if it exists, otherwise ~/.profile" profile_explain="~/.bash_profile if it exists, otherwise ~/.profile"
rc='~/.bashrc' rc='~/.bashrc'
;; ;;
fish )
profile='~/.config/fish/config.fish'
rc='~/.config/fish/config.fish'
;;
pwsh ) pwsh )
profile='~/.config/powershell/profile.ps1' profile='~/.config/powershell/profile.ps1'
rc='~/.config/powershell/profile.ps1' rc='~/.config/powershell/profile.ps1'
@ -121,13 +133,10 @@ function detect_profile() {
rc='~/.profile' rc='~/.profile'
;; ;;
* ) * )
if [ -n "$detect_for_detect_shell" ]; then
profile= profile=
rc= rc=
else profile_explain='your shell'\''s login startup file'
profile='your shell'\''s login startup file' rc_explain='your shell'\''s interactive startup file'
rc='your shell'\''s interactive startup file'
fi
;; ;;
esac esac
} }
@ -146,38 +155,32 @@ function help_() {
echo "# Add pyenv executable to PATH by running" echo "# Add pyenv executable to PATH by running"
echo "# the following interactively:" echo "# the following interactively:"
echo echo
echo 'set -Ux PYENV_ROOT $HOME/.pyenv' print_fish_user_path_setup
echo 'set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths'
echo echo
echo "# Load pyenv automatically by appending" echo "# Load pyenv automatically by appending"
echo "# the following to ~/.config/fish/config.fish:" echo "# the following to ~/.config/fish/config.fish:"
echo echo
echo 'pyenv init - fish | source' print_fish_shell_setup
echo echo
;; ;;
pwsh ) pwsh )
echo '# Load pyenv automatically by appending' echo '# Load pyenv automatically by appending'
echo "# the following to $profile :" echo "# the following to $profile :"
echo echo
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' print_pwsh_shell_setup
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")'
;; ;;
* ) * )
echo '# Load pyenv automatically by appending' echo '# Load pyenv automatically by appending'
echo -n "# the following to " echo -n "# the following to "
if [ "$profile" == "$rc" ]; then if [[ "$profile" == "$rc" && -z $rc_explain ]]; then
echo "$profile :" echo "${profile_explain:-$profile} :"
else else
echo echo
echo "# ${profile_explain:-$profile} (for login shells)" echo "# ${profile_explain:-$profile} (for login shells)"
echo "# and $rc (for interactive shells) :" echo "# and ${rc_explain:-$rc} (for interactive shells) :"
fi fi
echo echo
echo 'export PYENV_ROOT="$HOME/.pyenv"' print_posix_shell_setup
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"'
echo 'eval "$(pyenv init - '$shell')"'
;; ;;
esac esac
echo echo
@ -186,6 +189,154 @@ function help_() {
} >&2 } >&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() { function init_dirs() {
mkdir -p "${PYENV_ROOT}/"{shims,versions} mkdir -p "${PYENV_ROOT}/"{shims,versions}
} }

View File

@ -13,15 +13,29 @@ mkdir -p "$SHIM_PATH"
declare last_acquire_error declare last_acquire_error
acquire_lock() { 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 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 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)" \ 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 set +o noclobber
[[ -z "${ret}" ]] [[ -z "${ret}" ]]
} }
@ -32,6 +46,7 @@ remove_prototype_shim() {
release_lock() { release_lock() {
remove_prototype_shim remove_prototype_shim
trap - EXIT
} }
if [ ! -w "$SHIM_PATH" ]; then if [ ! -w "$SHIM_PATH" ]; then
@ -45,22 +60,8 @@ PYENV_REHASH_TIMEOUT=${PYENV_REHASH_TIMEOUT:-60}
while (( SECONDS <= start + PYENV_REHASH_TIMEOUT )); do while (( SECONDS <= start + PYENV_REHASH_TIMEOUT )); do
if acquire_lock; then if acquire_lock; then
acquired=1 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 break
else 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 # POSIX sleep(1) doesn't provide subsecond precision, but many others do
sleep 0.1 2>/dev/null || sleep 1 sleep 0.1 2>/dev/null || sleep 1
fi fi

View File

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

View File

@ -17,6 +17,7 @@ import os.path
import pathlib import pathlib
import pprint import pprint
import re import re
import shutil
import subprocess import subprocess
import sys import sys
import typing import typing
@ -46,6 +47,14 @@ EXCLUDED_VERSIONS= {
here = pathlib.Path(__file__).resolve() here = pathlib.Path(__file__).resolve()
OUT_DIR: pathlib.Path = here.parent.parent / "share" / "python-build" OUT_DIR: pathlib.Path = here.parent.parent / "share" / "python-build"
AUTO_ADD_VERSION_REF_RE = re.compile(
r"^(?P<object_id>[0-9a-f]{40,64})\t"
r"refs/heads/auto_add_version/(?P<versions>\S+)$"
)
OPENSSL_RELEASE_TAG_RE = re.compile(
r"^openssl-(?P<major>\d+)\.\d+(?:\.\d+)*(?:[a-z]+\d*)?$"
)
T_THUNK=\ T_THUNK=\
'''export PYTHON_BUILD_FREE_THREADING=1 '''export PYTHON_BUILD_FREE_THREADING=1
source "${BASH_SOURCE[0]%t}" source "${BASH_SOURCE[0]%t}"
@ -83,10 +92,13 @@ def adapt_script(version: packaging.version.Version,
url=new_package_url+'#'+new_package_hash, url=new_package_url+'#'+new_package_hash,
verify_py_suffix=verify_py_suffix) verify_py_suffix=verify_py_suffix)
elif m:=re.match(r'\s*install_package\s+"(?P<package>openssl-\S+)"\s+' elif m:=re.match(r'\s*install_package\s+'
r'"(?P<package>openssl-(?P<openssl_major>\d+)\.\S+)"\s+'
r'"(?P<url>\S+)"\s.*$', r'"(?P<url>\S+)"\s.*$',
line): line):
item = VersionDirectory.openssl.get_store_latest_release() item = VersionDirectory.openssl.get_store_latest_release(
int(m.group('openssl_major'))
)
line = Re.sub_groups(m, line = Re.sub_groups(m,
package=item.package_name, package=item.package_name,
@ -129,6 +141,8 @@ def add_version(version: packaging.version.Version):
return False return False
VersionDirectory.existing.append(_CPythonExistingScriptInfo(version,str(new_path))) VersionDirectory.existing.append(_CPythonExistingScriptInfo(version,str(new_path)))
handle_version_patches(version, previous_version, is_prerelease_upgrade)
cleanup_prerelease_upgrade(is_prerelease_upgrade, previous_version, version) cleanup_prerelease_upgrade(is_prerelease_upgrade, previous_version, version)
handle_t_thunks(version, previous_version, is_prerelease_upgrade) handle_t_thunks(version, previous_version, is_prerelease_upgrade)
@ -137,6 +151,51 @@ def add_version(version: packaging.version.Version):
return True return True
def handle_version_patches(
version: packaging.version.Version,
previous_version: packaging.version.Version,
is_prerelease_upgrade: bool)\
-> None:
if (previous_version.major, previous_version.minor) != (version.major, version.minor):
return
patches_dir = OUT_DIR / "patches"
previous_patches = patches_dir / str(previous_version)
if not previous_patches.exists():
return
new_patches = patches_dir / str(version)
if is_prerelease_upgrade:
logger.info(f"Git moving patches from {previous_version} to {version}")
subprocess.check_call((
"git", "-C", OUT_DIR, "mv",
f"patches/{previous_version}",
f"patches/{version}",
))
else:
logger.info(f"Copying patches from {previous_version} to {version}")
shutil.copytree(previous_patches, new_patches)
previous_package_patches = new_patches / f"Python-{previous_version}"
new_package_patches = new_patches / f"Python-{version}"
if is_prerelease_upgrade:
subprocess.check_call((
"git", "-C", OUT_DIR, "mv",
f"patches/{version}/Python-{previous_version}",
f"patches/{version}/Python-{version}",
))
else:
previous_package_patches.rename(new_package_patches)
previous_t_patches = patches_dir / f"{previous_version}t"
if previous_t_patches.exists() or previous_t_patches.is_symlink():
if is_prerelease_upgrade:
previous_t_patches.unlink()
(patches_dir / f"{version}t").symlink_to(
str(version), target_is_directory=True
)
def cleanup_prerelease_upgrade( def cleanup_prerelease_upgrade(
is_prerelease_upgrade: bool, is_prerelease_upgrade: bool,
previous_version: packaging.version.Version, previous_version: packaging.version.Version,
@ -211,7 +270,11 @@ def main():
VersionDirectory.available.get_store_available_source_downloads(release, True) VersionDirectory.available.get_store_available_source_downloads(release, True)
del release del release
versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys()) versions_to_add = sorted(
VersionDirectory.available.keys()
- VersionDirectory.existing.keys()
- get_pending_versions()
)
logger.info("Versions to add:\n"+pprint.pformat(versions_to_add)) logger.info("Versions to add:\n"+pprint.pformat(versions_to_add))
result = False result = False
@ -219,6 +282,27 @@ def main():
result = add_version(version_to_add) or result result = add_version(version_to_add) or result
return int(not result) return int(not result)
def get_pending_versions() -> typing.Set[packaging.version.Version]:
ls_remote = subprocess.check_output(
("git", "-C", OUT_DIR, "ls-remote", "origin",
"refs/heads/auto_add_version/*"),
text=True,
timeout=30,
)
pending_versions = set()
for line in ls_remote.splitlines():
match = AUTO_ADD_VERSION_REF_RE.fullmatch(line)
if not match:
raise ValueError(f"Unexpected git ls-remote output: {line!r}")
pending_versions.update(
packaging.version.Version(version)
for version in match.group("versions").split("_")
)
return pending_versions
def parse_args(): def parse_args():
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument( parser.add_argument(
@ -440,18 +524,41 @@ class _OpenSSLVersionInfo(typing.NamedTuple):
class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version.Version]): class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version.Version]):
key_field = "version" key_field = "version"
def get_store_latest_release(self) \ def get_store_latest_release(self, major: int) \
-> _OpenSSLVersionInfo: -> _OpenSSLVersionInfo:
if self: matching = [
#already retrieved release for release in self
return self[max(self.keys())] if release.version.major == major
]
if matching:
return max(matching, key=lambda release: release.version)
url = "https://api.github.com/repos/openssl/openssl/releases?per_page=100"
while url:
response = requests.get(url, timeout=30)
response.raise_for_status()
matching = [
release
for release in response.json()
if not release['draft']
and not release['prerelease']
and (match := OPENSSL_RELEASE_TAG_RE.fullmatch(
release['tag_name']
))
and int(match.group('major')) == major
]
if matching:
j_release = matching[0]
break
url = response.links.get('next', {}).get('url')
else:
raise ValueError(f"No OpenSSL {major}.x release found")
j = requests.get("https://api.github.com/repos/openssl/openssl/releases/latest", timeout=30).json()
# noinspection PyTypeChecker # noinspection PyTypeChecker
# urlparse can parse str as well as bytes # urlparse can parse str as well as bytes
shasum_url = more_itertools.one( shasum_url = more_itertools.one(
asset['browser_download_url'] asset['browser_download_url']
for asset in j['assets'] for asset in j_release['assets']
if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1].endswith('.sha256') if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1].endswith('.sha256')
) )
shasum_text = requests.get(shasum_url, timeout=30).text shasum_text = requests.get(shasum_url, timeout=30).text
@ -467,7 +574,7 @@ class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version.
package_url = more_itertools.one( package_url = more_itertools.one(
asset['browser_download_url'] asset['browser_download_url']
for asset in j['assets'] for asset in j_release['assets']
if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1] == package_filename if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1] == package_filename
) )

View File

@ -6,4 +6,4 @@ packaging
requests requests
sortedcontainers sortedcontainers
tqdm tqdm
jc @ git+https://github.com/native-api/jc@haslib_mode jc

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-3.6.3" "https://github.com/openssl/openssl/releases/download/openssl-3.6.3/openssl-3.6.3.tar.gz#243a86649cf6f23eeb6a2ff2456e09e5d77dd9018a54d3d96b0c6bdd6ba6c7f1" 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.13.14" "https://www.python.org/ftp/python/3.13.14/Python-3.13.14.tar.xz#639e43243c620a308f968213df9e00f2f8f62332f7adbaa7a7eeb9783057c690" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.14" "https://www.python.org/ftp/python/3.13.14/Python-3.13.14.tgz#5ae535a36af0ebca6fca176ecb8197f5db9c1cb8c8f0cd12cdf1787046db1f41" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,11 @@
prefer_openssl3_to_4
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.1" "https://github.com/openssl/openssl/releases/download/openssl-4.0.1/openssl-4.0.1.tar.gz#2db3f3a0d6ea4b59e1f094ace2c8cd536dffb87cdc39084c5afa1e6f7f37dd09" 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.14.6" "https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tar.xz#143b1dddefaec3bd2e21e3b839b34a2b7fb9842272883c576420d605e9f30c63" standard verify_py314 copy_python_gdb ensurepip
else
install_package "Python-3.14.6" "https://www.python.org/ftp/python/3.14.6/Python-3.14.6.tgz#74d0d71d0600e477651a077101d6e62d1e2e69b8e992ba18c993dd643b7ba222" standard verify_py314 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,2 @@
export PYTHON_BUILD_FREE_THREADING=1
source "${BASH_SOURCE[0]%t}"

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

@ -0,0 +1,2 @@
export PYTHON_BUILD_FREE_THREADING=1
source "${BASH_SOURCE[0]%t}"

View File

@ -2,7 +2,7 @@ prefer_openssl11
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then
install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tar.xz#0a833c398ac8cd7c5538f7232d8531afef943c60495c504484f308dac3af40de" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tar.xz#0a833c398ac8cd7c5538f7232d8531afef943c60495c504484f308dac3af40de" standard verify_py36 copy_python_gdb ensurepip
else else
install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tgz#7034dd7cba98d4f94c74f9edd7345bac71c8814c41672c64d9044fa2f96f334d" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.10" "https://www.python.org/ftp/python/3.6.10/Python-3.6.10.tgz#7034dd7cba98d4f94c74f9edd7345bac71c8814c41672c64d9044fa2f96f334d" standard verify_py36 copy_python_gdb ensurepip
fi fi

View File

@ -2,7 +2,7 @@ prefer_openssl11
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then
install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tar.xz#741ebdcbc4e3937a5ff23517dd455ebf7d543ea9fef6f5cf6f46e575d6c4fda4" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tar.xz#741ebdcbc4e3937a5ff23517dd455ebf7d543ea9fef6f5cf6f46e575d6c4fda4" standard verify_py36 copy_python_gdb ensurepip
else else
install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tgz#96621902f89746fffc22f39749c07da7c2917b232e72352e6837d41850f7b90c" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.11" "https://www.python.org/ftp/python/3.6.11/Python-3.6.11.tgz#96621902f89746fffc22f39749c07da7c2917b232e72352e6837d41850f7b90c" standard verify_py36 copy_python_gdb ensurepip
fi fi

View File

@ -2,7 +2,7 @@ prefer_openssl11
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then
install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tar.xz#70953a9b5d6891d92e65d184c3512126a15814bee15e1eff2ddcce04334e9a99" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tar.xz#70953a9b5d6891d92e65d184c3512126a15814bee15e1eff2ddcce04334e9a99" standard verify_py36 copy_python_gdb ensurepip
else else
install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tgz#12dddbe52385a0f702fb8071e12dcc6b3cb2dde07cd8db3ed60e90d90ab78693" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.12" "https://www.python.org/ftp/python/3.6.12/Python-3.6.12.tgz#12dddbe52385a0f702fb8071e12dcc6b3cb2dde07cd8db3ed60e90d90ab78693" standard verify_py36 copy_python_gdb ensurepip
fi fi

View File

@ -2,7 +2,7 @@ prefer_openssl11
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then
install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tar.xz#a47a43a53abb42286a2c11965343ff56711b9e64e8d11bf2c6701a4fb8ce1a0f" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tar.xz#a47a43a53abb42286a2c11965343ff56711b9e64e8d11bf2c6701a4fb8ce1a0f" standard verify_py36 copy_python_gdb ensurepip
else else
install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tgz#614950d3d54f6e78dac651b49c64cfe2ceefea5af3aff3371a9e4b27a53b2669" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.13" "https://www.python.org/ftp/python/3.6.13/Python-3.6.13.tgz#614950d3d54f6e78dac651b49c64cfe2ceefea5af3aff3371a9e4b27a53b2669" standard verify_py36 copy_python_gdb ensurepip
fi fi

View File

@ -2,7 +2,7 @@ prefer_openssl11
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then
install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz#81fd1401a9d66533b0a3e9e3f4ea1c7c6702d57d5b90d659f971e6f1b745f77d" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz#81fd1401a9d66533b0a3e9e3f4ea1c7c6702d57d5b90d659f971e6f1b745f77d" standard verify_py36 copy_python_gdb ensurepip
else else
install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tgz#b7c36f7ed8f7143b2c46153b7332db2227669f583ea0cce753facf549d1a4239" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.7" "https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tgz#b7c36f7ed8f7143b2c46153b7332db2227669f583ea0cce753facf549d1a4239" standard verify_py36 copy_python_gdb ensurepip
fi fi

View File

@ -2,7 +2,7 @@ prefer_openssl11
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then
install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz#35446241e995773b1bed7d196f4b624dadcadc8429f26282e756b2fb8a351193" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz#35446241e995773b1bed7d196f4b624dadcadc8429f26282e756b2fb8a351193" standard verify_py36 copy_python_gdb ensurepip
else else
install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz#7f5b1f08b3b0a595387ef6c64c85b1b13b38abef0dd871835ee923262e4f32f0" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.8" "https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz#7f5b1f08b3b0a595387ef6c64c85b1b13b38abef0dd871835ee923262e4f32f0" standard verify_py36 copy_python_gdb ensurepip
fi fi

View File

@ -2,7 +2,7 @@ prefer_openssl11
install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.0j" "https://www.openssl.org/source/old/1.1.0/openssl-1.1.0j.tar.gz#31bec6c203ce1a8e93d5994f4ed304c63ccf07676118b6634edded12ad1b3246" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then
install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tar.xz#5e2f5f554e3f8f7f0296f7e73d8600c4e9acbaee6b2555b83206edf5153870da" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tar.xz#5e2f5f554e3f8f7f0296f7e73d8600c4e9acbaee6b2555b83206edf5153870da" standard verify_py36 copy_python_gdb ensurepip
else else
install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz#47fc92a1dcb946b9ed0abc311d3767b7215c54e655b17fd1d3f9b538195525aa" standard verify_py37 copy_python_gdb ensurepip install_package "Python-3.6.9" "https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz#47fc92a1dcb946b9ed0abc311d3767b7215c54e655b17fd1d3f9b538195525aa" standard verify_py36 copy_python_gdb ensurepip
fi fi

View File

@ -0,0 +1 @@
3.14.6

View File

@ -1,30 +1,21 @@
case "$(pypy_architecture 2>/dev/null || true)" in case "$(pypy_architecture 2>/dev/null || true)" in
"linux" ) "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 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
;;
"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
;; ;;
"linux64" ) "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" ) "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" ) "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 { 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 assert_success
} }
@test "use the custom GET_PIP_URL for 2.6 versions" { @test "use custom GET_PIP_URLs" {
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 the custom GET_PIP_URL for 2.7 versions" { declare -a name_subdir=(\
run_inline_definition_with_name --name=2.7 <<OUT 2.6
echo "\${GET_PIP_URL}" 2.7
OUT 3.2
assert_output "https://bootstrap.pypa.io/pip/2.7/get-pip.py" 3.3
assert_success 3.4
} 3.5
3.6
3.7
3.8
3.9
@test "use the custom GET_PIP_URL for 3.2 versions" { "pypy2.7-7.3.12 2.7"
run_inline_definition_with_name --name=3.2 <<OUT "pypy-c-jit-latest-linux 2.7"
echo "\${GET_PIP_URL}" "pypy3.5-7.0.0 3.5"
OUT "pypy3.6-7.3.3 3.6"
assert_output "https://bootstrap.pypa.io/pip/3.2/get-pip.py" "pypy3.7-7.3.3 3.7"
assert_success "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" { "pyston-2.3.5 3.8"
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
}
@test "use the custom GET_PIP_URL for 3.4 versions" { for item_s in "${name_subdir[@]}"; do
run_inline_definition_with_name --name=3.4 <<OUT item=($item_s)
echo "\${GET_PIP_URL}" name="${item[0]}"
subdir="${item[1]:-$name}"
run_inline_definition_with_name --name="$name" <<OUT
echo "\${DEFINITION_PATH##*/}:\${GET_PIP_URL}"
OUT OUT
assert_output "https://bootstrap.pypa.io/pip/3.4/get-pip.py" assert_output "$name:https://bootstrap.pypa.io/pip/$subdir/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_success
done
} }

View File

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

View File

@ -79,6 +79,134 @@ OUT
assert_line "PYENV_SHELL_DETECT=bash" 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" { @test "option to skip rehash" {
run pyenv-init - --no-rehash run pyenv-init - --no-rehash
assert_success assert_success

View File

@ -38,18 +38,17 @@ pyenv: cannot rehash: couldn't acquire lock ${PYENV_ROOT}/shims/.pyenv-shim for
assert_success assert_success
} }
@test "stale lockfile is removed" { @test "removes stale lockfile" {
mkdir -p "${PYENV_ROOT}/shims" mkdir -p "${PYENV_ROOT}/shims"
#GNU and BSD `date` support generating relative dates via different syntax # A portable code to set mtime to "N minutes ago" is long and unwieldy,
# but BusyBox `date` used in Bash Docker images doesn't # 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" touch -t 200001010000.00 "${PYENV_ROOT}/shims/.pyenv-shim"
run pyenv-rehash run pyenv-rehash
assert_success "" assert_success ""
assert [ ! -e "${PYENV_ROOT}/shims/.pyenv-shim" ] assert [ ! -e "${PYENV_ROOT}/shims/.pyenv-shim" ]
} }
@test "creates shims" { @test "creates shims" {
create_alt_executable_in_version "2.7" "python" create_alt_executable_in_version "2.7" "python"
create_alt_executable_in_version "2.7" "fab" create_alt_executable_in_version "2.7" "fab"