diff options
author | Victor Stinner <vstinner@wyplay.com> | 2013-08-26 12:04:10 (GMT) |
---|---|---|
committer | Victor Stinner <vstinner@wyplay.com> | 2013-08-26 12:04:10 (GMT) |
commit | c82bfd871f33b824974469071469ac4fb491d547 (patch) | |
tree | b8a2b6d7d471815ef0c43f33c60719e2884f7afa /Python/errors.c | |
parent | e51321020c78f28571b499dcc284604217ef0eb0 (diff) | |
download | cpython-c82bfd871f33b824974469071469ac4fb491d547.zip cpython-c82bfd871f33b824974469071469ac4fb491d547.tar.gz cpython-c82bfd871f33b824974469071469ac4fb491d547.tar.bz2 |
Issue #18664, #18408: Rewrite PyErr_WriteUnraisable() to handle errors
* Catch PyFile_WriteString() and PyFile_WriteObject() errors
* Clear the current exception on _PyObject_GetAttrId() failure
* Use PyUnicode_CompareWithASCIIString() and PyFile_WriteObject() instead of
_PyUnicode_AsString() and strcmp() to avoid Unicode encoding error. stderr
has a more tolerant error handler than utf-8/strict.
Diffstat (limited to 'Python/errors.c')
-rw-r--r-- | Python/errors.c | 102 |
1 files changed, 62 insertions, 40 deletions
diff --git a/Python/errors.c b/Python/errors.c index 8c0c018..2d5eb6c 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -825,54 +825,76 @@ PyErr_WriteUnraisable(PyObject *obj) { _Py_IDENTIFIER(__module__); PyObject *f, *t, *v, *tb; + PyObject *moduleName = NULL; + char* className; + PyErr_Fetch(&t, &v, &tb); + f = PySys_GetObject("stderr"); - if (f != NULL && f != Py_None) { - if (obj) { - PyFile_WriteString("Exception ignored in: ", f); - PyFile_WriteObject(obj, f, 0); - PyFile_WriteString("\n", f); - } - PyTraceBack_Print(tb, f); - if (t) { - PyObject* moduleName; - char* className; - assert(PyExceptionClass_Check(t)); - className = PyExceptionClass_Name(t); - if (className != NULL) { - char *dot = strrchr(className, '.'); - if (dot != NULL) - className = dot+1; - } + if (f == NULL || f == Py_None) + goto done; + + if (obj) { + if (PyFile_WriteString("Exception ignored in: ", f) < 0) + goto done; + if (PyFile_WriteObject(obj, f, 0) < 0) + goto done; + if (PyFile_WriteString("\n", f) < 0) + goto done; + } - moduleName = _PyObject_GetAttrId(t, &PyId___module__); - if (moduleName == NULL) - PyFile_WriteString("<unknown>", f); - else { - char* modstr = _PyUnicode_AsString(moduleName); - if (modstr && - strcmp(modstr, "builtins") != 0) - { - PyFile_WriteString(modstr, f); - PyFile_WriteString(".", f); - } - } - if (className == NULL) - PyFile_WriteString("<unknown>", f); - else - PyFile_WriteString(className, f); - if (v && v != Py_None) { - PyFile_WriteString(": ", f); - PyFile_WriteObject(v, f, Py_PRINT_RAW); - } - PyFile_WriteString("\n", f); - Py_XDECREF(moduleName); + if (PyTraceBack_Print(tb, f) < 0) + goto done; + + if (!t) + goto done; + + assert(PyExceptionClass_Check(t)); + className = PyExceptionClass_Name(t); + if (className != NULL) { + char *dot = strrchr(className, '.'); + if (dot != NULL) + className = dot+1; + } + + moduleName = _PyObject_GetAttrId(t, &PyId___module__); + if (moduleName == NULL) { + PyErr_Clear(); + if (PyFile_WriteString("<unknown>", f) < 0) + goto done; + } + else { + if (PyUnicode_CompareWithASCIIString(moduleName, "builtins") != 0) { + if (PyFile_WriteObject(moduleName, f, Py_PRINT_RAW) < 0) + goto done; + if (PyFile_WriteString(".", f) < 0) + goto done; } - PyErr_Clear(); /* Just in case */ } + if (className == NULL) { + if (PyFile_WriteString("<unknown>", f) < 0) + goto done; + } + else { + if (PyFile_WriteString(className, f) < 0) + goto done; + } + + if (v && v != Py_None) { + if (PyFile_WriteString(": ", f) < 0) + goto done; + if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) + goto done; + } + if (PyFile_WriteString("\n", f) < 0) + goto done; + +done: + Py_XDECREF(moduleName); Py_XDECREF(t); Py_XDECREF(v); Py_XDECREF(tb); + PyErr_Clear(); /* Just in case */ } extern PyObject *PyModule_GetWarningsModule(void); |