##// END OF EJS Templates
Add chained exception to 'Plain' mode
Quentin Peter -
Show More
@@ -530,6 +530,30 b' class TBTools(colorable.Colorable):'
530 530
531 531 ostream = property(_get_ostream, _set_ostream)
532 532
533 def get_parts_of_chained_exception(self, evalue):
534 def get_chained_exception(exception_value):
535 cause = getattr(exception_value, '__cause__', None)
536 if cause:
537 return cause
538 if getattr(exception_value, '__suppress_context__', False):
539 return None
540 return getattr(exception_value, '__context__', None)
541
542 chained_evalue = get_chained_exception(evalue)
543
544 if chained_evalue:
545 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
546
547 def prepare_chained_exception_message(self, cause):
548 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
549 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
550
551 if cause:
552 message = [[direct_cause]]
553 else:
554 message = [[exception_during_handling]]
555 return message
556
533 557 def set_colors(self, *args, **kw):
534 558 """Shorthand access to the color table scheme selector method."""
535 559
@@ -603,7 +627,7 b' class ListTB(TBTools):'
603 627 self.ostream.write(self.text(etype, value, elist))
604 628 self.ostream.write('\n')
605 629
606 def structured_traceback(self, etype, value, elist, tb_offset=None,
630 def structured_traceback(self, etype, evalue, etb=None, tb_offset=None,
607 631 context=5):
608 632 """Return a color formatted string with the traceback info.
609 633
@@ -612,15 +636,15 b' class ListTB(TBTools):'
612 636 etype : exception type
613 637 Type of the exception raised.
614 638
615 value : object
639 evalue : object
616 640 Data stored in the exception
617 641
618 elist : list
619 List of frames, see class docstring for details.
642 etb : traceback
643 Traceback of the exception.
620 644
621 645 tb_offset : int, optional
622 646 Number of frames in the traceback to skip. If not given, the
623 instance value is used (set in constructor).
647 instance evalue is used (set in constructor).
624 648
625 649 context : int, optional
626 650 Number of lines of context information to print.
@@ -629,6 +653,14 b' class ListTB(TBTools):'
629 653 -------
630 654 String with formatted exception.
631 655 """
656 # if chained_exc_ids is None:
657 chained_exc_ids = set()
658 if isinstance(etb, list):
659 elist = etb
660 elif etb is not None:
661 elist = self._extract_tb(etb)
662 else:
663 elist = []
632 664 tb_offset = self.tb_offset if tb_offset is None else tb_offset
633 665 Colors = self.Colors
634 666 out_list = []
@@ -641,9 +673,21 b' class ListTB(TBTools):'
641 673 (Colors.normalEm, Colors.Normal) + '\n')
642 674 out_list.extend(self._format_list(elist))
643 675 # The exception info should be a single entry in the list.
644 lines = ''.join(self._format_exception_only(etype, value))
676 lines = ''.join(self._format_exception_only(etype, evalue))
645 677 out_list.append(lines)
646 678
679 exception = self.get_parts_of_chained_exception(evalue)
680
681 if exception and not id(exception[1]) in chained_exc_ids:
682 etype, evalue, etb = exception
683 chained_exc_ids.add(id(exception[1])) # trace exception to avoid infinite 'cause' loop
684 chained_exceptions_tb_offset = 0
685 out_list = (self.structured_traceback(
686 etype, evalue, etb, chained_exceptions_tb_offset, context)
687 + self.prepare_chained_exception_message(
688 evalue.__cause__)[0]
689 + out_list)
690
647 691 return out_list
648 692
649 693 def _format_list(self, extracted_list):
@@ -763,7 +807,7 b' class ListTB(TBTools):'
763 807 etype : exception type
764 808 value : exception value
765 809 """
766 return ListTB.structured_traceback(self, etype, value, [])
810 return ListTB.structured_traceback(self, etype, value)
767 811
768 812 def show_exception_only(self, etype, evalue):
769 813 """Only print the exception type and message, without a traceback.
@@ -1013,16 +1057,6 b' class VerboseTB(TBTools):'
1013 1057 _format_traceback_lines(lnum, index, lines, Colors, lvals,
1014 1058 _line_format)))
1015 1059
1016 def prepare_chained_exception_message(self, cause):
1017 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
1018 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
1019
1020 if cause:
1021 message = [[direct_cause]]
1022 else:
1023 message = [[exception_during_handling]]
1024 return message
1025
1026 1060 def prepare_header(self, etype, long_version=False):
1027 1061 colors = self.Colors # just a shorthand + quicker name lookup
1028 1062 colorsnormal = colors.Normal # used a lot
@@ -1117,20 +1151,6 b' class VerboseTB(TBTools):'
1117 1151 info('\nUnfortunately, your original traceback can not be constructed.\n')
1118 1152 return None
1119 1153
1120 def get_parts_of_chained_exception(self, evalue):
1121 def get_chained_exception(exception_value):
1122 cause = getattr(exception_value, '__cause__', None)
1123 if cause:
1124 return cause
1125 if getattr(exception_value, '__suppress_context__', False):
1126 return None
1127 return getattr(exception_value, '__context__', None)
1128
1129 chained_evalue = get_chained_exception(evalue)
1130
1131 if chained_evalue:
1132 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
1133
1134 1154 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
1135 1155 number_of_lines_of_context=5):
1136 1156 """Return a nice text document describing the traceback."""
@@ -1294,9 +1314,8 b' class FormattedTB(VerboseTB, ListTB):'
1294 1314 # out-of-date source code.
1295 1315 self.check_cache()
1296 1316 # Now we can extract and format the exception
1297 elist = self._extract_tb(tb)
1298 1317 return ListTB.structured_traceback(
1299 self, etype, value, elist, tb_offset, number_of_lines_of_context
1318 self, etype, value, tb, tb_offset, number_of_lines_of_context
1300 1319 )
1301 1320
1302 1321 def stb2text(self, stb):
General Comments 0
You need to be logged in to leave comments. Login now