Mercurial > cpython-lru_cache-weakref
comparison Python/traceback.c @ 55900:5dec8a12e455 legacy-trunk
tabbify
| author | Benjamin Peterson <benjamin@python.org> |
|---|---|
| date | Wed, 09 Sep 2009 11:40:54 +0000 |
| parents | 9ef683d41c9b |
| children | 8f6cf39c96dd |
comparison
equal
deleted
inserted
replaced
| 55895:67de42ca0a26 | 55900:5dec8a12e455 |
|---|---|
| 10 #include "traceback.h" | 10 #include "traceback.h" |
| 11 | 11 |
| 12 #define OFF(x) offsetof(PyTracebackObject, x) | 12 #define OFF(x) offsetof(PyTracebackObject, x) |
| 13 | 13 |
| 14 static PyMemberDef tb_memberlist[] = { | 14 static PyMemberDef tb_memberlist[] = { |
| 15 {"tb_next", T_OBJECT, OFF(tb_next), READONLY}, | |
| 16 {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY}, | |
| 17 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, | 15 {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, |
| 18 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, | 16 {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, |
| 19 {NULL} /* Sentinel */ | 17 {NULL} /* Sentinel */ |
| 20 }; | 18 }; |
| 21 | 19 |
| 42 tb_clear(PyTracebackObject *tb) | 40 tb_clear(PyTracebackObject *tb) |
| 43 { | 41 { |
| 44 Py_CLEAR(tb->tb_next); | 42 Py_CLEAR(tb->tb_next); |
| 45 Py_CLEAR(tb->tb_frame); | 43 Py_CLEAR(tb->tb_frame); |
| 46 } | 44 } |
| 45 | |
| 46 static PyObject * | |
| 47 tb_get_next(PyTracebackObject *tb) { | |
| 48 if (tb->tb_next) { | |
| 49 Py_INCREF(tb->tb_next); | |
| 50 return (PyObject *)tb->tb_next; | |
| 51 } | |
| 52 Py_RETURN_NONE; | |
| 53 } | |
| 54 | |
| 55 static int | |
| 56 tb_set_next(PyTracebackObject *tb, PyObject *new, void *context) { | |
| 57 if (!new) { | |
| 58 PyErr_SetString(PyExc_TypeError, "can't delete tb_next"); | |
| 59 return -1; | |
| 60 } | |
| 61 else if (new == Py_None) { | |
| 62 new = NULL; | |
| 63 } | |
| 64 else if (PyTraceBack_Check(new)) { | |
| 65 /* Check for cycles in the traceback. */ | |
| 66 PyTracebackObject *current = (PyTracebackObject *)new; | |
| 67 do { | |
| 68 if (tb == current) { | |
| 69 PyErr_SetString(PyExc_ValueError, "cycle in traceback"); | |
| 70 return -1; | |
| 71 } | |
| 72 } while ((current = current->tb_next)); | |
| 73 Py_INCREF(new); | |
| 74 } | |
| 75 else { | |
| 76 PyErr_SetString(PyExc_TypeError, | |
| 77 "tb_next must be an traceback object"); | |
| 78 return -1; | |
| 79 } | |
| 80 Py_XDECREF(tb->tb_next); | |
| 81 tb->tb_next = (PyTracebackObject *)new; | |
| 82 return 0; | |
| 83 } | |
| 84 | |
| 85 static PyObject * | |
| 86 tb_get_frame(PyTracebackObject *tb) { | |
| 87 if (tb->tb_frame) { | |
| 88 Py_INCREF(tb->tb_frame); | |
| 89 return (PyObject *)tb->tb_frame; | |
| 90 } | |
| 91 Py_RETURN_NONE; | |
| 92 } | |
| 93 | |
| 94 static int | |
| 95 tb_set_frame(PyTracebackObject *tb, PyObject *new, void *context) { | |
| 96 if (!new) { | |
| 97 PyErr_SetString(PyExc_TypeError, | |
| 98 "can't delete tb_frame attribute"); | |
| 99 return -1; | |
| 100 } | |
| 101 else if (new == Py_None) { | |
| 102 new = NULL; | |
| 103 } | |
| 104 else if (PyFrame_Check(new)) { | |
| 105 Py_INCREF(new); | |
| 106 } | |
| 107 else { | |
| 108 PyErr_SetString(PyExc_TypeError, | |
| 109 "tb_frame must be a frame object"); | |
| 110 return -1; | |
| 111 } | |
| 112 tb->tb_frame = (PyFrameObject *)new; | |
| 113 return 0; | |
| 114 } | |
| 115 | |
| 116 static PyGetSetDef tb_getset[] = { | |
| 117 {"tb_next", (getter)tb_get_next, (setter)tb_set_next, NULL}, | |
| 118 {"tb_frame", (getter)tb_get_frame, (setter)tb_set_frame, NULL}, | |
| 119 }; | |
| 47 | 120 |
| 48 PyTypeObject PyTraceBack_Type = { | 121 PyTypeObject PyTraceBack_Type = { |
| 49 PyVarObject_HEAD_INIT(&PyType_Type, 0) | 122 PyVarObject_HEAD_INIT(&PyType_Type, 0) |
| 50 "traceback", | 123 "traceback", |
| 51 sizeof(PyTracebackObject), | 124 sizeof(PyTracebackObject), |
| 73 0, /* tp_weaklistoffset */ | 146 0, /* tp_weaklistoffset */ |
| 74 0, /* tp_iter */ | 147 0, /* tp_iter */ |
| 75 0, /* tp_iternext */ | 148 0, /* tp_iternext */ |
| 76 0, /* tp_methods */ | 149 0, /* tp_methods */ |
| 77 tb_memberlist, /* tp_members */ | 150 tb_memberlist, /* tp_members */ |
| 78 0, /* tp_getset */ | 151 tb_getset, /* tp_getset */ |
| 79 0, /* tp_base */ | 152 0, /* tp_base */ |
| 80 0, /* tp_dict */ | 153 0, /* tp_dict */ |
| 81 }; | 154 }; |
| 82 | 155 |
| 83 static PyTracebackObject * | 156 static PyTracebackObject * |
| 243 depth++; | 316 depth++; |
| 244 tb1 = tb1->tb_next; | 317 tb1 = tb1->tb_next; |
| 245 } | 318 } |
| 246 while (tb != NULL && err == 0) { | 319 while (tb != NULL && err == 0) { |
| 247 if (depth <= limit) { | 320 if (depth <= limit) { |
| 248 err = tb_displayline(f, | 321 PyFrameObject *frame = tb->tb_frame; |
| 249 PyString_AsString( | 322 char *filename, *name; |
| 250 tb->tb_frame->f_code->co_filename), | 323 if (frame) { |
| 251 tb->tb_lineno, | 324 filename = PyString_AS_STRING(frame->f_code->co_filename); |
| 252 PyString_AsString(tb->tb_frame->f_code->co_name)); | 325 name = PyString_AS_STRING(frame->f_code->co_name); |
| 326 } | |
| 327 else { | |
| 328 filename = name = "unkown (no frame on traceback)"; | |
| 329 } | |
| 330 err = tb_displayline(f, filename, tb->tb_lineno, name); | |
| 253 } | 331 } |
| 254 depth--; | 332 depth--; |
| 255 tb = tb->tb_next; | 333 tb = tb->tb_next; |
| 256 if (err == 0) | 334 if (err == 0) |
| 257 err = PyErr_CheckSignals(); | 335 err = PyErr_CheckSignals(); |
