summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-02-06 17:16:02 (GMT)
committerGuido van Rossum <guido@python.org>1998-02-06 17:16:02 (GMT)
commita0fec2b5df6827300bf80511a1fd6596e6f71e21 (patch)
tree5352a8afa99f87bebe54b1207bb18af3765a30cf
parent8ee4a60c70df6ed9ee1afefae2bb71aaae8d291a (diff)
downloadcpython-a0fec2b5df6827300bf80511a1fd6596e6f71e21.zip
cpython-a0fec2b5df6827300bf80511a1fd6596e6f71e21.tar.gz
cpython-a0fec2b5df6827300bf80511a1fd6596e6f71e21.tar.bz2
Two more refinements of the cleanup process.
(1) Explicitly clear __builtin__._ and sys.{last,exc}_* before clearing anything else. These are common places where user values hide and people complain when their destructors fail. Since the modules containing them are deleted *last* of all, they would come too late in the normal destruction order. Sigh. (2) Add some debugging aid to cleanup (after a suggestion by Marc Lemburg) -- print the names of the modules being cleaned, and (when -vv is used) print the names of the variables being cleared.
-rw-r--r--Python/import.c55
1 files changed, 52 insertions, 3 deletions
diff --git a/Python/import.c b/Python/import.c
index 224a3bc..9dbbd25 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -148,8 +148,11 @@ clear_carefully(d)
while (PyDict_Next(d, &pos, &key, &value)) {
if (value != Py_None && PyString_Check(key)) {
char *s = PyString_AsString(key);
- if (s[0] == '_' && s[1] != '_')
+ if (s[0] == '_' && s[1] != '_') {
+ if (Py_VerboseFlag > 1)
+ fprintf(stderr, "# clear[1] %s\n", s);
PyDict_SetItem(d, key, Py_None);
+ }
}
}
@@ -158,8 +161,11 @@ clear_carefully(d)
while (PyDict_Next(d, &pos, &key, &value)) {
if (value != Py_None && PyString_Check(key)) {
char *s = PyString_AsString(key);
- if (s[0] != '_' || s[1] != '_')
+ if (s[0] != '_' || s[1] != '_') {
+ if (Py_VerboseFlag > 1)
+ fprintf(stderr, "# clear[2] %s\n", s);
PyDict_SetItem(d, key, Py_None);
+ }
}
}
@@ -169,6 +175,14 @@ clear_carefully(d)
}
+/* List of names to clear in sys */
+static char* sys_deletes[] = {
+ "exc_type", "exc_value", "exc_traceback",
+ "last_type", "last_value", "last_traceback",
+ NULL
+};
+
+
/* Un-initialize things, as good as we can */
void
@@ -183,6 +197,30 @@ PyImport_Cleanup()
if (modules == NULL)
return; /* Already done */
+ /* Delete some special variables first. These are common
+ places where user values hide and people complain when their
+ destructors fail. Since the modules containing them are
+ deleted *last* of all, they would come too late in the normal
+ destruction order. Sigh. */
+
+ value = PyDict_GetItemString(modules, "__builtin__");
+ if (value != NULL && PyModule_Check(value)) {
+ dict = PyModule_GetDict(value);
+ if (Py_VerboseFlag)
+ fprintf(stderr, "# clear __builtin__._\n");
+ PyDict_SetItemString(dict, "_", Py_None);
+ }
+ value = PyDict_GetItemString(modules, "sys");
+ if (value != NULL && PyModule_Check(value)) {
+ char **p;
+ dict = PyModule_GetDict(value);
+ for (p = sys_deletes; *p != NULL; p++) {
+ if (Py_VerboseFlag)
+ fprintf(stderr, "# clear sys.%s\n", *p);
+ PyDict_SetItemString(dict, *p, Py_None);
+ }
+ }
+
/* The special treatment of __builtin__ here is because even
when it's not referenced as a module, its dictionary is
referenced by almost every module's __builtins__. Since
@@ -212,6 +250,9 @@ PyImport_Cleanup()
continue;
if (strcmp(name, "sys") == 0)
continue;
+ if (Py_VerboseFlag)
+ fprintf(stderr,
+ "# cleanup[1] %s\n", name);
clear_carefully(dict);
PyDict_SetItem(modules, key, Py_None);
ndone++;
@@ -223,6 +264,8 @@ PyImport_Cleanup()
value = PyDict_GetItemString(modules, "__main__");
if (value != NULL && PyModule_Check(value)) {
dict = PyModule_GetDict(value);
+ if (Py_VerboseFlag)
+ fprintf(stderr, "# cleanup __main__\n");
clear_carefully(dict);
PyDict_SetItemString(modules, "__main__", Py_None);
}
@@ -237,6 +280,8 @@ PyImport_Cleanup()
continue;
if (strcmp(name, "sys") == 0)
continue;
+ if (Py_VerboseFlag)
+ fprintf(stderr, "# cleanup[2] %s\n", name);
clear_carefully(dict);
PyDict_SetItem(modules, key, Py_None);
}
@@ -246,13 +291,17 @@ PyImport_Cleanup()
value = PyDict_GetItemString(modules, "sys");
if (value != NULL && PyModule_Check(value)) {
dict = PyModule_GetDict(value);
+ if (Py_VerboseFlag)
+ fprintf(stderr, "# cleanup sys\n");
clear_carefully(dict);
PyDict_SetItemString(modules, "sys", Py_None);
}
value = PyDict_GetItemString(modules, "__builtin__");
if (value != NULL && PyModule_Check(value)) {
dict = PyModule_GetDict(value);
- clear_carefully(dict);
+ if (Py_VerboseFlag)
+ fprintf(stderr, "# cleanup __builtin__\n");
+ clear_carefully(dict); /* XXX Is this necessary? */
PyDict_SetItemString(modules, "__builtin__", Py_None);
}