Skip to content

gh-156495: Compare normalized prefixes in site._venv() - #156496

Open
Gronoxx wants to merge 2 commits into
python:mainfrom
Gronoxx:fix/site-venv-false-positive-warning
Open

gh-156495: Compare normalized prefixes in site._venv()#156496
Gronoxx wants to merge 2 commits into
python:mainfrom
Gronoxx:fix/site-venv-false-positive-warning

Conversation

@Gronoxx

@Gronoxx Gronoxx commented Aug 27, 2026

Copy link
Copy Markdown

Fixes #156495.

site._venv() compares sys.prefix against a site_prefix built with os.path.abspath(), using string equality. abspath() normalizes and getpath does not, so a venv interpreter started through a path such as ../venv/bin/python reports two spurious RuntimeWarnings about prefixes that name the same directory.

This compares normalized forms instead. No observable value changes: sys.prefix, sys.exec_prefix and sys.executable are untouched, and the message still reports the original value. Only the condition for warning changes, and genuine mismatches still warn, including the one from #154160.

The check itself came from GH-126987 (gh-126985), by Filipe Laíns, which replaced the earlier sys.prefix = sys.exec_prefix = site_prefix assignment. The abspath() on the other side has been there since #60723 (bpo-16519), reported by Christian Heimes and fixed by Vinay Sajip, added so that invoking the interpreter through a relative path would work. Both do what they were meant to do. Only the string comparison between them is too strict.

Two tests are added, since there was no coverage of this warning in test_site.py or test_venv.py. The first fails without the change. The second pins down a genuine mismatch, so that a future change cannot silence the check altogether.

Verification

Bisected on clean venvs, invoking ../v/bin/python from a sibling directory:

version warnings sys.prefix sys.executable
3.11.15 0 /tmp/v /tmp/sub/../v/bin/python
3.12.13 0 /tmp/v /tmp/sub/../v/bin/python
3.13.15 0 /tmp/v /tmp/sub/../v/bin/python
3.14.7 2 /tmp/sub/../v /tmp/sub/../v/bin/python
3.15.0rc1 2 /tmp/sub/../v /tmp/sub/../v/bin/python

sys.executable is identical throughout. Only sys.prefix and the check are new.

Every case, measured on this branch with and without the change:

case before after
../v/bin/python from a sibling directory 2 0
the same with env -i (no PATH in the environment) 2 0
relative PATH entry (the #154160 symptom) 2 2
absolute invocation 0 0
//tmp/v/bin/python 0 0
.. in the middle of the path 0 0
pyvenv.cfg next to the interpreter 2 2

Test suite, before and after, on test_venv test_site test_sys test_getpath test_embed test_sysconfig test_cmd_line test_cmd_line_script test_import test_frozen test_posixpath test_ntpath: 12 of 12 modules pass either way, 874 tests before and 876 after, the difference being the two added here.

os.path.normpath is _path_normpath, a C builtin, at 549 ns per call. That is roughly 1 µs per interpreter start, and only inside a venv. I could not measure it above noise end to end.

@python-cla-bot

python-cla-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

subprocess only resolves a relative executable against its cwd argument
on POSIX, so the test failed with FileNotFoundError on Windows. Change
directory in the test process instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

site emits two spurious RuntimeWarnings when a venv interpreter is started via a non-normalized path (3.14 regression)

1 participant