From 3ced1c475150e00dfcda4e8cca71a5670d5087b8 Mon Sep 17 00:00:00 2001 From: native-api Date: Fri, 11 Oct 2024 16:28:10 +0300 Subject: [PATCH] Support free-threaded CPython flavor in prefix resolution (#3090) Since 3.13, CPython is provided in 2 flavors: regular and free-threaded, with the 't' suffix. An incomplete prefix ending with '[0-9]t' resolves only among versions that also end with '[0-9]t' --- libexec/pyenv-latest | 13 +++++++++++-- test/latest.bats | 17 ++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/libexec/pyenv-latest b/libexec/pyenv-latest index 330e1e29..7d85e302 100755 --- a/libexec/pyenv-latest +++ b/libexec/pyenv-latest @@ -48,16 +48,25 @@ IFS=$'\n' exit $exitcode; fi + suffix="" + if [[ $prefix =~ ^(.*[0-9])t$ ]]; then + suffix="t" + prefix="${BASH_REMATCH[1]}" + fi + # https://stackoverflow.com/questions/11856054/is-there-an-easy-way-to-pass-a-raw-string-to-grep/63483807#63483807 prefix_re="$(sed 's/[^\^]/[&]/g;s/[\^]/\\&/g' <<< "$prefix")" + suffix_re="$(sed 's/[^\^]/[&]/g;s/[\^]/\\&/g' <<< "$suffix")" # FIXME: more reliable and readable would probably be to loop over them and transform in pure Bash DEFINITION_CANDIDATES=(\ $(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \ - grep -Ee "^$prefix_re[-.]" || true)) + grep -Ee "^$prefix_re[-.].*$suffix_re\$" || true)) DEFINITION_CANDIDATES=(\ $(printf '%s\n' "${DEFINITION_CANDIDATES[@]}" | \ - sed -E -e '/-dev$/d' -e '/-src$/d' -e '/-latest$/d' -e '/(a|b|rc)[0-9]+$/d' -e '/[0-9]+t$/d')); + sed -E -e '/-dev$/d' -e '/-src$/d' -e '/-latest$/d' -e '/(a|b|rc)[0-9]+$/d' \ + $(if [[ -z $suffix ]]; then echo "-e /[0-9]t\$/d"; fi) + )); # Compose a sorting key, followed by | and original value DEFINITION_CANDIDATES=(\ diff --git a/test/latest.bats b/test/latest.bats index 8881c9f5..4acfa89f 100644 --- a/test/latest.bats +++ b/test/latest.bats @@ -94,7 +94,7 @@ echo 3.10.6 ! } -@test "ignores rolling releases, branch tips, alternative srcs, prereleases and virtualenvs" { +@test "ignores rolling releases, branch tips, alternative srcs, prereleases, virtualenvs; 't' versions if prefix without 't'" { create_executable pyenv-versions <