From ee1b8ce26e700350e47a5f65201097121c41912e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 13 Aug 2024 14:44:57 -0600 Subject: gh-122907: Fix Builds Without HAVE_DYNAMIC_LOADING Set (gh-122952) As of 529a160 (gh-118204), building with HAVE_DYNAMIC_LOADING stopped working. This is a minimal fix just to get builds working again. There are actually a number of long-standing deficiencies with HAVE_DYNAMIC_LOADING builds that need to be resolved separately. --- Include/internal/pycore_importdl.h | 4 ++++ Lib/importlib/_bootstrap_external.py | 16 ++++++++-------- .../2024-08-12-11-19-37.gh-issue-122907.q68096.rst | 3 +++ Python/importdl.c | 12 ++++++++---- Tools/build/check_extension_modules.py | 9 +++++++++ 5 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst diff --git a/Include/internal/pycore_importdl.h b/Include/internal/pycore_importdl.h index e5f222b..525a16f 100644 --- a/Include/internal/pycore_importdl.h +++ b/Include/internal/pycore_importdl.h @@ -56,9 +56,11 @@ extern int _Py_ext_module_loader_info_init_for_core( extern int _Py_ext_module_loader_info_init_for_builtin( struct _Py_ext_module_loader_info *p_info, PyObject *name); +#ifdef HAVE_DYNAMIC_LOADING extern int _Py_ext_module_loader_info_init_from_spec( struct _Py_ext_module_loader_info *info, PyObject *spec); +#endif /* The result from running an extension module's init function. */ struct _Py_ext_module_loader_result { @@ -87,9 +89,11 @@ extern void _Py_ext_module_loader_result_apply_error( /* The module init function. */ typedef PyObject *(*PyModInitFunction)(void); +#ifdef HAVE_DYNAMIC_LOADING extern PyModInitFunction _PyImport_GetModInitFunc( struct _Py_ext_module_loader_info *info, FILE *fp); +#endif extern int _PyImport_RunModInitFunc( PyModInitFunction p0, struct _Py_ext_module_loader_info *info, diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 5bbcb37..1b76328 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1523,14 +1523,14 @@ def _get_supported_file_loaders(): Each item is a tuple (loader, suffixes). """ - if sys.platform in {"ios", "tvos", "watchos"}: - extension_loaders = [(AppleFrameworkLoader, [ - suffix.replace(".so", ".fwork") - for suffix in _imp.extension_suffixes() - ])] - else: - extension_loaders = [] - extension_loaders.append((ExtensionFileLoader, _imp.extension_suffixes())) + extension_loaders = [] + if hasattr(_imp, 'create_dynamic'): + if sys.platform in {"ios", "tvos", "watchos"}: + extension_loaders = [(AppleFrameworkLoader, [ + suffix.replace(".so", ".fwork") + for suffix in _imp.extension_suffixes() + ])] + extension_loaders.append((ExtensionFileLoader, _imp.extension_suffixes())) source = SourceFileLoader, SOURCE_SUFFIXES bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES return extension_loaders + [source, bytecode] diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst new file mode 100644 index 0000000..88c872f --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-08-12-11-19-37.gh-issue-122907.q68096.rst @@ -0,0 +1,3 @@ +Building with ``HAVE_DYNAMIC_LOADING`` now works as well as it did in 3.12. +Existing deficiences will be addressed separately. +(See https://github.com/python/cpython/issues/122950.) diff --git a/Python/importdl.c b/Python/importdl.c index 9646483..996ca7e 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -8,6 +8,8 @@ #include "pycore_pystate.h" #include "pycore_runtime.h" +#include "pycore_importdl.h" + /* ./configure sets HAVE_DYNAMIC_LOADING if dynamic loading of modules is supported on this platform. configure will then compile and link in one of the dynload_*.c files, as appropriate. We will call a function in @@ -15,8 +17,6 @@ */ #ifdef HAVE_DYNAMIC_LOADING -#include "pycore_importdl.h" - #ifdef MS_WINDOWS extern dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, const char *shortname, @@ -28,6 +28,8 @@ extern dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix, const char *pathname, FILE *fp); #endif +#endif /* HAVE_DYNAMIC_LOADING */ + /***********************************/ /* module info to use when loading */ @@ -205,6 +207,7 @@ _Py_ext_module_loader_info_init_for_core( return 0; } +#ifdef HAVE_DYNAMIC_LOADING int _Py_ext_module_loader_info_init_from_spec( struct _Py_ext_module_loader_info *p_info, @@ -226,6 +229,7 @@ _Py_ext_module_loader_info_init_from_spec( Py_DECREF(filename); return err; } +#endif /* HAVE_DYNAMIC_LOADING */ /********************************/ @@ -372,6 +376,7 @@ _Py_ext_module_loader_result_apply_error( /* getting/running the module init function */ /********************************************/ +#ifdef HAVE_DYNAMIC_LOADING PyModInitFunction _PyImport_GetModInitFunc(struct _Py_ext_module_loader_info *info, FILE *fp) @@ -406,6 +411,7 @@ _PyImport_GetModInitFunc(struct _Py_ext_module_loader_info *info, return (PyModInitFunction)exportfunc; } +#endif /* HAVE_DYNAMIC_LOADING */ int _PyImport_RunModInitFunc(PyModInitFunction p0, @@ -513,5 +519,3 @@ error: p_res->err = &p_res->_err; return -1; } - -#endif /* HAVE_DYNAMIC_LOADING */ diff --git a/Tools/build/check_extension_modules.py b/Tools/build/check_extension_modules.py index a9fee49..cef97a4 100644 --- a/Tools/build/check_extension_modules.py +++ b/Tools/build/check_extension_modules.py @@ -27,6 +27,7 @@ import re import sys import sysconfig import warnings +import _imp from importlib._bootstrap import _load as bootstrap_load from importlib.machinery import BuiltinImporter, ExtensionFileLoader, ModuleSpec @@ -153,6 +154,11 @@ class ModuleChecker: self.notavailable = [] def check(self): + if not hasattr(_imp, 'create_dynamic'): + logger.warning( + ('Dynamic extensions not supported ' + '(HAVE_DYNAMIC_LOADING not defined)'), + ) for modinfo in self.modules: logger.debug("Checking '%s' (%s)", modinfo.name, self.get_location(modinfo)) if modinfo.state == ModuleState.DISABLED: @@ -414,6 +420,9 @@ class ModuleChecker: logger.error("%s failed to import: %s", modinfo.name, e) raise except Exception as e: + if not hasattr(_imp, 'create_dynamic'): + logger.warning("Dynamic extension '%s' ignored", modinfo.name) + return logger.exception("Importing extension '%s' failed!", modinfo.name) raise -- cgit v0.12