Mercurial > cpython-lru_cache-weakref
diff Python/import.c @ 7202:fed3d200fb56 legacy-trunk
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.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Fri, 06 Feb 1998 17:16:02 +0000 |
| parents | f063f1eb2964 |
| children | 74c57288a02b |
line wrap: on
line diff
--- a/Python/import.c Fri Feb 06 16:01:52 1998 +0000 +++ b/Python/import.c Fri Feb 06 17:16:02 1998 +0000 @@ -148,8 +148,11 @@ 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 @@ 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 @@ } +/* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); }
