summaryrefslogtreecommitdiffstats
path: root/Python/errors.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@wyplay.com>2013-08-26 12:04:10 (GMT)
committerVictor Stinner <vstinner@wyplay.com>2013-08-26 12:04:10 (GMT)
commitc82bfd871f33b824974469071469ac4fb491d547 (patch)
treeb8a2b6d7d471815ef0c43f33c60719e2884f7afa /Python/errors.c
parente51321020c78f28571b499dcc284604217ef0eb0 (diff)
downloadcpython-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.c102
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);