##// END OF EJS Templates
Annotate and check typing in ultratb
Matthias Bussonnier -
Show More
@@ -95,6 +95,8 b' import pydoc'
95 95 import sys
96 96 import time
97 97 import traceback
98 from types import TracebackType
99 from typing import Tuple, List, Any, Optional
98 100
99 101 import stack_data
100 102 from pygments.formatters.terminal256 import Terminal256Formatter
@@ -130,7 +132,7 b" DEFAULT_SCHEME = 'NoColor'"
130 132 # (SyntaxErrors have to be treated specially because they have no traceback)
131 133
132 134
133 def _format_traceback_lines(lines, Colors, has_colors, lvals):
135 def _format_traceback_lines(lines, Colors, has_colors: bool, lvals):
134 136 """
135 137 Format tracebacks lines with pointing arrow, leading numbers...
136 138
@@ -250,21 +252,26 b' class TBTools(colorable.Colorable):'
250 252
251 253 ostream = property(_get_ostream, _set_ostream)
252 254
253 def get_parts_of_chained_exception(self, evalue):
254 def get_chained_exception(exception_value):
255 cause = getattr(exception_value, '__cause__', None)
256 if cause:
257 return cause
258 if getattr(exception_value, '__suppress_context__', False):
259 return None
260 return getattr(exception_value, '__context__', None)
255 @staticmethod
256 def _get_chained_exception(exception_value):
257 cause = getattr(exception_value, "__cause__", None)
258 if cause:
259 return cause
260 if getattr(exception_value, "__suppress_context__", False):
261 return None
262 return getattr(exception_value, "__context__", None)
263
264 def get_parts_of_chained_exception(
265 self, evalue
266 ) -> Optional[Tuple[type, BaseException, TracebackType]]:
261 267
262 chained_evalue = get_chained_exception(evalue)
268 chained_evalue = self._get_chained_exception(evalue)
263 269
264 270 if chained_evalue:
265 271 return chained_evalue.__class__, chained_evalue, chained_evalue.__traceback__
272 return None
266 273
267 def prepare_chained_exception_message(self, cause):
274 def prepare_chained_exception_message(self, cause) -> List[Any]:
268 275 direct_cause = "\nThe above exception was the direct cause of the following exception:\n"
269 276 exception_during_handling = "\nDuring handling of the above exception, another exception occurred:\n"
270 277
@@ -275,7 +282,7 b' class TBTools(colorable.Colorable):'
275 282 return message
276 283
277 284 @property
278 def has_colors(self):
285 def has_colors(self) -> bool:
279 286 return self.color_scheme_table.active_scheme_name.lower() != "nocolor"
280 287
281 288 def set_colors(self, *args, **kw):
@@ -304,7 +311,7 b' class TBTools(colorable.Colorable):'
304 311 """Convert a structured traceback (a list) to a string."""
305 312 return '\n'.join(stb)
306 313
307 def text(self, etype, value, tb, tb_offset=None, context=5):
314 def text(self, etype, value, tb, tb_offset: Optional[int] = None, context=5):
308 315 """Return formatted traceback.
309 316
310 317 Subclasses may override this if they add extra arguments.
@@ -313,8 +320,9 b' class TBTools(colorable.Colorable):'
313 320 tb_offset, context)
314 321 return self.stb2text(tb_list)
315 322
316 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
317 context=5, mode=None):
323 def structured_traceback(
324 self, etype, evalue, tb, tb_offset: Optional[int] = None, context=5, mode=None
325 ):
318 326 """Return a list of traceback frames.
319 327
320 328 Must be implemented by each class.
@@ -357,8 +365,14 b' class ListTB(TBTools):'
357 365 else:
358 366 return None
359 367
360 def structured_traceback(self, etype, evalue, etb=None, tb_offset=None,
361 context=5):
368 def structured_traceback(
369 self,
370 etype: type,
371 evalue: BaseException,
372 etb: Optional[TracebackType] = None,
373 tb_offset: Optional[int] = None,
374 context=5,
375 ):
362 376 """Return a color formatted string with the traceback info.
363 377
364 378 Parameters
@@ -367,7 +381,7 b' class ListTB(TBTools):'
367 381 Type of the exception raised.
368 382 evalue : object
369 383 Data stored in the exception
370 etb : object
384 etb : list | TracebackType | None
371 385 If list: List of frames, see class docstring for details.
372 386 If Traceback: Traceback of the exception.
373 387 tb_offset : int, optional
@@ -394,6 +408,7 b' class ListTB(TBTools):'
394 408 else:
395 409 elist = []
396 410 tb_offset = self.tb_offset if tb_offset is None else tb_offset
411 assert isinstance(tb_offset, int)
397 412 Colors = self.Colors
398 413 out_list = []
399 414 if elist:
@@ -594,10 +609,19 b' class VerboseTB(TBTools):'
594 609 traceback, to be used with alternate interpreters (because their own code
595 610 would appear in the traceback)."""
596 611
597 def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
598 tb_offset=0, long_header=False, include_vars=True,
599 check_cache=None, debugger_cls = None,
600 parent=None, config=None):
612 def __init__(
613 self,
614 color_scheme: str = "Linux",
615 call_pdb: bool = False,
616 ostream=None,
617 tb_offset: int = 0,
618 long_header: bool = False,
619 include_vars: bool = True,
620 check_cache=None,
621 debugger_cls=None,
622 parent=None,
623 config=None,
624 ):
601 625 """Specify traceback offset, headers and color scheme.
602 626
603 627 Define how many frames to drop from the tracebacks. Calling it with
@@ -735,7 +759,14 b' class VerboseTB(TBTools):'
735 759 return ['%s%s%s: %s' % (colors.excName, etype_str,
736 760 colorsnormal, py3compat.cast_unicode(evalue_str))]
737 761
738 def format_exception_as_a_whole(self, etype, evalue, etb, number_of_lines_of_context, tb_offset):
762 def format_exception_as_a_whole(
763 self,
764 etype: type,
765 evalue: BaseException,
766 etb: TracebackType,
767 number_of_lines_of_context,
768 tb_offset: Optional[int],
769 ):
739 770 """Formats the header, traceback and exception message for a single exception.
740 771
741 772 This may be called multiple times by Python 3 exception chaining
@@ -750,6 +781,7 b' class VerboseTB(TBTools):'
750 781 pass
751 782
752 783 tb_offset = self.tb_offset if tb_offset is None else tb_offset
784 assert isinstance(tb_offset, int)
753 785 head = self.prepare_header(etype, self.long_header)
754 786 records = self.get_records(etb, number_of_lines_of_context, tb_offset)
755 787
@@ -787,7 +819,9 b' class VerboseTB(TBTools):'
787 819
788 820 return [[head] + frames + [''.join(formatted_exception[0])]]
789 821
790 def get_records(self, etb, number_of_lines_of_context, tb_offset):
822 def get_records(
823 self, etb: TracebackType, number_of_lines_of_context: int, tb_offset: int
824 ):
791 825 context = number_of_lines_of_context - 1
792 826 after = context // 2
793 827 before = context - after
@@ -805,8 +839,14 b' class VerboseTB(TBTools):'
805 839 assert etb is not None
806 840 return list(stack_data.FrameInfo.stack_data(etb, options=options))[tb_offset:]
807 841
808 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
809 number_of_lines_of_context=5):
842 def structured_traceback(
843 self,
844 etype: type,
845 evalue: Optional[BaseException],
846 etb: TracebackType,
847 tb_offset: Optional[int] = None,
848 number_of_lines_of_context: int = 5,
849 ):
810 850 """Return a nice text document describing the traceback."""
811 851 assert etb is not None
812 852 formatted_exception = self.format_exception_as_a_whole(etype, evalue, etb, number_of_lines_of_context,
@@ -821,6 +861,7 b' class VerboseTB(TBTools):'
821 861 formatted_exceptions = formatted_exception
822 862 exception = self.get_parts_of_chained_exception(evalue)
823 863 if exception:
864 assert evalue is not None
824 865 formatted_exceptions += self.prepare_chained_exception_message(evalue.__cause__)
825 866 etype, evalue, etb = exception
826 867 else:
@@ -845,7 +886,7 b' class VerboseTB(TBTools):'
845 886
846 887 return structured_traceback_parts
847 888
848 def debugger(self, force=False):
889 def debugger(self, force: bool = False):
849 890 """Call up the pdb debugger if desired, always clean up the tb
850 891 reference.
851 892
@@ -879,6 +920,7 b' class VerboseTB(TBTools):'
879 920 else:
880 921 etb = self.tb = sys.last_traceback
881 922 while self.tb is not None and self.tb.tb_next is not None:
923 assert self.tb.tb_next is not None
882 924 self.tb = self.tb.tb_next
883 925 if etb and etb.tb_next:
884 926 etb = etb.tb_next
@@ -924,6 +966,8 b' class FormattedTB(VerboseTB, ListTB):'
924 966 occurs with python programs that themselves execute other python code,
925 967 like Python shells). """
926 968
969 mode: str
970
927 971 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
928 972 ostream=None,
929 973 tb_offset=0, long_header=False, include_vars=False,
@@ -970,8 +1014,7 b' class FormattedTB(VerboseTB, ListTB):'
970 1014 """Convert a structured traceback (a list) to a string."""
971 1015 return self.tb_join_char.join(stb)
972 1016
973
974 def set_mode(self, mode=None):
1017 def set_mode(self, mode: Optional[str] = None):
975 1018 """Switch to the desired mode.
976 1019
977 1020 If mode is not specified, cycles through the available modes."""
@@ -981,9 +1024,12 b' class FormattedTB(VerboseTB, ListTB):'
981 1024 len(self.valid_modes)
982 1025 self.mode = self.valid_modes[new_idx]
983 1026 elif mode not in self.valid_modes:
984 raise ValueError('Unrecognized mode in FormattedTB: <' + mode + '>\n'
985 'Valid modes: ' + str(self.valid_modes))
1027 raise ValueError(
1028 "Unrecognized mode in FormattedTB: <" + mode + ">\n"
1029 "Valid modes: " + str(self.valid_modes)
1030 )
986 1031 else:
1032 assert isinstance(mode, str)
987 1033 self.mode = mode
988 1034 # include variable details only in 'Verbose' mode
989 1035 self.include_vars = (self.mode == self.valid_modes[2])
@@ -1045,6 +1091,10 b' class AutoFormattedTB(FormattedTB):'
1045 1091
1046 1092 def structured_traceback(self, etype=None, value=None, tb=None,
1047 1093 tb_offset=None, number_of_lines_of_context=5):
1094
1095 etype: type
1096 value: BaseException
1097 # tb: TracebackType or tupleof tb types ?
1048 1098 if etype is None:
1049 1099 etype, value, tb = sys.exc_info()
1050 1100 if isinstance(tb, tuple):
General Comments 0
You need to be logged in to leave comments. Login now