Skip to content

🐛 fix: stop symlink resolution at stdlib landmark and framework builds#87

Merged
gaborbernat merged 1 commit into
mainfrom
fix/landmark-framework-stop
Jun 11, 2026
Merged

🐛 fix: stop symlink resolution at stdlib landmark and framework builds#87
gaborbernat merged 1 commit into
mainfrom
fix/landmark-framework-stop

Conversation

@gaborbernat

Copy link
Copy Markdown
Member

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.13 jobs: Homebrew's /opt/homebrew/bin/python3.12 resolves through the version-pinned Cellar/python@3.12/<version> directory, so the recorded home breaks on brew upgrade and the base site-packages shows up in created environments under a Cellar alias that no longer matches the interpreter's own reported paths. 🐛 Stable distro aliases such as Debian's /usr/bin/python3 were also rewritten to the versioned binary for no benefit.

Real getpath only 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.py is reachable, and macOS framework builds skip resolution entirely since they self-locate through the real binary via dyld at 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.

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 gaborbernat added the bug Something isn't working label Jun 11, 2026
@gaborbernat gaborbernat merged commit 4f6132b into main Jun 11, 2026
16 checks passed
@gaborbernat gaborbernat deleted the fix/landmark-framework-stop branch June 11, 2026 16:08
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Symlink resolution pins Homebrew Cellar paths and rewrites distro aliases

1 participant