Python symlink target in virtual envs

I’d like to propose a small change and to explain it let me start with the file layouts as I see them on my Linux box.

In /usr/bin there is the executable installed by the Linux distro:

python -> python3
python3 -> python3.13
python3.13

When I create a venv, the contents of its ../bin subdirectory depends on how it was created. The command python -m venv /opt/venv creates:

python -> /usr/bin/python  # <--- python points to /usr/bin
python3 -> python
python3.13 -> python

The command python3 -m venv /opt/venv creates:

python3 -> /usr/bin/python3  # <--- python3 points to /usr/bin
python -> python3
python3.13 -> python3

And python3.13 -m venv /opt/venv creates another permutation where python3.13 points to /usr/bin and the two remaining symlinks point to the the first one.


During an OS upgrade, version 3.13 was replaced by 3.14 (in /usr/bin) thus rendering all venvs unusable. But there is a difference:

  • Virtual envs that look for /usr/bin/python or /usr/bin/python3 fail with import errors and modules not found and the real reason is not so obvious. The fix is to upgrade the venvs one after another and to reinstall all site packages.
  • All virtual env that look for /usr/bin/python3.13 can be made working again quickly and in one step with installing python 3.13 parallel to the default and newest 3.14. The downtime is reduced and the upgrade can be made later. Also the error message clearly says what is wrong with “no such file”.

Long introduction, short proposal: regardless of the argv[0] of the python -m venv ... command, the venv should use the name identifying the interpreter version, i.e. python3.XY as the symlink target. Of course, this affects only symlink mode of venv installation, not the copy mode.

2 Likes