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