diff --git a/Include/internal/pycore_importdl.h b/Include/internal/pycore_importdl.h index e5f222b371a113..525a16f6b97274 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 5bbcb376a4a6b3..1b76328429f63a 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 00000000000000..88c872f4ef45f4 --- /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 964648338394c2..996ca7ed2a3108 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 @@ _PyImport_RunModInitFunc(PyModInitFunction p0, 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 a9fee4981ea915..cef97a4799ec4b 100644 --- a/Tools/build/check_extension_modules.py +++ b/Tools/build/check_extension_modules.py @@ -27,6 +27,7 @@ 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 @@ def __init__(self, cross_compiling: bool = False, strict: bool = False): 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 @@ def check_module_import(self, modinfo: ModuleInfo): 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