Show More
@@ -296,6 +296,25 b' except Exception:' | |||
|
296 | 296 | tt.AssertPrints("ValueError", suppress=False): |
|
297 | 297 | ip.run_cell(self.SUPPRESS_CHAINING_CODE) |
|
298 | 298 | |
|
299 | def test_plain_direct_cause_error(self): | |
|
300 | with tt.AssertPrints(["KeyError", "NameError", "direct cause"]): | |
|
301 | ip.run_cell("%xmode Plain") | |
|
302 | ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE) | |
|
303 | ip.run_cell("%xmode Verbose") | |
|
304 | ||
|
305 | def test_plain_exception_during_handling_error(self): | |
|
306 | with tt.AssertPrints(["KeyError", "NameError", "During handling"]): | |
|
307 | ip.run_cell("%xmode Plain") | |
|
308 | ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE) | |
|
309 | ip.run_cell("%xmode Verbose") | |
|
310 | ||
|
311 | def test_plain_suppress_exception_chaining(self): | |
|
312 | with tt.AssertNotPrints("ZeroDivisionError"), \ | |
|
313 | tt.AssertPrints("ValueError", suppress=False): | |
|
314 | ip.run_cell("%xmode Plain") | |
|
315 | ip.run_cell(self.SUPPRESS_CHAINING_CODE) | |
|
316 | ip.run_cell("%xmode Verbose") | |
|
317 | ||
|
299 | 318 | |
|
300 | 319 | class RecursionTest(unittest.TestCase): |
|
301 | 320 | DEFINITIONS = """ |
@@ -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, e |
|
|
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,16 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 |
e |
|
|
619 | List of frames, see class docstring for details. | |
|
642 | etb : object | |
|
643 | If list: List of frames, see class docstring for details. | |
|
644 | If Traceback: Traceback of the exception. | |
|
620 | 645 | |
|
621 | 646 | tb_offset : int, optional |
|
622 | 647 | Number of frames in the traceback to skip. If not given, the |
|
623 | instance value is used (set in constructor). | |
|
648 | instance evalue is used (set in constructor). | |
|
624 | 649 | |
|
625 | 650 | context : int, optional |
|
626 | 651 | Number of lines of context information to print. |
@@ -629,6 +654,19 b' class ListTB(TBTools):' | |||
|
629 | 654 | ------- |
|
630 | 655 | String with formatted exception. |
|
631 | 656 | """ |
|
657 | # This is a workaround to get chained_exc_ids in recursive calls | |
|
658 | # etb should not be a tuple if structured_traceback is not recursive | |
|
659 | if isinstance(etb, tuple): | |
|
660 | etb, chained_exc_ids = etb | |
|
661 | else: | |
|
662 | chained_exc_ids = set() | |
|
663 | ||
|
664 | if isinstance(etb, list): | |
|
665 | elist = etb | |
|
666 | elif etb is not None: | |
|
667 | elist = self._extract_tb(etb) | |
|
668 | else: | |
|
669 | elist = [] | |
|
632 | 670 | tb_offset = self.tb_offset if tb_offset is None else tb_offset |
|
633 | 671 | Colors = self.Colors |
|
634 | 672 | out_list = [] |
@@ -641,9 +679,25 b' class ListTB(TBTools):' | |||
|
641 | 679 | (Colors.normalEm, Colors.Normal) + '\n') |
|
642 | 680 | out_list.extend(self._format_list(elist)) |
|
643 | 681 | # The exception info should be a single entry in the list. |
|
644 | lines = ''.join(self._format_exception_only(etype, value)) | |
|
682 | lines = ''.join(self._format_exception_only(etype, evalue)) | |
|
645 | 683 | out_list.append(lines) |
|
646 | 684 | |
|
685 | exception = self.get_parts_of_chained_exception(evalue) | |
|
686 | ||
|
687 | if exception and not id(exception[1]) in chained_exc_ids: | |
|
688 | chained_exception_message = self.prepare_chained_exception_message( | |
|
689 | evalue.__cause__)[0] | |
|
690 | etype, evalue, etb = exception | |
|
691 | # Trace exception to avoid infinite 'cause' loop | |
|
692 | chained_exc_ids.add(id(exception[1])) | |
|
693 | chained_exceptions_tb_offset = 0 | |
|
694 | out_list = ( | |
|
695 | self.structured_traceback( | |
|
696 | etype, evalue, (etb, chained_exc_ids), | |
|
697 | chained_exceptions_tb_offset, context) | |
|
698 | + chained_exception_message | |
|
699 | + out_list) | |
|
700 | ||
|
647 | 701 | return out_list |
|
648 | 702 | |
|
649 | 703 | def _format_list(self, extracted_list): |
@@ -763,7 +817,7 b' class ListTB(TBTools):' | |||
|
763 | 817 | etype : exception type |
|
764 | 818 | value : exception value |
|
765 | 819 | """ |
|
766 |
return ListTB.structured_traceback(self, etype, value |
|
|
820 | return ListTB.structured_traceback(self, etype, value) | |
|
767 | 821 | |
|
768 | 822 | def show_exception_only(self, etype, evalue): |
|
769 | 823 | """Only print the exception type and message, without a traceback. |
@@ -1013,16 +1067,6 b' class VerboseTB(TBTools):' | |||
|
1013 | 1067 | _format_traceback_lines(lnum, index, lines, Colors, lvals, |
|
1014 | 1068 | _line_format))) |
|
1015 | 1069 | |
|
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 | 1070 | def prepare_header(self, etype, long_version=False): |
|
1027 | 1071 | colors = self.Colors # just a shorthand + quicker name lookup |
|
1028 | 1072 | colorsnormal = colors.Normal # used a lot |
@@ -1117,20 +1161,6 b' class VerboseTB(TBTools):' | |||
|
1117 | 1161 | info('\nUnfortunately, your original traceback can not be constructed.\n') |
|
1118 | 1162 | return None |
|
1119 | 1163 | |
|
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 | 1164 | def structured_traceback(self, etype, evalue, etb, tb_offset=None, |
|
1135 | 1165 | number_of_lines_of_context=5): |
|
1136 | 1166 | """Return a nice text document describing the traceback.""" |
@@ -1294,9 +1324,8 b' class FormattedTB(VerboseTB, ListTB):' | |||
|
1294 | 1324 | # out-of-date source code. |
|
1295 | 1325 | self.check_cache() |
|
1296 | 1326 | # Now we can extract and format the exception |
|
1297 | elist = self._extract_tb(tb) | |
|
1298 | 1327 | return ListTB.structured_traceback( |
|
1299 |
self, etype, value, |
|
|
1328 | self, etype, value, tb, tb_offset, number_of_lines_of_context | |
|
1300 | 1329 | ) |
|
1301 | 1330 | |
|
1302 | 1331 | def stb2text(self, stb): |
General Comments 0
You need to be logged in to leave comments.
Login now