]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-128469: warn when libpython was loaded from outside the build directory (#128645)
authorFilipe Laíns 🇵🇸 <lains@riseup.net>
Wed, 29 Jan 2025 22:35:55 +0000 (22:35 +0000)
committerGitHub <noreply@github.com>
Wed, 29 Jan 2025 22:35:55 +0000 (22:35 +0000)
Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
Lib/test/test_getpath.py
Modules/getpath.py

index f86df9d0d03485e874763d010150368aaf711ac5..ca7cee0c39872a185b685b9facce55f7fe43fd0c 100644 (file)
@@ -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 @@ class MockGetPathTests(unittest.TestCase):
         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(
index be2210345afbda5645a3a54ad93e1211fb5b6a46..9d531e29becbc8e9f7515df8ac306ef4f4cac2b8 100644 (file)
@@ -785,6 +785,19 @@ if os_name != 'nt' and build_prefix:
     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
 # ******************************************************************************