Repository navigation
Python may startup fails if the home variable in pyvenv.cfg is inaccurate #127440
Copy link
Copy link
Open
Labels
topic-installationtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Description
Bug report
Bug description:
The problem comes from getpath.py. When getpath.py cannot find STDLIB_LANDMARKS from executable_dir, it will set prefix to the PREFIX. If the directory set in PREFIX does not exist, an error occurs.
See details:
Lines 590 to 599 in 49f15d8
| # Detect prefix by searching from our executable location for the stdlib_dir | |
| if STDLIB_SUBDIR and STDLIB_LANDMARKS and executable_dir and not prefix: | |
| prefix = search_up(executable_dir, *STDLIB_LANDMARKS) | |
| if prefix and not stdlib_dir: | |
| stdlib_dir = joinpath(prefix, STDLIB_SUBDIR) | |
| if PREFIX and not prefix: | |
| prefix = PREFIX | |
| if not any(isfile(joinpath(prefix, f)) for f in STDLIB_LANDMARKS): | |
| warn('Could not find platform independent libraries <prefix>') |
How to reproduce
# 1. build cpython with prefix
./configure --prefix=/home/xx/tmp/install_dir
make
make install
# 2. copy install_dir to another
cd /home/xx/tmp
cp -r ./install_dir/ ./copy_dir
# 3. create a symlink from copy_dir/python
ln -s ./copy_dir/bin/python3 ./pylink
# 4. delete original install_dir
rm -rf ./install_dir/
# 5. use python symlink to create a venv
./pylink -m venv ./bad_venv
# 6. failed to start!
./bad_venv/bin/python3Error message
Could not find platform independent libraries <prefix>
Could not find platform dependent libraries <exec_prefix>
Python path configuration:
PYTHONHOME = (not set)
PYTHONPATH = (not set)
program name = './bad_venv/bin/python3'
isolated = 0
environment = 1
user site = 1
safe_path = 0
import site = 1
is in build tree = 0
stdlib dir = '/home/xx/tmp/install_dir/lib/python3.12'
sys._base_executable = '/home/xx/tmp/copy_dir/bin/python3.12'
sys.base_prefix = '/home/xx/tmp/install_dir'
sys.base_exec_prefix = '/home/xx/tmp/install_dir'
sys.platlibdir = 'lib'
sys.executable = '/home/xx/tmp/bad_venv/bin/python3'
sys.prefix = '/home/xx/tmp/install_dir'
sys.exec_prefix = '/home/xx/tmp/install_dir'
sys.path = [
'/home/xx/tmp/install_dir/lib/python312.zip',
'/home/xx/tmp/install_dir/lib/python3.12',
'/home/xx/tmp/install_dir/lib/python3.12/lib-dynload',
]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'
We can find that sys._base_executable here is correct, but sys.base_prefix is wrong.
We could configure base_prefix through the real interpreter path, which is used to search for libraries that Python depends on.
CPython versions tested on:
3.12
Operating systems tested on:
Linux
Linked PRs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
topic-installationtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
Activity
FFY00 commentedon Dec 4, 2024
I don't think it's a good idea to bypass
pyvenv.cfg'shomefor the prefix calculation by looking atbase_executable.That said, I do think the failure mode and error log are pretty bad. We should instead fail with a message explaining that there is a mismatch in the Python installation used to create the virtual environment, and the one being used to run it. We should also suggest using
python -m venv --upgradeto fix the issue.CharlieZhao95 commentedon Dec 5, 2024
Thanks for the suggestion :) But
python -m venv --upgradedoesn't work for me because the error occurs before the venv is created.Very few people use
./bad_venv/bin/python3to start python (I use this for debugging), so they don’t even see the error message above.I'm not trying to bypass
home, but provide a way to calculateprefixwhen thehomeis inaccurate, just likeif PREFIX and not prefix: ...does. Not sure if this has potential side effects, because the tests all passed, please let me know if there are.FFY00 commentedon Dec 5, 2024
Don't you have access to the base Python interpreter? The venv upgrade command is meant to be run with that, not with venv interpreter.
If not, I would like to see if we can figure out other way to deal with your use-case before opting for this approach.
CharlieZhao95 commentedon Dec 5, 2024
I guess this error has nothing to do with the base interpreter, it comes from:
The python used here is the python in the venv (
/venv/bin/python).FFY00 commentedon Dec 5, 2024
I think we should treat this as a venv bug, it should check
homeand update it if necessary.CharlieZhao95 commentedon Dec 9, 2024
I found that the doc for
venvdescribeshomelike this:It seems that the doc assumes that the location to run python command is always in the Python installation directory (Normally, this is correct).
But now the
homedoes not always point to the Python installation, it may point to any directory containing a python symlink used to create avenv. I'm not sure if this is what the designers ofvenvintended.Now we seem to expect
hometo always point to the real Python installation. Can anyone else help us identify the solution? @FFY00FFY00 commentedon Dec 12, 2024
After looking into this a bit more, I think your proposed solution is reasonable. To fix the root of the issue, though, I opened GH-127895. We can apply your solution to 3.12 and 3.13 as a bugfix, and move away from using
homeentirely in 3.14.