importdl.c 1.95 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
	char *lastdot, *shortname, *packagecontext, *oldcontext;
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
        oldcontext = _Py_PackageContext;
52
	_Py_PackageContext = packagecontext;
53
	(*p)();
54
	_Py_PackageContext = oldcontext;
55 56 57 58
	if (PyErr_Occurred())
		return NULL;
	if (_PyImport_FixupExtension(name, pathname) == NULL)
		return NULL;
59

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

#endif /* HAVE_DYNAMIC_LOADING */