Mercurial > cpython-lru_cache-weakref
comparison Python/sysmodule.c @ 66719:ba709ad3ff4c
Issue #10601: sys.displayhook uses 'backslashreplace' error handler on
UnicodeEncodeError.
| author | Victor Stinner <victor.stinner@haypocalc.com> |
|---|---|
| date | Sat, 04 Dec 2010 17:24:33 +0000 |
| parents | 724920a015f7 |
| children | b7be652daf6e |
comparison
equal
deleted
inserted
replaced
| 66717:779a23a08d8c | 66719:ba709ad3ff4c |
|---|---|
| 63 } | 63 } |
| 64 else | 64 else |
| 65 return PyDict_SetItemString(sd, name, v); | 65 return PyDict_SetItemString(sd, name, v); |
| 66 } | 66 } |
| 67 | 67 |
| 68 /* Write repr(o) to sys.stdout using sys.stdout.encoding and 'backslashreplace' | |
| 69 error handler. If sys.stdout has a buffer attribute, use | |
| 70 sys.stdout.buffer.write(encoded), otherwise redecode the string and use | |
| 71 sys.stdout.write(redecoded). | |
| 72 | |
| 73 Helper function for sys_displayhook(). */ | |
| 74 static int | |
| 75 sys_displayhook_unencodable(PyObject *outf, PyObject *o) | |
| 76 { | |
| 77 PyObject *stdout_encoding = NULL; | |
| 78 PyObject *encoded, *escaped_str, *repr_str, *buffer, *result; | |
| 79 char *stdout_encoding_str; | |
| 80 int ret; | |
| 81 | |
| 82 stdout_encoding = PyObject_GetAttrString(outf, "encoding"); | |
| 83 if (stdout_encoding == NULL) | |
| 84 goto error; | |
| 85 stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); | |
| 86 if (stdout_encoding_str == NULL) | |
| 87 goto error; | |
| 88 | |
| 89 repr_str = PyObject_Repr(o); | |
| 90 if (repr_str == NULL) | |
| 91 goto error; | |
| 92 encoded = PyUnicode_AsEncodedString(repr_str, | |
| 93 stdout_encoding_str, | |
| 94 "backslashreplace"); | |
| 95 Py_DECREF(repr_str); | |
| 96 if (encoded == NULL) | |
| 97 goto error; | |
| 98 | |
| 99 buffer = PyObject_GetAttrString(outf, "buffer"); | |
| 100 if (buffer) { | |
| 101 result = PyObject_CallMethod(buffer, "write", "(O)", encoded); | |
| 102 Py_DECREF(buffer); | |
| 103 Py_DECREF(encoded); | |
| 104 if (result == NULL) | |
| 105 goto error; | |
| 106 Py_DECREF(result); | |
| 107 } | |
| 108 else { | |
| 109 PyErr_Clear(); | |
| 110 escaped_str = PyUnicode_FromEncodedObject(encoded, | |
| 111 stdout_encoding_str, | |
| 112 "strict"); | |
| 113 Py_DECREF(encoded); | |
| 114 if (PyFile_WriteObject(escaped_str, outf, Py_PRINT_RAW) != 0) { | |
| 115 Py_DECREF(escaped_str); | |
| 116 goto error; | |
| 117 } | |
| 118 Py_DECREF(escaped_str); | |
| 119 } | |
| 120 ret = 0; | |
| 121 goto finally; | |
| 122 | |
| 123 error: | |
| 124 ret = -1; | |
| 125 finally: | |
| 126 Py_XDECREF(stdout_encoding); | |
| 127 return ret; | |
| 128 } | |
| 129 | |
| 68 static PyObject * | 130 static PyObject * |
| 69 sys_displayhook(PyObject *self, PyObject *o) | 131 sys_displayhook(PyObject *self, PyObject *o) |
| 70 { | 132 { |
| 71 PyObject *outf; | 133 PyObject *outf; |
| 72 PyInterpreterState *interp = PyThreadState_GET()->interp; | 134 PyInterpreterState *interp = PyThreadState_GET()->interp; |
| 73 PyObject *modules = interp->modules; | 135 PyObject *modules = interp->modules; |
| 74 PyObject *builtins = PyDict_GetItemString(modules, "builtins"); | 136 PyObject *builtins = PyDict_GetItemString(modules, "builtins"); |
| 137 int err; | |
| 75 | 138 |
| 76 if (builtins == NULL) { | 139 if (builtins == NULL) { |
| 77 PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); | 140 PyErr_SetString(PyExc_RuntimeError, "lost builtins module"); |
| 78 return NULL; | 141 return NULL; |
| 79 } | 142 } |
| 90 outf = PySys_GetObject("stdout"); | 153 outf = PySys_GetObject("stdout"); |
| 91 if (outf == NULL || outf == Py_None) { | 154 if (outf == NULL || outf == Py_None) { |
| 92 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); | 155 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); |
| 93 return NULL; | 156 return NULL; |
| 94 } | 157 } |
| 95 if (PyFile_WriteObject(o, outf, 0) != 0) | 158 if (PyFile_WriteObject(o, outf, 0) != 0) { |
| 96 return NULL; | 159 if (PyErr_ExceptionMatches(PyExc_UnicodeEncodeError)) { |
| 160 /* repr(o) is not encodable to sys.stdout.encoding with | |
| 161 * sys.stdout.errors error handler (which is probably 'strict') */ | |
| 162 PyErr_Clear(); | |
| 163 err = sys_displayhook_unencodable(outf, o); | |
| 164 if (err) | |
| 165 return NULL; | |
| 166 } | |
| 167 else { | |
| 168 return NULL; | |
| 169 } | |
| 170 } | |
| 97 if (PyFile_WriteString("\n", outf) != 0) | 171 if (PyFile_WriteString("\n", outf) != 0) |
| 98 return NULL; | 172 return NULL; |
| 99 if (PyObject_SetAttrString(builtins, "_", o) != 0) | 173 if (PyObject_SetAttrString(builtins, "_", o) != 0) |
| 100 return NULL; | 174 return NULL; |
| 101 Py_INCREF(Py_None); | 175 Py_INCREF(Py_None); |
