Show More
@@ -1735,7 +1735,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1735 | 1735 | This hook should be used sparingly, only in places which are not likely |
|
1736 | 1736 | to be true IPython errors. |
|
1737 | 1737 | """ |
|
1738 | self.showtraceback((etype,value,tb),tb_offset=0) | |
|
1738 | self.showtraceback((etype, value, tb), tb_offset=0) | |
|
1739 | 1739 | |
|
1740 | 1740 | def _get_exc_info(self, exc_tuple=None): |
|
1741 | 1741 | """get exc_info from a given tuple, sys.exc_info() or sys.last_type etc. |
@@ -1776,7 +1776,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
1776 | 1776 | """ |
|
1777 | 1777 | self.write_err("UsageError: %s" % exc) |
|
1778 | 1778 | |
|
1779 |
def showtraceback(self,exc_tuple |
|
|
1779 | def showtraceback(self, exc_tuple=None, filename=None, tb_offset=None, | |
|
1780 | 1780 | exception_only=False): |
|
1781 | 1781 | """Display the exception that just occurred. |
|
1782 | 1782 | |
@@ -2918,10 +2918,9 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2918 | 2918 | False : successful execution. |
|
2919 | 2919 | True : an error occurred. |
|
2920 | 2920 | """ |
|
2921 | ||
|
2922 | 2921 | # Set our own excepthook in case the user code tries to call it |
|
2923 | 2922 | # directly, so that the IPython crash handler doesn't get triggered |
|
2924 | old_excepthook,sys.excepthook = sys.excepthook, self.excepthook | |
|
2923 | old_excepthook, sys.excepthook = sys.excepthook, self.excepthook | |
|
2925 | 2924 | |
|
2926 | 2925 | # we save the original sys.excepthook in the instance, in case config |
|
2927 | 2926 | # code (such as magics) needs access to it. |
@@ -2939,8 +2938,8 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2939 | 2938 | self.showtraceback(exception_only=True) |
|
2940 | 2939 | warn("To exit: use 'exit', 'quit', or Ctrl-D.", level=1) |
|
2941 | 2940 | except self.custom_exceptions: |
|
2942 | etype,value,tb = sys.exc_info() | |
|
2943 | self.CustomTB(etype,value,tb) | |
|
2941 | etype, value, tb = sys.exc_info() | |
|
2942 | self.CustomTB(etype, value, tb) | |
|
2944 | 2943 | except: |
|
2945 | 2944 | self.showtraceback() |
|
2946 | 2945 | else: |
@@ -74,10 +74,10 b' Inheritance diagram:' | |||
|
74 | 74 | |
|
75 | 75 | # ***************************************************************************** |
|
76 | 76 | # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu> |
|
77 |
# |
|
|
77 | # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu> | |
|
78 | 78 | # |
|
79 |
# |
|
|
80 |
# |
|
|
79 | # Distributed under the terms of the BSD License. The full license is in | |
|
80 | # the file COPYING, distributed as part of this software. | |
|
81 | 81 | #***************************************************************************** |
|
82 | 82 | |
|
83 | 83 | from __future__ import unicode_literals |
@@ -262,7 +262,6 b' def _fixed_getinnerframes(etb, context=1, tb_offset=0):' | |||
|
262 | 262 | LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5 |
|
263 | 263 | |
|
264 | 264 | records = fix_frame_records_filenames(inspect.getinnerframes(etb, context)) |
|
265 | ||
|
266 | 265 | # If the error is at the console, don't build any context, since it would |
|
267 | 266 | # otherwise produce 5 blank lines printed out (there is no file at the |
|
268 | 267 | # console) |
@@ -274,6 +273,15 b' def _fixed_getinnerframes(etb, context=1, tb_offset=0):' | |||
|
274 | 273 | except IndexError: |
|
275 | 274 | pass |
|
276 | 275 | |
|
276 | # we don't want to truncate too much | |
|
277 | # when normal exception occurs there are two records usually | |
|
278 | # first is from ipython and has pre_hooks information and so on | |
|
279 | # however sometimes we have tracebacks without additional ipython information | |
|
280 | # for example from nested traceback (python3 exceptions have __context__ which | |
|
281 | # stores information about previous exceptions) | |
|
282 | if tb_offset >= len(records): | |
|
283 | tb_offset = len(records) - 2 | |
|
284 | ||
|
277 | 285 | aux = traceback.extract_tb(etb) |
|
278 | 286 | assert len(records) == len(aux) |
|
279 | 287 | for i, (file, lnum, _, _) in zip(range(len(records)), aux): |
@@ -516,7 +524,7 b' class ListTB(TBTools):' | |||
|
516 | 524 | ## out_list.append(lines[-1]) |
|
517 | 525 | |
|
518 | 526 | # This means it was indenting everything but the last line by a little |
|
519 | # bit. I've disabled this for now, but if we see ugliness somewhre we | |
|
527 | # bit. I've disabled this for now, but if we see ugliness somewhere we | |
|
520 | 528 | # can restore it. |
|
521 | 529 | |
|
522 | 530 | return out_list |
@@ -556,7 +564,6 b' class ListTB(TBTools):' | |||
|
556 | 564 | item += '%s %s%s\n' % (Colors.line, line.strip(), |
|
557 | 565 | Colors.Normal) |
|
558 | 566 | list.append(item) |
|
559 | #from pprint import pformat; print 'LISTTB', pformat(list) # dbg | |
|
560 | 567 | return list |
|
561 | 568 | |
|
562 | 569 | def _format_exception_only(self, etype, value): |
@@ -582,7 +589,6 b' class ListTB(TBTools):' | |||
|
582 | 589 | else: |
|
583 | 590 | if issubclass(etype, SyntaxError): |
|
584 | 591 | have_filedata = True |
|
585 | #print 'filename is',filename # dbg | |
|
586 | 592 | if not value.filename: value.filename = "<string>" |
|
587 | 593 | if value.lineno: |
|
588 | 594 | lineno = value.lineno |
@@ -697,107 +703,14 b' class VerboseTB(TBTools):' | |||
|
697 | 703 | check_cache = linecache.checkcache |
|
698 | 704 | self.check_cache = check_cache |
|
699 | 705 | |
|
700 | def structured_traceback(self, etype, evalue, etb, tb_offset=None, | |
|
701 | context=5): | |
|
702 | """Return a nice text document describing the traceback.""" | |
|
703 | ||
|
704 | tb_offset = self.tb_offset if tb_offset is None else tb_offset | |
|
705 | ||
|
706 | # some locals | |
|
707 | try: | |
|
708 | etype = etype.__name__ | |
|
709 | except AttributeError: | |
|
710 | pass | |
|
706 | def format_records(self, records): | |
|
711 | 707 | Colors = self.Colors # just a shorthand + quicker name lookup |
|
712 | 708 | ColorsNormal = Colors.Normal # used a lot |
|
713 | 709 | col_scheme = self.color_scheme_table.active_scheme_name |
|
714 | 710 | indent = ' ' * INDENT_SIZE |
|
715 | 711 | em_normal = '%s\n%s%s' % (Colors.valEm, indent, ColorsNormal) |
|
716 | 712 | undefined = '%sundefined%s' % (Colors.em, ColorsNormal) |
|
717 | exc = '%s%s%s' % (Colors.excName, etype, ColorsNormal) | |
|
718 | ||
|
719 | # some internal-use functions | |
|
720 | def text_repr(value): | |
|
721 | """Hopefully pretty robust repr equivalent.""" | |
|
722 | # this is pretty horrible but should always return *something* | |
|
723 | try: | |
|
724 | return pydoc.text.repr(value) | |
|
725 | except KeyboardInterrupt: | |
|
726 | raise | |
|
727 | except: | |
|
728 | try: | |
|
729 | return repr(value) | |
|
730 | except KeyboardInterrupt: | |
|
731 | raise | |
|
732 | except: | |
|
733 | try: | |
|
734 | # all still in an except block so we catch | |
|
735 | # getattr raising | |
|
736 | name = getattr(value, '__name__', None) | |
|
737 | if name: | |
|
738 | # ick, recursion | |
|
739 | return text_repr(name) | |
|
740 | klass = getattr(value, '__class__', None) | |
|
741 | if klass: | |
|
742 | return '%s instance' % text_repr(klass) | |
|
743 | except KeyboardInterrupt: | |
|
744 | raise | |
|
745 | except: | |
|
746 | return 'UNRECOVERABLE REPR FAILURE' | |
|
747 | ||
|
748 | def eqrepr(value, repr=text_repr): | |
|
749 | return '=%s' % repr(value) | |
|
750 | ||
|
751 | def nullrepr(value, repr=text_repr): | |
|
752 | return '' | |
|
753 | ||
|
754 | # meat of the code begins | |
|
755 | try: | |
|
756 | etype = etype.__name__ | |
|
757 | except AttributeError: | |
|
758 | pass | |
|
759 | ||
|
760 | if self.long_header: | |
|
761 | # Header with the exception type, python version, and date | |
|
762 | pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable | |
|
763 | date = time.ctime(time.time()) | |
|
764 | ||
|
765 | head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-' * 75, ColorsNormal, | |
|
766 | exc, ' ' * (75 - len(str(etype)) - len(pyver)), | |
|
767 | pyver, date.rjust(75) ) | |
|
768 | head += "\nA problem occured executing Python code. Here is the sequence of function" \ | |
|
769 | "\ncalls leading up to the error, with the most recent (innermost) call last." | |
|
770 | else: | |
|
771 | # Simplified header | |
|
772 | head = '%s%s%s\n%s%s' % (Colors.topline, '-' * 75, ColorsNormal, exc, | |
|
773 | 'Traceback (most recent call last)'. \ | |
|
774 | rjust(75 - len(str(etype))) ) | |
|
775 | 713 | frames = [] |
|
776 | # Flush cache before calling inspect. This helps alleviate some of the | |
|
777 | # problems with python 2.3's inspect.py. | |
|
778 | ##self.check_cache() | |
|
779 | # Drop topmost frames if requested | |
|
780 | try: | |
|
781 | # Try the default getinnerframes and Alex's: Alex's fixes some | |
|
782 | # problems, but it generates empty tracebacks for console errors | |
|
783 | # (5 blanks lines) where none should be returned. | |
|
784 | #records = inspect.getinnerframes(etb, context)[tb_offset:] | |
|
785 | #print 'python records:', records # dbg | |
|
786 | records = _fixed_getinnerframes(etb, context, tb_offset) | |
|
787 | #print 'alex records:', records # dbg | |
|
788 | except: | |
|
789 | ||
|
790 | # FIXME: I've been getting many crash reports from python 2.3 | |
|
791 | # users, traceable to inspect.py. If I can find a small test-case | |
|
792 | # to reproduce this, I should either write a better workaround or | |
|
793 | # file a bug report against inspect (if that's the real problem). | |
|
794 | # So far, I haven't been able to find an isolated example to | |
|
795 | # reproduce the problem. | |
|
796 | inspect_error() | |
|
797 | traceback.print_exc(file=self.ostream) | |
|
798 | info('\nUnfortunately, your original traceback can not be constructed.\n') | |
|
799 | return '' | |
|
800 | ||
|
801 | 714 | # build some color string templates outside these nested loops |
|
802 | 715 | tpl_link = '%s%%s%s' % (Colors.filenameEm, ColorsNormal) |
|
803 | 716 | tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm, |
@@ -808,11 +721,11 b' class VerboseTB(TBTools):' | |||
|
808 | 721 | tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal, |
|
809 | 722 | Colors.vName, ColorsNormal) |
|
810 | 723 | tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal) |
|
724 | ||
|
811 | 725 | tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal) |
|
812 | 726 | tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm, Colors.line, |
|
813 | 727 | ColorsNormal) |
|
814 | 728 | |
|
815 | # now, loop over all records printing context and info | |
|
816 | 729 | abspath = os.path.abspath |
|
817 | 730 | for frame, file, lnum, func, lines, index in records: |
|
818 | 731 | #print '*** record:',file,lnum,func,lines,index # dbg |
@@ -820,7 +733,7 b' class VerboseTB(TBTools):' | |||
|
820 | 733 | file = '?' |
|
821 | 734 | elif not (file.startswith(str("<")) and file.endswith(str(">"))): |
|
822 | 735 | # Guess that filenames like <string> aren't real filenames, so |
|
823 |
# don't call abspath on them. |
|
|
736 | # don't call abspath on them. | |
|
824 | 737 | try: |
|
825 | 738 | file = abspath(file) |
|
826 | 739 | except OSError: |
@@ -953,6 +866,47 b' class VerboseTB(TBTools):' | |||
|
953 | 866 | _format_traceback_lines(lnum, index, lines, Colors, lvals, |
|
954 | 867 | col_scheme)))) |
|
955 | 868 | |
|
869 | return frames | |
|
870 | ||
|
871 | def prepare_chained_exception_message(self, cause): | |
|
872 | direct_cause = "\nThe above exception was the direct cause of the following exception:\n" | |
|
873 | exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n" | |
|
874 | ||
|
875 | colors = self.Colors # just a shorthand + quicker name lookup | |
|
876 | colorsnormal = colors.Normal # used a lot | |
|
877 | head = '%s%s%s' % (colors.topline, '-' * 75, colorsnormal) | |
|
878 | if cause: | |
|
879 | message = [[head, direct_cause]] | |
|
880 | else: | |
|
881 | message = [[head, exception_during_handling]] | |
|
882 | return message | |
|
883 | ||
|
884 | def prepare_header(self, etype, long_version=False): | |
|
885 | colors = self.Colors # just a shorthand + quicker name lookup | |
|
886 | colorsnormal = colors.Normal # used a lot | |
|
887 | exc = '%s%s%s' % (colors.excName, etype, colorsnormal) | |
|
888 | if long_version: | |
|
889 | # Header with the exception type, python version, and date | |
|
890 | pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable | |
|
891 | date = time.ctime(time.time()) | |
|
892 | ||
|
893 | head = '%s%s%s\n%s%s%s\n%s' % (colors.topline, '-' * 75, colorsnormal, | |
|
894 | exc, ' ' * (75 - len(str(etype)) - len(pyver)), | |
|
895 | pyver, date.rjust(75) ) | |
|
896 | head += "\nA problem occurred executing Python code. Here is the sequence of function" \ | |
|
897 | "\ncalls leading up to the error, with the most recent (innermost) call last." | |
|
898 | else: | |
|
899 | # Simplified header | |
|
900 | head = '%s%s%s\n%s%s' % (colors.topline, '-' * 75, colorsnormal, exc, | |
|
901 | 'Traceback (most recent call last)'. \ | |
|
902 | rjust(75 - len(str(etype))) ) | |
|
903 | ||
|
904 | return head | |
|
905 | ||
|
906 | def format_exception(self, etype, evalue): | |
|
907 | colors = self.Colors # just a shorthand + quicker name lookup | |
|
908 | colorsnormal = colors.Normal # used a lot | |
|
909 | indent = ' ' * INDENT_SIZE | |
|
956 | 910 | # Get (safely) a string form of the exception info |
|
957 | 911 | try: |
|
958 | 912 | etype_str, evalue_str = map(str, (etype, evalue)) |
@@ -961,38 +915,119 b' class VerboseTB(TBTools):' | |||
|
961 | 915 | etype, evalue = str, sys.exc_info()[:2] |
|
962 | 916 | etype_str, evalue_str = map(str, (etype, evalue)) |
|
963 | 917 | # ... and format it |
|
964 |
exception = ['%s%s%s: %s' % ( |
|
|
965 |
|
|
|
918 | exception = ['%s%s%s: %s' % (colors.excName, etype_str, | |
|
919 | colorsnormal, py3compat.cast_unicode(evalue_str))] | |
|
920 | ||
|
966 | 921 | if (not py3compat.PY3) and type(evalue) is types.InstanceType: |
|
967 | 922 | try: |
|
968 | 923 | names = [w for w in dir(evalue) if isinstance(w, py3compat.string_types)] |
|
969 | 924 | except: |
|
970 | # Every now and then, an object with funny inernals blows up | |
|
925 | # Every now and then, an object with funny internals blows up | |
|
971 | 926 | # when dir() is called on it. We do the best we can to report |
|
972 | 927 | # the problem and continue |
|
973 | 928 | _m = '%sException reporting error (object with broken dir())%s:' |
|
974 |
exception.append(_m % ( |
|
|
929 | exception.append(_m % (colors.excName, colorsnormal)) | |
|
975 | 930 | etype_str, evalue_str = map(str, sys.exc_info()[:2]) |
|
976 |
exception.append('%s%s%s: %s' % ( |
|
|
977 |
|
|
|
931 | exception.append('%s%s%s: %s' % (colors.excName, etype_str, | |
|
932 | colorsnormal, py3compat.cast_unicode(evalue_str))) | |
|
978 | 933 | names = [] |
|
979 | 934 | for name in names: |
|
980 | 935 | value = text_repr(getattr(evalue, name)) |
|
981 | 936 | exception.append('\n%s%s = %s' % (indent, name, value)) |
|
937 | return exception | |
|
982 | 938 | |
|
983 | # vds: >> | |
|
984 |
|
|
|
985 | filepath, lnum = records[-1][1:3] | |
|
986 | #print "file:", str(file), "linenb", str(lnum) # dbg | |
|
987 | filepath = os.path.abspath(filepath) | |
|
988 | ipinst = get_ipython() | |
|
989 | if ipinst is not None: | |
|
990 | ipinst.hooks.synchronize_with_editor(filepath, lnum, 0) | |
|
991 | # vds: << | |
|
939 | def get_records(self, etb, number_of_lines_of_context, tb_offset): | |
|
940 | try: | |
|
941 | # Try the default getinnerframes and Alex's: Alex's fixes some | |
|
942 | # problems, but it generates empty tracebacks for console errors | |
|
943 | # (5 blanks lines) where none should be returned. | |
|
944 | return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset) | |
|
945 | except: | |
|
946 | ||
|
947 | # FIXME: I've been getting many crash reports from python 2.3 | |
|
948 | # users, traceable to inspect.py. If I can find a small test-case | |
|
949 | # to reproduce this, I should either write a better workaround or | |
|
950 | # file a bug report against inspect (if that's the real problem). | |
|
951 | # So far, I haven't been able to find an isolated example to | |
|
952 | # reproduce the problem. | |
|
953 | inspect_error() | |
|
954 | traceback.print_exc(file=self.ostream) | |
|
955 | info('\nUnfortunately, your original traceback can not be constructed.\n') | |
|
956 | return None | |
|
992 | 957 | |
|
993 | # return all our info assembled as a single string | |
|
994 | # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) ) | |
|
995 | return [head] + frames + [''.join(exception[0])] | |
|
958 | def get_exception_from_context(self, evalue): | |
|
959 | if hasattr(evalue, '__context__'): # and not evalue.__suppress_context__: | |
|
960 | context = evalue.__context__ | |
|
961 | if not context: | |
|
962 | return None | |
|
963 | else: | |
|
964 | exception_traceback = context.__traceback__ | |
|
965 | exception_type = context.__class__.__name__ | |
|
966 | return exception_type, context, exception_traceback | |
|
967 | else: | |
|
968 | return None | |
|
969 | ||
|
970 | def structured_traceback(self, etype, evalue, etb, tb_offset=None, | |
|
971 | number_of_lines_of_context=5): | |
|
972 | """Return a nice text document describing the traceback.""" | |
|
973 | tb_offset = self.tb_offset if tb_offset is None else tb_offset | |
|
974 | ||
|
975 | # some locals | |
|
976 | try: | |
|
977 | etype = etype.__name__ | |
|
978 | except AttributeError: | |
|
979 | pass | |
|
980 | ||
|
981 | structured_traceback_parts = [] | |
|
982 | ||
|
983 | exceptions = [] | |
|
984 | current_exception_value = evalue | |
|
985 | if py3compat.PY3: | |
|
986 | while current_exception_value: | |
|
987 | head = self.prepare_header(etype, self.long_header) | |
|
988 | records = self.get_records(etb, number_of_lines_of_context, tb_offset) | |
|
989 | ||
|
990 | frames = self.format_records(records) | |
|
991 | if records is None: | |
|
992 | return "" | |
|
993 | ||
|
994 | formatted_exception = self.format_exception(etype, current_exception_value) | |
|
995 | if records: | |
|
996 | filepath, lnum = records[-1][1:3] | |
|
997 | filepath = os.path.abspath(filepath) | |
|
998 | ipinst = get_ipython() | |
|
999 | if ipinst is not None: | |
|
1000 | ipinst.hooks.synchronize_with_editor(filepath, lnum, 0) | |
|
1001 | ||
|
1002 | exceptions += [[head] + frames + [''.join(formatted_exception[0])]] | |
|
1003 | ||
|
1004 | exception = self.get_exception_from_context(current_exception_value) | |
|
1005 | if exception: | |
|
1006 | exceptions += self.prepare_chained_exception_message(current_exception_value.__cause__) | |
|
1007 | etype, current_exception_value, etb = exception | |
|
1008 | else: | |
|
1009 | break | |
|
1010 | ||
|
1011 | for exception in reversed(exceptions): | |
|
1012 | structured_traceback_parts += exception | |
|
1013 | else: | |
|
1014 | head = self.prepare_header(etype, self.long_header) | |
|
1015 | records = self.get_records(etb, number_of_lines_of_context, tb_offset) | |
|
1016 | ||
|
1017 | frames = self.format_records(records) | |
|
1018 | if records is None: | |
|
1019 | return "" | |
|
1020 | ||
|
1021 | exception = self.format_exception(etype, evalue) | |
|
1022 | if records: | |
|
1023 | filepath, lnum = records[-1][1:3] | |
|
1024 | filepath = os.path.abspath(filepath) | |
|
1025 | ipinst = get_ipython() | |
|
1026 | if ipinst is not None: | |
|
1027 | ipinst.hooks.synchronize_with_editor(filepath, lnum, 0) | |
|
1028 | structured_traceback_parts.append([head] + frames + [''.join(exception[0])]) | |
|
1029 | ||
|
1030 | return structured_traceback_parts | |
|
996 | 1031 | |
|
997 | 1032 | def debugger(self, force=False): |
|
998 | 1033 | """Call up the pdb debugger if desired, always clean up the tb |
@@ -1100,13 +1135,13 b' class FormattedTB(VerboseTB, ListTB):' | |||
|
1100 | 1135 | else: |
|
1101 | 1136 | return None |
|
1102 | 1137 | |
|
1103 | def structured_traceback(self, etype, value, tb, tb_offset=None, context=5): | |
|
1138 | def structured_traceback(self, etype, value, tb, tb_offset=None, number_of_lines_of_context=5): | |
|
1104 | 1139 | tb_offset = self.tb_offset if tb_offset is None else tb_offset |
|
1105 | 1140 | mode = self.mode |
|
1106 | 1141 | if mode in self.verbose_modes: |
|
1107 | 1142 | # Verbose modes need a full traceback |
|
1108 | 1143 | return VerboseTB.structured_traceback( |
|
1109 | self, etype, value, tb, tb_offset, context | |
|
1144 | self, etype, value, tb, tb_offset, number_of_lines_of_context | |
|
1110 | 1145 | ) |
|
1111 | 1146 | else: |
|
1112 | 1147 | # We must check the source cache because otherwise we can print |
@@ -1115,7 +1150,7 b' class FormattedTB(VerboseTB, ListTB):' | |||
|
1115 | 1150 | # Now we can extract and format the exception |
|
1116 | 1151 | elist = self._extract_tb(tb) |
|
1117 | 1152 | return ListTB.structured_traceback( |
|
1118 | self, etype, value, elist, tb_offset, context | |
|
1153 | self, etype, value, elist, tb_offset, number_of_lines_of_context | |
|
1119 | 1154 | ) |
|
1120 | 1155 | |
|
1121 | 1156 | def stb2text(self, stb): |
@@ -1129,7 +1164,7 b' class FormattedTB(VerboseTB, ListTB):' | |||
|
1129 | 1164 | If mode is not specified, cycles through the available modes.""" |
|
1130 | 1165 | |
|
1131 | 1166 | if not mode: |
|
1132 |
new_idx = ( |
|
|
1167 | new_idx = (self.valid_modes.index(self.mode) + 1 ) % \ | |
|
1133 | 1168 | len(self.valid_modes) |
|
1134 | 1169 | self.mode = self.valid_modes[new_idx] |
|
1135 | 1170 | elif mode not in self.valid_modes: |
@@ -1193,12 +1228,12 b' class AutoFormattedTB(FormattedTB):' | |||
|
1193 | 1228 | print("\nKeyboardInterrupt") |
|
1194 | 1229 | |
|
1195 | 1230 | def structured_traceback(self, etype=None, value=None, tb=None, |
|
1196 | tb_offset=None, context=5): | |
|
1231 | tb_offset=None, number_of_lines_of_context=5): | |
|
1197 | 1232 | if etype is None: |
|
1198 | 1233 | etype, value, tb = sys.exc_info() |
|
1199 | 1234 | self.tb = tb |
|
1200 | 1235 | return FormattedTB.structured_traceback( |
|
1201 | self, etype, value, tb, tb_offset, context) | |
|
1236 | self, etype, value, tb, tb_offset, number_of_lines_of_context) | |
|
1202 | 1237 | |
|
1203 | 1238 | |
|
1204 | 1239 | #--------------------------------------------------------------------------- |
@@ -1221,6 +1256,7 b' class SyntaxTB(ListTB):' | |||
|
1221 | 1256 | |
|
1222 | 1257 | def __call__(self, etype, value, elist): |
|
1223 | 1258 | self.last_syntax_error = value |
|
1259 | ||
|
1224 | 1260 | ListTB.__call__(self, etype, value, elist) |
|
1225 | 1261 | |
|
1226 | 1262 | def structured_traceback(self, etype, value, elist, tb_offset=None, |
@@ -1249,7 +1285,48 b' class SyntaxTB(ListTB):' | |||
|
1249 | 1285 | return ''.join(stb) |
|
1250 | 1286 | |
|
1251 | 1287 | |
|
1288 | # some internal-use functions | |
|
1289 | def text_repr(value): | |
|
1290 | """Hopefully pretty robust repr equivalent.""" | |
|
1291 | # this is pretty horrible but should always return *something* | |
|
1292 | try: | |
|
1293 | return pydoc.text.repr(value) | |
|
1294 | except KeyboardInterrupt: | |
|
1295 | raise | |
|
1296 | except: | |
|
1297 | try: | |
|
1298 | return repr(value) | |
|
1299 | except KeyboardInterrupt: | |
|
1300 | raise | |
|
1301 | except: | |
|
1302 | try: | |
|
1303 | # all still in an except block so we catch | |
|
1304 | # getattr raising | |
|
1305 | name = getattr(value, '__name__', None) | |
|
1306 | if name: | |
|
1307 | # ick, recursion | |
|
1308 | return text_repr(name) | |
|
1309 | klass = getattr(value, '__class__', None) | |
|
1310 | if klass: | |
|
1311 | return '%s instance' % text_repr(klass) | |
|
1312 | except KeyboardInterrupt: | |
|
1313 | raise | |
|
1314 | except: | |
|
1315 | return 'UNRECOVERABLE REPR FAILURE' | |
|
1316 | ||
|
1317 | ||
|
1318 | def eqrepr(value, repr=text_repr): | |
|
1319 | return '=%s' % repr(value) | |
|
1320 | ||
|
1321 | ||
|
1322 | def nullrepr(value, repr=text_repr): | |
|
1323 | return '' | |
|
1324 | ||
|
1325 | ||
|
1326 | ||
|
1327 | ||
|
1252 | 1328 | #---------------------------------------------------------------------------- |
|
1329 | ||
|
1253 | 1330 | # module testing (minimal) |
|
1254 | 1331 | if __name__ == "__main__": |
|
1255 | 1332 | def spam(c, d_e): |
General Comments 0
You need to be logged in to leave comments.
Login now