@@ -481,7 +481,7 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
481
481
# permit backwards compat with the existing API, otherwise we
482
482
# need stub thunk objects just to glue it together.
483
483
# Handle loops in __cause__ or __context__.
484
- _is_chained = _seen is not None
484
+ is_recursive_call = _seen is not None
485
485
if _seen is None :
486
486
_seen = set ()
487
487
_seen .add (id (exc_value ))
@@ -506,14 +506,12 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
506
506
self .__suppress_context__ = \
507
507
exc_value .__suppress_context__ if exc_value else False
508
508
509
- # Convert __cause__ and __context__ to TracebackExceptions, use a
510
- # queue to avoid recursion
511
- if not _is_chained :
509
+ # Convert __cause__ and __context__ to ` TracebackExceptions`s , use a
510
+ # queue to avoid recursion (only the top-level call gets _seen == None)
511
+ if not is_recursive_call :
512
512
queue = [(self , exc_value )]
513
513
while queue :
514
514
te , e = queue .pop ()
515
- # Gracefully handle (the way Python 2.4 and earlier did) the
516
- # case of being called with no type or value (None, None, None)
517
515
if (e and e .__cause__ is not None
518
516
and id (e .__cause__ ) not in _seen ):
519
517
cause = TracebackException (
@@ -631,28 +629,28 @@ def format(self, *, chain=True):
631
629
string in the output.
632
630
"""
633
631
634
- stack = []
632
+ output = []
635
633
exc = self
636
634
while exc :
637
635
if chain :
638
- if exc .__cause__ :
636
+ if exc .__cause__ is not None :
639
637
chained_msg = _cause_message
640
638
chained_exc = exc .__cause__
641
- elif exc .__context__ and not exc .__suppress_context__ :
639
+ elif (exc .__context__ is not None and
640
+ not exc .__suppress_context__ ):
642
641
chained_msg = _context_message
643
642
chained_exc = exc .__context__
644
643
else :
645
644
chained_msg = None
646
645
chained_exc = None
647
646
648
- stack .append ((chained_msg , exc ))
647
+ output .append ((chained_msg , exc ))
649
648
exc = chained_exc
650
649
else :
651
- stack .append ((None , exc ))
650
+ output .append ((None , exc ))
652
651
exc = None
653
652
654
- while stack :
655
- msg , exc = stack .pop ()
653
+ for msg , exc in reversed (output ):
656
654
if msg is not None :
657
655
yield msg
658
656
if exc .stack :
0 commit comments