Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7407fe4

Browse files
authored
bpo-46028: Calculate base_executable by resolving symlinks in a venv (GH-30144)
1 parent 3239829 commit 7407fe4

File tree

3 files changed

+47
-1
lines changed

3 files changed

+47
-1
lines changed

Lib/test/test_getpath.py

+32
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,38 @@ def test_venv_posix(self):
328328
actual = getpath(ns, expected)
329329
self.assertEqual(expected, actual)
330330

331+
def test_venv_changed_name_posix(self):
332+
"Test a venv layout on *nix."
333+
ns = MockPosixNamespace(
334+
argv0="python",
335+
PREFIX="/usr",
336+
ENV_PATH="/venv/bin:/usr/bin",
337+
)
338+
ns.add_known_xfile("/usr/bin/python3")
339+
ns.add_known_xfile("/venv/bin/python")
340+
ns.add_known_link("/venv/bin/python", "/usr/bin/python3")
341+
ns.add_known_file("/usr/lib/python9.8/os.py")
342+
ns.add_known_dir("/usr/lib/python9.8/lib-dynload")
343+
ns.add_known_file("/venv/pyvenv.cfg", [
344+
r"home = /usr/bin"
345+
])
346+
expected = dict(
347+
executable="/venv/bin/python",
348+
prefix="/usr",
349+
exec_prefix="/usr",
350+
base_executable="/usr/bin/python3",
351+
base_prefix="/usr",
352+
base_exec_prefix="/usr",
353+
module_search_paths_set=1,
354+
module_search_paths=[
355+
"/usr/lib/python98.zip",
356+
"/usr/lib/python9.8",
357+
"/usr/lib/python9.8/lib-dynload",
358+
],
359+
)
360+
actual = getpath(ns, expected)
361+
self.assertEqual(expected, actual)
362+
331363
def test_symlink_normal_posix(self):
332364
"Test a 'standard' install layout via symlink on *nix"
333365
ns = MockPosixNamespace(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixes calculation of :data:`sys._base_executable` when inside a virtual
2+
environment that uses symlinks with different binary names than the base
3+
environment provides.

Modules/getpath.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,18 @@ def search_up(prefix, *landmarks, test=isfile):
351351
key, had_equ, value = line.partition('=')
352352
if had_equ and key.strip().lower() == 'home':
353353
executable_dir = real_executable_dir = value.strip()
354-
base_executable = joinpath(executable_dir, basename(executable))
354+
if not base_executable:
355+
# First try to resolve symlinked executables, since that may be
356+
# more accurate than assuming the executable in 'home'.
357+
try:
358+
base_executable = realpath(executable)
359+
if base_executable == executable:
360+
# No change, so probably not a link. Clear it and fall back
361+
base_executable = ''
362+
except OSError:
363+
pass
364+
if not base_executable:
365+
base_executable = joinpath(executable_dir, basename(executable))
355366
break
356367
else:
357368
venv_prefix = None

0 commit comments

Comments
 (0)