@@ -375,6 +375,62 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject *
375
375
return result ;
376
376
}
377
377
378
+ int
379
+ _Py_DisplayLine (PyObject * f , PyObject * line_obj , PyObject * * line ,
380
+ int indent , int * truncation )
381
+ {
382
+ if (line ) {
383
+ Py_INCREF (line_obj );
384
+ * line = line_obj ;
385
+ }
386
+
387
+ int i , kind , err = -1 ;
388
+ const void * data ;
389
+ char buf [MAXPATHLEN + 1 ];
390
+
391
+ /* remove the indentation of the line */
392
+ kind = PyUnicode_KIND (line_obj );
393
+ data = PyUnicode_DATA (line_obj );
394
+ for (i = 0 ; i < PyUnicode_GET_LENGTH (line_obj ); i ++ ) {
395
+ Py_UCS4 ch = PyUnicode_READ (kind , data , i );
396
+ if (ch != ' ' && ch != '\t' && ch != '\014' )
397
+ break ;
398
+ }
399
+ if (i ) {
400
+ PyObject * truncated ;
401
+ truncated = PyUnicode_Substring (line_obj , i , PyUnicode_GET_LENGTH (line_obj ));
402
+ if (truncated ) {
403
+ Py_DECREF (line_obj );
404
+ line_obj = truncated ;
405
+ } else {
406
+ PyErr_Clear ();
407
+ }
408
+ }
409
+
410
+ if (truncation != NULL ) {
411
+ * truncation = i - indent ;
412
+ }
413
+
414
+ /* Write some spaces before the line */
415
+ strcpy (buf , " " );
416
+ assert (strlen (buf ) == 10 );
417
+ while (indent > 0 ) {
418
+ if (indent < 10 )
419
+ buf [indent ] = '\0' ;
420
+ err = PyFile_WriteString (buf , f );
421
+ if (err != 0 )
422
+ break ;
423
+ indent -= 10 ;
424
+ }
425
+
426
+ /* finally display the line */
427
+ if (err == 0 )
428
+ err = PyFile_WriteObject (line_obj , f , Py_PRINT_RAW );
429
+ Py_DECREF (line_obj );
430
+ if (err == 0 )
431
+ err = PyFile_WriteString ("\n" , f );
432
+ return err ;
433
+ }
378
434
int
379
435
_Py_DisplaySourceLine (PyObject * f , PyObject * filename , int lineno , int indent , int * truncation , PyObject * * line )
380
436
{
@@ -389,8 +445,6 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent, i
389
445
PyObject * lineobj = NULL ;
390
446
PyObject * res ;
391
447
char buf [MAXPATHLEN + 1 ];
392
- int kind ;
393
- const void * data ;
394
448
395
449
/* open the file */
396
450
if (filename == NULL )
@@ -467,53 +521,34 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent, i
467
521
return err ;
468
522
}
469
523
470
- if (line ) {
471
- Py_INCREF (lineobj );
472
- * line = lineobj ;
473
- }
524
+ return _Py_DisplayLine (f , lineobj , line , indent , truncation );
525
+ }
474
526
475
- /* remove the indentation of the line */
476
- kind = PyUnicode_KIND (lineobj );
477
- data = PyUnicode_DATA (lineobj );
478
- for (i = 0 ; i < PyUnicode_GET_LENGTH (lineobj ); i ++ ) {
479
- Py_UCS4 ch = PyUnicode_READ (kind , data , i );
480
- if (ch != ' ' && ch != '\t' && ch != '\014' )
481
- break ;
482
- }
483
- if (i ) {
484
- PyObject * truncated ;
485
- truncated = PyUnicode_Substring (lineobj , i , PyUnicode_GET_LENGTH (lineobj ));
486
- if (truncated ) {
487
- Py_DECREF (lineobj );
488
- lineobj = truncated ;
489
- } else {
490
- PyErr_Clear ();
491
- }
527
+ int
528
+ _Py_DisplayInteractiveSourceLine (PyObject * f , PyFrameObject * frame , int lineno , int indent ,
529
+ int * truncation , PyObject * * line )
530
+ {
531
+ PyObject * globals = _PyFrame_GetGlobals (frame );
532
+ PyObject * source = PyDict_GetItemString (globals , "__source__" );
533
+ if (!source ) {
534
+ return -1 ;
492
535
}
493
536
494
- if (truncation != NULL ) {
495
- * truncation = i - indent ;
537
+ PyObject * lines = PyUnicode_Splitlines (source , 0 );
538
+ if (!lines || PyList_GET_SIZE (lines ) < lineno ) {
539
+ Py_XDECREF (lines );
540
+ return -1 ;
496
541
}
497
542
498
- /* Write some spaces before the line */
499
- strcpy (buf , " " );
500
- assert (strlen (buf ) == 10 );
501
- while (indent > 0 ) {
502
- if (indent < 10 )
503
- buf [indent ] = '\0' ;
504
- err = PyFile_WriteString (buf , f );
505
- if (err != 0 )
506
- break ;
507
- indent -= 10 ;
543
+ PyObject * lineobj = PyList_GetItem (lines , lineno - 1 );
544
+ if (!lineobj ) {
545
+ Py_DECREF (lines );
546
+ return -1 ;
508
547
}
548
+ Py_INCREF (lineobj );
549
+ Py_DECREF (lines );
509
550
510
- /* finally display the line */
511
- if (err == 0 )
512
- err = PyFile_WriteObject (lineobj , f , Py_PRINT_RAW );
513
- Py_DECREF (lineobj );
514
- if (err == 0 )
515
- err = PyFile_WriteString ("\n" , f );
516
- return err ;
551
+ return _Py_DisplayLine (f , lineobj , line , indent , truncation );
517
552
}
518
553
519
554
/* AST based Traceback Specialization
@@ -702,8 +737,16 @@ tb_displayline(PyTracebackObject* tb, PyObject *f, PyObject *filename, int linen
702
737
int truncation = _TRACEBACK_SOURCE_LINE_INDENT ;
703
738
PyObject * source_line = NULL ;
704
739
705
- if (_Py_DisplaySourceLine (f , filename , lineno , _TRACEBACK_SOURCE_LINE_INDENT ,
706
- & truncation , & source_line ) != 0 ) {
740
+ if (PyUnicode_CompareWithASCIIString (filename , "<stdin>" ) == 0 ) {
741
+ err = _Py_DisplayInteractiveSourceLine (f , frame , lineno , _TRACEBACK_SOURCE_LINE_INDENT ,
742
+ & truncation , & source_line );
743
+ }
744
+ else {
745
+ err = _Py_DisplaySourceLine (f , filename , lineno , _TRACEBACK_SOURCE_LINE_INDENT ,
746
+ & truncation , & source_line );
747
+ }
748
+
749
+ if (err != 0 ) {
707
750
/* ignore errors since we can't report them, can we? */
708
751
err = ignore_source_errors ();
709
752
goto done ;
0 commit comments