Skip to content

Commit 29b3ce8

Browse files
FFY00ZeroIntensity
andauthored
GH-128469: warn when libpython was loaded from outside the build directory (#128645)
Co-authored-by: Peter Bierma <[email protected]>
1 parent a1a4e9f commit 29b3ce8

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

Lib/test/test_getpath.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import copy
22
import ntpath
3+
import os
34
import pathlib
45
import posixpath
6+
import shutil
7+
import subprocess
8+
import sys
9+
import sysconfig
10+
import tempfile
511
import unittest
612

713
from test.support import verbose
@@ -864,6 +870,37 @@ def test_PYTHONHOME_in_venv(self):
864870
actual = getpath(ns, expected)
865871
self.assertEqual(expected, actual)
866872

873+
874+
class RealGetPathTests(unittest.TestCase):
875+
@unittest.skipUnless(
876+
sysconfig.is_python_build(),
877+
'Test only available when running from the buildir',
878+
)
879+
@unittest.skipUnless(
880+
any(sys.platform.startswith(p) for p in ('linux', 'freebsd', 'centos')),
881+
'Test only support on Linux-like OS-es (support LD_LIBRARY_PATH)',
882+
)
883+
@unittest.skipUnless(
884+
sysconfig.get_config_var('LDLIBRARY') != sysconfig.get_config_var('LIBRARY'),
885+
'Test only available when using a dynamic libpython',
886+
)
887+
def test_builddir_wrong_library_warning(self):
888+
library_name = sysconfig.get_config_var('INSTSONAME')
889+
with tempfile.TemporaryDirectory() as tmpdir:
890+
shutil.copy2(
891+
os.path.join(sysconfig.get_config_var('srcdir'), library_name),
892+
os.path.join(tmpdir, library_name)
893+
)
894+
env = os.environ.copy()
895+
env['LD_LIBRARY_PATH'] = tmpdir
896+
process = subprocess.run(
897+
[sys.executable, '-c', ''],
898+
env=env, check=True, capture_output=True, text=True,
899+
)
900+
error_msg = 'The runtime library has been loaded from outside the build directory'
901+
self.assertTrue(process.stderr.startswith(error_msg), process.stderr)
902+
903+
867904
# ******************************************************************************
868905

869906
DEFAULT_NAMESPACE = dict(

Modules/getpath.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,19 @@ def search_up(prefix, *landmarks, test=isfile):
785785
base_exec_prefix = config.get('base_exec_prefix') or EXEC_PREFIX or base_prefix
786786

787787

788+
# ******************************************************************************
789+
# MISC. RUNTIME WARNINGS
790+
# ******************************************************************************
791+
792+
# When running Python from the build directory, if libpython is dynamically
793+
# linked, the wrong library might be loaded.
794+
if build_prefix and library and not dirname(abspath(library)).startswith(build_prefix):
795+
msg = f'The runtime library has been loaded from outside the build directory ({library})!'
796+
if os_name == 'posix':
797+
msg += ' Consider setting LD_LIBRARY_PATH=. to force it to be loaded from the build directory.'
798+
warn(msg)
799+
800+
788801
# ******************************************************************************
789802
# SET pythonpath FROM _PTH FILE
790803
# ******************************************************************************

0 commit comments

Comments
 (0)