weird cyclic symlink on macos
Too many issues will kill our team's development velocity, drastically. Make sure you have checked all steps below.
Prerequisite
- [x] Make sure your problem is not listed in the common build problems.
- [x] Make sure no duplicated issue has already been reported in the pyenv-virtualenv issues. You should look in closed issues, too.
- [x] Make sure you are not asking us to help solving your specific issue.
- GitHub issues is opened mainly for development purposes. If you want to ask someone to help solving your problem, go to some community site like Gitter, StackOverflow, etc.
- [x] Make sure your problem is not derived from packaging (e.g. Homebrew).
- Please refer to the package documentation for the installation issues, etc.
- [x] Make sure your problem is not derived from other plugins.
- This repository is maintaining the
pyenv-virtualenvplugin only. Please refrain from reporting issues of other plugins here.
- This repository is maintaining the
Description
- [x] Platform information (e.g. Ubuntu Linux 20.04): apple mac m1 pro
- [x] OS architecture (e.g. amd64): aarch64/arm64
- [x] pyenv version: 2.4.7
- [x] pyenv-virtualenv version: 1.2.3
- [x] Python version: v3.10.14
- [x] virtualenv version (if installed): 20.26.3
- [x] Please attach the debug log of a faulty Pyenv invocation as a gist
- If the problem happens in a Pyenv invocation, you can turn on debug logging by setting
PYENV_DEBUG=1, e.g.env PYENV_DEBUG=1 pyenv install -v 3.6.4 - If the problem happens outside of a Pyenv invocation, get the debug log like this:
# for Bash export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' # for Zsh export PS4='+(%x:%I): %N(%i): ' set -x <reproduce the problem> set +x
- If the problem happens in a Pyenv invocation, you can turn on debug logging by setting
Problem description
This line here creates a weird cyclic symlink inside of a virtualenv directory.
For example, this line attempts to create the following symlink:
$ ln -fs /Users/user.name/.pyenv/versions/3.10.14/envs/venvname /Users/user.name/.pyenv/versions/venvname
However the target and the source directory is the same directory:
$ ls -la /Users/user.name/.pyenv/versions/venvname
lrwxr-xr-x 1 user.name staff 59 Jul 9 17:37 /Users/user.name/.pyenv/versions/venvname -> /Users/user.name/.pyenv/versions/3.10.14/envs/venvname
As a result
$ ls -la /Users/user.name/.pyenv/versions/3.10.14/envs/venvname/
total 8
drwxr-xr-x 7 user.name staff 224 Jul 9 18:21 .
drwxr-xr-x 4 user.name staff 128 Jul 9 17:37 ..
drwxr-xr-x 16 user.name staff 512 Jul 9 17:37 bin
lrwxr-xr-x 1 user.name staff 59 Jul 9 18:21 venvname -> /Users/user.name/.pyenv/versions/3.10.14/envs/venvname
drwxr-xr-x 2 user.name staff 64 Jul 9 17:37 include
drwxr-xr-x 3 user.name staff 96 Jul 9 17:37 lib
-rw-r--r-- 1 user.name staff 117 Jul 9 18:21 pyvenv.cfg
If I'd prepend this line with echo, like this
echo ln -fs "${VIRTUALENV_PATH}" "${COMPAT_VIRTUALENV_PATH}"
There is no weird cyclic symlink getting created.
Is this something expected or a bug?
Please provide a debug log showcasing the problem (i.e. the link's creation) as per the issue template.
That line is supposed to create a link $PYENV_ROOT/versions/<env_name> -> $PYENV_ROOT/versions/<python_version>/envs/<env_name>.
sure, here is the relevant part (line no. 17)
+(/opt/homebrew/Cellar/pyenv/2.4.7/libexec/pyenv-exec:48): exec /Users/user.name/.pyenv/versions/3.10.14/bin/python3.10 -m venv /Users/user.name/.pyenv/versions/3.10.14/envs/venvname
+(/opt/homebrew/bin/pyenv-virtualenv:610): shopt -s nullglob
+(/opt/homebrew/bin/pyenv-virtualenv:611): for extra_binary in "$PREFIX"/bin/python*-config
++(/opt/homebrew/bin/pyenv-virtualenv:612): basename /Users/user.name/.pyenv/versions/3.10.14/bin/python-config
+(/opt/homebrew/bin/pyenv-virtualenv:612): extra_binary_linkname=/Users/user.name/.pyenv/versions/3.10.14/envs/venvname/bin/python-config
+(/opt/homebrew/bin/pyenv-virtualenv:613): [[ -e /Users/user.name/.pyenv/versions/3.10.14/envs/venvname/bin/python-config ]]
+(/opt/homebrew/bin/pyenv-virtualenv:611): for extra_binary in "$PREFIX"/bin/python*-config
++(/opt/homebrew/bin/pyenv-virtualenv:612): basename /Users/user.name/.pyenv/versions/3.10.14/bin/python3-config
+(/opt/homebrew/bin/pyenv-virtualenv:612): extra_binary_linkname=/Users/user.name/.pyenv/versions/3.10.14/envs/venvname/bin/python3-config
+(/opt/homebrew/bin/pyenv-virtualenv:613): [[ -e /Users/user.name/.pyenv/versions/3.10.14/envs/venvname/bin/python3-config ]]
+(/opt/homebrew/bin/pyenv-virtualenv:611): for extra_binary in "$PREFIX"/bin/python*-config
++(/opt/homebrew/bin/pyenv-virtualenv:612): basename /Users/user.name/.pyenv/versions/3.10.14/bin/python3.10-config
+(/opt/homebrew/bin/pyenv-virtualenv:612): extra_binary_linkname=/Users/user.name/.pyenv/versions/3.10.14/envs/venvname/bin/python3.10-config
+(/opt/homebrew/bin/pyenv-virtualenv:613): [[ -e /Users/user.name/.pyenv/versions/3.10.14/envs/venvname/bin/python3.10-config ]]
+(/opt/homebrew/bin/pyenv-virtualenv:619): '[' -d /Users/user.name/.pyenv/versions/3.10.14/envs/venvname ']'
+(/opt/homebrew/bin/pyenv-virtualenv:619): '[' -n /Users/user.name/.pyenv/versions/venvname ']'
+(/opt/homebrew/bin/pyenv-virtualenv:620): ln -fs /Users/user.name/.pyenv/versions/3.10.14/envs/venvname /Users/user.name/.pyenv/versions/venvname
+(/opt/homebrew/bin/pyenv-virtualenv:623): '[' '!' -e /Users/user.name/.pyenv/versions/3.10.14/envs/venvname/bin/pydoc ']'
+(/opt/homebrew/bin/pyenv-virtualenv:634): '[' -z 1 ']'
+(/opt/homebrew/bin/pyenv-virtualenv:646): '[' 0 == 0 ']'
+(/opt/homebrew/bin/pyenv-virtualenv:647): pyenv-rehash
+(/opt/homebrew/Cellar/pyenv/2.4.7/libexec/pyenv-rehash:7): SHIM_PATH=/Users/user.name/.pyenv/shims
just fyi, ln works a little bit different on macos, it creates not only a symlink at the target, but also at the source, for example:
$ ln -fs /Users/user.name/.pyenv/versions/3.10.14/envs/venvname /Users/user.name/.pyenv/versions/venvname
$ ls -la /Users/user.name/.pyenv/versions/venvname
lrwxr-xr-x@ 1 user.name staff 59 Jul 11 10:10 /Users/user.name/.pyenv/versions/venvname -> /Users/user.name/.pyenv/versions/3.10.14/envs/venvname
$ ls -la /Users/user.name/.pyenv/versions/venvname/venvname
lrwxr-xr-x@ 1 user.name staff 59 Jul 11 10:14 /Users/user.name/.pyenv/versions/venvname/venvname -> /Users/user.name/.pyenv/versions/3.10.14/envs/venvname
versus
$ ln -fsn /Users/user.name/.pyenv/versions/3.10.14/envs/venvname /Users/user.name/.pyenv/versions/venvname
$ ls -la /Users/user.name/.pyenv/versions/venvname
lrwxr-xr-x@ 1 user.name staff 59 Jul 11 10:17 /Users/user.name/.pyenv/versions/venvname -> /Users/user.name/.pyenv/versions/3.10.14/envs/venvname
$ ls -la /Users/user.name/.pyenv/versions/venvname/venvname
ls: /Users/user.name/.pyenv/versions/venvname/venvname: No such file or directory
to sum up, I have to use ln -fsn instead of ln -fs to overcome that
So, the erroneous behavior happens because the symlink /Users/user.name/.pyenv/versions/venvname already exists.
But it shouldn't -- because you've just created the environment!
Are you trying to create an environment with the same name as one that already exists?
Okay, I see that this can happen legitimately, if you're overwriting the environment with -f.
Already reported and patch suggested here: #453 Finally fixed, thank you.