importdl.c 1.98 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, *d, *s;
25
	char *lastdot, *shortname, *packagecontext;
26
	dl_funcptr p;
27

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

42
	p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
43
	if (PyErr_Occurred())
44 45
		return NULL;
	if (p == NULL) {
46
		PyErr_Format(PyExc_ImportError,
47 48
		   "dynamic module does not define init function (init%.200s)",
			     shortname);
49 50
		return NULL;
	}
51
	_Py_PackageContext = packagecontext;
52
	(*p)();
53
	_Py_PackageContext = NULL;
54 55 56 57
	if (PyErr_Occurred())
		return NULL;
	if (_PyImport_FixupExtension(name, pathname) == NULL)
		return NULL;
58

59
	m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
60
	if (m == NULL) {
61 62
		PyErr_SetString(PyExc_SystemError,
				"dynamic module not initialized properly");
63 64
		return NULL;
	}
Guido van Rossum's avatar
Guido van Rossum committed
65
	/* Remember the filename as the __file__ attribute */
66 67 68 69 70 71
	d = PyModule_GetDict(m);
	s = PyString_FromString(pathname);
	if (s == NULL || PyDict_SetItemString(d, "__file__", s) != 0)
		PyErr_Clear(); /* Not important enough to report */
	Py_XDECREF(s);
	if (Py_VerboseFlag)
72
		PySys_WriteStderr(
73 74
			"import %s # dynamically loaded from %s\n",
			name, pathname);
75
	Py_INCREF(m);
76
	return m;
77
}
78 79

#endif /* HAVE_DYNAMIC_LOADING */