##// END OF EJS Templates
Display exception notes in tracebacks
EtiennePelletier -
Show More
@@ -27,6 +27,7 b' __pycache__'
27 *.swp
27 *.swp
28 .pytest_cache
28 .pytest_cache
29 .python-version
29 .python-version
30 .venv*/
30 venv*/
31 venv*/
31 .mypy_cache/
32 .mypy_cache/
32
33
@@ -89,6 +89,7 b' Inheritance diagram:'
89 #*****************************************************************************
89 #*****************************************************************************
90
90
91
91
92 from collections.abc import Sequence
92 import functools
93 import functools
93 import inspect
94 import inspect
94 import linecache
95 import linecache
@@ -183,6 +184,14 b' def get_line_number_of_frame(frame: types.FrameType) -> int:'
183 return count_lines_in_py_file(filename)
184 return count_lines_in_py_file(filename)
184
185
185
186
187 def _safe_string(value, what, func=str):
188 # Copied from cpython/Lib/traceback.py
189 try:
190 return func(value)
191 except:
192 return f"<{what} {func.__name__}() failed>"
193
194
186 def _format_traceback_lines(lines, Colors, has_colors: bool, lvals):
195 def _format_traceback_lines(lines, Colors, has_colors: bool, lvals):
187 """
196 """
188 Format tracebacks lines with pointing arrow, leading numbers...
197 Format tracebacks lines with pointing arrow, leading numbers...
@@ -999,9 +1008,26 b' class VerboseTB(TBTools):'
999 # User exception is improperly defined.
1008 # User exception is improperly defined.
1000 etype, evalue = str, sys.exc_info()[:2]
1009 etype, evalue = str, sys.exc_info()[:2]
1001 etype_str, evalue_str = map(str, (etype, evalue))
1010 etype_str, evalue_str = map(str, (etype, evalue))
1011
1012 notes = getattr(evalue, "__notes__", [])
1013 if not isinstance(notes, Sequence) or isinstance(notes, (str, bytes)):
1014 notes = [_safe_string(notes, "__notes__", func=repr)]
1015
1002 # ... and format it
1016 # ... and format it
1003 return ['%s%s%s: %s' % (colors.excName, etype_str,
1017 return [
1004 colorsnormal, py3compat.cast_unicode(evalue_str))]
1018 "{}{}{}: {}".format(
1019 colors.excName,
1020 etype_str,
1021 colorsnormal,
1022 py3compat.cast_unicode(evalue_str),
1023 ),
1024 *(
1025 "{}{}".format(
1026 colorsnormal, _safe_string(py3compat.cast_unicode(n), "note")
1027 )
1028 for n in notes
1029 ),
1030 ]
1005
1031
1006 def format_exception_as_a_whole(
1032 def format_exception_as_a_whole(
1007 self,
1033 self,
@@ -1068,7 +1094,7 b' class VerboseTB(TBTools):'
1068 if ipinst is not None:
1094 if ipinst is not None:
1069 ipinst.hooks.synchronize_with_editor(frame_info.filename, frame_info.lineno, 0)
1095 ipinst.hooks.synchronize_with_editor(frame_info.filename, frame_info.lineno, 0)
1070
1096
1071 return [[head] + frames + [''.join(formatted_exception[0])]]
1097 return [[head] + frames + formatted_exception]
1072
1098
1073 def get_records(
1099 def get_records(
1074 self, etb: TracebackType, number_of_lines_of_context: int, tb_offset: int
1100 self, etb: TracebackType, number_of_lines_of_context: int, tb_offset: int
General Comments 0
You need to be logged in to leave comments. Login now