Skip to content

Commit bcc72a5

Browse files
Only use PyDict_* for dicts.
1 parent eed5e24 commit bcc72a5

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

Python/import.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -471,21 +471,43 @@ PyImport_Cleanup(void)
471471
if (PyErr_Occurred()) \
472472
PyErr_Clear(); \
473473
}
474+
#define CLEAR_MODULE(name, mod) \
475+
if (PyModule_Check(mod)) { \
476+
if (Py_VerboseFlag && PyUnicode_Check(name)) \
477+
PySys_FormatStderr("# cleanup[2] removing %U\n", name); \
478+
STORE_MODULE_WEAKREF(name, mod); \
479+
PyObject_SetItem(modules, name, Py_None); \
480+
}
474481

475482
/* Remove all modules from sys.modules, hoping that garbage collection
476483
can reclaim most of them. */
477-
pos = 0;
478-
while (PyDict_Next(modules, &pos, &key, &value)) {
479-
if (PyModule_Check(value)) {
480-
if (Py_VerboseFlag && PyUnicode_Check(key))
481-
PySys_FormatStderr("# cleanup[2] removing %U\n", key);
482-
STORE_MODULE_WEAKREF(key, value);
483-
PyObject_SetItem(modules, key, Py_None);
484+
if (PyDict_CheckExact(modules)) {
485+
pos = 0;
486+
while (PyDict_Next(modules, &pos, &key, &value)) {
487+
CLEAR_MODULE(key, value);
488+
}
489+
}
490+
else {
491+
PyObject *iterator = PyObject_GetIter(modules);
492+
if (iterator == NULL) {
493+
PyErr_Clear();
494+
}
495+
else {
496+
while ((value = PyIter_Next(iterator))) {
497+
CLEAR_MODULE(key, value);
498+
}
484499
}
485500
}
486501

487502
/* Clear the modules dict. */
488-
PyDict_Clear(modules);
503+
if (PyDict_CheckExact(modules)) {
504+
PyDict_Clear(modules);
505+
}
506+
else {
507+
_Py_IDENTIFIER(clear);
508+
if (_PyObject_CallMethodId(modules, &PyId_clear, "") == NULL)
509+
PyErr_Clear();
510+
}
489511
/* Restore the original builtins dict, to ensure that any
490512
user data gets cleared. */
491513
dict = PyDict_Copy(interp->builtins);

0 commit comments

Comments
 (0)