mirror of
https://github.com/pyenv/pyenv.git
synced 2026-04-06 21:55:11 +09:00
Compare commits
No commits in common. "master" and "v2.6.24" have entirely different histories.
2
.github/workflows/add_version.yml
vendored
2
.github/workflows/add_version.yml
vendored
@ -41,7 +41,7 @@ jobs:
|
|||||||
# https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens
|
# https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens
|
||||||
- name: Generate Github token
|
- name: Generate Github token
|
||||||
if: env.rc == 0
|
if: env.rc == 0
|
||||||
uses: actions/create-github-app-token@v3
|
uses: actions/create-github-app-token@v2
|
||||||
id: generate-token
|
id: generate-token
|
||||||
with:
|
with:
|
||||||
app-id: ${{ vars.PYENV_BOT_APP_ID }}
|
app-id: ${{ vars.PYENV_BOT_APP_ID }}
|
||||||
|
|||||||
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,16 +1,5 @@
|
|||||||
# Version History
|
# Version History
|
||||||
|
|
||||||
## Release v2.6.26
|
|
||||||
* versions: fast path for --bare --skip-aliases by @jakelodwick in https://github.com/pyenv/pyenv/pull/3411
|
|
||||||
* Fix MacPorts OpenSSL formula detection by @tekintian in https://github.com/pyenv/pyenv/pull/3417
|
|
||||||
* rehash: streamline executables discovery; fix regression by @native-api in https://github.com/pyenv/pyenv/pull/3418
|
|
||||||
* rehash: simplify source.bash pipeline by @jakelodwick in https://github.com/pyenv/pyenv/pull/3419
|
|
||||||
* Add CPython 3.15.0a7 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3421
|
|
||||||
|
|
||||||
## Release v2.6.25
|
|
||||||
* Add miniforge3-26.1.0-0 by @native-api in https://github.com/pyenv/pyenv/pull/3413
|
|
||||||
* Add CPython 3.12.13 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3414
|
|
||||||
|
|
||||||
## Release v2.6.24
|
## Release v2.6.24
|
||||||
* CI: add_version: use Github App token to create PR by @native-api in https://github.com/pyenv/pyenv/pull/3406
|
* CI: add_version: use Github App token to create PR by @native-api in https://github.com/pyenv/pyenv/pull/3406
|
||||||
* Add Anaconda3-2025.12-2 by @binbjz in https://github.com/pyenv/pyenv/pull/3408
|
* Add Anaconda3-2025.12-2 by @binbjz in https://github.com/pyenv/pyenv/pull/3408
|
||||||
|
|||||||
17
COMMANDS.md
17
COMMANDS.md
@ -40,8 +40,9 @@ Lists all available pyenv commands.
|
|||||||
|
|
||||||
Sets a local application-specific Python version by writing the version
|
Sets a local application-specific Python version by writing the version
|
||||||
name to a `.python-version` file in the current directory. This version
|
name to a `.python-version` file in the current directory. This version
|
||||||
overrides the [global version](#pyenv-global), and can be overridden
|
overrides the global version, and can be overridden itself by setting
|
||||||
itself with the [`pyenv shell`](#pyenv-shell) command.
|
the `PYENV_VERSION` environment variable or with the `pyenv shell`
|
||||||
|
command.
|
||||||
|
|
||||||
$ pyenv local 2.7.6
|
$ pyenv local 2.7.6
|
||||||
|
|
||||||
@ -97,8 +98,9 @@ This is mainly useful in special cases like provisioning scripts.
|
|||||||
## `pyenv global`
|
## `pyenv global`
|
||||||
|
|
||||||
Sets the global version of Python to be used in all shells by writing
|
Sets the global version of Python to be used in all shells by writing
|
||||||
the version name to the `$PYENV_ROOT/version` file. This version can be
|
the version name to the `~/.pyenv/version` file. This version can be
|
||||||
overridden with [`pyenv local`](#pyenv-local) or [`pyenv shell`](#pyenv-shell).
|
overridden by an application-specific `.python-version` file, or by
|
||||||
|
setting the `PYENV_VERSION` environment variable.
|
||||||
|
|
||||||
$ pyenv global 2.7.6
|
$ pyenv global 2.7.6
|
||||||
|
|
||||||
@ -234,7 +236,6 @@ Then install the desired versions:
|
|||||||
You can also install the latest version of Python in a specific version line by supplying a prefix instead of a complete name:
|
You can also install the latest version of Python in a specific version line by supplying a prefix instead of a complete name:
|
||||||
|
|
||||||
$ pyenv install 3.10
|
$ pyenv install 3.10
|
||||||
$ pyenv install 3
|
|
||||||
|
|
||||||
See the [`pyenv latest` documentation](#pyenv-latest) for details on prefix resolution.
|
See the [`pyenv latest` documentation](#pyenv-latest) for details on prefix resolution.
|
||||||
|
|
||||||
@ -242,6 +243,9 @@ An older option is to use the `:latest` syntax. For example, to install the late
|
|||||||
|
|
||||||
pyenv install 3.8:latest
|
pyenv install 3.8:latest
|
||||||
|
|
||||||
|
To install the latest major release for Python 3 try:
|
||||||
|
|
||||||
|
pyenv install 3:latest
|
||||||
|
|
||||||
## `pyenv uninstall`
|
## `pyenv uninstall`
|
||||||
|
|
||||||
@ -348,9 +352,10 @@ locations of the currently selected versions.
|
|||||||
|
|
||||||
Displays the latest installed or known version with the given prefix
|
Displays the latest installed or known version with the given prefix
|
||||||
|
|
||||||
Usage: pyenv latest [-k|--known] <prefix>
|
Usage: pyenv latest [-k|--known] [-q|--quiet] <prefix>
|
||||||
|
|
||||||
-k/--known Select from all known versions instead of installed
|
-k/--known Select from all known versions instead of installed
|
||||||
|
-q/--quiet Do not print an error message on resolution failure
|
||||||
|
|
||||||
Only full prefixes are searched: in the actual name, the given prefix must be followed by a dot or a dash.
|
Only full prefixes are searched: in the actual name, the given prefix must be followed by a dot or a dash.
|
||||||
|
|
||||||
|
|||||||
@ -407,7 +407,7 @@ of the following commands:
|
|||||||
|
|
||||||
* [`pyenv shell <version>`](COMMANDS.md#pyenv-shell) -- select just for current shell session
|
* [`pyenv shell <version>`](COMMANDS.md#pyenv-shell) -- select just for current shell session
|
||||||
* [`pyenv local <version>`](COMMANDS.md#pyenv-local) -- automatically select whenever you are in the current directory (or its subdirectories)
|
* [`pyenv local <version>`](COMMANDS.md#pyenv-local) -- automatically select whenever you are in the current directory (or its subdirectories)
|
||||||
* [`pyenv global <version>`](COMMANDS.md#pyenv-global) -- select globally for your user account
|
* [`pyenv global <version>`](COMMANDS.md#pyenv-shell) -- select globally for your user account
|
||||||
|
|
||||||
E.g. to select the above-mentioned newly-installed Python 3.10.4 as your preferred version to use:
|
E.g. to select the above-mentioned newly-installed Python 3.10.4 as your preferred version to use:
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
set -e
|
set -e
|
||||||
[ -n "$PYENV_DEBUG" ] && set -x
|
[ -n "$PYENV_DEBUG" ] && set -x
|
||||||
|
|
||||||
version="2.6.26"
|
version="2.6.24"
|
||||||
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
|
||||||
|
|||||||
@ -3,19 +3,19 @@
|
|||||||
# Usage: pyenv commands [--sh|--no-sh]
|
# Usage: pyenv commands [--sh|--no-sh]
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
[[ -n $PYENV_DEBUG ]] && set -x
|
[ -n "$PYENV_DEBUG" ] && set -x
|
||||||
|
|
||||||
# Provide pyenv completions
|
# Provide pyenv completions
|
||||||
if [[ $1 = "--complete" ]]; then
|
if [ "$1" = "--complete" ]; then
|
||||||
echo --sh
|
echo --sh
|
||||||
echo --no-sh
|
echo --no-sh
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $1 = "--sh" ]]; then
|
if [ "$1" = "--sh" ]; then
|
||||||
sh=1
|
sh=1
|
||||||
shift
|
shift
|
||||||
elif [[ $1 = "--no-sh" ]]; then
|
elif [ "$1" = "--no-sh" ]; then
|
||||||
nosh=1
|
nosh=1
|
||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
@ -24,25 +24,20 @@ IFS=: paths=($PATH)
|
|||||||
|
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
|
|
||||||
{
|
{ for path in "${paths[@]}"; do
|
||||||
if [[ -n $sh ]]; then
|
for command in "${path}/pyenv-"*; do
|
||||||
for path in "${paths[@]}"; do
|
command="${command##*pyenv-}"
|
||||||
for command in "${path}"/pyenv-sh-*; do
|
if [ -n "$sh" ]; then
|
||||||
echo "${command##*/pyenv-sh-}"
|
if [ "${command:0:3}" = "sh-" ]; then
|
||||||
done
|
echo "${command##sh-}"
|
||||||
done
|
fi
|
||||||
else
|
elif [ -n "$nosh" ]; then
|
||||||
for path in "${paths[@]}"; do
|
if [ "${command:0:3}" != "sh-" ]; then
|
||||||
for command in "${path}"/pyenv-*; do
|
echo "${command##sh-}"
|
||||||
command="${command##*/pyenv-}"
|
|
||||||
if [[ -n $nosh ]]; then
|
|
||||||
if [[ ${command:0:3} != "sh-" ]]; then
|
|
||||||
echo "$command"
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo "${command##sh-}"
|
echo "${command##sh-}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
fi
|
} | sort | uniq
|
||||||
} | sort -u
|
|
||||||
|
|||||||
@ -110,6 +110,17 @@ remove_outdated_shims() {
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# List basenames of executables for every Python version
|
||||||
|
list_executable_names() {
|
||||||
|
local version file
|
||||||
|
pyenv-versions --bare --skip-aliases | \
|
||||||
|
while read -r version; do
|
||||||
|
for file in "${PYENV_ROOT}/versions/${version}/bin/"*; do
|
||||||
|
echo "${file##*/}"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
# The basename of each argument passed to `make_shims` will be
|
# The basename of each argument passed to `make_shims` will be
|
||||||
# registered for installation as a shim. In this way, plugins may call
|
# registered for installation as a shim. In this way, plugins may call
|
||||||
# `make_shims` with a glob to register many shims at once.
|
# `make_shims` with a glob to register many shims at once.
|
||||||
@ -185,7 +196,7 @@ shopt -s nullglob
|
|||||||
create_prototype_shim
|
create_prototype_shim
|
||||||
remove_outdated_shims
|
remove_outdated_shims
|
||||||
# shellcheck disable=SC2046
|
# shellcheck disable=SC2046
|
||||||
make_shims $(pyenv-versions --executables)
|
make_shims $(list_executable_names)
|
||||||
|
|
||||||
|
|
||||||
# Allow plugins to register shims.
|
# Allow plugins to register shims.
|
||||||
|
|||||||
@ -1,21 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Summary: List all Python versions available to pyenv
|
# Summary: List all Python versions available to pyenv
|
||||||
# Usage: pyenv versions [--bare] [--skip-aliases] [--skip-envs] [--executables]
|
# Usage: pyenv versions [--bare] [--skip-aliases] [--skip-envs]
|
||||||
#
|
#
|
||||||
# Lists all Python versions found in `$PYENV_ROOT/versions/*'.
|
# Lists all Python versions found in `$PYENV_ROOT/versions/*'.
|
||||||
#
|
|
||||||
# --bare List just the names, omit `system'
|
|
||||||
# --skip-aliases Skip symlinks to other versions and to virtual environments
|
|
||||||
# --skip-envs Skip virtual environments (under <version>/envs)
|
|
||||||
# --executables Internal. Overrides other options.
|
|
||||||
# Optimally get a deduplicated list of all executable names in Pyenv-managed
|
|
||||||
# versions and environments for `pyenv rehash'
|
|
||||||
#
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
[ -n "$PYENV_DEBUG" ] && set -x
|
[ -n "$PYENV_DEBUG" ] && set -x
|
||||||
|
|
||||||
unset bare skip_aliases skip_envs executables
|
unset bare skip_aliases skip_envs
|
||||||
# Provide pyenv completions
|
# Provide pyenv completions
|
||||||
for arg; do
|
for arg; do
|
||||||
case "$arg" in
|
case "$arg" in
|
||||||
@ -24,7 +16,6 @@ for arg; do
|
|||||||
echo --skip-aliases
|
echo --skip-aliases
|
||||||
echo --skip-envs
|
echo --skip-envs
|
||||||
exit ;;
|
exit ;;
|
||||||
--executables ) executables=1; break ;;
|
|
||||||
--bare ) bare=1 ;;
|
--bare ) bare=1 ;;
|
||||||
--skip-aliases ) skip_aliases=1 ;;
|
--skip-aliases ) skip_aliases=1 ;;
|
||||||
--skip-envs ) skip_envs=1 ;;
|
--skip-envs ) skip_envs=1 ;;
|
||||||
@ -35,21 +26,8 @@ for arg; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
versions_dir="${PYENV_ROOT}/versions"
|
versions_dir="${PYENV_ROOT}/versions"
|
||||||
|
|
||||||
# Fast path for rehash: skip filtering and link resolution
|
|
||||||
if [[ -n "$executables" ]]; then
|
|
||||||
if [ -d "$versions_dir" ]; then
|
|
||||||
shopt -s dotglob nullglob
|
|
||||||
# MacOS 12+ and FreeBSD 15 support `xargs -r -0' and `basename -a'
|
|
||||||
# `sort -u` is simpler and a bit faster than `awk '!seen[$0]++'`, with the same result for rehash purposes
|
|
||||||
printf '%s\0' "$versions_dir"/*/bin/* "$versions_dir"/*/envs/*/bin/* | xargs -0 -r basename -a | sort -u
|
|
||||||
shopt -u dotglob nullglob
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! enable -f "${BASH_SOURCE%/*}"/pyenv-realpath.dylib realpath 2>/dev/null; then
|
if ! enable -f "${BASH_SOURCE%/*}"/pyenv-realpath.dylib realpath 2>/dev/null; then
|
||||||
if [ -n "$PYENV_NATIVE_EXT" ]; then
|
if [ -n "$PYENV_NATIVE_EXT" ]; then
|
||||||
echo "pyenv: failed to load \`realpath' builtin" >&2
|
echo "pyenv: failed to load \`realpath' builtin" >&2
|
||||||
|
|||||||
@ -112,8 +112,8 @@ else
|
|||||||
echo "The \`$PYENV_COMMAND' command exists in these Python versions:"
|
echo "The \`$PYENV_COMMAND' command exists in these Python versions:"
|
||||||
echo "$versions" | sed 's/^/ /g'
|
echo "$versions" | sed 's/^/ /g'
|
||||||
echo
|
echo
|
||||||
echo "Note: See 'pyenv help global' for tips on allowing multiple"
|
echo "Note: See 'pyenv help global' for tips on allowing both"
|
||||||
echo " Python versions to be found at the same time."
|
echo " python2 and python3 to be found."
|
||||||
} >&2
|
} >&2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -175,7 +175,6 @@ You can set certain environment variables to control the build process.
|
|||||||
* `PYTHON_BUILD_SKIP_HOMEBREW`, if set, will not search for libraries installed by Homebrew when it would normally will.
|
* `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_USE_HOMEBREW`, if set, will search for libraries installed by Homebrew when it would normally not.
|
||||||
* `PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA`, override the Homebrew OpenSSL formula to use.
|
* `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_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_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_USE_MACPORTS`, if set, will search for libraries installed by MacPorts when it would normally not.
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
# -g/--debug Build a debug version
|
# -g/--debug Build a debug version
|
||||||
#
|
#
|
||||||
|
|
||||||
PYTHON_BUILD_VERSION="2.6.26"
|
PYTHON_BUILD_VERSION="2.6.24"
|
||||||
|
|
||||||
OLDIFS="$IFS"
|
OLDIFS="$IFS"
|
||||||
|
|
||||||
@ -202,14 +202,7 @@ build_failed() {
|
|||||||
colorize 33 "Results logged to ${LOG_PATH}"
|
colorize 33 "Results logged to ${LOG_PATH}"
|
||||||
printf "\n\n"
|
printf "\n\n"
|
||||||
echo "Last 10 log lines:"
|
echo "Last 10 log lines:"
|
||||||
TAIL=`tail -n 10 "$LOG_PATH"`
|
tail -n 10 "$LOG_PATH"
|
||||||
echo "$TAIL"
|
|
||||||
if echo "$TAIL" | grep -q "no acceptable C compiler found"; then
|
|
||||||
printf "\n"
|
|
||||||
echo "Are the build dependencies for Python correctly installed?"
|
|
||||||
echo "Please consult to the Wiki page for more info."
|
|
||||||
echo "https://github.com/pyenv/pyenv/wiki#suggested-build-environment"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
} >&3
|
} >&3
|
||||||
exit 1
|
exit 1
|
||||||
@ -1670,20 +1663,12 @@ prefer_openssl11() {
|
|||||||
# Allow overriding the preference of OpenSSL version per definition basis (#1302, #1325, #1326)
|
# Allow overriding the preference of OpenSSL version per definition basis (#1302, #1325, #1326)
|
||||||
PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA="${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl@1.1 openssl}"
|
PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA="${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl@1.1 openssl}"
|
||||||
export PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA
|
export PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA
|
||||||
|
|
||||||
PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA="${PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA:-openssl11 openssl3 openssl}"
|
|
||||||
export PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prefer_openssl3() {
|
prefer_openssl3() {
|
||||||
# Allow overriding the preference of OpenSSL version per definition basis (#1302, #1325, #1326)
|
# Allow overriding the preference of OpenSSL version per definition basis (#1302, #1325, #1326)
|
||||||
PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA="${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl@3 openssl@1.1 openssl}"
|
PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA="${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl@3 openssl@1.1 openssl}"
|
||||||
export PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA
|
export PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA
|
||||||
|
|
||||||
# Set MacPorts OpenSSL formula names for MacPorts environment
|
|
||||||
PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA="${PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA:-openssl3 openssl openssl11}"
|
|
||||||
export PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build_package_mac_readline() {
|
build_package_mac_readline() {
|
||||||
@ -1742,8 +1727,7 @@ use_macports_openssl() {
|
|||||||
command -v port >/dev/null || return 1
|
command -v port >/dev/null || return 1
|
||||||
local port_location="$(command -v port)"
|
local port_location="$(command -v port)"
|
||||||
local prefix="${port_location%/bin/port}"
|
local prefix="${port_location%/bin/port}"
|
||||||
# MacPorts uses a different package naming convention and does not use the @ symbol.
|
for openssl in ${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl}; do
|
||||||
for openssl in ${PYTHON_BUILD_MACPORTS_OPENSSL_FORMULA:-openssl3 openssl}; do
|
|
||||||
if [[ $(port -q installed ${openssl} | awk '{print $3}') == "(active)" ]]; then
|
if [[ $(port -q installed ${openssl} | awk '{print $3}') == "(active)" ]]; then
|
||||||
echo "python-build: use ${openssl} from MacPorts"
|
echo "python-build: use ${openssl} from MacPorts"
|
||||||
if [[ -n "${PYTHON_BUILD_CONFIGURE_WITH_OPENSSL:-}" ]]; then
|
if [[ -n "${PYTHON_BUILD_CONFIGURE_WITH_OPENSSL:-}" ]]; then
|
||||||
|
|||||||
@ -47,9 +47,9 @@ here = Path(__file__).resolve()
|
|||||||
out_dir: Path = here.parent.parent / "share" / "python-build"
|
out_dir: Path = here.parent.parent / "share" / "python-build"
|
||||||
|
|
||||||
def download_sha(url):
|
def download_sha(url):
|
||||||
logger.info(f'Downloading SHA file {url}')
|
logger.info('Downloading SHA file %(url)s', locals())
|
||||||
tup = tuple(reversed(requests.get(url).text.replace('./', '').rstrip().split()))
|
tup = tuple(reversed(requests.get(url).text.replace('./', '').rstrip().split()))
|
||||||
logger.debug(f'Got {tup}')
|
logger.debug('Got %(tup)s', locals())
|
||||||
return tup
|
return tup
|
||||||
|
|
||||||
def create_spec(filename, sha, url):
|
def create_spec(filename, sha, url):
|
||||||
@ -72,7 +72,7 @@ def create_spec(filename, sha, url):
|
|||||||
'installer_filename': f'{flavor_with_suffix.lower()}-{version}-{subversion}',
|
'installer_filename': f'{flavor_with_suffix.lower()}-{version}-{subversion}',
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug(f'Created spec {spec}')
|
logger.debug('Created spec %(spec)s', locals())
|
||||||
|
|
||||||
return spec
|
return spec
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ def add_version(release, distributions):
|
|||||||
if count > 0:
|
if count > 0:
|
||||||
output_file = out_dir / distribution_specs[0]['installer_filename']
|
output_file = out_dir / distribution_specs[0]['installer_filename']
|
||||||
|
|
||||||
logger.info(f'Writing {count} specs for {distribution} to {output_file}')
|
logger.info('Writing %(count)d specs for %(distribution)s to %(output_file)s', locals())
|
||||||
|
|
||||||
script_str = install_script_fmt.format(
|
script_str = install_script_fmt.format(
|
||||||
install_lines="\n".join([install_line_fmt.format_map(s) for s in distribution_specs]),
|
install_lines="\n".join([install_line_fmt.format_map(s) for s in distribution_specs]),
|
||||||
@ -122,7 +122,7 @@ def add_version(release, distributions):
|
|||||||
with open(output_file, 'w') as f:
|
with open(output_file, 'w') as f:
|
||||||
f.write(script_str)
|
f.write(script_str)
|
||||||
else:
|
else:
|
||||||
logger.info(f'Did not find specs for {distribution}')
|
logger.info('Did not find specs for %(distribution)s', locals())
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@ -132,7 +132,7 @@ def main():
|
|||||||
if version in SKIPPED_RELEASES:
|
if version in SKIPPED_RELEASES:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logger.info(f'Looking for {version} in {out_dir}')
|
logger.info('Looking for %(version)s in %(out_dir)s', locals())
|
||||||
|
|
||||||
# mambaforge is retired https://github.com/conda-forge/miniforge/releases/tag/24.11.2-0
|
# mambaforge is retired https://github.com/conda-forge/miniforge/releases/tag/24.11.2-0
|
||||||
if version_tuple(version) >= (24, 11, 2):
|
if version_tuple(version) >= (24, 11, 2):
|
||||||
@ -141,7 +141,7 @@ def main():
|
|||||||
distributions = DISTRIBUTIONS_PRE25
|
distributions = DISTRIBUTIONS_PRE25
|
||||||
|
|
||||||
if any(not list(out_dir.glob(f'{distribution}*-{version}')) for distribution in distributions):
|
if any(not list(out_dir.glob(f'{distribution}*-{version}')) for distribution in distributions):
|
||||||
logger.info(f'Downloading {version}')
|
logger.info('Downloading %(version)s', locals())
|
||||||
add_version(release, distributions)
|
add_version(release, distributions)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
prefer_openssl3
|
|
||||||
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
|
|
||||||
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
|
|
||||||
install_package "openssl-3.6.1" "https://github.com/openssl/openssl/releases/download/openssl-3.6.1/openssl-3.6.1.tar.gz#b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e" 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.12.13" "https://www.python.org/ftp/python/3.12.13/Python-3.12.13.tar.xz#c08bc65a81971c1dd5783182826503369466c7e67374d1646519adf05207b684" standard verify_py312 copy_python_gdb ensurepip
|
|
||||||
else
|
|
||||||
install_package "Python-3.12.13" "https://www.python.org/ftp/python/3.12.13/Python-3.12.13.tgz#0816c4761c97ecdb3f50a3924de0a93fd78cb63ee8e6c04201ddfaedca500b0b" standard verify_py312 copy_python_gdb ensurepip
|
|
||||||
fi
|
|
||||||
@ -4,7 +4,7 @@ export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
|
|||||||
install_package "openssl-3.6.1" "https://github.com/openssl/openssl/releases/download/openssl-3.6.1/openssl-3.6.1.tar.gz#b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e" mac_openssl --if has_broken_mac_openssl
|
install_package "openssl-3.6.1" "https://github.com/openssl/openssl/releases/download/openssl-3.6.1/openssl-3.6.1.tar.gz#b1bfedcd5b289ff22aee87c9d600f515767ebf45f77168cb6d64f231f518a82e" 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
|
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
|
if has_tar_xz_support; then
|
||||||
install_package "Python-3.15.0a7" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0a7.tar.xz#8f590c428b7f0d406df928b85737e7a3afa28eddd4d1419410ea809687ed1ea7" standard verify_py315 copy_python_gdb ensurepip
|
install_package "Python-3.15.0a6" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0a6.tar.xz#8e2a4e1b2afb93a84d659d431b1f384544b3da00a4b8ff5bf3580f07ad4ff989" standard verify_py315 copy_python_gdb ensurepip
|
||||||
else
|
else
|
||||||
install_package "Python-3.15.0a7" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0a7.tgz#a3ab00d82e04559369fecc98fab90ccb38e14f00bc0171f06e94821c1d2b1413" standard verify_py315 copy_python_gdb ensurepip
|
install_package "Python-3.15.0a6" "https://www.python.org/ftp/python/3.15.0/Python-3.15.0a6.tgz#2539a4693f26f5df1e59cd64b55c7624294ba296ad00f49e328083059720c20f" standard verify_py315 copy_python_gdb ensurepip
|
||||||
fi
|
fi
|
||||||
@ -1,20 +0,0 @@
|
|||||||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
|
||||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
|
||||||
"Linux-aarch64" )
|
|
||||||
install_script "Miniconda3-py310_26.1.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.1.1-1-Linux-aarch64.sh#0a78d6620113acd42d840925514c0f5eec9f2e1e8ae4394755c401b3b605875b" "miniconda" verify_py310
|
|
||||||
;;
|
|
||||||
"Linux-x86_64" )
|
|
||||||
install_script "Miniconda3-py310_26.1.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.1.1-1-Linux-x86_64.sh#4410410a6343f688bbfd48d80eb23e3125964e254e4c18802679d2e61b06876e" "miniconda" verify_py310
|
|
||||||
;;
|
|
||||||
"MacOSX-arm64" )
|
|
||||||
install_script "Miniconda3-py310_26.1.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.1.1-1-MacOSX-arm64.sh#cadb31098a13b7dcc016594f54b01bcf1371161ba762a9ac3ba0d8f04b2615e2" "miniconda" verify_py310
|
|
||||||
;;
|
|
||||||
* )
|
|
||||||
{ echo
|
|
||||||
colorize 1 "ERROR"
|
|
||||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
|
||||||
echo
|
|
||||||
} >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
|
||||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
|
||||||
"Linux-aarch64" )
|
|
||||||
install_script "Miniconda3-py311_26.1.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.1.1-1-Linux-aarch64.sh#1726ea55308160a32e82d90a6f4914caa46f58fe157442224f2faf92fdef1e0e" "miniconda" verify_py311
|
|
||||||
;;
|
|
||||||
"Linux-x86_64" )
|
|
||||||
install_script "Miniconda3-py311_26.1.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.1.1-1-Linux-x86_64.sh#52d1f19154b0716d7dc0872f0d858702640da08a4e53fd0035ba988608203d6b" "miniconda" verify_py311
|
|
||||||
;;
|
|
||||||
"MacOSX-arm64" )
|
|
||||||
install_script "Miniconda3-py311_26.1.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.1.1-1-MacOSX-arm64.sh#720266b29d46b8da1b466342aa02d7d04683670bf2bf53576cc70d89253f60ca" "miniconda" verify_py311
|
|
||||||
;;
|
|
||||||
* )
|
|
||||||
{ echo
|
|
||||||
colorize 1 "ERROR"
|
|
||||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
|
||||||
echo
|
|
||||||
} >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
|
||||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
|
||||||
"Linux-aarch64" )
|
|
||||||
install_script "Miniconda3-py312_26.1.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.1.1-1-Linux-aarch64.sh#0a84d50ec92fbb248e31bff0a5888bf2f4dc322fc979e94ecc6e9946d0324ce7" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
"Linux-x86_64" )
|
|
||||||
install_script "Miniconda3-py312_26.1.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.1.1-1-Linux-x86_64.sh#eef1283cdc9d37f55743778ea4567e91aa28c2e3be4adab529dda324c3c897a2" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
"MacOSX-arm64" )
|
|
||||||
install_script "Miniconda3-py312_26.1.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.1.1-1-MacOSX-arm64.sh#4a1e3630353121edad84fe79982a99ad8001425e27313c34f7ba9b6cec95d3dd" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
* )
|
|
||||||
{ echo
|
|
||||||
colorize 1 "ERROR"
|
|
||||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
|
||||||
echo
|
|
||||||
} >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
|
|
||||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
|
||||||
"Linux-aarch64" )
|
|
||||||
install_script "Miniconda3-py313_26.1.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.1.1-1-Linux-aarch64.sh#07c82b5aec04d5f0f3e4b246835b6bc85e104821cbcb0a059c7ea80f028503f4" "miniconda" verify_py313
|
|
||||||
;;
|
|
||||||
"Linux-x86_64" )
|
|
||||||
install_script "Miniconda3-py313_26.1.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.1.1-1-Linux-x86_64.sh#f6dfb5b59614fd7b2956b240b2575a9d58203ec7f7a99f85128158a0fdc5c1d7" "miniconda" verify_py313
|
|
||||||
;;
|
|
||||||
"MacOSX-arm64" )
|
|
||||||
install_script "Miniconda3-py313_26.1.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.1.1-1-MacOSX-arm64.sh#745f97a6553ebdce0bfdaafe00b0d1939784b38cdaadb3378ca7868a51616a65" "miniconda" verify_py313
|
|
||||||
;;
|
|
||||||
* )
|
|
||||||
{ echo
|
|
||||||
colorize 1 "ERROR"
|
|
||||||
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
|
|
||||||
echo
|
|
||||||
} >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
case "$(anaconda_architecture 2>/dev/null || true)" in
|
|
||||||
"Linux-aarch64" )
|
|
||||||
install_script "Miniforge3-26.1.0-0-Linux-aarch64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.1.0-0/Miniforge3-26.1.0-0-Linux-aarch64.sh#8baf8844ecf13e1458f81659ea286251d04b2d5ed90040efb77f158adedb2d95" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
"Linux-ppc64le" )
|
|
||||||
install_script "Miniforge3-26.1.0-0-Linux-ppc64le.sh" "https://github.com/conda-forge/miniforge/releases/download/26.1.0-0/Miniforge3-26.1.0-0-Linux-ppc64le.sh#902190ad825b74b78a6a2816364453bb4d6989a599172aa3785d4afd0ebeb917" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
"Linux-x86_64" )
|
|
||||||
install_script "Miniforge3-26.1.0-0-Linux-x86_64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.1.0-0/Miniforge3-26.1.0-0-Linux-x86_64.sh#127b5e14cfe6c83b787f624487cdc2168645ed82fdca1b0c1937caa086aed6d5" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
"MacOSX-arm64" )
|
|
||||||
install_script "Miniforge3-26.1.0-0-MacOSX-arm64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.1.0-0/Miniforge3-26.1.0-0-MacOSX-arm64.sh#219b9e0d733fa2086d7d094a5ed830db146ccf22ae32c330b2da5df5c9604b78" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
"MacOSX-x86_64" )
|
|
||||||
install_script "Miniforge3-26.1.0-0-MacOSX-x86_64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.1.0-0/Miniforge3-26.1.0-0-MacOSX-x86_64.sh#90a41a28ad0221fbaf728ca1267f6243638a56c579fba8a1b970edfee4062d53" "miniconda" verify_py312
|
|
||||||
;;
|
|
||||||
* )
|
|
||||||
{ echo
|
|
||||||
colorize 1 "ERROR"
|
|
||||||
echo ": The binary distribution of Miniforge is not available for $(anaconda_architecture 2>/dev/null || true)."
|
|
||||||
echo
|
|
||||||
} >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@ -2,7 +2,7 @@ PROTOTYPE_SOURCE_SHIM_PATH="${SHIM_PATH}/.pyenv-source-shim"
|
|||||||
|
|
||||||
shims=()
|
shims=()
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
for shim in $(sort -u "${BASH_SOURCE%/*}/source.d/"*".list" | sed -e 's/#.*$//' -e '/^[[:space:]]*$/d'); do
|
for shim in $(cat "${BASH_SOURCE%/*}/source.d/"*".list" | sort | uniq | sed -e 's/#.*$//' | sed -e '/^[[:space:]]*$/d'); do
|
||||||
if [ -n "${shim##*/}" ]; then
|
if [ -n "${shim##*/}" ]; then
|
||||||
shims[${#shims[*]}]="${shim})return 0;;"
|
shims[${#shims[*]}]="${shim})return 0;;"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -135,7 +135,7 @@ path_without() {
|
|||||||
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
|
if [ "$found" != "${PYENV_ROOT}/shims" ]; then
|
||||||
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
|
alt="${PYENV_TEST_DIR}/$(echo "${found#/}" | tr '/' '-')"
|
||||||
mkdir -p "$alt"
|
mkdir -p "$alt"
|
||||||
for util in bash head cut readlink greadlink tr sed xargs basename sort; do
|
for util in bash head cut readlink greadlink tr sed; do
|
||||||
if [ -x "${found}/$util" ]; then
|
if [ -x "${found}/$util" ]; then
|
||||||
ln -s "${found}/$util" "${alt}/$util"
|
ln -s "${found}/$util" "${alt}/$util"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -11,11 +11,6 @@ create_alias() {
|
|||||||
ln -s "$2" "${PYENV_ROOT}/versions/$1"
|
ln -s "$2" "${PYENV_ROOT}/versions/$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
create_external_version() {
|
|
||||||
mkdir -p "$PYENV_TEST_DIR/${1:?}"
|
|
||||||
create_alias "${1:?}" "$PYENV_TEST_DIR/${1:?}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_setup() {
|
_setup() {
|
||||||
mkdir -p "$PYENV_TEST_DIR"
|
mkdir -p "$PYENV_TEST_DIR"
|
||||||
cd "$PYENV_TEST_DIR"
|
cd "$PYENV_TEST_DIR"
|
||||||
@ -173,39 +168,15 @@ OUT
|
|||||||
@test "doesn't list symlink aliases when --skip-aliases" {
|
@test "doesn't list symlink aliases when --skip-aliases" {
|
||||||
create_version "1.8.7"
|
create_version "1.8.7"
|
||||||
create_alias "1.8" "1.8.7"
|
create_alias "1.8" "1.8.7"
|
||||||
create_external_version "moo"
|
mkdir moo
|
||||||
|
create_alias "1.9" "${PWD}/moo"
|
||||||
|
|
||||||
run pyenv-versions --bare --skip-aliases
|
run pyenv-versions --bare --skip-aliases
|
||||||
assert_success
|
assert_success
|
||||||
|
|
||||||
assert_output <<OUT
|
assert_output <<OUT
|
||||||
1.8.7
|
1.8.7
|
||||||
moo
|
1.9
|
||||||
OUT
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "--executables lists executables everywhere and overrides other switches" {
|
|
||||||
create_alt_executable_in_version "3.5.0" "python"
|
|
||||||
create_alt_executable_in_version "3.5.0" "python1"
|
|
||||||
create_alt_executable_in_version "3.6.0" "python"
|
|
||||||
create_alt_executable_in_version "3.5.0/envs/foo" "python_foo"
|
|
||||||
create_alt_executable_in_version "3.6.0/envs/bar" "python_bar"
|
|
||||||
create_alias "bar" "3.6.0/envs/bar"
|
|
||||||
create_external_version "moo"
|
|
||||||
create_alt_executable_in_version "moo" "moopython"
|
|
||||||
|
|
||||||
run pyenv-versions --skip-aliases --skip-envs --executables
|
|
||||||
assert_success
|
|
||||||
#The sort order does not matter for this functionality. However,
|
|
||||||
#MacOS 15 `sort` sorts differently that Linux's due to a different LC_COLLATE definition for en-US:
|
|
||||||
#https://unix.stackexchange.com/questions/362728/why-does-gnu-sort-sort-differently-on-my-osx-machine-and-linux-machine
|
|
||||||
#So to get a match, we have to check against the same order that the local `sort` produces
|
|
||||||
sort <<OUT | assert_output
|
|
||||||
moopython
|
|
||||||
python
|
|
||||||
python1
|
|
||||||
python_bar
|
|
||||||
python_foo
|
|
||||||
OUT
|
OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -68,8 +68,8 @@ pyenv: py.test: command not found
|
|||||||
The \`py.test' command exists in these Python versions:
|
The \`py.test' command exists in these Python versions:
|
||||||
3.4
|
3.4
|
||||||
|
|
||||||
Note: See 'pyenv help global' for tips on allowing multiple
|
Note: See 'pyenv help global' for tips on allowing both
|
||||||
Python versions to be found at the same time.
|
python2 and python3 to be found.
|
||||||
OUT
|
OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,8 +85,8 @@ pyenv: py.test: command not found
|
|||||||
The \`py.test' command exists in these Python versions:
|
The \`py.test' command exists in these Python versions:
|
||||||
3.4
|
3.4
|
||||||
|
|
||||||
Note: See 'pyenv help global' for tips on allowing multiple
|
Note: See 'pyenv help global' for tips on allowing both
|
||||||
Python versions to be found at the same time.
|
python2 and python3 to be found.
|
||||||
OUT
|
OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +118,8 @@ The \`py.test' command exists in these Python versions:
|
|||||||
3.3
|
3.3
|
||||||
3.4
|
3.4
|
||||||
|
|
||||||
Note: See 'pyenv help global' for tips on allowing multiple
|
Note: See 'pyenv help global' for tips on allowing both
|
||||||
Python versions to be found at the same time.
|
python2 and python3 to be found.
|
||||||
OUT
|
OUT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user