Skip to content

Commit dff1ad5

Browse files
authored
bpo-42208: Move _PyImport_Cleanup() to pylifecycle.c (GH-23040)
Move _PyImport_Cleanup() to pylifecycle.c, rename it to finalize_modules(), split it (200 lines) into many smaller sub-functions and cleanup the code.
1 parent 8b34148 commit dff1ad5

File tree

2 files changed

+290
-230
lines changed

2 files changed

+290
-230
lines changed

Python/import.c

-227
Original file line numberDiff line numberDiff line change
@@ -406,233 +406,6 @@ import_ensure_initialized(PyThreadState *tstate, PyObject *mod, PyObject *name)
406406
}
407407

408408

409-
/* List of names to clear in sys */
410-
static const char * const sys_deletes[] = {
411-
"path", "argv", "ps1", "ps2",
412-
"last_type", "last_value", "last_traceback",
413-
"path_hooks", "path_importer_cache", "meta_path",
414-
"__interactivehook__",
415-
NULL
416-
};
417-
418-
static const char * const sys_files[] = {
419-
"stdin", "__stdin__",
420-
"stdout", "__stdout__",
421-
"stderr", "__stderr__",
422-
NULL
423-
};
424-
425-
/* Un-initialize things, as good as we can */
426-
427-
void
428-
_PyImport_Cleanup(PyThreadState *tstate)
429-
{
430-
PyInterpreterState *interp = tstate->interp;
431-
PyObject *modules = interp->modules;
432-
if (modules == NULL) {
433-
/* Already done */
434-
return;
435-
}
436-
437-
/* Delete some special variables first. These are common
438-
places where user values hide and people complain when their
439-
destructors fail. Since the modules containing them are
440-
deleted *last* of all, they would come too late in the normal
441-
destruction order. Sigh. */
442-
443-
/* XXX Perhaps these precautions are obsolete. Who knows? */
444-
445-
int verbose = _PyInterpreterState_GetConfig(interp)->verbose;
446-
if (verbose) {
447-
PySys_WriteStderr("# clear builtins._\n");
448-
}
449-
if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) {
450-
PyErr_WriteUnraisable(NULL);
451-
}
452-
453-
const char * const *p;
454-
for (p = sys_deletes; *p != NULL; p++) {
455-
if (verbose) {
456-
PySys_WriteStderr("# clear sys.%s\n", *p);
457-
}
458-
if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) {
459-
PyErr_WriteUnraisable(NULL);
460-
}
461-
}
462-
for (p = sys_files; *p != NULL; p+=2) {
463-
if (verbose) {
464-
PySys_WriteStderr("# restore sys.%s\n", *p);
465-
}
466-
PyObject *value = _PyDict_GetItemStringWithError(interp->sysdict,
467-
*(p+1));
468-
if (value == NULL) {
469-
if (_PyErr_Occurred(tstate)) {
470-
PyErr_WriteUnraisable(NULL);
471-
}
472-
value = Py_None;
473-
}
474-
if (PyDict_SetItemString(interp->sysdict, *p, value) < 0) {
475-
PyErr_WriteUnraisable(NULL);
476-
}
477-
}
478-
479-
/* We prepare a list which will receive (name, weakref) tuples of
480-
modules when they are removed from sys.modules. The name is used
481-
for diagnosis messages (in verbose mode), while the weakref helps
482-
detect those modules which have been held alive. */
483-
PyObject *weaklist = PyList_New(0);
484-
if (weaklist == NULL) {
485-
PyErr_WriteUnraisable(NULL);
486-
}
487-
488-
#define STORE_MODULE_WEAKREF(name, mod) \
489-
if (weaklist != NULL) { \
490-
PyObject *wr = PyWeakref_NewRef(mod, NULL); \
491-
if (wr) { \
492-
PyObject *tup = PyTuple_Pack(2, name, wr); \
493-
if (!tup || PyList_Append(weaklist, tup) < 0) { \
494-
PyErr_WriteUnraisable(NULL); \
495-
} \
496-
Py_XDECREF(tup); \
497-
Py_DECREF(wr); \
498-
} \
499-
else { \
500-
PyErr_WriteUnraisable(NULL); \
501-
} \
502-
}
503-
#define CLEAR_MODULE(name, mod) \
504-
if (PyModule_Check(mod)) { \
505-
if (verbose && PyUnicode_Check(name)) { \
506-
PySys_FormatStderr("# cleanup[2] removing %U\n", name); \
507-
} \
508-
STORE_MODULE_WEAKREF(name, mod); \
509-
if (PyObject_SetItem(modules, name, Py_None) < 0) { \
510-
PyErr_WriteUnraisable(NULL); \
511-
} \
512-
}
513-
514-
/* Remove all modules from sys.modules, hoping that garbage collection
515-
can reclaim most of them. */
516-
if (PyDict_CheckExact(modules)) {
517-
Py_ssize_t pos = 0;
518-
PyObject *key, *value;
519-
while (PyDict_Next(modules, &pos, &key, &value)) {
520-
CLEAR_MODULE(key, value);
521-
}
522-
}
523-
else {
524-
PyObject *iterator = PyObject_GetIter(modules);
525-
if (iterator == NULL) {
526-
PyErr_WriteUnraisable(NULL);
527-
}
528-
else {
529-
PyObject *key;
530-
while ((key = PyIter_Next(iterator))) {
531-
PyObject *value = PyObject_GetItem(modules, key);
532-
if (value == NULL) {
533-
PyErr_WriteUnraisable(NULL);
534-
continue;
535-
}
536-
CLEAR_MODULE(key, value);
537-
Py_DECREF(value);
538-
Py_DECREF(key);
539-
}
540-
if (PyErr_Occurred()) {
541-
PyErr_WriteUnraisable(NULL);
542-
}
543-
Py_DECREF(iterator);
544-
}
545-
}
546-
547-
/* Clear the modules dict. */
548-
if (PyDict_CheckExact(modules)) {
549-
PyDict_Clear(modules);
550-
}
551-
else {
552-
_Py_IDENTIFIER(clear);
553-
if (_PyObject_CallMethodIdNoArgs(modules, &PyId_clear) == NULL) {
554-
PyErr_WriteUnraisable(NULL);
555-
}
556-
}
557-
/* Restore the original builtins dict, to ensure that any
558-
user data gets cleared. */
559-
PyObject *dict = PyDict_Copy(interp->builtins);
560-
if (dict == NULL) {
561-
PyErr_WriteUnraisable(NULL);
562-
}
563-
PyDict_Clear(interp->builtins);
564-
if (PyDict_Update(interp->builtins, interp->builtins_copy)) {
565-
_PyErr_Clear(tstate);
566-
}
567-
Py_XDECREF(dict);
568-
/* Collect references */
569-
_PyGC_CollectNoFail(tstate);
570-
/* Dump GC stats before it's too late, since it uses the warnings
571-
machinery. */
572-
_PyGC_DumpShutdownStats(tstate);
573-
574-
/* Now, if there are any modules left alive, clear their globals to
575-
minimize potential leaks. All C extension modules actually end
576-
up here, since they are kept alive in the interpreter state.
577-
578-
The special treatment of "builtins" here is because even
579-
when it's not referenced as a module, its dictionary is
580-
referenced by almost every module's __builtins__. Since
581-
deleting a module clears its dictionary (even if there are
582-
references left to it), we need to delete the "builtins"
583-
module last. Likewise, we don't delete sys until the very
584-
end because it is implicitly referenced (e.g. by print). */
585-
if (weaklist != NULL) {
586-
Py_ssize_t i;
587-
/* Since dict is ordered in CPython 3.6+, modules are saved in
588-
importing order. First clear modules imported later. */
589-
for (i = PyList_GET_SIZE(weaklist) - 1; i >= 0; i--) {
590-
PyObject *tup = PyList_GET_ITEM(weaklist, i);
591-
PyObject *name = PyTuple_GET_ITEM(tup, 0);
592-
PyObject *mod = PyWeakref_GET_OBJECT(PyTuple_GET_ITEM(tup, 1));
593-
if (mod == Py_None)
594-
continue;
595-
assert(PyModule_Check(mod));
596-
dict = PyModule_GetDict(mod);
597-
if (dict == interp->builtins || dict == interp->sysdict)
598-
continue;
599-
Py_INCREF(mod);
600-
if (verbose && PyUnicode_Check(name)) {
601-
PySys_FormatStderr("# cleanup[3] wiping %U\n", name);
602-
}
603-
_PyModule_Clear(mod);
604-
Py_DECREF(mod);
605-
}
606-
Py_DECREF(weaklist);
607-
}
608-
609-
/* Next, delete sys and builtins (in that order) */
610-
if (verbose) {
611-
PySys_FormatStderr("# cleanup[3] wiping sys\n");
612-
}
613-
_PyModule_ClearDict(interp->sysdict);
614-
if (verbose) {
615-
PySys_FormatStderr("# cleanup[3] wiping builtins\n");
616-
}
617-
_PyModule_ClearDict(interp->builtins);
618-
619-
/* Clear module dict copies stored in the interpreter state */
620-
_PyInterpreterState_ClearModules(interp);
621-
622-
/* Clear and delete the modules directory. Actual modules will
623-
still be there only if imported during the execution of some
624-
destructor. */
625-
interp->modules = NULL;
626-
Py_DECREF(modules);
627-
628-
/* Once more */
629-
_PyGC_CollectNoFail(tstate);
630-
631-
#undef CLEAR_MODULE
632-
#undef STORE_MODULE_WEAKREF
633-
}
634-
635-
636409
/* Helper for pythonrun.c -- return magic number and tag. */
637410

638411
long

0 commit comments

Comments
 (0)