Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance and output of pyenv virtualenvs #502

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

samdoran
Copy link

@samdoran samdoran commented Feb 13, 2025

The biggest change is reusing most of the code used for pyenv versions in pyenv virtualenvs. This dramatically improves performance while making the output consistent.

Related to #490. Maybe fixes the problem?

With 128 virtual environments, it currently takes about 13 seconds to run pyenv virtualenvs --bare.

> time pyenv virtualenvs --bare > /dev/null 2>&1

________________________________________________________
Executed in   13.14 secs    fish           external
   usr time    6.32 secs    0.33 millis    6.32 secs
   sys time    6.13 secs    2.19 millis    6.13 secs
Output
1brc
3.10.13/envs/instruct-lab
3.10.13/envs/parquet-compactor-3.10.13
3.10.14/envs/ipython-3.10.14
3.10.15/envs/ipython-3.10.15
3.10.7/envs/cherry_picker-3.10.7
3.10.9/envs/pyls-3.10.9
3.11.0/envs/argcomplete-3.11.0
3.11.0/envs/asciinema-3.11.0
3.11.0/envs/borg-3.11.0
3.11.0/envs/cherry_picker-3.11.0
3.11.0/envs/cookiecutter-3.11.0
3.11.0/envs/diceware-3.11.0
3.11.0/envs/flake8-3.11.0
3.11.0/envs/ipdb-3.11.0
3.11.0/envs/isort-3.11.0
3.11.0/envs/jello-3.11.0
3.11.0/envs/mackup-3.11.0
3.11.0/envs/maestral-3.11.0
3.11.0/envs/mitmproxy-3.11.0
3.11.0/envs/mypy-3.11.0
3.11.0/envs/pipfile2req-3.11.0
3.11.0/envs/pur-3.11.0
3.11.0/envs/pylint-3.11.0
3.11.0/envs/pyspy-3.11.0
3.11.0/envs/pytest-3.11.0
3.11.0/envs/qrimg-3.11.0
3.11.0/envs/shiv-3.11.0
3.11.0/envs/speedtest-cli-3.11.0
3.11.0/envs/sphinx-3.11.0
3.11.0/envs/tox-3.11.0
3.11.0/envs/tweet-delete-3.11.0
3.11.0/envs/yamllint-3.11.0
3.11.0/envs/youtube-dl-3.11.0
3.11.1/envs/borg-3.11.1
3.11.1/envs/qontract-3.11.1
3.11.1/envs/requests-3.11.1
3.11.1/envs/titlecase-3.11.1
3.11.1/envs/uptime-kuma-3.11.1
3.11.10/envs/ipython-3.11.10
3.11.10/envs/koku-dev-3.11.10
3.11.10/envs/koku-test
3.11.2/envs/bonfire-3.11.2
3.11.2/envs/testing
3.11.3/envs/ansible-dev-3.11.3
3.11.3/envs/qr-coding-3.11.3
3.11.4/envs/flash
3.11.4/envs/json-linter-3.11.4
3.11.4/envs/youtube-dl-dev
3.11.5/envs/parquet-compactor-3.11.5
3.11.6/envs/ansible-core-3.11.6
3.11.6/envs/pre-commit
3.11.6/envs/pylibssh-dev-3.11.6
3.11.6/envs/tasmota-3.11.6
3.11.7/envs/pipenv-3.11.7
3.11.7/envs/tasmota-3.11.7
3.11.8/envs/cffi-dev-3.11.8
3.11.8/envs/koku-dev-3.11.8
3.11.8/envs/koku-dev-dj4-3.11.8
3.11.9/envs/ipython-3.11.9
3.11.9/envs/koku-dev-3.11.9
3.11.9/envs/nise-populator-3.11.9
3.12.0/envs/ansible-core-3.12.0
3.12.0/envs/cla-dev-3.12.0
3.12.0/envs/ipython-3.12.0
3.12.0/envs/jupyter
3.12.0/envs/koku-metrics-operator-3.12.0
3.12.0/envs/pytorch
3.12.0/envs/requests-3.12.0
3.12.0/envs/rh-pre-commit-3.12.0
3.12.1/envs/ipython-3.12.1
3.12.2/envs/1brc
3.12.2/envs/ansible-core-3.12.2
3.12.2/envs/black
3.12.2/envs/cffi-dev-3.12.2
3.12.2/envs/codecov-cli
3.12.2/envs/dr-content-3.12.2
3.12.2/envs/harlequin
3.12.2/envs/ipython-3.12.2
3.12.2/envs/pip-audit
3.12.2/envs/pygments-3.12.2
3.12.2/envs/pyright
3.12.2/envs/qrcode
3.12.2/envs/ruff
3.12.3/envs/ipython-3.12.3
3.12.5/envs/ipython-3.12.5
3.12.5/envs/shellai
3.12.6/envs/build-definitions
3.12.6/envs/ipython-3.12.6
3.12.6/envs/kflux-rel-data
3.12.7/envs/aoc-2024
3.12.7/envs/ipython-3.12.7
3.12.8/envs/dr-backend-3.12.8
3.12.8/envs/ipython-3.12.8
3.12.8/envs/lifecycle-defs
3.12.8/envs/rlsapi-dev
3.12.8/envs/rlsrag
3.13.0/envs/cffi-3.13.0
3.13.0/envs/cicd-tools
3.13.0/envs/ipython-3.13.0
3.13.0/envs/thefuck
3.13.1/envs/docling
3.13.1/envs/httpie
3.13.1/envs/ipython-3.13.1
3.13.1/envs/llm
3.13.1/envs/locust
3.13.1/envs/poetry
3.13.1/envs/prefix
3.13.1/envs/tox
3.6.15/envs/ipython-3.6.15
3.7.15/envs/ipython-3.7.15
3.7.16/envs/ipython-3.7.16
3.8.14/envs/ansible-dev-3.8.14
3.8.15/envs/ipython-3.8.15
3.8.15/envs/nise-populator-3.8.15
3.8.16/envs/koku-nise-dev-3.8.16
3.8.17/envs/ipython-3.8.17
3.8.18/envs/parquet-compactor-3.8.18
3.8.20/envs/ipython-3.8.20
3.9.14/envs/iqe-3.9.14
3.9.15/envs/ipython-3.9.15
3.9.16/envs/koku-dev-logging-3.9.16
3.9.17/envs/event-sign-3.9.17
3.9.17/envs/ipython-3.9.17
3.9.18/envs/koku-dev-3.9.18
3.9.18/envs/koku-rediscache-debug
3.9.18/envs/parquet-compactor-3.9.18
3.9.19/envs/ipython-3.9.19
3.9.19/envs/koku-dev-3.9.19
ansible-core-3.11.6
ansible-core-3.12.0
ansible-core-3.12.2
ansible-dev-3.11.3
ansible-dev-3.8.14
aoc-2024
argcomplete-3.11.0
asciinema-3.11.0
black
bonfire-3.11.2
borg-3.11.0
borg-3.11.1
build-definitions
cffi-3.13.0
cffi-dev-3.11.8
cffi-dev-3.12.2
cherry_picker-3.10.7
cherry_picker-3.11.0
cicd-tools
cla-dev-3.12.0
codecov-cli
cookiecutter-3.11.0
diceware-3.11.0
docling
dr-backend-3.12.8
dr-content-3.12.2
event-sign-3.9.17
flake8-3.11.0
flash
harlequin
httpie
instruct-lab
ipdb-3.11.0
ipython-3.10.14
ipython-3.10.15
ipython-3.11.10
ipython-3.11.9
ipython-3.12.0
ipython-3.12.1
ipython-3.12.2
ipython-3.12.3
ipython-3.12.5
ipython-3.12.6
ipython-3.12.7
ipython-3.12.8
ipython-3.13.0
ipython-3.13.1
ipython-3.6.15
ipython-3.7.15
ipython-3.7.16
ipython-3.8.15
ipython-3.8.17
ipython-3.8.20
ipython-3.9.15
ipython-3.9.17
ipython-3.9.19
iqe-3.9.14
isort-3.11.0
jello-3.11.0
json-linter-3.11.4
jupyter
kflux-rel-data
koku-dev-3.11.10
koku-dev-3.11.8
koku-dev-3.11.9
koku-dev-3.9.18
koku-dev-3.9.19
koku-dev-dj4-3.11.8
koku-dev-logging-3.9.16
koku-metrics-operator-3.12.0
koku-nise-dev-3.8.16
koku-rediscache-debug
koku-test
lifecycle-defs
llm
locust
mackup-3.11.0
maestral-3.11.0
mitmproxy-3.11.0
mypy-3.11.0
nise-populator-3.11.9
nise-populator-3.8.15
parquet-compactor-3.10.13
parquet-compactor-3.11.5
parquet-compactor-3.8.18
parquet-compactor-3.9.18
pip-audit
pipenv-3.11.7
pipfile2req-3.11.0
poetry
pre-commit
prefix
pur-3.11.0
pygments-3.12.2
pylibssh-dev-3.11.6
pylint-3.11.0
pyls-3.10.9
pyright
pyspy-3.11.0
pytest-3.11.0
pytorch
qontract-3.11.1
qr-coding-3.11.3
qrcode
qrimg-3.11.0
requests-3.11.1
requests-3.12.0
rh-pre-commit-3.12.0
rlsapi-dev
rlsrag
ruff
shellai
shiv-3.11.0
speedtest-cli-3.11.0
sphinx-3.11.0
tasmota-3.11.6
tasmota-3.11.7
testing
thefuck
titlecase-3.11.1
tox
tox-3.11.0
tweet-delete-3.11.0
uptime-kuma-3.11.1
yamllint-3.11.0
youtube-dl-3.11.0
youtube-dl-dev

With the changes in this branch it is 236ms:

> time pyenv virtualenvs --bare > /dev/null 2>&1

________________________________________________________
Executed in  236.02 millis    fish           external
   usr time   36.14 millis    0.31 millis   35.83 millis
   sys time   31.66 millis    3.17 millis   28.48 millis
Output
3.10.13/envs/instruct-lab
3.10.13/envs/parquet-compactor-3.10.13
3.10.14/envs/ipython-3.10.14
3.10.15/envs/ipython-3.10.15
3.10.7/envs/cherry_picker-3.10.7
3.10.9/envs/pyls-3.10.9
3.11.0/envs/argcomplete-3.11.0
3.11.0/envs/asciinema-3.11.0
3.11.0/envs/borg-3.11.0
3.11.0/envs/cherry_picker-3.11.0
3.11.0/envs/cookiecutter-3.11.0
3.11.0/envs/diceware-3.11.0
3.11.0/envs/flake8-3.11.0
3.11.0/envs/ipdb-3.11.0
3.11.0/envs/isort-3.11.0
3.11.0/envs/jello-3.11.0
3.11.0/envs/mackup-3.11.0
3.11.0/envs/maestral-3.11.0
3.11.0/envs/mitmproxy-3.11.0
3.11.0/envs/mypy-3.11.0
3.11.0/envs/pipfile2req-3.11.0
3.11.0/envs/pur-3.11.0
3.11.0/envs/pylint-3.11.0
3.11.0/envs/pyspy-3.11.0
3.11.0/envs/pytest-3.11.0
3.11.0/envs/qrimg-3.11.0
3.11.0/envs/shiv-3.11.0
3.11.0/envs/speedtest-cli-3.11.0
3.11.0/envs/sphinx-3.11.0
3.11.0/envs/tox-3.11.0
3.11.0/envs/tweet-delete-3.11.0
3.11.0/envs/yamllint-3.11.0
3.11.0/envs/youtube-dl-3.11.0
3.11.1/envs/borg-3.11.1
3.11.1/envs/qontract-3.11.1
3.11.1/envs/requests-3.11.1
3.11.1/envs/titlecase-3.11.1
3.11.1/envs/uptime-kuma-3.11.1
3.11.10/envs/ipython-3.11.10
3.11.10/envs/koku-dev-3.11.10
3.11.10/envs/koku-test
3.11.2/envs/bonfire-3.11.2
3.11.2/envs/testing
3.11.3/envs/ansible-dev-3.11.3
3.11.3/envs/qr-coding-3.11.3
3.11.4/envs/flash
3.11.4/envs/json-linter-3.11.4
3.11.4/envs/youtube-dl-dev
3.11.5/envs/parquet-compactor-3.11.5
3.11.6/envs/ansible-core-3.11.6
3.11.6/envs/pre-commit
3.11.6/envs/pylibssh-dev-3.11.6
3.11.6/envs/tasmota-3.11.6
3.11.7/envs/pipenv-3.11.7
3.11.7/envs/tasmota-3.11.7
3.11.8/envs/cffi-dev-3.11.8
3.11.8/envs/koku-dev-3.11.8
3.11.8/envs/koku-dev-dj4-3.11.8
3.11.9/envs/ipython-3.11.9
3.11.9/envs/koku-dev-3.11.9
3.11.9/envs/nise-populator-3.11.9
3.12.0/envs/ansible-core-3.12.0
3.12.0/envs/cla-dev-3.12.0
3.12.0/envs/ipython-3.12.0
3.12.0/envs/jupyter
3.12.0/envs/koku-metrics-operator-3.12.0
3.12.0/envs/pytorch
3.12.0/envs/requests-3.12.0
3.12.0/envs/rh-pre-commit-3.12.0
3.12.1/envs/ipython-3.12.1
3.12.2/envs/1brc
3.12.2/envs/ansible-core-3.12.2
3.12.2/envs/black
3.12.2/envs/cffi-dev-3.12.2
3.12.2/envs/codecov-cli
3.12.2/envs/dr-content-3.12.2
3.12.2/envs/harlequin
3.12.2/envs/ipython-3.12.2
3.12.2/envs/pip-audit
3.12.2/envs/pygments-3.12.2
3.12.2/envs/pyright
3.12.2/envs/qrcode
3.12.2/envs/ruff
3.12.3/envs/ipython-3.12.3
3.12.5/envs/ipython-3.12.5
3.12.5/envs/shellai
3.12.6/envs/build-definitions
3.12.6/envs/ipython-3.12.6
3.12.6/envs/kflux-rel-data
3.12.7/envs/aoc-2024
3.12.7/envs/ipython-3.12.7
3.12.8/envs/dr-backend-3.12.8
3.12.8/envs/ipython-3.12.8
3.12.8/envs/lifecycle-defs
3.12.8/envs/rlsapi-dev
3.12.8/envs/rlsrag
3.13.0/envs/cffi-3.13.0
3.13.0/envs/cicd-tools
3.13.0/envs/ipython-3.13.0
3.13.0/envs/thefuck
3.13.1/envs/docling
3.13.1/envs/httpie
3.13.1/envs/ipython-3.13.1
3.13.1/envs/llm
3.13.1/envs/locust
3.13.1/envs/poetry
3.13.1/envs/prefix
3.13.1/envs/tox
3.6.15/envs/ipython-3.6.15
3.7.15/envs/ipython-3.7.15
3.7.16/envs/ipython-3.7.16
3.8.14/envs/ansible-dev-3.8.14
3.8.15/envs/ipython-3.8.15
3.8.15/envs/nise-populator-3.8.15
3.8.16/envs/koku-nise-dev-3.8.16
3.8.17/envs/ipython-3.8.17
3.8.18/envs/parquet-compactor-3.8.18
3.8.20/envs/ipython-3.8.20
3.9.14/envs/iqe-3.9.14
3.9.15/envs/ipython-3.9.15
3.9.16/envs/koku-dev-logging-3.9.16
3.9.17/envs/event-sign-3.9.17
3.9.17/envs/ipython-3.9.17
3.9.18/envs/koku-dev-3.9.18
3.9.18/envs/koku-rediscache-debug
3.9.18/envs/parquet-compactor-3.9.18
3.9.19/envs/ipython-3.9.19
3.9.19/envs/koku-dev-3.9.19
1brc
ansible-core-3.11.6
ansible-core-3.12.0
ansible-core-3.12.2
ansible-dev-3.11.3
ansible-dev-3.8.14
aoc-2024
argcomplete-3.11.0
asciinema-3.11.0
black
bonfire-3.11.2
borg-3.11.0
borg-3.11.1
build-definitions
cffi-3.13.0
cffi-dev-3.11.8
cffi-dev-3.12.2
cherry_picker-3.10.7
cherry_picker-3.11.0
cicd-tools
cla-dev-3.12.0
codecov-cli
cookiecutter-3.11.0
diceware-3.11.0
docling
dr-backend-3.12.8
dr-content-3.12.2
event-sign-3.9.17
flake8-3.11.0
flash
harlequin
httpie
instruct-lab
ipdb-3.11.0
ipython-3.10.14
ipython-3.10.15
ipython-3.11.10
ipython-3.11.9
ipython-3.12.0
ipython-3.12.1
ipython-3.12.2
ipython-3.12.3
ipython-3.12.5
ipython-3.12.6
ipython-3.12.7
ipython-3.12.8
ipython-3.13.0
ipython-3.13.1
ipython-3.6.15
ipython-3.7.15
ipython-3.7.16
ipython-3.8.15
ipython-3.8.17
ipython-3.8.20
ipython-3.9.15
ipython-3.9.17
ipython-3.9.19
iqe-3.9.14
isort-3.11.0
jello-3.11.0
json-linter-3.11.4
jupyter
kflux-rel-data
koku-dev-3.11.10
koku-dev-3.11.8
koku-dev-3.11.9
koku-dev-3.9.18
koku-dev-3.9.19
koku-dev-dj4-3.11.8
koku-dev-logging-3.9.16
koku-metrics-operator-3.12.0
koku-nise-dev-3.8.16
koku-rediscache-debug
koku-test
lifecycle-defs
llm
locust
mackup-3.11.0
maestral-3.11.0
mitmproxy-3.11.0
mypy-3.11.0
nise-populator-3.11.9
nise-populator-3.8.15
parquet-compactor-3.10.13
parquet-compactor-3.11.5
parquet-compactor-3.8.18
parquet-compactor-3.9.18
pip-audit
pipenv-3.11.7
pipfile2req-3.11.0
poetry
pre-commit
prefix
pur-3.11.0
pygments-3.12.2
pylibssh-dev-3.11.6
pylint-3.11.0
pyls-3.10.9
pyright
pyspy-3.11.0
pytest-3.11.0
pytorch
qontract-3.11.1
qr-coding-3.11.3
qrcode
qrimg-3.11.0
requests-3.11.1
requests-3.12.0
rh-pre-commit-3.12.0
rlsapi-dev
rlsrag
ruff
shellai
shiv-3.11.0
speedtest-cli-3.11.0
sphinx-3.11.0
tasmota-3.11.6
tasmota-3.11.7
testing
thefuck
titlecase-3.11.1
tox
tox-3.11.0
tweet-delete-3.11.0
uptime-kuma-3.11.1
yamllint-3.11.0
youtube-dl-3.11.0
youtube-dl-dev

Output formatting changes

This PR also includes changes to the output format to make it more consistent with pyenv versions.

pyenv versions output
  3.10.13/envs/instruct-lab
  3.10.13/envs/parquet-compactor-3.10.13
  3.10.14/envs/ipython-3.10.14
  3.10.15/envs/ipython-3.10.15
  3.10.7/envs/cherry_picker-3.10.7
  3.10.9/envs/pyls-3.10.9
  3.11.0/envs/argcomplete-3.11.0
  3.11.0/envs/asciinema-3.11.0
  3.11.0/envs/borg-3.11.0
  3.11.0/envs/cherry_picker-3.11.0
  3.11.0/envs/cookiecutter-3.11.0
  3.11.0/envs/diceware-3.11.0
  3.11.0/envs/flake8-3.11.0
  3.11.0/envs/ipdb-3.11.0
  3.11.0/envs/isort-3.11.0
  3.11.0/envs/jello-3.11.0
  3.11.0/envs/mackup-3.11.0
  3.11.0/envs/maestral-3.11.0
  3.11.0/envs/mitmproxy-3.11.0
  3.11.0/envs/mypy-3.11.0
  3.11.0/envs/pipfile2req-3.11.0
  3.11.0/envs/pur-3.11.0
  3.11.0/envs/pylint-3.11.0
  3.11.0/envs/pyspy-3.11.0
  3.11.0/envs/pytest-3.11.0
  3.11.0/envs/qrimg-3.11.0
  3.11.0/envs/shiv-3.11.0
  3.11.0/envs/speedtest-cli-3.11.0
  3.11.0/envs/sphinx-3.11.0
  3.11.0/envs/tox-3.11.0
  3.11.0/envs/tweet-delete-3.11.0
  3.11.0/envs/yamllint-3.11.0
  3.11.0/envs/youtube-dl-3.11.0
  3.11.1/envs/borg-3.11.1
  3.11.1/envs/qontract-3.11.1
  3.11.1/envs/requests-3.11.1
  3.11.1/envs/titlecase-3.11.1
  3.11.1/envs/uptime-kuma-3.11.1
  3.11.10/envs/ipython-3.11.10
  3.11.10/envs/koku-dev-3.11.10
  3.11.10/envs/koku-test
  3.11.2/envs/bonfire-3.11.2
  3.11.2/envs/testing
  3.11.3/envs/ansible-dev-3.11.3
  3.11.3/envs/qr-coding-3.11.3
  3.11.4/envs/flash
  3.11.4/envs/json-linter-3.11.4
  3.11.4/envs/youtube-dl-dev
  3.11.5/envs/parquet-compactor-3.11.5
  3.11.6/envs/ansible-core-3.11.6
  3.11.6/envs/pre-commit
  3.11.6/envs/pylibssh-dev-3.11.6
  3.11.6/envs/tasmota-3.11.6
  3.11.7/envs/pipenv-3.11.7
  3.11.7/envs/tasmota-3.11.7
  3.11.8/envs/cffi-dev-3.11.8
  3.11.8/envs/koku-dev-3.11.8
  3.11.8/envs/koku-dev-dj4-3.11.8
  3.11.9/envs/ipython-3.11.9
  3.11.9/envs/koku-dev-3.11.9
  3.11.9/envs/nise-populator-3.11.9
  3.12.0/envs/ansible-core-3.12.0
  3.12.0/envs/cla-dev-3.12.0
  3.12.0/envs/ipython-3.12.0
  3.12.0/envs/jupyter
  3.12.0/envs/koku-metrics-operator-3.12.0
  3.12.0/envs/pytorch
  3.12.0/envs/requests-3.12.0
  3.12.0/envs/rh-pre-commit-3.12.0
  3.12.1/envs/ipython-3.12.1
  3.12.2/envs/1brc
  3.12.2/envs/ansible-core-3.12.2
  3.12.2/envs/black
  3.12.2/envs/cffi-dev-3.12.2
  3.12.2/envs/codecov-cli
  3.12.2/envs/dr-content-3.12.2
  3.12.2/envs/harlequin
  3.12.2/envs/ipython-3.12.2
  3.12.2/envs/pip-audit
  3.12.2/envs/pygments-3.12.2
  3.12.2/envs/pyright
  3.12.2/envs/qrcode
  3.12.2/envs/ruff
  3.12.3/envs/ipython-3.12.3
  3.12.5/envs/ipython-3.12.5
  3.12.5/envs/shellai
  3.12.6/envs/build-definitions
  3.12.6/envs/ipython-3.12.6
  3.12.6/envs/kflux-rel-data
  3.12.7/envs/aoc-2024
  3.12.7/envs/ipython-3.12.7
  3.12.8/envs/dr-backend-3.12.8
  3.12.8/envs/ipython-3.12.8
  3.12.8/envs/lifecycle-defs
  3.12.8/envs/rlsapi-dev
  3.12.8/envs/rlsrag
  3.13.0/envs/cffi-3.13.0
  3.13.0/envs/cicd-tools
  3.13.0/envs/ipython-3.13.0
  3.13.0/envs/thefuck
  3.13.1/envs/docling
  3.13.1/envs/httpie
  3.13.1/envs/ipython-3.13.1
  3.13.1/envs/llm
  3.13.1/envs/locust
  3.13.1/envs/poetry
  3.13.1/envs/prefix
  3.13.1/envs/tox
  3.6.15/envs/ipython-3.6.15
  3.7.15/envs/ipython-3.7.15
  3.7.16/envs/ipython-3.7.16
  3.8.14/envs/ansible-dev-3.8.14
  3.8.15/envs/ipython-3.8.15
  3.8.15/envs/nise-populator-3.8.15
  3.8.16/envs/koku-nise-dev-3.8.16
  3.8.17/envs/ipython-3.8.17
  3.8.18/envs/parquet-compactor-3.8.18
  3.8.20/envs/ipython-3.8.20
  3.9.14/envs/iqe-3.9.14
  3.9.15/envs/ipython-3.9.15
  3.9.16/envs/koku-dev-logging-3.9.16
  3.9.17/envs/event-sign-3.9.17
  3.9.17/envs/ipython-3.9.17
  3.9.18/envs/koku-dev-3.9.18
  3.9.18/envs/koku-rediscache-debug
  3.9.18/envs/parquet-compactor-3.9.18
  3.9.19/envs/ipython-3.9.19
  3.9.19/envs/koku-dev-3.9.19
  1brc --> /Users/sdoran/.pyenv/versions/3.12.2/envs/1brc
  ansible-core-3.11.6 --> /Users/sdoran/.pyenv/versions/3.11.6/envs/ansible-core-3.11.6
  ansible-core-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/ansible-core-3.12.0
  ansible-core-3.12.2 --> /Users/sdoran/.pyenv/versions/3.12.2/envs/ansible-core-3.12.2
  ansible-dev-3.11.3 --> /Users/sdoran/.pyenv/versions/3.11.3/envs/ansible-dev-3.11.3
  ansible-dev-3.8.14 --> /Users/sdoran/.pyenv/versions/3.8.14/envs/ansible-dev-3.8.14
  aoc-2024 --> /Users/sdoran/.pyenv/versions/3.12.7/envs/aoc-2024
  argcomplete-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/argcomplete-3.11.0
  asciinema-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/asciinema-3.11.0
  black --> /Users/sdoran/.pyenv/versions/3.12.2/envs/black
  bonfire-3.11.2 --> /Users/sdoran/.pyenv/versions/3.11.2/envs/bonfire-3.11.2
  borg-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/borg-3.11.0
  borg-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/borg-3.11.1
  build-definitions --> /Users/sdoran/.pyenv/versions/3.12.6/envs/build-definitions
  cffi-3.13.0 --> /Users/sdoran/.pyenv/versions/3.13.0/envs/cffi-3.13.0
  cffi-dev-3.11.8 --> /Users/sdoran/.pyenv/versions/3.11.8/envs/cffi-dev-3.11.8
  cffi-dev-3.12.2 --> /Users/sdoran/.pyenv/versions/3.12.2/envs/cffi-dev-3.12.2
  cherry_picker-3.10.7 --> /Users/sdoran/.pyenv/versions/3.10.7/envs/cherry_picker-3.10.7
  cherry_picker-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/cherry_picker-3.11.0
  cicd-tools --> /Users/sdoran/.pyenv/versions/3.13.0/envs/cicd-tools
  cla-dev-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/cla-dev-3.12.0
  codecov-cli --> /Users/sdoran/.pyenv/versions/3.12.2/envs/codecov-cli
  cookiecutter-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/cookiecutter-3.11.0
  diceware-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/diceware-3.11.0
  docling --> /Users/sdoran/.pyenv/versions/3.13.1/envs/docling
  dr-backend-3.12.8 --> /Users/sdoran/.pyenv/versions/3.12.8/envs/dr-backend-3.12.8
  dr-content-3.12.2 --> /Users/sdoran/.pyenv/versions/3.12.2/envs/dr-content-3.12.2
  event-sign-3.9.17 --> /Users/sdoran/.pyenv/versions/3.9.17/envs/event-sign-3.9.17
  flake8-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/flake8-3.11.0
  flash --> /Users/sdoran/.pyenv/versions/3.11.4/envs/flash
  harlequin --> /Users/sdoran/.pyenv/versions/3.12.2/envs/harlequin
  httpie --> /Users/sdoran/.pyenv/versions/3.13.1/envs/httpie
  instruct-lab --> /Users/sdoran/.pyenv/versions/3.10.13/envs/instruct-lab
  ipdb-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/ipdb-3.11.0
  ipython-3.10.14 --> /Users/sdoran/.pyenv/versions/3.10.14/envs/ipython-3.10.14
  ipython-3.10.15 --> /Users/sdoran/.pyenv/versions/3.10.15/envs/ipython-3.10.15
  ipython-3.11.10 --> /Users/sdoran/.pyenv/versions/3.11.10/envs/ipython-3.11.10
  ipython-3.11.9 --> /Users/sdoran/.pyenv/versions/3.11.9/envs/ipython-3.11.9
  ipython-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/ipython-3.12.0
  ipython-3.12.1 --> /Users/sdoran/.pyenv/versions/3.12.1/envs/ipython-3.12.1
  ipython-3.12.2 --> /Users/sdoran/.pyenv/versions/3.12.2/envs/ipython-3.12.2
  ipython-3.12.3 --> /Users/sdoran/.pyenv/versions/3.12.3/envs/ipython-3.12.3
  ipython-3.12.5 --> /Users/sdoran/.pyenv/versions/3.12.5/envs/ipython-3.12.5
  ipython-3.12.6 --> /Users/sdoran/.pyenv/versions/3.12.6/envs/ipython-3.12.6
  ipython-3.12.7 --> /Users/sdoran/.pyenv/versions/3.12.7/envs/ipython-3.12.7
  ipython-3.12.8 --> /Users/sdoran/.pyenv/versions/3.12.8/envs/ipython-3.12.8
  ipython-3.13.0 --> /Users/sdoran/.pyenv/versions/3.13.0/envs/ipython-3.13.0
  ipython-3.13.1 --> /Users/sdoran/.pyenv/versions/3.13.1/envs/ipython-3.13.1
  ipython-3.6.15 --> /Users/sdoran/.pyenv/versions/3.6.15/envs/ipython-3.6.15
  ipython-3.7.15 --> /Users/sdoran/.pyenv/versions/3.7.15/envs/ipython-3.7.15
  ipython-3.7.16 --> /Users/sdoran/.pyenv/versions/3.7.16/envs/ipython-3.7.16
  ipython-3.8.15 --> /Users/sdoran/.pyenv/versions/3.8.15/envs/ipython-3.8.15
  ipython-3.8.17 --> /Users/sdoran/.pyenv/versions/3.8.17/envs/ipython-3.8.17
  ipython-3.8.20 --> /Users/sdoran/.pyenv/versions/3.8.20/envs/ipython-3.8.20
  ipython-3.9.15 --> /Users/sdoran/.pyenv/versions/3.9.15/envs/ipython-3.9.15
  ipython-3.9.17 --> /Users/sdoran/.pyenv/versions/3.9.17/envs/ipython-3.9.17
  ipython-3.9.19 --> /Users/sdoran/.pyenv/versions/3.9.19/envs/ipython-3.9.19
  iqe-3.9.14 --> /Users/sdoran/.pyenv/versions/3.9.14/envs/iqe-3.9.14
  isort-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/isort-3.11.0
  jello-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/jello-3.11.0
  json-linter-3.11.4 --> /Users/sdoran/.pyenv/versions/3.11.4/envs/json-linter-3.11.4
  jupyter --> /Users/sdoran/.pyenv/versions/3.12.0/envs/jupyter
  kflux-rel-data --> /Users/sdoran/.pyenv/versions/3.12.6/envs/kflux-rel-data
  koku-dev-3.11.10 --> /Users/sdoran/.pyenv/versions/3.11.10/envs/koku-dev-3.11.10
  koku-dev-3.11.8 --> /Users/sdoran/.pyenv/versions/3.11.8/envs/koku-dev-3.11.8
  koku-dev-3.11.9 --> /Users/sdoran/.pyenv/versions/3.11.9/envs/koku-dev-3.11.9
  koku-dev-3.9.18 --> /Users/sdoran/.pyenv/versions/3.9.18/envs/koku-dev-3.9.18
  koku-dev-3.9.19 --> /Users/sdoran/.pyenv/versions/3.9.19/envs/koku-dev-3.9.19
  koku-dev-dj4-3.11.8 --> /Users/sdoran/.pyenv/versions/3.11.8/envs/koku-dev-dj4-3.11.8
  koku-dev-logging-3.9.16 --> /Users/sdoran/.pyenv/versions/3.9.16/envs/koku-dev-logging-3.9.16
  koku-metrics-operator-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/koku-metrics-operator-3.12.0
  koku-nise-dev-3.8.16 --> /Users/sdoran/.pyenv/versions/3.8.16/envs/koku-nise-dev-3.8.16
  koku-rediscache-debug --> /Users/sdoran/.pyenv/versions/3.9.18/envs/koku-rediscache-debug
  koku-test --> /Users/sdoran/.pyenv/versions/3.11.10/envs/koku-test
  lifecycle-defs --> /Users/sdoran/.pyenv/versions/3.12.8/envs/lifecycle-defs
  llm --> /Users/sdoran/.pyenv/versions/3.13.1/envs/llm
  locust --> /Users/sdoran/.pyenv/versions/3.13.1/envs/locust
  mackup-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/mackup-3.11.0
  maestral-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/maestral-3.11.0
  mitmproxy-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/mitmproxy-3.11.0
  mypy-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/mypy-3.11.0
  nise-populator-3.11.9 --> /Users/sdoran/.pyenv/versions/3.11.9/envs/nise-populator-3.11.9
  nise-populator-3.8.15 --> /Users/sdoran/.pyenv/versions/3.8.15/envs/nise-populator-3.8.15
  parquet-compactor-3.10.13 --> /Users/sdoran/.pyenv/versions/3.10.13/envs/parquet-compactor-3.10.13
  parquet-compactor-3.11.5 --> /Users/sdoran/.pyenv/versions/3.11.5/envs/parquet-compactor-3.11.5
  parquet-compactor-3.8.18 --> /Users/sdoran/.pyenv/versions/3.8.18/envs/parquet-compactor-3.8.18
  parquet-compactor-3.9.18 --> /Users/sdoran/.pyenv/versions/3.9.18/envs/parquet-compactor-3.9.18
  pip-audit --> /Users/sdoran/.pyenv/versions/3.12.2/envs/pip-audit
  pipenv-3.11.7 --> /Users/sdoran/.pyenv/versions/3.11.7/envs/pipenv-3.11.7
  pipfile2req-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/pipfile2req-3.11.0
  poetry --> /Users/sdoran/.pyenv/versions/3.13.1/envs/poetry
  pre-commit --> /Users/sdoran/.pyenv/versions/3.11.6/envs/pre-commit
  prefix --> /Users/sdoran/.pyenv/versions/3.13.1/envs/prefix
  pur-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/pur-3.11.0
  pygments-3.12.2 --> /Users/sdoran/.pyenv/versions/3.12.2/envs/pygments-3.12.2
  pylibssh-dev-3.11.6 --> /Users/sdoran/.pyenv/versions/3.11.6/envs/pylibssh-dev-3.11.6
  pylint-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/pylint-3.11.0
  pyls-3.10.9 --> /Users/sdoran/.pyenv/versions/3.10.9/envs/pyls-3.10.9
  pyright --> /Users/sdoran/.pyenv/versions/3.12.2/envs/pyright
  pyspy-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/pyspy-3.11.0
  pytest-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/pytest-3.11.0
  pytorch --> /Users/sdoran/.pyenv/versions/3.12.0/envs/pytorch
  qontract-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/qontract-3.11.1
  qr-coding-3.11.3 --> /Users/sdoran/.pyenv/versions/3.11.3/envs/qr-coding-3.11.3
  qrcode --> /Users/sdoran/.pyenv/versions/3.12.2/envs/qrcode
  qrimg-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/qrimg-3.11.0
  requests-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/requests-3.11.1
  requests-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/requests-3.12.0
  rh-pre-commit-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/rh-pre-commit-3.12.0
  rlsapi-dev --> /Users/sdoran/.pyenv/versions/3.12.8/envs/rlsapi-dev
  rlsrag --> /Users/sdoran/.pyenv/versions/3.12.8/envs/rlsrag
  ruff --> /Users/sdoran/.pyenv/versions/3.12.2/envs/ruff
  shellai --> /Users/sdoran/.pyenv/versions/3.12.5/envs/shellai
  shiv-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/shiv-3.11.0
  speedtest-cli-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/speedtest-cli-3.11.0
  sphinx-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/sphinx-3.11.0
  tasmota-3.11.6 --> /Users/sdoran/.pyenv/versions/3.11.6/envs/tasmota-3.11.6
  tasmota-3.11.7 --> /Users/sdoran/.pyenv/versions/3.11.7/envs/tasmota-3.11.7
  testing --> /Users/sdoran/.pyenv/versions/3.11.2/envs/testing
  thefuck --> /Users/sdoran/.pyenv/versions/3.13.0/envs/thefuck
  titlecase-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/titlecase-3.11.1
  tox --> /Users/sdoran/.pyenv/versions/3.13.1/envs/tox
  tox-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/tox-3.11.0
  tweet-delete-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/tweet-delete-3.11.0
  uptime-kuma-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/uptime-kuma-3.11.1
  yamllint-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/yamllint-3.11.0
  youtube-dl-3.11.0 --> /Users/sdoran/.pyenv/versions/3.11.0/envs/youtube-dl-3.11.0
  youtube-dl-dev --> /Users/sdoran/.pyenv/versions/3.11.4/envs/youtube-dl-dev

There is now an --only-aliases flag. I found this useful to make the shell completions less verbose.

The completions for pyenv virtualenv now omit aliases and envs. I believe only installed Python versions should be suggested instead of current virtual environments, which are aliases.

Use the code from pyenv-versions for efficiency and consistent output.

The main performance problem was in the call to pyenv-virtualenv-prefix,
which called pyenv-prefix, which then enumerated every virtual environment.
This was done inside a loop, compounding the problem.

Simply the virtual environment listing so that it does not have to call
pyenv-virtualenv-prefix anymore.
This is useful for listing the “frinedly” virtualenv names instead of
the short path which includes the Python version.
…vironments

Having the current virtual environments listed as options in the competion
is noisy since only bare Python versions, such as 3.11.1, make sense as
suggested completions for `pyenv virtualenv [version]`.
This makes the suggested completetions cleaner.
@samdoran
Copy link
Author

I could use some help getting the tests correct. I made a few changes but I don't understand why the unstub commands were failing or how to get a virtual env to show up as "activated" in the test environment.

@pyenv pyenv deleted a comment from samdoran Feb 13, 2025
@ChristianFredrikJohnsen

Seems like only two tests are failing 😄

I just randomly checked into virtualenv. I recently did some perf improvements on the main pyenv repo, and I found myself spending more work fixing the tests (and understanding bats, etc.) than actually improving the source code.
In the pyenv repo, I found that some parts of the code were just written to enable tests to pass, and had no actual value beyond that.

I am not sure if this applies to your situation as well, haven't looked much into it. The main idea I have is:

The code may be perfectly fine, but the tests can be a mess!

@samdoran
Copy link
Author

The tests do need some adjusting since I've changed the output a bit. I'm just having a hard time figuring out what exactly stub and unstub do as well as how to "activate" a venv in the test environment. Testing is always the hard part.

@ChristianFredrikJohnsen

Hehe, and the test file hasn't been touched in 10 years 😆
Same thing I ran into in the pyenv project. Probably only the guy who initially created this stuff knows.

I did not encounter stub and unstub when I did testing in pyenv, and there was no activate there as well (since no virtualenvs of course). Yeah, I don't have any quick answers 💀 It's a pain 🥲

@samdoran
Copy link
Author

The code itself that was the source of the performance issue is 10-12 years old. Not that old code is bad, but there were some inefficiencies in there.

@ChristianFredrikJohnsen

No it's not that the old code is bad. It was probably good at the time it was written. It's more of a problem that the code has design principles which made sense back then, but fast forward 10 years and it's not as intuitive anymore.

And if you're unlucky, you're facing tests which were quick-fix set up 10 years ago, and suddenly you need to fix the problem of ...
Not necessarily the problem of any one person either, it's just that the entire structure doesn't feel intuitive.

It's a challenge for sure 😄

Comment on lines 168 to 182
if [ -z "$only_aliases" ]; then
for env_path in "${venv_dir_entries[@]}"; do
if [ -d "${env_path}" ]; then
print_version "${env_path#"${PYENV_ROOT}"/versions/}" "${env_path}"
fi
virtualenv_prefix="$(pyenv-virtualenv-prefix "${path##*/}" 2>/dev/null || true)"
if [ -d "${virtualenv_prefix}" ]; then
print_version "${path##*/}" " (created from ${virtualenv_prefix})"
done
fi

if [ -z "$skip_aliases" ]; then
for env_path in "${version_dir_entries[@]}"; do
if [ -d "${env_path}" ] && [ -L "${env_path}" ]; then
print_version "${env_path#"${PYENV_ROOT}"/versions/}" "${env_path}"
fi
for venv_path in "${path}/envs/"*; do
venv="${path##*/}/envs/${venv_path##*/}"
virtualenv_prefix="$(pyenv-virtualenv-prefix "${venv}" 2>/dev/null || true)"
if [ -d "${virtualenv_prefix}" ]; then
print_version "${venv}" " (created from ${virtualenv_prefix})"
fi
done
fi
done
done
fi
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens with conda installations? They are currently listed, now they seem to stop being so.
Not sure why they are listed and if that's intended. Technically, each one contains a "base" environment -- but the same could be said about any other Python installation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know anything about or use conda, so I omitted those. 😊
I will work on adding that back in as they should be listed in the output.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through the previous code, it seems like the intent was to look for certain indicator files and if they are present, list the directory as a virtual environment. I don't really know if that's a good heuristic or not.

Calling pyenv-virtualenv-prefix was what caused the program to take so long to run. If we think this behavior should remain, I'll have to reimplement this functionality using a more efficient approach.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, the changes in this PR may actually be doing a better job with this than the current code.

I installed miniconda3 and created a new env.

pyenv install miniconda3-latest
pyenv shell miniconda3-latest
conda create -n my_conda_env

I only see my_conda_env in the second output.

Current output running master
> pyenv virtualenvs
  3.10.2/envs/pyls-3.10.2 (created from /Users/sdoran/.pyenv/versions/3.10.2)
  3.10.3/envs/ansible-2.12-3.10.3 (created from /Users/sdoran/.pyenv/versions/3.10.3)
  3.10.3/envs/boto-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.3)
  3.10.3/envs/lexicon-3.10.3 (created from /Users/sdoran/.pyenv/versions/3.10.3)
  3.10.4/envs/ansible-2.12-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  3.10.4/envs/ansible-dev-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  3.10.4/envs/flake8-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  3.10.4/envs/jello-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  3.10.4/envs/jsbeautifier-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  3.10.4/envs/youtube-dl-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  3.10.6/envs/ipython-3.10.6 (created from /Users/sdoran/.pyenv/versions/3.10.6)
  3.10.6/envs/shiv-3.10.6 (created from /Users/sdoran/.pyenv/versions/3.10.6)
  3.10.6/envs/speedtest-cli-3.10.6 (created from /Users/sdoran/.pyenv/versions/3.10.6)
  3.11.1/envs/ansible-2.14-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  3.11.1/envs/ipython-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  3.11.1/envs/titlecase-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  3.11.1/envs/uptime-kuma-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  3.11.3/envs/ipython-3.11.3 (created from /Users/sdoran/.pyenv/versions/3.11.3)
  3.11.3/envs/tasmota (created from /Users/sdoran/.pyenv/versions/3.11.3)
  3.11.7/envs/tasmota-3.11.7 (created from /Users/sdoran/.pyenv/versions/3.11.7)
  3.12.0/envs/ansible-2.16-3.12.0 (created from /Users/sdoran/.pyenv/versions/3.12.0)
  3.12.0/envs/ipython-3.12.0 (created from /Users/sdoran/.pyenv/versions/3.12.0)
  3.12.2/envs/borg (created from /Users/sdoran/.pyenv/versions/3.12.2)
  3.12.2/envs/yt-dlp (created from /Users/sdoran/.pyenv/versions/3.12.2)
  3.12.4/envs/qrcode (created from /Users/sdoran/.pyenv/versions/3.12.4)
  3.12.8/envs/ansible-lint (created from /Users/sdoran/.pyenv/versions/3.12.8)
  3.12.8/envs/cowsay (created from /Users/sdoran/.pyenv/versions/3.12.8)
  3.12.8/envs/pyright-3.12.8 (created from /Users/sdoran/.pyenv/versions/3.12.8)
  3.12.8/envs/ruff-3.12.8 (created from /Users/sdoran/.pyenv/versions/3.12.8)
  3.13.1/envs/asciinema (created from /Users/sdoran/.pyenv/versions/3.13.1)
  3.13.1/envs/diceware (created from /Users/sdoran/.pyenv/versions/3.13.1)
  3.13.1/envs/ipython-3.13.1 (created from /Users/sdoran/.pyenv/versions/3.13.1)
  3.6.15/envs/ipython-3.6.15 (created from /Users/sdoran/.pyenv/versions/3.6.15)
  3.7.12/envs/appomni-dev-3.7.12 (created from /Users/sdoran/.pyenv/versions/3.7.12)
  3.7.12/envs/ipython-3.7.12 (created from /Users/sdoran/.pyenv/versions/3.7.12)
  3.8.12/envs/ipython-3.8.12 (created from /Users/sdoran/.pyenv/versions/3.8.12)
  3.9.9/envs/ipython-3.9.9 (created from /Users/sdoran/.pyenv/versions/3.9.9)
  ansible-2.12-3.10.3 (created from /Users/sdoran/.pyenv/versions/3.10.3)
  ansible-2.12-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  ansible-2.14-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  ansible-2.16-3.12.0 (created from /Users/sdoran/.pyenv/versions/3.12.0)
  ansible-dev-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  ansible-lint (created from /Users/sdoran/.pyenv/versions/3.12.8)
  appomni-dev-3.7.12 (created from /Users/sdoran/.pyenv/versions/3.7.12)
  asciinema (created from /Users/sdoran/.pyenv/versions/3.13.1)
  borg (created from /Users/sdoran/.pyenv/versions/3.12.2)
  boto-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.3)
  cowsay (created from /Users/sdoran/.pyenv/versions/3.12.8)
  diceware (created from /Users/sdoran/.pyenv/versions/3.13.1)
  flake8-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  ipython-3.10.6 (created from /Users/sdoran/.pyenv/versions/3.10.6)
  ipython-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  ipython-3.11.3 (created from /Users/sdoran/.pyenv/versions/3.11.3)
  ipython-3.12.0 (created from /Users/sdoran/.pyenv/versions/3.12.0)
  ipython-3.13.1 (created from /Users/sdoran/.pyenv/versions/3.13.1)
  ipython-3.6.15 (created from /Users/sdoran/.pyenv/versions/3.6.15)
  ipython-3.7.12 (created from /Users/sdoran/.pyenv/versions/3.7.12)
  ipython-3.8.12 (created from /Users/sdoran/.pyenv/versions/3.8.12)
  ipython-3.9.9 (created from /Users/sdoran/.pyenv/versions/3.9.9)
  jello-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  jsbeautifier-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  lexicon-3.10.3 (created from /Users/sdoran/.pyenv/versions/3.10.3)
  miniconda3-latest (created from /Users/sdoran/.pyenv/versions/miniconda3-latest)
  pyls-3.10.2 (created from /Users/sdoran/.pyenv/versions/3.10.2)
  pyright-3.12.8 (created from /Users/sdoran/.pyenv/versions/3.12.8)
  qrcode (created from /Users/sdoran/.pyenv/versions/3.12.4)
  ruff-3.12.8 (created from /Users/sdoran/.pyenv/versions/3.12.8)
  shiv-3.10.6 (created from /Users/sdoran/.pyenv/versions/3.10.6)
  speedtest-cli-3.10.6 (created from /Users/sdoran/.pyenv/versions/3.10.6)
  tasmota (created from /Users/sdoran/.pyenv/versions/3.11.3)
  tasmota-3.11.7 (created from /Users/sdoran/.pyenv/versions/3.11.7)
  titlecase-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  uptime-kuma-3.11.1 (created from /Users/sdoran/.pyenv/versions/3.11.1)
  youtube-dl-3.10.4 (created from /Users/sdoran/.pyenv/versions/3.10.4)
  yt-dlp (created from /Users/sdoran/.pyenv/versions/3.12.2)
New output from this branch
  3.10.2/envs/pyls-3.10.2
  3.10.3/envs/ansible-2.12-3.10.3
  3.10.3/envs/boto-3.10.4
  3.10.3/envs/lexicon-3.10.3
  3.10.4/envs/ansible-2.12-3.10.4
  3.10.4/envs/ansible-dev-3.10.4
  3.10.4/envs/flake8-3.10.4
  3.10.4/envs/jello-3.10.4
  3.10.4/envs/jsbeautifier-3.10.4
  3.10.4/envs/youtube-dl-3.10.4
  3.10.6/envs/ipython-3.10.6
  3.10.6/envs/shiv-3.10.6
  3.10.6/envs/speedtest-cli-3.10.6
  3.11.1/envs/ansible-2.14-3.11.1
  3.11.1/envs/ipython-3.11.1
  3.11.1/envs/titlecase-3.11.1
  3.11.1/envs/uptime-kuma-3.11.1
  3.11.3/envs/ipython-3.11.3
  3.11.3/envs/tasmota
  3.11.7/envs/tasmota-3.11.7
  3.12.0/envs/ansible-2.16-3.12.0
  3.12.0/envs/ipython-3.12.0
  3.12.2/envs/borg
  3.12.2/envs/yt-dlp
  3.12.4/envs/qrcode
  3.12.8/envs/ansible-lint
  3.12.8/envs/cowsay
  3.12.8/envs/pyright-3.12.8
  3.12.8/envs/ruff-3.12.8
  3.13.1/envs/asciinema
  3.13.1/envs/diceware
  3.13.1/envs/ipython-3.13.1
  3.6.15/envs/ipython-3.6.15
  3.7.12/envs/appomni-dev-3.7.12
  3.7.12/envs/ipython-3.7.12
  3.8.12/envs/ipython-3.8.12
  3.9.9/envs/ipython-3.9.9
  miniconda3-latest/envs/my_conda_env
  ansible-2.12-3.10.3 --> /Users/sdoran/.pyenv/versions/3.10.3/envs/ansible-2.12-3.10.3
  ansible-2.12-3.10.4 --> /Users/sdoran/.pyenv/versions/3.10.4/envs/ansible-2.12-3.10.4
  ansible-2.14-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/ansible-2.14-3.11.1
  ansible-2.16-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/ansible-2.16-3.12.0
  ansible-dev-3.10.4 --> /Users/sdoran/.pyenv/versions/3.10.4/envs/ansible-dev-3.10.4
  ansible-lint --> /Users/sdoran/.pyenv/versions/3.12.8/envs/ansible-lint
  appomni-dev-3.7.12 --> /Users/sdoran/.pyenv/versions/3.7.12/envs/appomni-dev-3.7.12
  asciinema --> /Users/sdoran/.pyenv/versions/3.13.1/envs/asciinema
  borg --> /Users/sdoran/.pyenv/versions/3.12.2/envs/borg
  boto-3.10.4 --> /Users/sdoran/.pyenv/versions/3.10.3/envs/boto-3.10.4
  cowsay --> /Users/sdoran/.pyenv/versions/3.12.8/envs/cowsay
  diceware --> /Users/sdoran/.pyenv/versions/3.13.1/envs/diceware
  flake8-3.10.4 --> /Users/sdoran/.pyenv/versions/3.10.4/envs/flake8-3.10.4
  ipython-3.10.6 --> /Users/sdoran/.pyenv/versions/3.10.6/envs/ipython-3.10.6
  ipython-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/ipython-3.11.1
  ipython-3.11.3 --> /Users/sdoran/.pyenv/versions/3.11.3/envs/ipython-3.11.3
  ipython-3.12.0 --> /Users/sdoran/.pyenv/versions/3.12.0/envs/ipython-3.12.0
  ipython-3.13.1 --> /Users/sdoran/.pyenv/versions/3.13.1/envs/ipython-3.13.1
  ipython-3.6.15 --> /Users/sdoran/.pyenv/versions/3.6.15/envs/ipython-3.6.15
  ipython-3.7.12 --> /Users/sdoran/.pyenv/versions/3.7.12/envs/ipython-3.7.12
  ipython-3.8.12 --> /Users/sdoran/.pyenv/versions/3.8.12/envs/ipython-3.8.12
  ipython-3.9.9 --> /Users/sdoran/.pyenv/versions/3.9.9/envs/ipython-3.9.9
  jello-3.10.4 --> /Users/sdoran/.pyenv/versions/3.10.4/envs/jello-3.10.4
  jsbeautifier-3.10.4 --> /Users/sdoran/.pyenv/versions/3.10.4/envs/jsbeautifier-3.10.4
  lexicon-3.10.3 --> /Users/sdoran/.pyenv/versions/3.10.3/envs/lexicon-3.10.3
  pyls-3.10.2 --> /Users/sdoran/.pyenv/versions/3.10.2/envs/pyls-3.10.2
  pyright-3.12.8 --> /Users/sdoran/.pyenv/versions/3.12.8/envs/pyright-3.12.8
  qrcode --> /Users/sdoran/.pyenv/versions/3.12.4/envs/qrcode
  ruff-3.12.8 --> /Users/sdoran/.pyenv/versions/3.12.8/envs/ruff-3.12.8
  shiv-3.10.6 --> /Users/sdoran/.pyenv/versions/3.10.6/envs/shiv-3.10.6
  speedtest-cli-3.10.6 --> /Users/sdoran/.pyenv/versions/3.10.6/envs/speedtest-cli-3.10.6
  tasmota --> /Users/sdoran/.pyenv/versions/3.11.3/envs/tasmota
  tasmota-3.11.7 --> /Users/sdoran/.pyenv/versions/3.11.7/envs/tasmota-3.11.7
  titlecase-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/titlecase-3.11.1
  uptime-kuma-3.11.1 --> /Users/sdoran/.pyenv/versions/3.11.1/envs/uptime-kuma-3.11.1
  youtube-dl-3.10.4 --> /Users/sdoran/.pyenv/versions/3.10.4/envs/youtube-dl-3.10.4
  yt-dlp --> /Users/sdoran/.pyenv/versions/3.12.2/envs/yt-dlp

Comment on lines +9 to +10
ln -s "venv27" "${PYENV_ROOT}/versions/venv27"
ln -s "venv33" "${PYENV_ROOT}/versions/venv33"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICS the links are created in the current directory. That doesn't seem correct.
There's a dedicated function to create aliases.

Comment on lines +48 to +49
2.7.6/envs/venv27
* 3.3.3/envs/venv33
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diagnosed this failure. The logic does not equate "xxx" with "yyy/envs/xxx". If you set current version to "venv33", the alias will be the highlighted entry, not the full name.

To diagnose stuff in tests, I set PS4 to the long value from the launcher and run the command with PYENV_DEBUG=1. Then make sure there's a command later that prints its output in some form (in this case, assert_output failure handling logic).

Comment on lines +41 to +42
stub pyenv-virtualenv-prefix "venv27 : echo \"${PYENV_ROOT}/versions/2.7.6\""
stub pyenv-virtualenv-prefix "venv33 : echo \"${PYENV_ROOT}/versions/3.3.3\""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this change improves anything. As a rule of thumb, one should not change test cases unless you've changed the behavior in them -- to avoid accidentally losing test cover.

OUT

unstub pyenv-version-name
unstub pyenv-virtualenv-prefix
# unstub pyenv-version-name
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unstub checcks if the specific stubbed executable was called exactly according to the sequence set up with stub calls. If not, it fails and prints the plan and the fact.
The implementation is in test_helper.bash and the stubs/stub script which the former calls.

@@ -17,7 +17,7 @@ set -e
# Provide pyenv completions
if [ "$1" = "--complete" ]; then
echo --unset
exec pyenv-virtualenvs --bare
exec pyenv-virtualenvs --bare --only-aliases
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a design change -- so this should be discussed separately. Envs are supposed to be accessible under both full name and alias. I'm not sure why that is; aliases are internally called "compat", indicating that they were added for compatibility with... something.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll remove that change for now and we can discuss elsewhere. What's the best place to have a design discussion?

@samdoran
Copy link
Author

Thank you for the feedback @native-api. I'll address this later in the week.

@samdoran
Copy link
Author

I had a crazy week and a full weekend away from home. I will work on this during the week.

This was removed by accident.
For consistency, use conditional expressions instead of
arithmetic evaluation when comparing bash versions.
The new implementation is not using realpath.
@samdoran
Copy link
Author

Thanks for all the feedback. I didn't get to fixing up the tests. I need to get some sleep for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants