@@ -414,57 +414,68 @@ tb_displayline(PyObject *f, PyObject *filename, int lineno, PyObject *name)
414
414
return err ;
415
415
}
416
416
417
+ static int
418
+ tb_print_line_repeated (PyObject * f , long cnt )
419
+ {
420
+ int err ;
421
+ PyObject * line = PyUnicode_FromFormat (
422
+ " [Previous line repeated %ld more times]\n" , cnt - 3 );
423
+ if (line == NULL ) {
424
+ return -1 ;
425
+ }
426
+ err = PyFile_WriteObject (line , f , Py_PRINT_RAW );
427
+ Py_DECREF (line );
428
+ return err ;
429
+ }
430
+
417
431
static int
418
432
tb_printinternal (PyTracebackObject * tb , PyObject * f , long limit )
419
433
{
420
434
int err = 0 ;
421
- long depth = 0 ;
435
+ Py_ssize_t depth = 0 ;
422
436
PyObject * last_file = NULL ;
423
437
int last_line = -1 ;
424
438
PyObject * last_name = NULL ;
425
439
long cnt = 0 ;
426
- PyObject * line ;
427
440
PyTracebackObject * tb1 = tb ;
428
441
while (tb1 != NULL ) {
429
442
depth ++ ;
430
443
tb1 = tb1 -> tb_next ;
431
444
}
445
+ while (tb != NULL && depth > limit ) {
446
+ depth -- ;
447
+ tb = tb -> tb_next ;
448
+ }
432
449
while (tb != NULL && err == 0 ) {
433
- if (depth <= limit ) {
434
- if ( last_file != NULL &&
435
- tb -> tb_frame -> f_code -> co_filename == last_file &&
436
- last_line != -1 && tb -> tb_lineno == last_line &&
437
- last_name != NULL &&
438
- tb -> tb_frame -> f_code -> co_name == last_name ) {
439
- cnt ++ ;
440
- } else {
441
- if (cnt > 3 ) {
442
- line = PyUnicode_FromFormat (
443
- " [Previous line repeated %d more times]\n" , cnt - 3 );
444
- err = PyFile_WriteObject ( line , f , Py_PRINT_RAW ) ;
445
- Py_DECREF ( line ) ;
446
- }
447
- last_file = tb -> tb_frame -> f_code -> co_filename ;
448
- last_line = tb -> tb_lineno ;
449
- last_name = tb -> tb_frame -> f_code -> co_name ;
450
- cnt = 0 ;
451
- }
452
- if ( cnt < 3 )
453
- err = tb_displayline ( f ,
454
- tb -> tb_frame -> f_code -> co_filename ,
455
- tb -> tb_lineno ,
456
- tb -> tb_frame -> f_code -> co_name );
450
+ if (last_file != NULL &&
451
+ tb -> tb_frame -> f_code -> co_filename == last_file &&
452
+ last_line != -1 && tb -> tb_lineno == last_line &&
453
+ last_name != NULL && tb -> tb_frame -> f_code -> co_name == last_name )
454
+ {
455
+ cnt ++ ;
456
+ }
457
+ else {
458
+ if (cnt > 3 ) {
459
+ err = tb_print_line_repeated ( f , cnt );
460
+ }
461
+ last_file = tb -> tb_frame -> f_code -> co_filename ;
462
+ last_line = tb -> tb_lineno ;
463
+ last_name = tb -> tb_frame -> f_code -> co_name ;
464
+ cnt = 0 ;
465
+ }
466
+ if ( err == 0 && cnt < 3 ) {
467
+ err = tb_displayline ( f ,
468
+ tb -> tb_frame -> f_code -> co_filename ,
469
+ tb -> tb_lineno ,
470
+ tb -> tb_frame -> f_code -> co_name );
471
+ if ( err == 0 ) {
472
+ err = PyErr_CheckSignals ();
473
+ }
457
474
}
458
- depth -- ;
459
475
tb = tb -> tb_next ;
460
- if (err == 0 )
461
- err = PyErr_CheckSignals ();
462
476
}
463
- if (cnt > 3 ) {
464
- line = PyUnicode_FromFormat (
465
- " [Previous line repeated %d more times]\n" , cnt - 3 );
466
- err = PyFile_WriteObject (line , f , Py_PRINT_RAW );
467
- Py_DECREF (line );
477
+ if (err == 0 && cnt > 3 ) {
478
+ err = tb_print_line_repeated (f , cnt );
468
479
}
469
480
return err ;
470
481
}
@@ -485,26 +496,15 @@ PyTraceBack_Print(PyObject *v, PyObject *f)
485
496
return -1 ;
486
497
}
487
498
limitv = PySys_GetObject ("tracebacklimit" );
488
- if (limitv ) {
489
- PyObject * exc_type , * exc_value , * exc_tb ;
490
-
491
- PyErr_Fetch (& exc_type , & exc_value , & exc_tb );
492
- limit = PyLong_AsLong (limitv );
493
- if (limit == -1 && PyErr_Occurred ()) {
494
- if (PyErr_ExceptionMatches (PyExc_OverflowError )) {
495
- limit = PyTraceBack_LIMIT ;
496
- }
497
- else {
498
- Py_XDECREF (exc_type );
499
- Py_XDECREF (exc_value );
500
- Py_XDECREF (exc_tb );
501
- return 0 ;
502
- }
499
+ if (limitv && PyLong_Check (limitv )) {
500
+ int overflow ;
501
+ limit = PyLong_AsLongAndOverflow (limitv , & overflow );
502
+ if (overflow > 0 ) {
503
+ limit = LONG_MAX ;
503
504
}
504
505
else if (limit <= 0 ) {
505
- limit = PyTraceBack_LIMIT ;
506
+ return 0 ;
506
507
}
507
- PyErr_Restore (exc_type , exc_value , exc_tb );
508
508
}
509
509
err = PyFile_WriteString ("Traceback (most recent call last):\n" , f );
510
510
if (!err )
0 commit comments