🐛 fix: stop symlink resolution at stdlib landmark and framework builds#87
Merged
Conversation
Following every hop pinned Homebrew's versioned Cellar path into the recorded home (breaks on brew upgrade, changes the alias under which base site-packages appear) and rewrote stable aliases like Debian's /usr/bin/python3. Mirror getpath: resolve only while lib(64)/pythonX.Y/os.py is not reachable next to the executable, and never for macOS framework builds, which self-locate through the real binary via dyld. Fixes #86.
gaborbernat
added a commit
to pypa/virtualenv
that referenced
this pull request
Jun 11, 2026
…3166) Creating an environment with `-p` pointing at a symlink to just the interpreter binary recorded the symlink in `pyvenv.cfg`: `home` ended up as the symlink's directory, which contains no `lib/`, and `base-executable` kept the unresolved link. 🐛 Standard CPython survives because `getpath` re-resolves the link when reading `home`, but layouts where `home` must directly locate the base stdlib, such as python-build-standalone, produce a broken environment (#3157). The resolution lives in python-discovery (tox-dev/python-discovery#85, refined by tox-dev/python-discovery#87): `system_executable` follows the symlink chain of the executable's final path component only, stopping as soon as the stdlib landmark is reachable and never touching macOS framework builds, the same semantics CPython's `getpath` uses and its `venv` adopts in python/cpython#115237. A barren-directory symlink resolves to the real interpreter while stable aliases like Homebrew's `opt` paths, Debian's `/usr/bin/python3`, or a fully symlinked interpreter tree keep their recorded form. This PR raises the dependency floor to `python-discovery>=1.4.2` and bumps the app-data `py_info` cache key from `4` to `5` so interpreter records probed by older virtualenv versions are not shared with the corrected ones. CI needs python-discovery `1.4.2` on PyPI (tox-dev/python-discovery#87 merge + release) to go green. Fixes #3157.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The resolution added in #84 follows every symlink hop of the executable. pypa/virtualenv CI caught two unwanted consequences on its
brew@3.12/brew@3.13jobs: Homebrew's/opt/homebrew/bin/python3.12resolves through the version-pinnedCellar/python@3.12/<version>directory, so the recordedhomebreaks onbrew upgradeand the base site-packages shows up in created environments under aCellaralias that no longer matches the interpreter's own reported paths. 🐛 Stable distro aliases such as Debian's/usr/bin/python3were also rewritten to the versioned binary for no benefit.Real
getpathonly follows the executable symlink while the stdlib landmark is missing beside it, so the walk now stops as soon as<dir>/../lib(64)/pythonX.Y/os.pyis reachable, and macOS framework builds skip resolution entirely since they self-locate through the real binary viadyldat runtime. The pypa/virtualenv#3157 scenario, a symlink in a directory with no installation around it, keeps resolving to the real interpreter exactly as before, verified against both a python-build-standalone interpreter and a Homebrew one where created environments now match the pre-#84 layout byte for byte.Fixes #86.