Compare commits

...

8 Commits

Author SHA1 Message Date
native-api
f9d17bfc06
Rename PYTHON_BUILD_TCLTK_FORMULA to PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA; deprecate the old name (#3580)
* Update tcl/tk note
2026-10-03 18:51:15 +03:00
Ivan Pozdeev
67cfc116b9 -redundant check
invalid-format checksums will be rejected during comparison anyway
2026-10-03 17:37:36 +03:00
Ivan Pozdeev
f217e6c6cf Fix "broken pipe" in pyenv-binary-install 2026-10-03 17:15:05 +03:00
Ivan Pozdeev
07171d013c 2.8.8 2026-10-03 11:30:37 +03:00
pyenv-bot[bot]
7d8d87afc0
Add CPython 3.15.0rc3 (#3578)
Co-authored-by: native-api <2670332+native-api@users.noreply.github.com>
2026-10-03 09:47:28 +03:00
native-api
411a5188e5
README: grammar fixes [no ci] 2026-10-03 07:09:29 +03:00
Michał
f8b1d7ae09
pyenv-exec: add the --environment option for programs that embed libpython without a path (#3537)
---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: native-api <vano@mail.mipt.ru>
2026-10-02 11:17:30 +03:00
Ayush
6ff25c51d3
pyenv-binary: allow local definitions to override published packages (#3577) 2026-10-02 05:19:21 +03:00
14 changed files with 227 additions and 34 deletions

View File

@ -1,5 +1,9 @@
# Version History
## Release v2.8.8
* pyenv-binary: allow local definitions to override published packages by @macayu17 in https://github.com/pyenv/pyenv/pull/3577
* exec: add the `--environment` option for programs that embed `libpython` without a path by @Romwierz in https://github.com/pyenv/pyenv/pull/3537
* Add CPython 3.15.0rc3 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3578
## Release v2.8.7
* Fix rehash repair of individually corrupted shims by @aprylewu in https://github.com/pyenv/pyenv/pull/3540

View File

@ -315,7 +315,7 @@ Lists all Python versions with the given command installed.
## `pyenv exec`
Usage: pyenv exec <command> [arg1 arg2...]
Usage: pyenv exec [-N|--environment] <command> [arg1 arg2...]
Runs an executable by first preparing PATH so that the selected Python
version's `bin` directory is at the front.
@ -326,7 +326,18 @@ For example, if the currently selected Python version is 3.9.7:
is equivalent to:
PATH="$PYENV_ROOT/versions/3.9.7/bin:$PATH" pip install -r requirements.txt
PYENV_VERSION="3.9.7" PATH="$PYENV_ROOT/versions/3.9.7/bin:$PATH" pip install -r requirements.txt
The `--environment` option sets `PYTHONHOME` and `LD_LIBRARY_PATH` (`DYLD_LIBRARY_PATH` in macOS) in the program's environment.
This is needed to run programs that embed Python by loading `libpython` without specifying rpath or an explicit path.
This breaks linking for programs that expect to link to a different `libpython` with the same name as one
in selected Python -- thus it's not done by default.
In macOS, System Integrity Protection (SIP) removes `DYLD_LIBRARY_PATH` from a process' environment
upon `exec` (not `fork`) if the executable being run is protected. The protection covers preinstalled system software
(including preinstalled shells) and does not cover user-installed apps and 3rd-party software. See
[About System Integrity Protection on your Mac - Apple Support](https://support.apple.com/en-us/102149)
for details.
## `pyenv root`

View File

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

View File

@ -2,7 +2,17 @@
#
# Summary: Run an executable with the selected Python version
#
# Usage: pyenv exec <command> [arg1 arg2...]
# Usage: pyenv exec [-N|--environment] <command> [arg1 arg2...]
#
# -N/--environment Set PYTHONHOME and LD_LIBRARY_PATH (DYLD_LIBRARY_PATH in macOS)
# envvars for the running command.
# This allows to run programs that embed Python without using rpath or
# exact library path to libpython.
# WARNING: For the running command and its child processes, this will
# break linkage for programs that expect to be linked to a different
# libpython instance with the same name!
# WARNING: In macOS, DYLD_LIBRARY_PATH will be unset by the system for
# processes covered by System Integrity Protection.
#
# Runs an executable by first preparing PATH so that the selected Python
# version's `bin' directory is at the front.
@ -18,9 +28,16 @@ set -e
# Provide pyenv completions
if [ "$1" = "--complete" ]; then
echo --environment
exec pyenv-shims --short
fi
unset MODIFY_ENV
if [ "$1" = "-N" ] || [ "$1" = "--environment" ]; then
MODIFY_ENV=true
shift
fi
PYENV_VERSION="$(pyenv-version-name -f)"
PYENV_COMMAND="$1"
@ -54,4 +71,27 @@ if [ "${PYENV_BIN_PATH#${PYENV_ROOT}}" != "${PYENV_BIN_PATH}" ]; then
# Only add to $PATH for non-system version.
export PATH="${PYENV_BIN_PATH}:${PATH}"
fi
if [ -n "$MODIFY_ENV" ]; then
# Check if multiple Python versions are selected
VERSIONS=$(pyenv-prefix)
if [[ "$VERSIONS" == *:* ]]; then
VERSION="${VERSIONS%%:*}"
echo "pyenv: Warning: multiple Python versions are selected." \
"Setting environment variables for the first one, (${VERSION#$PYENV_ROOT})" >&2
else
VERSION="$VERSIONS"
fi
# Assign the correct version of PYTHONHOME
export PYTHONHOME="$VERSION"
case "$(uname -s)" in
Darwin)
export DYLD_LIBRARY_PATH="${PYTHONHOME}/lib${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}"
;;
*)
export LD_LIBRARY_PATH="${PYTHONHOME}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
;;
esac
fi
exec "$PYENV_COMMAND_PATH" "$@"

View File

@ -33,6 +33,11 @@ proceeds.
pyenv binary install 3.14.7
```
A definition with the selected package entry's name in a plugin's
`share/python-build` directory overrides the published definition. The normal
Python-Build search order applies, including `PYTHON_BUILD_DEFINITIONS`.
Local definitions are installed without downloading the stock definition.
### `pyenv binary package [-v|--verbose] <version>[:<entry>] --archive-base-url <url>`
Installs `<version>` from source under a separate name, packages that install

View File

@ -100,10 +100,12 @@ if [ -z "$entry" ]; then
echo "pyenv-binary: no binary available for $requested on $os/$arch" >&2
exit 1
fi
if ! [[ "$expected_sha" =~ ^[0-9a-fA-F]{64}$ ]]; then
echo "pyenv-binary: invalid checksum for $entry" >&2
exit 1
definitions="$(pyenv-install --list --bare)"
if grep -qxF -- "$entry" <<<"$definitions"; then
pyenv-install "$entry:$version"
exit
fi
expected_sha="$(printf '%s' "$expected_sha" | tr '[:upper:]' '[:lower:]')"
curl -fsSL -o "$tmpdir/$entry" "$base_url/$entry"
@ -117,7 +119,7 @@ else
echo "pyenv-binary: need sha256sum, shasum or openssl to verify $entry" >&2
exit 1
fi
if [ "$actual_sha" != "$expected_sha" ]; then
if [[ $expected_sha != "$actual_sha" ]]; then
echo "pyenv-binary: checksum mismatch for $entry" >&2
exit 1
fi

View File

@ -44,7 +44,7 @@ STUB
"$(host_distro)" 0 >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
stub_downloads
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub pyenv-install 'echo installed'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo installed'
run pyenv-binary-install 3.14.7
assert_failure
@ -58,6 +58,50 @@ STUB
assert_success ""
}
@test "a plugin definition overrides a published binary without its checksum" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
export TMPDIR="$BATS_TEST_TMPDIR/temp"
mkdir -p "$TMPDIR"
local entry="3.14.7-ubuntu-24.04-x86_64"
printf '3.14.7\t%s\tLinux\tx86_64\t%s\t%s\n' "$entry" \
"$(host_distro)" "" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub curl 'touch "$BATS_TEST_TMPDIR/downloaded"; exit 1'
PATH="${BATS_TEST_DIRNAME}/../../python-build/bin:$PATH"
mkdir -p "$PYENV_ROOT/plugins/first/share/python-build" "$PYENV_ROOT/plugins/second/share/python-build"
printf '%s\n' 'mkdir -p "$PREFIX_PATH"; echo first > "$PREFIX_PATH/marker"' \
> "$PYENV_ROOT/plugins/first/share/python-build/$entry"
echo 'exit 1' > "$PYENV_ROOT/plugins/second/share/python-build/$entry"
run pyenv-binary-install 3.14
assert_success ""
assert_equal first "$(cat "$PYENV_ROOT/versions/3.14.7/marker")"
[ ! -e "$BATS_TEST_TMPDIR/downloaded" ]
assert_equal "" "$(find "$TMPDIR" -mindepth 1 -maxdepth 1 -type d)"
}
@test "an explicit definition path takes precedence over a plugin definition" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
local entry="3.14.7-ubuntu-24.04-x86_64"
printf '3.14.7\t%s\tLinux\tx86_64\t%s\t%s\n' "$entry" \
"$(host_distro)" "$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub curl 'touch "$BATS_TEST_TMPDIR/downloaded"; exit 1'
PATH="${BATS_TEST_DIRNAME}/../../python-build/bin:$PATH"
export PYTHON_BUILD_DEFINITIONS="$BATS_TEST_TMPDIR/custom definitions"
mkdir -p "$PYTHON_BUILD_DEFINITIONS" "$PYENV_ROOT/plugins/custom/share/python-build"
printf '%s\n' 'mkdir -p "$PREFIX_PATH"; echo custom > "$PREFIX_PATH/marker"' \
> "$PYTHON_BUILD_DEFINITIONS/$entry"
echo 'exit 1' > "$PYENV_ROOT/plugins/custom/share/python-build/$entry"
run pyenv-binary-install 3.14.7
assert_success ""
assert_equal custom "$(cat "$PYENV_ROOT/versions/3.14.7/marker")"
[ ! -e "$BATS_TEST_TMPDIR/downloaded" ]
}
@test "installs a matching published binary with an uppercase checksum" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
@ -70,6 +114,7 @@ STUB
stub_downloads
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub pyenv-install <<'STUB'
[ "$1" = --list ] && exit
definition="${1%:*}"
printf '%s:%s\n' "${definition##*/}" "${1##*:}"
cat "$definition"
@ -89,7 +134,7 @@ definition"
"$(host_distro)" "$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
stub_downloads
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub pyenv-install 'echo "${1##*:}"'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo "${1##*:}"'
run pyenv-binary-install 3.14
assert_success "3.14.10"
@ -125,7 +170,7 @@ definition"
stub_downloads
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
create_stub sw_vers 'echo 26.6.2'
create_stub pyenv-install 'echo "${1##*:}"'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo "${1##*:}"'
run pyenv-binary-install 3.14.7
assert_success "3.14.7"
@ -137,7 +182,7 @@ definition"
"$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
create_stub sw_vers 'echo 15.7.8'
create_stub pyenv-install 'echo installed'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo installed'
run pyenv-binary-install 3.14.7
assert_failure "pyenv-binary: no binary available for 3.14.7 on Darwin/arm64"

View File

@ -182,13 +182,13 @@ You can set certain environment variables to control the build process.
their original source URLs instead of using a mirror.
* `PYTHON_BUILD_HTTP_CLIENT`, explicitly specify the HTTP client type to use. `aria2`, `curl` and `wget` are the supported values and by default, are searched in that order.
* `PYTHON_BUILD_CURL_OPTS`, `PYTHON_BUILD_WGET_OPTS`, `PYTHON_BUILD_ARIA2_OPTS` pass additional parameters to the corresponding HTTP client.
* `PYTHON_BUILD_SKIP_HOMEBREW`, if set, will not search for libraries installed by Homebrew when it would normally will.
* `PYTHON_BUILD_USE_HOMEBREW`, if set, will search for libraries installed by Homebrew when it would normally not.
* `PYTHON_BUILD_SKIP_HOMEBREW`, if set, will not search for libraries installed by Homebrew when it normally would.
* `PYTHON_BUILD_USE_HOMEBREW`, if set, will search for libraries installed by Homebrew when it normally wouldn't.
* `PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA`, override the Homebrew OpenSSL formula to use.
* `PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA`, override the MacPorts OpenSSL formula to use. The default is `openssl3 openssl`.
* `PYTHON_BUILD_TCLTK_FORMULA`, override the Homebrew Tcl/Tk formula to use.
* `PYTHON_BUILD_SKIP_MACPORTS`, if set, will not search for libraries installed by MacPorts when it would normally will.
* `PYTHON_BUILD_USE_MACPORTS`, if set, will search for libraries installed by MacPorts when it would normally not.
* `PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA`, override the Homebrew Tcl/Tk formula to use.
* `PYTHON_BUILD_SKIP_MACPORTS`, if set, will not search for libraries installed by MacPorts when it normally would.
* `PYTHON_BUILD_USE_MACPORTS`, if set, will search for libraries installed by MacPorts when it normally wouldn't.
* `PYTHON_BUILD_ROOT` overrides the default location from where build definitions
in `share/python-build/` are looked up.
* `PYTHON_BUILD_DEFINITIONS` can be a list of colon-separated paths that get

View File

@ -14,7 +14,7 @@
# -g/--debug Build a debug version
#
PYTHON_BUILD_VERSION="2.8.7"
PYTHON_BUILD_VERSION="2.8.8"
OLDIFS="$IFS"
@ -2006,9 +2006,14 @@ use_homebrew_tcltk() {
can_use_homebrew || return 1
local tcltk_formula
# Since https://github.com/Homebrew/homebrew-core/commit/f10e88617b41555193c22fdcba6109fe82155ee2 (10.11.2024),
# tcl-tk is 9.0. It's supported in CPython since 3.14.0a1 (gh-124111) but is not officially supported as of 3.14.0
# so we prefer 8
for tcltk_formula in ${PYTHON_BUILD_TCLTK_FORMULA:-tcl-tk@8 tcl-tk}; do
# tcl-tk is 9.0. It's supported in CPython since 3.14.0a1 (gh-124111) but is not officially supported as of 3.14.0,
# as of 3.15.0rc3, there are still test failures.
# So we prefer 8.
if [[ -n $PYTHON_BUILD_TCLTK_FORMULA ]]; then
export PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA="${PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA:-$PYTHON_BUILD_TCLTK_FORMULA}"
echo "warning: the PYTHON_BUILD_TCLTK_FORMULA envvar has been renamed to PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA" >&2
fi
for tcltk_formula in ${PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA:-tcl-tk@8 tcl-tk}; do
local tcltk_prefix="$(brew --prefix "${tcltk_formula}" 2>/dev/null || true)"
if [ -d "$tcltk_prefix" ]; then
echo "python-build: use ${tcltk_formula} from homebrew"

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-4.0.2" "https://github.com/openssl/openssl/releases/download/openssl-4.0.2/openssl-4.0.2.tar.gz#736b467530f916737b7031310ccb21d8218c6229e61e8e160cd1d3458cd543a8" 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.0rc2" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc2.tar.xz#8d93af5eaaaea5adfd41bd786a7ba3f03f2ad1ab57c6a65e0b963deab91d5ad7" standard verify_py315 copy_python_gdb ensurepip
else
install_package "Python-3.15.0rc2" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc2.tgz#164dbb80f5e1fdd8768387724bfa014da1000401b2015d872a2396c8b858b829" 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.3" "https://github.com/openssl/openssl/releases/download/openssl-4.0.3/openssl-4.0.3.tar.gz#325b5c806167c13b40b1ffeadfe0248197c00eccc4cf123ec1e28d2d2fd216d9" 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.0rc3" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc3.tar.xz#506630aa66d5441188f34df22c0760bfe87fc92212630493ebc9ff3b3a7a1d49" standard verify_py315 copy_python_gdb ensurepip
else
install_package "Python-3.15.0rc3" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0rc3.tgz#98a6264c7a48e4ce0f9a9ea4bdd211ea9fcff32b55c79c5efc1ae6d91b032210" standard verify_py315 copy_python_gdb ensurepip
fi

View File

@ -1066,8 +1066,10 @@ make install
OUT
}
@test "tcl-tk is linked from Homebrew with PYTHON_BUILD_TCLTK_FORMULA" {
test_tcltk_var() {
local var="${1:?}"
cached_tarball "Python-3.6.2"
stub_tcltk "${tcl_tk_libdir:=$BATS_TEST_TMPDIR/homebrew-tcl-tk}"
stub uname '-s : echo Darwin'
@ -1080,7 +1082,7 @@ OUT
stub_make_install
run_inline_definition <<DEF
PYTHON_BUILD_TCLTK_FORMULA=tcl-tk-custom
$var=tcl-tk-custom
install_package "Python-3.6.2" "http://python.org/ftp/python/3.6.2/Python-3.6.2.tar.gz"
DEF
assert_success
@ -1098,6 +1100,34 @@ make install
OUT
}
@test "tcl-tk is linked from Homebrew with PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA" {
test_tcltk_var PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA
}
@test "tcl-tk is linked from Homebrew with PYTHON_BUILD_TCLTK_FORMULA" {
test_tcltk_var PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA
}
@test "PYTHON_BUILD_TCLTK_FORMULA produces a deprecation warning" {
cached_tarball "Python-3.6.2"
stub uname '-s : echo Darwin'
stub sw_vers '-productVersion : echo 1010'
stub brew '--prefix openssl : false'
stub brew "--prefix tcl-tk-custom : echo '$tcl_tk_libdir'"
for i in {1..4}; do stub brew false; done
stub_make_install
run_inline_definition <<DEF
PYTHON_BUILD_TCLTK_FORMULA=tcl-tk-whatever
install_package "Python-3.6.2" "http://python.org/ftp/python/3.6.2/Python-3.6.2.tar.gz"
DEF
assert_success
assert_line "warning: the PYTHON_BUILD_TCLTK_FORMULA envvar has been renamed to PYTHON_BUILD_HOMEBREW_TCLTK_FORMULA"
}
@test "tcl-tk is linked from Homebrew via pkg-config and override vars" {
cached_tarball "Python-3.6.2" - TCLTK_CFLAGS TCLTK_LIBS
stub_tcltk "${tcl_tk_libdir:=$BATS_TEST_TMPDIR/homebrew-tcl-tk}"

View File

@ -34,6 +34,7 @@ EOF
assert_success
assert_output <<OUT
--help
--environment
fab
python
OUT
@ -139,3 +140,53 @@ $envvarname=/unusual/shim/location:/another/shim/location
_PYENV_SHIM_PATH=
!
}
@test "--environment sets envvars in Linux" {
export PYENV_VERSION="test"
create_alt_executable print_env <<!
#!$BASH
echo PYTHONHOME="\$PYTHONHOME"
echo LD_LIBRARY_PATH="\$LD_LIBRARY_PATH"
!
create_path_executable uname "echo Linux"
LD_LIBRARY_PATH= run pyenv-exec -N print_env
assert_output_glob <<!
PYTHONHOME=*/test
LD_LIBRARY_PATH=*/test/lib
!
LD_LIBRARY_PATH=/foo/bar run pyenv-exec -N print_env
assert_output_glob <<!
PYTHONHOME=*/test
LD_LIBRARY_PATH=*/test/lib:/foo/bar
!
}
@test "--environment sets envvars in macOS" {
if [[ $(uname -s) == "Darwin" && $BASH == "/bin/bash" \
&& $(LC_ALL=C csrutil status) == *"enabled." ]]; then
skip "macOS with Bash covered by SIP"
fi
export PYENV_VERSION="test"
create_alt_executable print_env <<!
#!$BASH
echo PYTHONHOME="\$PYTHONHOME"
echo DYLD_LIBRARY_PATH="\$DYLD_LIBRARY_PATH"
!
create_path_executable uname "echo Darwin"
DYLD_LIBRARY_PATH= run pyenv-exec -N print_env
assert_output_glob <<!
PYTHONHOME=*/test
DYLD_LIBRARY_PATH=*/test/lib
!
DYLD_LIBRARY_PATH=/foo/bar run pyenv-exec -N print_env
assert_output_glob <<!
PYTHONHOME=*/test
DYLD_LIBRARY_PATH=*/test/lib:/foo/bar
!
}