From 5fe0a39b66c8bd57aa60ac72f4415532e6b39dab Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Tue, 24 Jun 2025 16:28:13 -0700 Subject: [PATCH] feat: relative venv home path --- Lib/test/test_getpath.py | 36 ++++++++++++++++++++++++++++++++++++ Modules/getpath.py | 5 ++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py index f86df9d0d03485..01b8179358844c 100644 --- a/Lib/test/test_getpath.py +++ b/Lib/test/test_getpath.py @@ -354,6 +354,42 @@ def test_venv_posix(self): actual = getpath(ns, expected) self.assertEqual(expected, actual) + def test_venv_relative_home(self): + ns = MockPosixNamespace( + argv0="/somedir/venv/bin/python3", + PREFIX="/usr/local-fallback", + ENV_PATH="/usr/bin", + ) + + ns.add_known_xfile("/somedir/runtime/bin/python3") + ns.add_known_file("/somedir/runtime/lib/python9.8/os.py") + ns.add_known_dir("/somedir/runtime/lib/python9.8/lib-dynload") + + ns.add_known_xfile("/somedir/venv/bin/python3") + # NOTE: Normally a relative symlink would be used, but the mock + # realpath() doesn't handle relative symlinks, so point it to + # where it ultimately would resolve to. + ns.add_known_link("/somedir/venv/bin/python3", "/somedir/runtime/bin/python3") + ns.add_known_file("/somedir/venv/pyvenv.cfg", [ + "home = ../runtime/bin" + ]) + expected = dict( + executable="/somedir/venv/bin/python3", + prefix="/somedir/venv", + exec_prefix="/somedir/venv", + base_executable="/somedir/runtime/bin/python3", + base_prefix="/somedir/runtime", + base_exec_prefix="/somedir/runtime", + module_search_paths_set=1, + module_search_paths=[ + "/somedir/runtime/lib/python98.zip", + "/somedir/runtime/lib/python9.8", + "/somedir/runtime/lib/python9.8/lib-dynload", + ], + ) + actual = getpath(ns, expected) + self.assertEqual(expected, actual) + def test_venv_changed_name_posix(self): "Test a venv layout on *nix." ns = MockPosixNamespace( diff --git a/Modules/getpath.py b/Modules/getpath.py index be2210345afbda..03a3a6b27e71ba 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -374,10 +374,13 @@ def search_up(prefix, *landmarks, test=isfile): # If PYTHONHOME was set, ignore 'home' from pyvenv.cfg. if home: break + value = value.strip() + if not isabs(value): + value = realpath(joinpath(venv_prefix, value)) # Override executable_dir/real_executable_dir with the value from 'home'. # These values may be later used to calculate prefix/base_prefix, if a more # reliable source — like the runtime library (libpython) path — isn't available. - executable_dir = real_executable_dir = value.strip() + executable_dir = real_executable_dir = value # If base_executable — which points to the Python interpreted from # the base installation — isn't set (eg. when embedded), try to find # it in 'home'. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy