From: Pablo Galindo Salgado Date: Sat, 6 Dec 2025 21:09:35 +0000 (+0000) Subject: gh-142236: Fix incorrect keyword suggestions for syntax errors (#142328) X-Git-Tag: v3.15.0a3~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed4f78a4b318e57c9cadad2296c8b977431df6b3;p=thirdparty%2FPython%2Fcpython.git 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. --- diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index 3876f1a74bbc..d107ad925941 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -1784,6 +1784,23 @@ class TestKeywordTypoSuggestions(unittest.TestCase): stderr_text = stderr.decode('utf-8') self.assertIn(f"Did you mean '{expected_kw}'", stderr_text) + def test_no_keyword_suggestion_for_comma_errors(self): + # When the parser identifies a missing comma, don't suggest + # bogus keyword replacements like 'print' -> 'not' + code = '''\ +import sys +print( + "line1" + "line2" + file=sys.stderr +) +''' + source = textwrap.dedent(code).strip() + rc, stdout, stderr = assert_python_failure('-c', source) + stderr_text = stderr.decode('utf-8') + self.assertIn("Perhaps you forgot a comma", stderr_text) + self.assertNotIn("Did you mean", stderr_text) + @requires_debug_ranges() @force_not_colorized_test_class class PurePythonTracebackErrorCaretTests( diff --git a/Lib/traceback.py b/Lib/traceback.py index 8a3e0f77e765..c1052adeed25 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1340,6 +1340,15 @@ class TracebackException: if len(error_code) > 1024: return + # If the original code doesn't raise SyntaxError, we can't validate + # that a keyword replacement actually fixes anything + try: + codeop.compile_command(error_code, symbol="exec", flags=codeop.PyCF_ONLY_AST) + except SyntaxError: + pass # Good - the original code has a syntax error we might fix + else: + return # Original code compiles or is incomplete - can't validate fixes + error_lines = error_code.splitlines() tokens = tokenize.generate_tokens(io.StringIO(error_code).readline) tokens_left_to_process = 10 diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-00-16-43.gh-issue-142236.m3EF9E.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-00-16-43.gh-issue-142236.m3EF9E.rst new file mode 100644 index 000000000000..b5c6a27fd6a2 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-12-06-00-16-43.gh-issue-142236.m3EF9E.rst @@ -0,0 +1,4 @@ +Fix incorrect keyword suggestions for syntax errors in :mod:`traceback`. The +keyword typo suggestion mechanism would incorrectly suggest replacements when +the extracted source code was incomplete rather than containing an actual typo. +Patch by Pablo Galindo.