@@ -411,13 +411,13 @@ def filter(
411
411
"""
412
412
return Traceback (filter (fn , self ), self ._excinfo )
413
413
414
- def getcrashentry (self ) -> TracebackEntry :
414
+ def getcrashentry (self ) -> Optional [ TracebackEntry ] :
415
415
"""Return last non-hidden traceback entry that lead to the exception of a traceback."""
416
416
for i in range (- 1 , - len (self ) - 1 , - 1 ):
417
417
entry = self [i ]
418
418
if not entry .ishidden ():
419
419
return entry
420
- return self [ - 1 ]
420
+ return None
421
421
422
422
def recursionindex (self ) -> Optional [int ]:
423
423
"""Return the index of the frame/TracebackEntry where recursion originates if
@@ -598,9 +598,11 @@ def errisinstance(
598
598
"""
599
599
return isinstance (self .value , exc )
600
600
601
- def _getreprcrash (self ) -> "ReprFileLocation" :
601
+ def _getreprcrash (self ) -> Optional [ "ReprFileLocation" ] :
602
602
exconly = self .exconly (tryshort = True )
603
603
entry = self .traceback .getcrashentry ()
604
+ if entry is None :
605
+ return None
604
606
path , lineno = entry .frame .code .raw .co_filename , entry .lineno
605
607
return ReprFileLocation (path , lineno + 1 , exconly )
606
608
@@ -647,7 +649,9 @@ def getrepr(
647
649
return ReprExceptionInfo (
648
650
reprtraceback = ReprTracebackNative (
649
651
traceback .format_exception (
650
- self .type , self .value , self .traceback [0 ]._rawentry
652
+ self .type ,
653
+ self .value ,
654
+ self .traceback [0 ]._rawentry if self .traceback else None ,
651
655
)
652
656
),
653
657
reprcrash = self ._getreprcrash (),
@@ -803,12 +807,16 @@ def repr_locals(self, locals: Mapping[str, object]) -> Optional["ReprLocals"]:
803
807
804
808
def repr_traceback_entry (
805
809
self ,
806
- entry : TracebackEntry ,
810
+ entry : Optional [ TracebackEntry ] ,
807
811
excinfo : Optional [ExceptionInfo [BaseException ]] = None ,
808
812
) -> "ReprEntry" :
809
813
lines : List [str ] = []
810
- style = entry ._repr_style if entry ._repr_style is not None else self .style
811
- if style in ("short" , "long" ):
814
+ style = (
815
+ entry ._repr_style
816
+ if entry is not None and entry ._repr_style is not None
817
+ else self .style
818
+ )
819
+ if style in ("short" , "long" ) and entry is not None :
812
820
source = self ._getentrysource (entry )
813
821
if source is None :
814
822
source = Source ("???" )
@@ -857,17 +865,21 @@ def repr_traceback(self, excinfo: ExceptionInfo[BaseException]) -> "ReprTracebac
857
865
else :
858
866
extraline = None
859
867
868
+ if not traceback :
869
+ if extraline is None :
870
+ extraline = "All traceback entries are hidden. Pass `--full-trace` to see hidden and internal frames."
871
+ entries = [self .repr_traceback_entry (None , excinfo )]
872
+ return ReprTraceback (entries , extraline , style = self .style )
873
+
860
874
last = traceback [- 1 ]
861
- entries = []
862
875
if self .style == "value" :
863
- reprentry = self .repr_traceback_entry (last , excinfo )
864
- entries .append (reprentry )
876
+ entries = [self .repr_traceback_entry (last , excinfo )]
865
877
return ReprTraceback (entries , None , style = self .style )
866
878
867
- for index , entry in enumerate ( traceback ):
868
- einfo = ( last == entry ) and excinfo or None
869
- reprentry = self . repr_traceback_entry ( entry , einfo )
870
- entries . append ( reprentry )
879
+ entries = [
880
+ self . repr_traceback_entry ( entry , excinfo if last == entry else None )
881
+ for entry in traceback
882
+ ]
871
883
return ReprTraceback (entries , extraline , style = self .style )
872
884
873
885
def _truncate_recursive_traceback (
@@ -924,6 +936,7 @@ def repr_excinfo(
924
936
seen : Set [int ] = set ()
925
937
while e is not None and id (e ) not in seen :
926
938
seen .add (id (e ))
939
+
927
940
if excinfo_ :
928
941
# Fall back to native traceback as a temporary workaround until
929
942
# full support for exception groups added to ExceptionInfo.
@@ -950,8 +963,8 @@ def repr_excinfo(
950
963
traceback .format_exception (type (e ), e , None )
951
964
)
952
965
reprcrash = None
953
-
954
966
repr_chain += [(reprtraceback , reprcrash , descr )]
967
+
955
968
if e .__cause__ is not None and self .chain :
956
969
e = e .__cause__
957
970
excinfo_ = (
@@ -1042,7 +1055,7 @@ def toterminal(self, tw: TerminalWriter) -> None:
1042
1055
@dataclasses .dataclass (eq = False )
1043
1056
class ReprExceptionInfo (ExceptionRepr ):
1044
1057
reprtraceback : "ReprTraceback"
1045
- reprcrash : "ReprFileLocation"
1058
+ reprcrash : Optional [ "ReprFileLocation" ]
1046
1059
1047
1060
def toterminal (self , tw : TerminalWriter ) -> None :
1048
1061
self .reprtraceback .toterminal (tw )
@@ -1147,8 +1160,8 @@ def _write_entry_lines(self, tw: TerminalWriter) -> None:
1147
1160
1148
1161
def toterminal (self , tw : TerminalWriter ) -> None :
1149
1162
if self .style == "short" :
1150
- assert self .reprfileloc is not None
1151
- self .reprfileloc .toterminal (tw )
1163
+ if self .reprfileloc :
1164
+ self .reprfileloc .toterminal (tw )
1152
1165
self ._write_entry_lines (tw )
1153
1166
if self .reprlocals :
1154
1167
self .reprlocals .toterminal (tw , indent = " " * 8 )
0 commit comments