From: Stefano Rivera Date: Mon, 27 Jul 2026 13:05:40 +0000 (-0700) Subject: gh-122931: Allow stable abi3 API extensions to include a multiarch tuple in the filen... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7961bbf2bbbd96679eba89419c34128481b9b0ff;p=thirdparty%2FPython%2Fcpython.git gh-122931: Allow stable abi3 API extensions to include a multiarch tuple in the filename (GH-152461) This permits stable ABI extensions for multiple architectures to be co-installed into the same directory, without clashing with each other, the same way (non-stable ABI) regular extensions can. It is listed before the current platform-less suffixes since it's more specific. The platform is stored in a new pyconfig.h define & sysconfig variable, SOABI_PLATFORM. On some known architectures (FreeBSD, Windows), this will be undefined/zero; these won't have the new tag (yet). Add SOABI_PLATFORM & ALT_SOABI the info to `make pythoninfo` as well. Co-authored-by: Petr Viktorin Co-authored-by: Victor Stinner --- diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index df2ca138db32..250558dd1341 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -873,6 +873,14 @@ Other language changes imports ``pkg.sub.mod``. (Contributed by Gregory P. Smith in :gh:`83065`.) +* File names of Stable ABI extensions that use the ``.so`` suffix may now + include a multiarch tuple, for example, ``foo.abi3-x86-64-linux-gnu.so``. + This permits stable ABI extensions for multiple architectures to be + co-installed into the same directory, without clashing with each + other, as regular dynamic extensions do. + (Contributed by Stefano Rivera in :gh:`122931`.) + + Default interactive shell ========================= diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 13a3199b1f12..ea7edb798051 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -570,6 +570,7 @@ def collect_sysconfig(info_add): for name in ( 'ABIFLAGS', + 'ALT_SOABI', 'ANDROID_API_LEVEL', 'CC', 'CCSHARED', @@ -595,6 +596,7 @@ def collect_sysconfig(info_add): 'Py_REMOTE_DEBUG', 'SHELL', 'SOABI', + 'SOABI_PLATFORM', 'TEST_MODULES', 'VAPTH', 'abs_builddir', @@ -1315,6 +1317,12 @@ def collect_system(info_add): info_add('system.hardware', hardware) +def collect_importlib(info_add): + import importlib.machinery + info_add('importlib.extension_suffixes', + importlib.machinery.EXTENSION_SUFFIXES) + + def collect_info(info): error = False info_add = info.add @@ -1357,6 +1365,7 @@ def collect_info(info): collect_zstd, collect_libregrtest_utils, collect_system, + collect_importlib, # Collecting from tests should be last as they have side effects. collect_test_socket, diff --git a/Lib/test/test_importlib/extension/test_finder.py b/Lib/test/test_importlib/extension/test_finder.py index dc77fa78a203..e33c04656546 100644 --- a/Lib/test/test_importlib/extension/test_finder.py +++ b/Lib/test/test_importlib/extension/test_finder.py @@ -5,6 +5,7 @@ machinery = util.import_importlib('importlib.machinery') import unittest import sys +import sysconfig class FinderTests(abc.FinderTests): @@ -61,6 +62,7 @@ class FinderTests(abc.FinderTests): def test_abi3_extension_suffixes(self): suffixes = self.machinery.EXTENSION_SUFFIXES + platform = sysconfig.get_config_var("SOABI_PLATFORM") if 'win32' in sys.platform: # Either "_d.pyd" or ".pyd" must be in suffixes self.assertTrue({"_d.pyd", ".pyd"}.intersection(suffixes)) @@ -73,6 +75,13 @@ class FinderTests(abc.FinderTests): self.assertIn(".abi3.so", suffixes) self.assertIn(".abi3t.so", suffixes) + if platform: + if Py_GIL_DISABLED: + self.assertNotIn(f".abi3-{platform}.so", suffixes) + else: + self.assertIn(f".abi3-{platform}.so", suffixes) + self.assertIn(f".abi3t-{platform}.so", suffixes) + (Frozen_FinderTests, Source_FinderTests diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index e6f99581f0b7..9bb3e326ff3e 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -457,6 +457,15 @@ class TestSysConfig(unittest.TestCase, VirtualEnvironmentMixin): soabi = sysconfig.get_config_var('SOABI') self.assertIn(soabi, _imp.extension_suffixes()[0]) + @unittest.skipIf(not _imp.extension_suffixes(), "stub loader has no suffixes") + @unittest.skipIf(sys.platform == "win32", "Does not apply to Windows") + @unittest.skipIf(sysconfig.get_config_var('SOABI_PLATFORM') == 0, + "SOABI_PLATFORM is undefined") + def test_soabi_platform(self): + soabi_platform = sysconfig.get_config_var('SOABI_PLATFORM') + soabi = sysconfig.get_config_var('SOABI') + self.assertIn(soabi_platform, soabi) + def test_library(self): library = sysconfig.get_config_var('LIBRARY') ldlibrary = sysconfig.get_config_var('LDLIBRARY') diff --git a/Misc/NEWS.d/next/C_API/2024-08-12-09-48-04.gh-issue-122931.x435Mb.rst b/Misc/NEWS.d/next/C_API/2024-08-12-09-48-04.gh-issue-122931.x435Mb.rst new file mode 100644 index 000000000000..ff972aaefc74 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-08-12-09-48-04.gh-issue-122931.x435Mb.rst @@ -0,0 +1 @@ +Allow importing stable ABI C extensions that include a multiarch tuple in their filename, e.g. ``foo.abi3-x86-64-linux-gnu.so``. diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 0ff88ad330fd..f7f7c9229200 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -46,8 +46,14 @@ const char *_PyImport_DynLoadFiletab[] = { "." ALT_SOABI ".so", #endif #ifndef Py_GIL_DISABLED +#ifdef SOABI_PLATFORM + ".abi" PYTHON_ABI_STRING "-" SOABI_PLATFORM ".so", +#endif /* SOABI_PLATFORM */ ".abi" PYTHON_ABI_STRING ".so", #endif /* Py_GIL_DISABLED */ +#ifdef SOABI_PLATFORM + ".abi" PYTHON_ABI_STRING "t-" SOABI_PLATFORM ".so", +#endif /* SOABI_PLATFORM */ ".abi" PYTHON_ABI_STRING "t.so", ".so", #endif /* __CYGWIN__ */ diff --git a/configure b/configure index dc23b9f7c20d..69d76f7b9f2d 100755 --- a/configure +++ b/configure @@ -7395,6 +7395,12 @@ case $ac_sys_system in #( ;; esac +if test x$SOABI_PLATFORM != x; then + +printf "%s\n" "#define SOABI_PLATFORM \"${SOABI_PLATFORM}\"" >>confdefs.h + +fi + if test x$MULTIARCH != x; then MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" fi diff --git a/configure.ac b/configure.ac index 5a59e70d64ba..93b211eef749 100644 --- a/configure.ac +++ b/configure.ac @@ -1221,6 +1221,10 @@ AS_CASE([$ac_sys_system], [SOABI_PLATFORM=$PLATFORM_TRIPLET] ) +if test x$SOABI_PLATFORM != x; then + AC_DEFINE_UNQUOTED([SOABI_PLATFORM], ["${SOABI_PLATFORM}"], [Platform tag, used in binary module extension filenames.]) +fi + if test x$MULTIARCH != x; then MULTIARCH_CPPFLAGS="-DMULTIARCH=\\\"$MULTIARCH\\\"" fi diff --git a/pyconfig.h.in b/pyconfig.h.in index 25c4842d25e8..2658fe811678 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1968,6 +1968,9 @@ /* The size of '_Bool', as computed by sizeof. */ #undef SIZEOF__BOOL +/* Platform tag, used in binary module extension filenames. */ +#undef SOABI_PLATFORM + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS