Skip to content

venv using symlinks and empty pyvenv.cfg isn't recognized as venv / able to find python home #135773

Open
@rickeylev

Description

@rickeylev

Bug report

Bug description:

Previously, it was possible to have a functional (enough) venv by simply doing two things:

  1. Creating an empty pyvenv.cfg file
  2. Creating a bin/python3 which symlinked to the actual interpreter

The net effect was you had a sufficiently relocatable venv (at the interpreter level) to make it into a fully relocatable venv (at the application level). This is because Python would follow the symlink to locate its home, which let it get through initial bootstrapping, enough to pick a venv-relative site-packages directory.

The net effect was Python followed the symlink to find home, which let it bootstrap itself enough to find the venv's site-packages. Once at that point, application code is able to hook in and do some fixups.

This bug seems to be introduced by #126987

I'm still looking at the changes to figure out why, exactly. I'm pretty confident it's that PR, though -- in my reproducer, things work before it, but break after it.

This behavior of automatically find Python home is something Bazel's rules_python has come to rely on. Insofar as venvs are concerned, the two particular constraints Bazel imposes are:

  1. Absolute paths can't be used. This is because they may be machine specific. In Bazel, the machine that generates pyvenv.cfg may be different than who uses it at runtime (e.g a remote build worker generates it, and a user runs it locally).
  2. The file system must be assumed to be read-only after building. This prevents creating/modifying a pyvenv.cfg at runtime in the venv's directory to work around (1).

(As an aside, how the env var PYTHONEXECUTABLE gets handled might have also been affected by this; I haven't looked deeply yet, but one of my tricks was to set that to the venv bin/python3 path and invoke the real interpreter, but that seems to no longer work, either)

I'll post a more self contained reproducer in a bit. In the meantime, something like this can demonstrate the issue:

mkdir myvenv
cd myvenv
touch pyvenv.cfg
mkdir bin
ln -s <path to python> bin/python3
mkdir -p lib/python3.14/site-packages
bin/python3 -c 'import sys; print(sys.prefix); print(sys.base_prefix); print(sys.path)'

After the change, it'll print warnings and e.g. /usr/local as the prefixes, which is incorrect. sys.path won't have the venv's site-packages directory, which is incorrect.

Before the change, it'll print the venv directory, underlying interpreter directory, and the venv's site-packages, which is correct.

cc @FFY00 (author of above PR)

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibPython modules in the Lib dirtopic-venvRelated to the venv moduletype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions