Mercurial > cpython-lru_cache-weakref
comparison Python/traceback.c @ 62393:fa830371c724 3.1
Merged revisions 82059,82061 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
........
r82059 | victor.stinner | 2010-06-18 01:08:50 +0200 (ven., 18 juin 2010) | 5 lines
Issue #6543: Write the traceback in the terminal encoding instead of utf-8.
Fix the encoding of the modules filename.
Reindent also traceback.h, just because I hate tabs :-)
........
r82061 | victor.stinner | 2010-06-18 01:17:37 +0200 (ven., 18 juin 2010) | 2 lines
Issue #6543: Mention the author of the patch, Amaury Forgeot d'Arc
........
| author | Victor Stinner <victor.stinner@haypocalc.com> |
|---|---|
| date | Thu, 17 Jun 2010 23:23:37 +0000 |
| parents | f197407bdba2 |
| children | 6296632ad2cb |
comparison
equal
deleted
inserted
replaced
| 62392:07449b367935 | 62393:fa830371c724 |
|---|---|
| 132 tstate->curexc_traceback = (PyObject *)tb; | 132 tstate->curexc_traceback = (PyObject *)tb; |
| 133 Py_XDECREF(oldtb); | 133 Py_XDECREF(oldtb); |
| 134 return 0; | 134 return 0; |
| 135 } | 135 } |
| 136 | 136 |
| 137 static int | 137 static PyObject * |
| 138 _Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open_flags) | 138 _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *io) |
| 139 { | 139 { |
| 140 int i; | 140 Py_ssize_t i; |
| 141 int fd = -1; | 141 PyObject *binary; |
| 142 PyObject *v; | 142 PyObject *v; |
| 143 Py_ssize_t _npath; | 143 Py_ssize_t npath; |
| 144 int npath; | |
| 145 size_t taillen; | 144 size_t taillen; |
| 146 PyObject *syspath; | 145 PyObject *syspath; |
| 147 const char* path; | 146 const char* path; |
| 148 const char* tail; | 147 const char* tail; |
| 148 const char* filepath; | |
| 149 Py_ssize_t len; | 149 Py_ssize_t len; |
| 150 | 150 |
| 151 filepath = _PyUnicode_AsString(filename); | |
| 152 if (filepath == NULL) { | |
| 153 PyErr_Clear(); | |
| 154 return NULL; | |
| 155 } | |
| 156 | |
| 151 /* Search tail of filename in sys.path before giving up */ | 157 /* Search tail of filename in sys.path before giving up */ |
| 152 tail = strrchr(filename, SEP); | 158 tail = strrchr(filepath, SEP); |
| 153 if (tail == NULL) | 159 if (tail == NULL) |
| 154 tail = filename; | 160 tail = filepath; |
| 155 else | 161 else |
| 156 tail++; | 162 tail++; |
| 157 taillen = strlen(tail); | 163 taillen = strlen(tail); |
| 158 | 164 |
| 159 syspath = PySys_GetObject("path"); | 165 syspath = PySys_GetObject("path"); |
| 160 if (syspath == NULL || !PyList_Check(syspath)) | 166 if (syspath == NULL || !PyList_Check(syspath)) |
| 161 return -1; | 167 return NULL; |
| 162 _npath = PyList_Size(syspath); | 168 npath = PyList_Size(syspath); |
| 163 npath = Py_SAFE_DOWNCAST(_npath, Py_ssize_t, int); | |
| 164 | 169 |
| 165 for (i = 0; i < npath; i++) { | 170 for (i = 0; i < npath; i++) { |
| 166 v = PyList_GetItem(syspath, i); | 171 v = PyList_GetItem(syspath, i); |
| 167 if (v == NULL) { | 172 if (v == NULL) { |
| 168 PyErr_Clear(); | 173 PyErr_Clear(); |
| 169 break; | 174 break; |
| 170 } | 175 } |
| 171 if (!PyUnicode_Check(v)) | 176 if (!PyUnicode_Check(v)) |
| 172 continue; | 177 continue; |
| 173 path = _PyUnicode_AsStringAndSize(v, &len); | 178 path = _PyUnicode_AsStringAndSize(v, &len); |
| 179 if (path == NULL) { | |
| 180 PyErr_Clear(); | |
| 181 continue; | |
| 182 } | |
| 174 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) | 183 if (len + 1 + (Py_ssize_t)taillen >= (Py_ssize_t)namelen - 1) |
| 175 continue; /* Too long */ | 184 continue; /* Too long */ |
| 176 strcpy(namebuf, path); | 185 strcpy(namebuf, path); |
| 177 if (strlen(namebuf) != len) | 186 if (strlen(namebuf) != len) |
| 178 continue; /* v contains '\0' */ | 187 continue; /* v contains '\0' */ |
| 179 if (len > 0 && namebuf[len-1] != SEP) | 188 if (len > 0 && namebuf[len-1] != SEP) |
| 180 namebuf[len++] = SEP; | 189 namebuf[len++] = SEP; |
| 181 strcpy(namebuf+len, tail); | 190 strcpy(namebuf+len, tail); |
| 182 Py_BEGIN_ALLOW_THREADS | 191 |
| 183 fd = open(namebuf, open_flags); | 192 binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb"); |
| 184 Py_END_ALLOW_THREADS | 193 if (binary != NULL) |
| 185 if (0 <= fd) { | 194 return binary; |
| 186 return fd; | 195 PyErr_Clear(); |
| 187 } | 196 } |
| 188 } | 197 return NULL; |
| 189 return -1; | |
| 190 } | 198 } |
| 191 | 199 |
| 192 int | 200 int |
| 193 _Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent) | 201 _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) |
| 194 { | 202 { |
| 195 int err = 0; | 203 int err = 0; |
| 196 int fd; | 204 int fd; |
| 197 int i; | 205 int i; |
| 198 char *found_encoding; | 206 char *found_encoding; |
| 199 char *encoding; | 207 char *encoding; |
| 208 PyObject *io; | |
| 209 PyObject *binary; | |
| 200 PyObject *fob = NULL; | 210 PyObject *fob = NULL; |
| 201 PyObject *lineobj = NULL; | 211 PyObject *lineobj = NULL; |
| 202 #ifdef O_BINARY | |
| 203 const int open_flags = O_RDONLY | O_BINARY; /* necessary for Windows */ | |
| 204 #else | |
| 205 const int open_flags = O_RDONLY; | |
| 206 #endif | |
| 207 char buf[MAXPATHLEN+1]; | 212 char buf[MAXPATHLEN+1]; |
| 208 Py_UNICODE *u, *p; | 213 Py_UNICODE *u, *p; |
| 209 Py_ssize_t len; | 214 Py_ssize_t len; |
| 210 | 215 |
| 211 /* open the file */ | 216 /* open the file */ |
| 212 if (filename == NULL) | 217 if (filename == NULL) |
| 213 return 0; | 218 return 0; |
| 214 Py_BEGIN_ALLOW_THREADS | 219 |
| 215 fd = open(filename, open_flags); | 220 io = PyImport_ImportModuleNoBlock("io"); |
| 216 Py_END_ALLOW_THREADS | 221 if (io == NULL) |
| 217 if (fd < 0) { | 222 return -1; |
| 218 fd = _Py_FindSourceFile(filename, buf, sizeof(buf), open_flags); | 223 binary = PyObject_CallMethod(io, "open", "Os", filename, "rb"); |
| 219 if (fd < 0) | 224 |
| 225 if (binary == NULL) { | |
| 226 binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); | |
| 227 if (binary == NULL) { | |
| 228 Py_DECREF(io); | |
| 220 return 0; | 229 return 0; |
| 221 filename = buf; | 230 } |
| 222 } | 231 } |
| 223 | 232 |
| 224 /* use the right encoding to decode the file as unicode */ | 233 /* use the right encoding to decode the file as unicode */ |
| 234 fd = PyObject_AsFileDescriptor(binary); | |
| 225 found_encoding = PyTokenizer_FindEncoding(fd); | 235 found_encoding = PyTokenizer_FindEncoding(fd); |
| 226 encoding = (found_encoding != NULL) ? found_encoding : | 236 encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; |
| 227 (char*)PyUnicode_GetDefaultEncoding(); | |
| 228 lseek(fd, 0, 0); /* Reset position */ | 237 lseek(fd, 0, 0); /* Reset position */ |
| 229 fob = PyFile_FromFd(fd, (char*)filename, "r", -1, (char*)encoding, | 238 fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding); |
| 230 NULL, NULL, 1); | 239 Py_DECREF(io); |
| 240 Py_DECREF(binary); | |
| 231 PyMem_FREE(found_encoding); | 241 PyMem_FREE(found_encoding); |
| 242 | |
| 232 if (fob == NULL) { | 243 if (fob == NULL) { |
| 233 PyErr_Clear(); | 244 PyErr_Clear(); |
| 234 close(fd); | |
| 235 return 0; | 245 return 0; |
| 236 } | 246 } |
| 237 | 247 |
| 238 /* get the line number lineno */ | 248 /* get the line number lineno */ |
| 239 for (i = 0; i < lineno; i++) { | 249 for (i = 0; i < lineno; i++) { |
| 286 err = PyFile_WriteString("\n", f); | 296 err = PyFile_WriteString("\n", f); |
| 287 return err; | 297 return err; |
| 288 } | 298 } |
| 289 | 299 |
| 290 static int | 300 static int |
| 291 tb_displayline(PyObject *f, const char *filename, int lineno, const char *name) | 301 tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name) |
| 292 { | 302 { |
| 293 int err = 0; | 303 int err; |
| 294 char linebuf[2000]; | 304 PyObject *line; |
| 295 | 305 |
| 296 if (filename == NULL || name == NULL) | 306 if (filename == NULL || name == NULL) |
| 297 return -1; | 307 return -1; |
| 298 /* This is needed by Emacs' compile command */ | 308 line = PyUnicode_FromFormat(" File \"%U\", line %d, in %U\n", |
| 299 #define FMT " File \"%.500s\", line %d, in %.500s\n" | 309 filename, lineno, name); |
| 300 PyOS_snprintf(linebuf, sizeof(linebuf), FMT, filename, lineno, name); | 310 if (line == NULL) |
| 301 err = PyFile_WriteString(linebuf, f); | 311 return -1; |
| 312 err = PyFile_WriteObject(line, f, Py_PRINT_RAW); | |
| 313 Py_DECREF(line); | |
| 302 if (err != 0) | 314 if (err != 0) |
| 303 return err; | 315 return err; |
| 304 return _Py_DisplaySourceLine(f, filename, lineno, 4); | 316 return _Py_DisplaySourceLine(f, filename, lineno, 4); |
| 305 } | 317 } |
| 306 | 318 |
| 315 tb1 = tb1->tb_next; | 327 tb1 = tb1->tb_next; |
| 316 } | 328 } |
| 317 while (tb != NULL && err == 0) { | 329 while (tb != NULL && err == 0) { |
| 318 if (depth <= limit) { | 330 if (depth <= limit) { |
| 319 err = tb_displayline(f, | 331 err = tb_displayline(f, |
| 320 _PyUnicode_AsString( | 332 tb->tb_frame->f_code->co_filename, |
| 321 tb->tb_frame->f_code->co_filename), | 333 tb->tb_lineno, |
| 322 tb->tb_lineno, | 334 tb->tb_frame->f_code->co_name); |
| 323 _PyUnicode_AsString(tb->tb_frame->f_code->co_name)); | |
| 324 } | 335 } |
| 325 depth--; | 336 depth--; |
| 326 tb = tb->tb_next; | 337 tb = tb->tb_next; |
| 327 if (err == 0) | 338 if (err == 0) |
| 328 err = PyErr_CheckSignals(); | 339 err = PyErr_CheckSignals(); |
