@@ -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
@@ -621,9 +622,11 @@ def errisinstance(
621
622
"""
622
623
return isinstance (self .value , exc )
623
624
624
- def _getreprcrash (self ) -> "ReprFileLocation" :
625
+ def _getreprcrash (self ) -> Optional [ "ReprFileLocation" ] :
625
626
exconly = self .exconly (tryshort = True )
626
627
entry = self .traceback .getcrashentry ()
628
+ if entry is None :
629
+ return None
627
630
path , lineno = entry .frame .code .raw .co_filename , entry .lineno
628
631
return ReprFileLocation (path , lineno + 1 , exconly )
629
632
@@ -670,7 +673,9 @@ def getrepr(
670
673
return ReprExceptionInfo (
671
674
reprtraceback = ReprTracebackNative (
672
675
traceback .format_exception (
673
- self .type , self .value , self .traceback [0 ]._rawentry
676
+ self .type ,
677
+ self .value ,
678
+ self .traceback [0 ]._rawentry if self .traceback else None ,
674
679
)
675
680
),
676
681
reprcrash = self ._getreprcrash (),
@@ -826,12 +831,16 @@ def repr_locals(self, locals: Mapping[str, object]) -> Optional["ReprLocals"]:
826
831
827
832
def repr_traceback_entry (
828
833
self ,
829
- entry : TracebackEntry ,
834
+ entry : Optional [ TracebackEntry ] ,
830
835
excinfo : Optional [ExceptionInfo [BaseException ]] = None ,
831
836
) -> "ReprEntry" :
832
837
lines : List [str ] = []
833
- style = entry ._repr_style if entry ._repr_style is not None else self .style
834
- if style in ("short" , "long" ):
838
+ style = (
839
+ entry ._repr_style
840
+ if entry is not None and entry ._repr_style is not None
841
+ else self .style
842
+ )
843
+ if style in ("short" , "long" ) and entry is not None :
835
844
source = self ._getentrysource (entry )
836
845
if source is None :
837
846
source = Source ("???" )
@@ -880,17 +889,21 @@ def repr_traceback(self, excinfo: ExceptionInfo[BaseException]) -> "ReprTracebac
880
889
else :
881
890
extraline = None
882
891
892
+ if not traceback :
893
+ if extraline is None :
894
+ extraline = "All traceback entries are hidden. Pass `--full-trace` to see hidden and internal frames."
895
+ entries = [self .repr_traceback_entry (None , excinfo )]
896
+ return ReprTraceback (entries , extraline , style = self .style )
897
+
883
898
last = traceback [- 1 ]
884
- entries = []
885
899
if self .style == "value" :
886
- reprentry = self .repr_traceback_entry (last , excinfo )
887
- entries .append (reprentry )
900
+ entries = [self .repr_traceback_entry (last , excinfo )]
888
901
return ReprTraceback (entries , None , style = self .style )
889
902
890
- for index , entry in enumerate ( traceback ):
891
- einfo = ( last == entry ) and excinfo or None
892
- reprentry = self . repr_traceback_entry ( entry , einfo )
893
- entries . append ( reprentry )
903
+ entries = [
904
+ self . repr_traceback_entry ( entry , excinfo if last == entry else None )
905
+ for entry in traceback
906
+ ]
894
907
return ReprTraceback (entries , extraline , style = self .style )
895
908
896
909
def _truncate_recursive_traceback (
@@ -947,6 +960,7 @@ def repr_excinfo(
947
960
seen : Set [int ] = set ()
948
961
while e is not None and id (e ) not in seen :
949
962
seen .add (id (e ))
963
+
950
964
if excinfo_ :
951
965
# Fall back to native traceback as a temporary workaround until
952
966
# full support for exception groups added to ExceptionInfo.
@@ -973,8 +987,8 @@ def repr_excinfo(
973
987
traceback .format_exception (type (e ), e , None )
974
988
)
975
989
reprcrash = None
976
-
977
990
repr_chain += [(reprtraceback , reprcrash , descr )]
991
+
978
992
if e .__cause__ is not None and self .chain :
979
993
e = e .__cause__
980
994
excinfo_ = ExceptionInfo .from_exception (e ) if e .__traceback__ else None
@@ -1057,7 +1071,7 @@ def toterminal(self, tw: TerminalWriter) -> None:
1057
1071
@dataclasses .dataclass (eq = False )
1058
1072
class ReprExceptionInfo (ExceptionRepr ):
1059
1073
reprtraceback : "ReprTraceback"
1060
- reprcrash : "ReprFileLocation"
1074
+ reprcrash : Optional [ "ReprFileLocation" ]
1061
1075
1062
1076
def toterminal (self , tw : TerminalWriter ) -> None :
1063
1077
self .reprtraceback .toterminal (tw )
@@ -1162,8 +1176,8 @@ def _write_entry_lines(self, tw: TerminalWriter) -> None:
1162
1176
1163
1177
def toterminal (self , tw : TerminalWriter ) -> None :
1164
1178
if self .style == "short" :
1165
- assert self .reprfileloc is not None
1166
- self .reprfileloc .toterminal (tw )
1179
+ if self .reprfileloc :
1180
+ self .reprfileloc .toterminal (tw )
1167
1181
self ._write_entry_lines (tw )
1168
1182
if self .reprlocals :
1169
1183
self .reprlocals .toterminal (tw , indent = " " * 8 )
0 commit comments