Skip to content

Commit ed4f78a

Browse files
authored
gh-142236: Fix incorrect keyword suggestions for syntax errors (#142328)
The keyword typo suggestion mechanism in traceback would incorrectly suggest replacements when the extracted source code was merely incomplete rather than containing an actual typo. For example, when a missing comma caused a syntax error, the system would suggest replacing 'print' with 'not' because the incomplete code snippet happened to pass validation. The fix adds a validation step that first checks whether the original extracted code raises a SyntaxError. If the code compiles successfully or is simply incomplete (compile_command returns None), the function returns early since there is no way to verify that a keyword replacement would actually fix the problem.
1 parent 07eff89 commit ed4f78a

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

Lib/test/test_traceback.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,23 @@ def test_keyword_suggestions_from_command_string(self):
17841784
stderr_text = stderr.decode('utf-8')
17851785
self.assertIn(f"Did you mean '{expected_kw}'", stderr_text)
17861786

1787+
def test_no_keyword_suggestion_for_comma_errors(self):
1788+
# When the parser identifies a missing comma, don't suggest
1789+
# bogus keyword replacements like 'print' -> 'not'
1790+
code = '''\
1791+
import sys
1792+
print(
1793+
"line1"
1794+
"line2"
1795+
file=sys.stderr
1796+
)
1797+
'''
1798+
source = textwrap.dedent(code).strip()
1799+
rc, stdout, stderr = assert_python_failure('-c', source)
1800+
stderr_text = stderr.decode('utf-8')
1801+
self.assertIn("Perhaps you forgot a comma", stderr_text)
1802+
self.assertNotIn("Did you mean", stderr_text)
1803+
17871804
@requires_debug_ranges()
17881805
@force_not_colorized_test_class
17891806
class PurePythonTracebackErrorCaretTests(

Lib/traceback.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,6 +1340,15 @@ def _find_keyword_typos(self):
13401340
if len(error_code) > 1024:
13411341
return
13421342

1343+
# If the original code doesn't raise SyntaxError, we can't validate
1344+
# that a keyword replacement actually fixes anything
1345+
try:
1346+
codeop.compile_command(error_code, symbol="exec", flags=codeop.PyCF_ONLY_AST)
1347+
except SyntaxError:
1348+
pass # Good - the original code has a syntax error we might fix
1349+
else:
1350+
return # Original code compiles or is incomplete - can't validate fixes
1351+
13431352
error_lines = error_code.splitlines()
13441353
tokens = tokenize.generate_tokens(io.StringIO(error_code).readline)
13451354
tokens_left_to_process = 10
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix incorrect keyword suggestions for syntax errors in :mod:`traceback`. The
2+
keyword typo suggestion mechanism would incorrectly suggest replacements when
3+
the extracted source code was incomplete rather than containing an actual typo.
4+
Patch by Pablo Galindo.

0 commit comments

Comments
 (0)