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'.
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: