importdl.c 2.16 KB
Newer Older
1 2 3

/* Support for dynamic loading of extension modules */

4
#include "Python.h"
5

6 7 8 9
/* ./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.
10
*/
11
#ifdef HAVE_DYNAMIC_LOADING
12

13 14
#include "importdl.h"

15
extern dl_funcptr _PyImport_GetDynLoadFunc(const char *name,
16
					   const char *shortname,
17
					   const char *pathname, FILE *fp);
18

19

20

21
PyObject *
22
_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *fp)
23
{
24
	PyObject *m;
25
	PyObject *path;
26
	char *lastdot, *shortname, *packagecontext, *oldcontext;
27 28 29
	dl_funcptr p0;
	PyObject* (*p)(void);
	struct PyModuleDef *def;
30

31 32 33 34
	if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
		Py_INCREF(m);
		return m;
	}
35 36 37 38 39 40 41 42 43
	lastdot = strrchr(name, '.');
	if (lastdot == NULL) {
		packagecontext = NULL;
		shortname = name;
	}
	else {
		packagecontext = name;
		shortname = lastdot+1;
	}
44

45 46
	p0 = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
	p = (PyObject*(*)(void))p0;
47
	if (PyErr_Occurred())
48 49
		return NULL;
	if (p == NULL) {
50
		PyErr_Format(PyExc_ImportError,
51
		   "dynamic module does not define init function (PyInit_%.200s)",
52
			     shortname);
53 54
		return NULL;
	}
55
        oldcontext = _Py_PackageContext;
56
	_Py_PackageContext = packagecontext;
57
	m = (*p)();
58
	_Py_PackageContext = oldcontext;
59
	if (m == NULL)
60
		return NULL;
61

62 63 64 65 66
	if (PyErr_Occurred()) {
		Py_DECREF(m);
		PyErr_Format(PyExc_SystemError,
			     "initialization of %s raised unreported exception",
			     shortname);
67 68
		return NULL;
	}
69 70 71 72 73

	/* Remember pointer to module init function. */
	def = PyModule_GetDef(m);
	def->m_base.m_init = p;

Guido van Rossum's avatar
Guido van Rossum committed
74
	/* Remember the filename as the __file__ attribute */
75 76
	path = PyUnicode_DecodeFSDefault(pathname);
	if (PyModule_AddObject(m, "__file__", path) < 0)
77
		PyErr_Clear(); /* Not important enough to report */
78

79
	if (_PyImport_FixupExtension(m, name, pathname) < 0)
80
		return NULL;
81
	if (Py_VerboseFlag)
82
		PySys_WriteStderr(
83 84 85
			"import %s # dynamically loaded from %s\n",
			name, pathname);
	return m;
86
}
87 88

#endif /* HAVE_DYNAMIC_LOADING */