Skip to content

Commit 2a4bea3

Browse files
fix(traceback): TracebackException to handle error messages with punctuations
1 parent 6fcac09 commit 2a4bea3

File tree

1 file changed

+39
-41
lines changed

1 file changed

+39
-41
lines changed

Lib/traceback.py

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,50 +1081,30 @@ def __init__(self, exc_type, exc_value, exc_traceback, *, limit=None,
10811081

10821082
self._is_syntax_error = False
10831083
self._have_exc_type = exc_type is not None
1084-
if exc_type is not None:
1084+
1085+
if self._have_exc_type:
10851086
self.exc_type_qualname = exc_type.__qualname__
10861087
self.exc_type_module = exc_type.__module__
1088+
if issubclass(exc_type, SyntaxError):
1089+
# Handle SyntaxError's specially
1090+
self.filename = exc_value.filename
1091+
lno = exc_value.lineno
1092+
self.lineno = str(lno) if lno is not None else None
1093+
end_lno = exc_value.end_lineno
1094+
self.end_lineno = str(end_lno) if end_lno is not None else None
1095+
self.text = exc_value.text
1096+
self.offset = exc_value.offset
1097+
self.end_offset = exc_value.end_offset
1098+
self.msg = exc_value.msg
1099+
self._is_syntax_error = True
1100+
self._exc_metadata = getattr(exc_value, "_metadata", None)
1101+
elif suggestion := _compute_suggestion_message(exc_type, exc_value, exc_traceback):
1102+
punctuation = "" if self._str.rstrip().endswith(('.', '!')) else "."
1103+
self._str += f"{punctuation} {suggestion}"
10871104
else:
10881105
self.exc_type_qualname = None
10891106
self.exc_type_module = None
1090-
1091-
if exc_type and issubclass(exc_type, SyntaxError):
1092-
# Handle SyntaxError's specially
1093-
self.filename = exc_value.filename
1094-
lno = exc_value.lineno
1095-
self.lineno = str(lno) if lno is not None else None
1096-
end_lno = exc_value.end_lineno
1097-
self.end_lineno = str(end_lno) if end_lno is not None else None
1098-
self.text = exc_value.text
1099-
self.offset = exc_value.offset
1100-
self.end_offset = exc_value.end_offset
1101-
self.msg = exc_value.msg
1102-
self._is_syntax_error = True
1103-
self._exc_metadata = getattr(exc_value, "_metadata", None)
1104-
elif exc_type and issubclass(exc_type, ImportError) and \
1105-
getattr(exc_value, "name_from", None) is not None:
1106-
wrong_name = getattr(exc_value, "name_from", None)
1107-
suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name)
1108-
if suggestion:
1109-
self._str += f". Did you mean: '{suggestion}'?"
1110-
elif exc_type and issubclass(exc_type, ModuleNotFoundError) and \
1111-
sys.flags.no_site and \
1112-
getattr(exc_value, "name", None) not in sys.stdlib_module_names:
1113-
self._str += (". Site initialization is disabled, did you forget to "
1114-
+ "add the site-packages directory to sys.path?")
1115-
elif exc_type and issubclass(exc_type, (NameError, AttributeError)) and \
1116-
getattr(exc_value, "name", None) is not None:
1117-
wrong_name = getattr(exc_value, "name", None)
1118-
suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name)
1119-
if suggestion:
1120-
self._str += f". Did you mean: '{suggestion}'?"
1121-
if issubclass(exc_type, NameError):
1122-
wrong_name = getattr(exc_value, "name", None)
1123-
if wrong_name is not None and wrong_name in sys.stdlib_module_names:
1124-
if suggestion:
1125-
self._str += f" Or did you forget to import '{wrong_name}'?"
1126-
else:
1127-
self._str += f". Did you forget to import '{wrong_name}'?"
1107+
11281108
if lookup_lines:
11291109
self._load_lines()
11301110
self.__suppress_context__ = \
@@ -1384,7 +1364,6 @@ def _find_keyword_typos(self):
13841364
self.msg = f"invalid syntax. Did you mean '{suggestion}'?"
13851365
return
13861366

1387-
13881367
def _format_syntax_error(self, stype, **kwargs):
13891368
"""Format SyntaxError exceptions (internal helper)."""
13901369
# Show exactly where the problem was found.
@@ -1577,7 +1556,6 @@ def format(self, *, chain=True, _ctx=None, **kwargs):
15771556
assert _ctx.exception_group_depth == 1
15781557
_ctx.exception_group_depth = 0
15791558

1580-
15811559
def print(self, *, file=None, chain=True, **kwargs):
15821560
"""Print the result of self.format(chain=chain) to 'file'."""
15831561
colorize = kwargs.get("colorize", False)
@@ -1732,6 +1710,26 @@ def _compute_suggestion_error(exc_value, tb, wrong_name):
17321710
return suggestion
17331711

17341712

1713+
def _compute_suggestion_message(exc_type, exc_value, exc_traceback) -> str | None:
1714+
if issubclass(exc_type, ModuleNotFoundError) and \
1715+
sys.flags.no_site and \
1716+
getattr(exc_value, "name", None) not in sys.stdlib_module_names:
1717+
return ("Site initialization is disabled, did you forget to "
1718+
"add the site-packages directory to sys.path?")
1719+
if issubclass(exc_type, (ImportError, NameError, AttributeError)):
1720+
name_attribute = "name_from" if issubclass(exc_type, ImportError) else "name"
1721+
wrong_name = getattr(exc_value, name_attribute, None)
1722+
if wrong_name:
1723+
suggestion_error = _compute_suggestion_error(exc_value, exc_traceback, wrong_name)
1724+
suggestion_text = f"Did you mean: '{suggestion_error}'?" if suggestion_error else None
1725+
if issubclass(exc_type, NameError) and wrong_name in sys.stdlib_module_names:
1726+
if suggestion_error:
1727+
return f"{suggestion_text} Or did you forget to import '{wrong_name}'?"
1728+
return f"Did you forget to import '{wrong_name}'?"
1729+
return suggestion_text
1730+
return None
1731+
1732+
17351733
def _levenshtein_distance(a, b, max_cost):
17361734
# A Python implementation of Python/suggestions.c:levenshtein_distance.
17371735

0 commit comments

Comments
 (0)