diff options
author | Guido van Rossum <guido@python.org> | 1998-02-19 20:51:52 +0000 |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1998-02-19 20:51:52 +0000 |
commit | bd446962924feaed73c11b68fd4b1c1656679dad (patch) | |
tree | 22002af93768efe5dc108eec89e0a0aeda00030d /Objects/moduleobject.c | |
parent | e8ea7f5e2fe26d09f3ebd347df2214481df5f45c (diff) | |
download | cpython-bd446962924feaed73c11b68fd4b1c1656679dad.tar.gz |
Add internal routine _PyModule_Clear(), which does approximately what
clear_carefully() used to do in import.c. Differences: leave only
__builtins__ alone in the 2nd pass; and don't clear the dictionary (on
the theory that as long as there are references left to the
dictionary, those might be destructors that might expect __builtins__
to be alive when they run; and __builtins__ can't normally be part of
a cycle).
Diffstat (limited to 'Objects/moduleobject.c')
-rw-r--r-- | Objects/moduleobject.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 1ba1a1b705..7a41439360 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -93,6 +93,55 @@ PyModule_GetName(m) return PyString_AsString(nameobj); } +void +_PyModule_Clear(m) + PyObject *m; +{ + /* To make the execution order of destructors for global + objects a bit more predictable, we first zap all objects + whose name starts with a single underscore, before we clear + the entire dictionary. We zap them by replacing them with + None, rather than deleting them from the dictionary, to + avoid rehashing the dictionary (to some extent). */ + + int pos; + PyObject *key, *value; + PyObject *d; + + d = ((PyModuleObject *)m)->md_dict; + + /* First, clear only names starting with a single underscore */ + pos = 0; + 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 (Py_VerboseFlag > 1) + fprintf(stderr, "# clear[1] %s\n", s); + PyDict_SetItem(d, key, Py_None); + } + } + } + + /* Next, clear all names except for __builtins__ */ + pos = 0; + while (PyDict_Next(d, &pos, &key, &value)) { + if (value != Py_None && PyString_Check(key)) { + char *s = PyString_AsString(key); + if (s[0] != '_' || strcmp(s, "__builtins__") != 0) { + if (Py_VerboseFlag > 1) + fprintf(stderr, "# clear[2] %s\n", s); + PyDict_SetItem(d, key, Py_None); + } + } + } + + /* Note: we leave __builtins__ in place, so that destructors + of non-global objects defined in this module can still use + builtins, in particularly 'None'. */ + +} + /* Methods */ static void @@ -100,7 +149,7 @@ module_dealloc(m) PyModuleObject *m; { if (m->md_dict != NULL) { - PyDict_Clear(m->md_dict); + _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } free((char *)m); |