diff Python/import.c @ 5926:8d2194e22e67 legacy-trunk

The last of the mass checkins for separate (sub)interpreters. Everything should now work again. See the comments for the .h files mass checkin (e.g. pystate.h) for more detail.
author Guido van Rossum <guido@python.org>
date Sat, 02 Aug 1997 03:10:38 +0000
parents e2df95b7be78
children 222faeb43d02
line wrap: on
line diff
--- a/Python/import.c	Sat Aug 02 03:07:46 1997 +0000
+++ b/Python/import.c	Sat Aug 02 03:10:38 1997 +0000
@@ -61,18 +61,15 @@
 /* New way to come up with the magic number: (YEAR-1995), MONTH, DAY */
 #define MAGIC (20121 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
-static PyObject *_PyImport_Modules; /* This becomes sys.modules */
+/* See _PyImport_FixupExtension() below */
+static PyObject *extensions = NULL;
 
 
 /* Initialize things */
 
 void
-PyImport_Init()
+_PyImport_Init()
 {
-	if (_PyImport_Modules != NULL)
-		Py_FatalError("duplicate initimport() call");
-	if ((_PyImport_Modules = PyDict_New()) == NULL)
-		Py_FatalError("no mem for dictionary of modules");
 	if (Py_OptimizeFlag) {
 		/* Replace ".pyc" with ".pyo" in import_filetab */
 		struct filedescr *p;
@@ -83,21 +80,44 @@
 	}
 }
 
+void
+_PyImport_Fini()
+{
+	Py_XDECREF(extensions);
+	extensions = NULL;
+}
+
+
+/* Helper for sys */
+
+PyObject *
+PyImport_GetModuleDict()
+{
+	PyInterpreterState *interp = PyThreadState_Get()->interp;
+	if (interp->modules == NULL)
+		Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
+	return interp->modules;
+}
+
 
 /* Un-initialize things, as good as we can */
 
 void
 PyImport_Cleanup()
 {
-	if (_PyImport_Modules != NULL) {
-		PyObject *tmp = _PyImport_Modules;
-		_PyImport_Modules = NULL;
-		/* This deletes all modules from sys.modules.
-		   When a module is deallocated, it in turn clears its
-		   dictionary, thus hopefully breaking any circular
-		   references between modules and between a module's
-		   dictionary and its functions.  Note that "import"
-		   will fail while we are cleaning up.  */
+	PyInterpreterState *interp = PyThreadState_Get()->interp;
+	PyObject *tmp = interp->modules;
+	if (tmp != NULL) {
+		int pos;
+		PyObject *key, *value;
+		interp->modules = NULL;
+		pos = 0;
+		while (PyDict_Next(tmp, &pos, &key, &value)) {
+			if (PyModule_Check(value)) {
+				PyObject *d = PyModule_GetDict(value);
+				PyDict_Clear(d);
+			}
+		}
 		PyDict_Clear(tmp);
 		Py_DECREF(tmp);
 	}
@@ -113,12 +133,70 @@
 }
 
 
-/* Helper for sysmodule.c -- return modules dictionary */
+/* Magic for extension modules (built-in as well as dynamically
+   loaded).  To prevent initializing an extension module more than
+   once, we keep a static dictionary 'extensions' keyed by module name
+   (for built-in modules) or by filename (for dynamically loaded
+   modules), containing these modules.  A copy od the module's
+   dictionary is stored by calling _PyImport_FixupExtension()
+   immediately after the module initialization function succeeds.  A
+   copy can be retrieved from there by calling
+   _PyImport_FindExtension(). */
 
 PyObject *
-PyImport_GetModuleDict()
+_PyImport_FixupExtension(name, filename)
+	char *name;
+	char *filename;
 {
-	return _PyImport_Modules;
+	PyObject *modules, *mod, *dict, *copy;
+	if (extensions == NULL) {
+		extensions = PyDict_New();
+		if (extensions == NULL)
+			return NULL;
+	}
+	modules = PyImport_GetModuleDict();
+	mod = PyDict_GetItemString(modules, name);
+	if (mod == NULL || !PyModule_Check(mod)) {
+		PyErr_SetString(PyExc_SystemError,
+				"_PyImport_FixupExtension: module not loaded");
+		return NULL;
+	}
+	dict = PyModule_GetDict(mod);
+	if (dict == NULL)
+		return NULL;
+	copy = PyObject_CallMethod(dict, "copy", "");
+	if (copy == NULL)
+		return NULL;
+	PyDict_SetItemString(extensions, filename, copy);
+	Py_DECREF(copy);
+	return copy;
+}
+
+PyObject *
+_PyImport_FindExtension(name, filename)
+	char *name;
+	char *filename;
+{
+	PyObject *dict, *mod, *mdict, *result;
+	if (extensions == NULL)
+		return NULL;
+	dict = PyDict_GetItemString(extensions, filename);
+	if (dict == NULL)
+		return NULL;
+	mod = PyImport_AddModule(name);
+	if (mod == NULL)
+		return NULL;
+	mdict = PyModule_GetDict(mod);
+	if (mdict == NULL)
+		return NULL;
+	result = PyObject_CallMethod(mdict, "update", "O", dict);
+	if (result == NULL)
+		return NULL;
+	Py_DECREF(result);
+	if (Py_VerboseFlag)
+		fprintf(stderr, "import %s # previously loaded (%s)\n",
+			name, filename);
+	return mod;
 }
 
 
@@ -132,20 +210,16 @@
 PyImport_AddModule(name)
 	char *name;
 {
+	PyObject *modules = PyImport_GetModuleDict();
 	PyObject *m;
 
-	if (_PyImport_Modules == NULL) {
-		PyErr_SetString(PyExc_SystemError,
-				"sys.modules has been deleted");
-		return NULL;
-	}
-	if ((m = PyDict_GetItemString(_PyImport_Modules, name)) != NULL &&
+	if ((m = PyDict_GetItemString(modules, name)) != NULL &&
 	    PyModule_Check(m))
 		return m;
 	m = PyModule_New(name);
 	if (m == NULL)
 		return NULL;
-	if (PyDict_SetItemString(_PyImport_Modules, name, m) != 0) {
+	if (PyDict_SetItemString(modules, name, m) != 0) {
 		Py_DECREF(m);
 		return NULL;
 	}
@@ -163,6 +237,7 @@
 	char *name;
 	PyObject *co;
 {
+	PyObject *modules = PyImport_GetModuleDict();
 	PyObject *m, *d, *v;
 
 	m = PyImport_AddModule(name);
@@ -183,7 +258,7 @@
 		return NULL;
 	Py_DECREF(v);
 
-	if ((m = PyDict_GetItemString(_PyImport_Modules, name)) == NULL) {
+	if ((m = PyDict_GetItemString(modules, name)) == NULL) {
 		PyErr_SetString(PyExc_SystemError,
 				"loaded module not found in sys.modules");
 		return NULL;
@@ -573,20 +648,27 @@
 init_builtin(name)
 	char *name;
 {
-	int i;
-	for (i = 0; _PyImport_Inittab[i].name != NULL; i++) {
-		if (strcmp(name, _PyImport_Inittab[i].name) == 0) {
-			if (_PyImport_Inittab[i].initfunc == NULL) {
+	PyInterpreterState *interp = PyThreadState_Get()->interp;
+	struct _inittab *p;
+	PyObject *mod;
+
+	if ((mod = _PyImport_FindExtension(name, name)) != NULL)
+		return 1;
+
+	for (p = _PyImport_Inittab; p->name != NULL; p++) {
+		if (strcmp(name, p->name) == 0) {
+			if (p->initfunc == NULL) {
 				PyErr_SetString(PyExc_ImportError,
 					   "Cannot re-init internal module");
 				return -1;
 			}
 			if (Py_VerboseFlag)
-				fprintf(stderr, "import %s # builtin\n",
-					name);
-			(*_PyImport_Inittab[i].initfunc)();
+				fprintf(stderr, "import %s # builtin\n", name);
+			(*p->initfunc)();
 			if (PyErr_Occurred())
 				return -1;
+			if (_PyImport_FixupExtension(name, name) == NULL)
+				return -1;
 			return 1;
 		}
 	}
@@ -666,14 +748,10 @@
 PyImport_ImportModule(name)
 	char *name;
 {
+	PyObject *modules = PyImport_GetModuleDict();
 	PyObject *m;
 
-	if (_PyImport_Modules == NULL) {
-		PyErr_SetString(PyExc_SystemError,
-				"sys.modules has been deleted");
-		return NULL;
-	}
-	if ((m = PyDict_GetItemString(_PyImport_Modules, name)) != NULL) {
+	if ((m = PyDict_GetItemString(modules, name)) != NULL) {
 		Py_INCREF(m);
 	}
 	else {
@@ -682,7 +760,7 @@
 		    (i = PyImport_ImportFrozenModule(name))) {
 			if (i < 0)
 				return NULL;
-			if ((m = PyDict_GetItemString(_PyImport_Modules,
+			if ((m = PyDict_GetItemString(modules,
 						      name)) == NULL) {
 			    if (PyErr_Occurred() == NULL)
 			        PyErr_SetString(PyExc_SystemError,
@@ -706,6 +784,7 @@
 PyImport_ReloadModule(m)
 	PyObject *m;
 {
+	PyObject *modules = PyImport_GetModuleDict();
 	char *name;
 	int i;
 
@@ -717,12 +796,7 @@
 	name = PyModule_GetName(m);
 	if (name == NULL)
 		return NULL;
-	if (_PyImport_Modules == NULL) {
-		PyErr_SetString(PyExc_SystemError,
-				"sys.modules has been deleted");
-		return NULL;
-	}
-	if (m != PyDict_GetItemString(_PyImport_Modules, name)) {
+	if (m != PyDict_GetItemString(modules, name)) {
 		PyErr_SetString(PyExc_ImportError,
 				"reload() module not in sys.modules");
 		return NULL;