@@ -622,10 +622,14 @@ class TracebackException:
622
622
occurred.
623
623
- :attr:`lineno` For syntax errors - the linenumber where the error
624
624
occurred.
625
+ - :attr:`end_lineno` For syntax errors - the end linenumber where the error
626
+ occurred. Can be `None` if not present.
625
627
- :attr:`text` For syntax errors - the text where the error
626
628
occurred.
627
629
- :attr:`offset` For syntax errors - the offset into the text where the
628
630
error occurred.
631
+ - :attr:`end_offset` For syntax errors - the offset into the text where the
632
+ error occurred. Can be `None` if not present.
629
633
- :attr:`msg` For syntax errors - the compiler error message.
630
634
"""
631
635
@@ -655,8 +659,11 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
655
659
self .filename = exc_value .filename
656
660
lno = exc_value .lineno
657
661
self .lineno = str (lno ) if lno is not None else None
662
+ end_lno = exc_value .end_lineno
663
+ self .end_lineno = str (end_lno ) if end_lno is not None else None
658
664
self .text = exc_value .text
659
665
self .offset = exc_value .offset
666
+ self .end_offset = exc_value .end_offset
660
667
self .msg = exc_value .msg
661
668
if lookup_lines :
662
669
self ._load_lines ()
@@ -771,12 +778,20 @@ def _format_syntax_error(self, stype):
771
778
ltext = rtext .lstrip (' \n \f ' )
772
779
spaces = len (rtext ) - len (ltext )
773
780
yield ' {}\n ' .format (ltext )
774
- # Convert 1-based column offset to 0-based index into stripped text
775
- caret = (self .offset or 0 ) - 1 - spaces
776
- if caret >= 0 :
777
- # non-space whitespace (likes tabs) must be kept for alignment
778
- caretspace = ((c if c .isspace () else ' ' ) for c in ltext [:caret ])
779
- yield ' {}^\n ' .format ('' .join (caretspace ))
781
+
782
+ if self .offset is not None :
783
+ offset = self .offset
784
+ end_offset = self .end_offset if self .end_offset is not None else offset
785
+ if offset == end_offset or end_offset == - 1 :
786
+ end_offset = offset + 1
787
+
788
+ # Convert 1-based column offset to 0-based index into stripped text
789
+ colno = offset - 1 - spaces
790
+ end_colno = end_offset - 1 - spaces
791
+ if colno >= 0 :
792
+ # non-space whitespace (likes tabs) must be kept for alignment
793
+ caretspace = ((c if c .isspace () else ' ' ) for c in ltext [:colno ])
794
+ yield ' {}{}' .format ("" .join (caretspace ), ('^' * (end_colno - colno ) + "\n " ))
780
795
msg = self .msg or "<no detail available>"
781
796
yield "{}: {}{}\n " .format (stype , msg , filename_suffix )
782
797
0 commit comments