comparison Python/pythonrun.c @ 48474:2ee09afee126

implement chained exception tracebacks patch from Antoine Pitrou #3112
author Benjamin Peterson <benjamin@python.org>
date Tue, 15 Jul 2008 15:32:09 +0000
parents da47e7e135ae
children e26c724d5e23
comparison
equal deleted inserted replaced
48473:7d570df5e90a 48474:2ee09afee126
1240 } 1240 }
1241 PyErr_Fetch(&exception, &v, &tb); 1241 PyErr_Fetch(&exception, &v, &tb);
1242 if (exception == NULL) 1242 if (exception == NULL)
1243 return; 1243 return;
1244 PyErr_NormalizeException(&exception, &v, &tb); 1244 PyErr_NormalizeException(&exception, &v, &tb);
1245 tb = tb ? tb : Py_None;
1246 PyException_SetTraceback(v, tb);
1245 if (exception == NULL) 1247 if (exception == NULL)
1246 return; 1248 return;
1247 /* Now we know v != NULL too */ 1249 /* Now we know v != NULL too */
1248 if (set_sys_last_vars) { 1250 if (set_sys_last_vars) {
1249 PySys_SetObject("last_type", exception); 1251 PySys_SetObject("last_type", exception);
1250 PySys_SetObject("last_value", v); 1252 PySys_SetObject("last_value", v);
1251 PySys_SetObject("last_traceback", tb ? tb : Py_None); 1253 PySys_SetObject("last_traceback", tb);
1252 } 1254 }
1253 hook = PySys_GetObject("excepthook"); 1255 hook = PySys_GetObject("excepthook");
1254 if (hook) { 1256 if (hook) {
1255 PyObject *args = PyTuple_Pack(3, 1257 PyObject *args = PyTuple_Pack(3, exception, v, tb);
1256 exception, v, tb ? tb : Py_None);
1257 PyObject *result = PyEval_CallObject(hook, args); 1258 PyObject *result = PyEval_CallObject(hook, args);
1258 if (result == NULL) { 1259 if (result == NULL) {
1259 PyObject *exception2, *v2, *tb2; 1260 PyObject *exception2, *v2, *tb2;
1260 if (PyErr_ExceptionMatches(PyExc_SystemExit)) { 1261 if (PyErr_ExceptionMatches(PyExc_SystemExit)) {
1261 handle_system_exit(); 1262 handle_system_exit();
1291 Py_XDECREF(exception); 1292 Py_XDECREF(exception);
1292 Py_XDECREF(v); 1293 Py_XDECREF(v);
1293 Py_XDECREF(tb); 1294 Py_XDECREF(tb);
1294 } 1295 }
1295 1296
1296 void 1297 static void
1297 PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) 1298 print_exception(PyObject *f, PyObject *value)
1298 { 1299 {
1299 int err = 0; 1300 int err = 0;
1300 PyObject *f = PySys_GetObject("stderr"); 1301 PyObject *type, *tb;
1302
1301 Py_INCREF(value); 1303 Py_INCREF(value);
1302 if (f == Py_None) { 1304 fflush(stdout);
1303 /* pass */ 1305 type = (PyObject *) Py_TYPE(value);
1304 } 1306 tb = PyException_GetTraceback(value);
1305 else if (f == NULL) { 1307 if (tb && tb != Py_None)
1306 _PyObject_Dump(value); 1308 err = PyTraceBack_Print(tb, f);
1307 fprintf(stderr, "lost sys.stderr\n"); 1309 if (err == 0 &&
1310 PyObject_HasAttrString(value, "print_file_and_line"))
1311 {
1312 PyObject *message;
1313 const char *filename, *text;
1314 int lineno, offset;
1315 if (!parse_syntax_error(value, &message, &filename,
1316 &lineno, &offset, &text))
1317 PyErr_Clear();
1318 else {
1319 char buf[10];
1320 PyFile_WriteString(" File \"", f);
1321 if (filename == NULL)
1322 PyFile_WriteString("<string>", f);
1323 else
1324 PyFile_WriteString(filename, f);
1325 PyFile_WriteString("\", line ", f);
1326 PyOS_snprintf(buf, sizeof(buf), "%d", lineno);
1327 PyFile_WriteString(buf, f);
1328 PyFile_WriteString("\n", f);
1329 if (text != NULL)
1330 print_error_text(f, offset, text);
1331 Py_DECREF(value);
1332 value = message;
1333 /* Can't be bothered to check all those
1334 PyFile_WriteString() calls */
1335 if (PyErr_Occurred())
1336 err = -1;
1337 }
1338 }
1339 if (err) {
1340 /* Don't do anything else */
1308 } 1341 }
1309 else { 1342 else {
1310 fflush(stdout); 1343 assert(PyExceptionClass_Check(type));
1311 if (tb && tb != Py_None) 1344 PyObject* moduleName;
1312 err = PyTraceBack_Print(tb, f); 1345 char* className = PyExceptionClass_Name(type);
1313 if (err == 0 && 1346 if (className != NULL) {
1314 PyObject_HasAttrString(value, "print_file_and_line")) 1347 char *dot = strrchr(className, '.');
1348 if (dot != NULL)
1349 className = dot+1;
1350 }
1351
1352 moduleName = PyObject_GetAttrString(type, "__module__");
1353 if (moduleName == NULL || !PyUnicode_Check(moduleName))
1315 { 1354 {
1316 PyObject *message; 1355 Py_DECREF(moduleName);
1317 const char *filename, *text; 1356 err = PyFile_WriteString("<unknown>", f);
1318 int lineno, offset; 1357 }
1319 if (!parse_syntax_error(value, &message, &filename, 1358 else {
1320 &lineno, &offset, &text)) 1359 char* modstr = PyUnicode_AsString(moduleName);
1321 PyErr_Clear(); 1360 if (modstr && strcmp(modstr, "builtins"))
1322 else { 1361 {
1323 char buf[10]; 1362 err = PyFile_WriteString(modstr, f);
1324 PyFile_WriteString(" File \"", f); 1363 err += PyFile_WriteString(".", f);
1325 if (filename == NULL)
1326 PyFile_WriteString("<string>", f);
1327 else
1328 PyFile_WriteString(filename, f);
1329 PyFile_WriteString("\", line ", f);
1330 PyOS_snprintf(buf, sizeof(buf), "%d", lineno);
1331 PyFile_WriteString(buf, f);
1332 PyFile_WriteString("\n", f);
1333 if (text != NULL)
1334 print_error_text(f, offset, text);
1335 Py_DECREF(value);
1336 value = message;
1337 /* Can't be bothered to check all those
1338 PyFile_WriteString() calls */
1339 if (PyErr_Occurred())
1340 err = -1;
1341 } 1364 }
1342 } 1365 Py_DECREF(moduleName);
1343 if (err) { 1366 }
1344 /* Don't do anything else */ 1367 if (err == 0) {
1345 } 1368 if (className == NULL)
1346 else if (PyExceptionClass_Check(exception)) { 1369 err = PyFile_WriteString("<unknown>", f);
1347 PyObject* moduleName; 1370 else
1348 char* className = PyExceptionClass_Name(exception); 1371 err = PyFile_WriteString(className, f);
1349 if (className != NULL) { 1372 }
1350 char *dot = strrchr(className, '.'); 1373 }
1351 if (dot != NULL) 1374 if (err == 0 && (value != Py_None)) {
1352 className = dot+1; 1375 PyObject *s = PyObject_Str(value);
1353 } 1376 /* only print colon if the str() of the
1354 1377 object is not the empty string
1355 moduleName = PyObject_GetAttrString(exception, "__module__"); 1378 */
1356 if (moduleName == NULL || !PyUnicode_Check(moduleName)) 1379 if (s == NULL)
1357 { 1380 err = -1;
1358 Py_DECREF(moduleName); 1381 else if (!PyUnicode_Check(s) ||
1359 err = PyFile_WriteString("<unknown>", f); 1382 PyUnicode_GetSize(s) != 0)
1360 } 1383 err = PyFile_WriteString(": ", f);
1361 else { 1384 if (err == 0)
1362 char* modstr = PyUnicode_AsString(moduleName); 1385 err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
1363 if (modstr && strcmp(modstr, "builtins")) 1386 Py_XDECREF(s);
1364 { 1387 }
1365 err = PyFile_WriteString(modstr, f); 1388 /* try to write a newline in any case */
1366 err += PyFile_WriteString(".", f); 1389 err += PyFile_WriteString("\n", f);
1367 } 1390 Py_XDECREF(tb);
1368 Py_DECREF(moduleName);
1369 }
1370 if (err == 0) {
1371 if (className == NULL)
1372 err = PyFile_WriteString("<unknown>", f);
1373 else
1374 err = PyFile_WriteString(className, f);
1375 }
1376 }
1377 else
1378 err = PyFile_WriteObject(exception, f, Py_PRINT_RAW);
1379 if (err == 0 && (value != Py_None)) {
1380 PyObject *s = PyObject_Str(value);
1381 /* only print colon if the str() of the
1382 object is not the empty string
1383 */
1384 if (s == NULL)
1385 err = -1;
1386 else if (!PyUnicode_Check(s) ||
1387 PyUnicode_GetSize(s) != 0)
1388 err = PyFile_WriteString(": ", f);
1389 if (err == 0)
1390 err = PyFile_WriteObject(s, f, Py_PRINT_RAW);
1391 Py_XDECREF(s);
1392 }
1393 /* try to write a newline in any case */
1394 err += PyFile_WriteString("\n", f);
1395 }
1396 Py_DECREF(value); 1391 Py_DECREF(value);
1397 /* If an error happened here, don't show it. 1392 /* If an error happened here, don't show it.
1398 XXX This is wrong, but too many callers rely on this behavior. */ 1393 XXX This is wrong, but too many callers rely on this behavior. */
1399 if (err != 0) 1394 if (err != 0)
1400 PyErr_Clear(); 1395 PyErr_Clear();
1396 }
1397
1398 static const char *cause_message =
1399 "\nThe above exception was the direct cause "
1400 "of the following exception:\n\n";
1401
1402 static const char *context_message =
1403 "\nDuring handling of the above exception, "
1404 "another exception occurred:\n\n";
1405
1406 static void
1407 print_exception_recursive(PyObject *f, PyObject *value, PyObject *seen)
1408 {
1409 int err = 0, res;
1410 PyObject *cause, *context;
1411
1412 if (seen != NULL) {
1413 /* Exception chaining */
1414 if (PySet_Add(seen, value) == -1)
1415 PyErr_Clear();
1416 else if (PyExceptionInstance_Check(value)) {
1417 cause = PyException_GetCause(value);
1418 context = PyException_GetContext(value);
1419 if (cause) {
1420 res = PySet_Contains(seen, cause);
1421 if (res == -1)
1422 PyErr_Clear();
1423 if (res == 0) {
1424 print_exception_recursive(
1425 f, cause, seen);
1426 err |= PyFile_WriteString(
1427 cause_message, f);
1428 }
1429 }
1430 if (context) {
1431 res = PySet_Contains(seen, context);
1432 if (res == -1)
1433 PyErr_Clear();
1434 if (res == 0) {
1435 print_exception_recursive(
1436 f, context, seen);
1437 err |= PyFile_WriteString(
1438 context_message, f);
1439 }
1440 }
1441 Py_XDECREF(context);
1442 Py_XDECREF(cause);
1443 }
1444 }
1445 print_exception(f, value);
1446 if (err != 0)
1447 PyErr_Clear();
1448 }
1449
1450 void
1451 PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb)
1452 {
1453 PyObject *seen;
1454 PyObject *f = PySys_GetObject("stderr");
1455 if (f == Py_None) {
1456 /* pass */
1457 }
1458 else if (f == NULL) {
1459 _PyObject_Dump(value);
1460 fprintf(stderr, "lost sys.stderr\n");
1461 }
1462 else {
1463 /* We choose to ignore seen being possibly NULL, and report
1464 at least the main exception (it could be a MemoryError).
1465 */
1466 seen = PySet_New(NULL);
1467 if (seen == NULL)
1468 PyErr_Clear();
1469 print_exception_recursive(f, value, seen);
1470 Py_XDECREF(seen);
1471 }
1401 } 1472 }
1402 1473
1403 PyObject * 1474 PyObject *
1404 PyRun_StringFlags(const char *str, int start, PyObject *globals, 1475 PyRun_StringFlags(const char *str, int start, PyObject *globals,
1405 PyObject *locals, PyCompilerFlags *flags) 1476 PyObject *locals, PyCompilerFlags *flags)