bpo-33330: Improve error handling in PyImport_Cleanup(). (GH-6564)

(cherry picked from commit e9d9494d6b)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
Miss Islington (bot) 2018-04-25 11:32:52 -07:00 committed by GitHub
parent 53d36cc961
commit 291c9d4f74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -364,7 +364,7 @@ PyImport_GetModule(PyObject *name)
} }
else { else {
m = PyObject_GetItem(modules, name); m = PyObject_GetItem(modules, name);
if (PyErr_ExceptionMatches(PyExc_KeyError)) { if (m == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) {
PyErr_Clear(); PyErr_Clear();
} }
} }
@ -416,12 +416,16 @@ PyImport_Cleanup(void)
if (Py_VerboseFlag) if (Py_VerboseFlag)
PySys_WriteStderr("# clear builtins._\n"); PySys_WriteStderr("# clear builtins._\n");
PyDict_SetItemString(interp->builtins, "_", Py_None); if (PyDict_SetItemString(interp->builtins, "_", Py_None) < 0) {
PyErr_Clear();
}
for (p = sys_deletes; *p != NULL; p++) { for (p = sys_deletes; *p != NULL; p++) {
if (Py_VerboseFlag) if (Py_VerboseFlag)
PySys_WriteStderr("# clear sys.%s\n", *p); PySys_WriteStderr("# clear sys.%s\n", *p);
PyDict_SetItemString(interp->sysdict, *p, Py_None); if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) {
PyErr_Clear();
}
} }
for (p = sys_files; *p != NULL; p+=2) { for (p = sys_files; *p != NULL; p+=2) {
if (Py_VerboseFlag) if (Py_VerboseFlag)
@ -429,7 +433,9 @@ PyImport_Cleanup(void)
value = PyDict_GetItemString(interp->sysdict, *(p+1)); value = PyDict_GetItemString(interp->sysdict, *(p+1));
if (value == NULL) if (value == NULL)
value = Py_None; value = Py_None;
PyDict_SetItemString(interp->sysdict, *p, value); if (PyDict_SetItemString(interp->sysdict, *p, value) < 0) {
PyErr_Clear();
}
} }
/* We prepare a list which will receive (name, weakref) tuples of /* We prepare a list which will receive (name, weakref) tuples of
@ -443,21 +449,26 @@ PyImport_Cleanup(void)
#define STORE_MODULE_WEAKREF(name, mod) \ #define STORE_MODULE_WEAKREF(name, mod) \
if (weaklist != NULL) { \ if (weaklist != NULL) { \
PyObject *wr = PyWeakref_NewRef(mod, NULL); \ PyObject *wr = PyWeakref_NewRef(mod, NULL); \
if (name && wr) { \ if (wr) { \
PyObject *tup = PyTuple_Pack(2, name, wr); \ PyObject *tup = PyTuple_Pack(2, name, wr); \
PyList_Append(weaklist, tup); \ if (!tup || PyList_Append(weaklist, tup) < 0) { \
PyErr_Clear(); \
} \
Py_XDECREF(tup); \ Py_XDECREF(tup); \
Py_DECREF(wr); \
} \ } \
Py_XDECREF(wr); \ else { \
if (PyErr_Occurred()) \
PyErr_Clear(); \ PyErr_Clear(); \
} \
} }
#define CLEAR_MODULE(name, mod) \ #define CLEAR_MODULE(name, mod) \
if (PyModule_Check(mod)) { \ if (PyModule_Check(mod)) { \
if (Py_VerboseFlag && PyUnicode_Check(name)) \ if (Py_VerboseFlag && PyUnicode_Check(name)) \
PySys_FormatStderr("# cleanup[2] removing %U\n", name); \ PySys_FormatStderr("# cleanup[2] removing %U\n", name); \
STORE_MODULE_WEAKREF(name, mod); \ STORE_MODULE_WEAKREF(name, mod); \
PyObject_SetItem(modules, name, Py_None); \ if (PyObject_SetItem(modules, name, Py_None) < 0) { \
PyErr_Clear(); \
} \
} }
/* Remove all modules from sys.modules, hoping that garbage collection /* Remove all modules from sys.modules, hoping that garbage collection
@ -484,6 +495,9 @@ PyImport_Cleanup(void)
Py_DECREF(value); Py_DECREF(value);
Py_DECREF(key); Py_DECREF(key);
} }
if (PyErr_Occurred()) {
PyErr_Clear();
}
Py_DECREF(iterator); Py_DECREF(iterator);
} }
} }
@ -564,6 +578,7 @@ PyImport_Cleanup(void)
/* Once more */ /* Once more */
_PyGC_CollectNoFail(); _PyGC_CollectNoFail();
#undef CLEAR_MODULE
#undef STORE_MODULE_WEAKREF #undef STORE_MODULE_WEAKREF
} }