| /* Support for dynamic loading of extension modules */ | |
| #include "Python.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 | |
| those modules to get a function pointer to the module's init function. | |
| */ | |
| #ifdef HAVE_DYNAMIC_LOADING | |
| #include "importdl.h" | |
| extern dl_funcptr _PyImport_GetDynLoadFunc(const char *name, | |
| const char *shortname, | |
| const char *pathname, FILE *fp); | |
| PyObject * | |
| _PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp) | |
| { | |
| PyObject *m; | |
| char *lastdot, *shortname, *packagecontext, *oldcontext; | |
| dl_funcptr p; | |
| if ((m = _PyImport_FindExtension(name, pathname)) != NULL) { | |
| Py_INCREF(m); | |
| return m; | |
| } | |
| lastdot = strrchr(name, '.'); | |
| if (lastdot == NULL) { | |
| packagecontext = NULL; | |
| shortname = name; | |
| } | |
| else { | |
| packagecontext = name; | |
| shortname = lastdot+1; | |
| } | |
| p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp); | |
| if (PyErr_Occurred()) | |
| return NULL; | |
| if (p == NULL) { | |
| PyErr_Format(PyExc_ImportError, | |
| "dynamic module does not define init function (init%.200s)", | |
| shortname); | |
| return NULL; | |
| } | |
| oldcontext = _Py_PackageContext; | |
| _Py_PackageContext = packagecontext; | |
| (*p)(); | |
| _Py_PackageContext = oldcontext; | |
| if (PyErr_Occurred()) | |
| return NULL; | |
| m = PyDict_GetItemString(PyImport_GetModuleDict(), name); | |
| if (m == NULL) { | |
| PyErr_SetString(PyExc_SystemError, | |
| "dynamic module not initialized properly"); | |
| return NULL; | |
| } | |
| /* Remember the filename as the __file__ attribute */ | |
| if (PyModule_AddStringConstant(m, "__file__", pathname) < 0) | |
| PyErr_Clear(); /* Not important enough to report */ | |
| if (_PyImport_FixupExtension(name, pathname) == NULL) | |
| return NULL; | |
| if (Py_VerboseFlag) | |
| PySys_WriteStderr( | |
| "import %s # dynamically loaded from %s\n", | |
| name, pathname); | |
| Py_INCREF(m); | |
| return m; | |
| } | |
| #endif /* HAVE_DYNAMIC_LOADING */ |