diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py index f86df9d0d03485..ca7cee0c39872a 100644 --- a/Lib/test/test_getpath.py +++ b/Lib/test/test_getpath.py @@ -1,7 +1,13 @@ import copy import ntpath +import os import pathlib import posixpath +import shutil +import subprocess +import sys +import sysconfig +import tempfile import unittest from test.support import verbose @@ -864,6 +870,37 @@ def test_PYTHONHOME_in_venv(self): actual = getpath(ns, expected) self.assertEqual(expected, actual) + +class RealGetPathTests(unittest.TestCase): + @unittest.skipUnless( + sysconfig.is_python_build(), + 'Test only available when running from the buildir', + ) + @unittest.skipUnless( + any(sys.platform.startswith(p) for p in ('linux', 'freebsd', 'centos')), + 'Test only support on Linux-like OS-es (support LD_LIBRARY_PATH)', + ) + @unittest.skipUnless( + sysconfig.get_config_var('LDLIBRARY') != sysconfig.get_config_var('LIBRARY'), + 'Test only available when using a dynamic libpython', + ) + def test_builddir_wrong_library_warning(self): + library_name = sysconfig.get_config_var('INSTSONAME') + with tempfile.TemporaryDirectory() as tmpdir: + shutil.copy2( + os.path.join(sysconfig.get_config_var('srcdir'), library_name), + os.path.join(tmpdir, library_name) + ) + env = os.environ.copy() + env['LD_LIBRARY_PATH'] = tmpdir + process = subprocess.run( + [sys.executable, '-c', ''], + env=env, check=True, capture_output=True, text=True, + ) + error_msg = 'The runtime library has been loaded from outside the build directory' + self.assertTrue(process.stderr.startswith(error_msg), process.stderr) + + # ****************************************************************************** DEFAULT_NAMESPACE = dict( diff --git a/Modules/getpath.py b/Modules/getpath.py index be2210345afbda..9d531e29becbc8 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -785,6 +785,19 @@ def search_up(prefix, *landmarks, test=isfile): base_exec_prefix = config.get('base_exec_prefix') or EXEC_PREFIX or base_prefix +# ****************************************************************************** +# MISC. RUNTIME WARNINGS +# ****************************************************************************** + +# When running Python from the build directory, if libpython is dynamically +# linked, the wrong library might be loaded. +if build_prefix and library and not dirname(abspath(library)).startswith(build_prefix): + msg = f'The runtime library has been loaded from outside the build directory ({library})!' + if os_name == 'posix': + msg += ' Consider setting LD_LIBRARY_PATH=. to force it to be loaded from the build directory.' + warn(msg) + + # ****************************************************************************** # SET pythonpath FROM _PTH FILE # ******************************************************************************