gh-137078: Fix keyword typo recognition when executed over files (#13… · python/cpython@4e08a9f

GitHub

GitHub CopilotWrite better code with AI | MCP RegistryIntegrate external tools | ActionsAutomate any workflow | CodespacesInstant dev environments | IssuesPlan and track work | Code ReviewManage code changes | Code QualityEnforce quality at merge | Why GitHub | Marketplace | View all features | Enterprises | Small and medium teams | Startups | View all use cases | View all industries | View all solutions | AI | Software Development | DevOps | Security | View all topics | Customer stories | Events & webinars | Ebooks & reports | Business insights | Trust center | Partners | View all resources

@@ -19,7 +19,7 @@

1919requires_debug_ranges, has_no_debug_ranges,

2020requires_subprocess)

2121fromtest.support.os_helperimportTESTFN, unlink

22-fromtest.support.script_helperimportassert_python_ok, assert_python_failure

22+fromtest.support.script_helperimportassert_python_ok, assert_python_failure, make_script

2323fromtest.support.import_helperimportforget

2424fromtest.supportimportforce_not_colorized, force_not_colorized_test_class

2525@@ -1740,6 +1740,49 @@ def f():

17401740 ]

17411741self.assertEqual(result_lines, expected)

174217421743+classTestKeywordTypoSuggestions(unittest.TestCase):

1744+TYPO_CASES= [

1745+ ("with block ad something:\n pass", "and"),

1746+ ("fur a in b:\n pass", "for"),

1747+ ("for a in b:\n pass\nelso:\n pass", "else"),

1748+ ("whille True:\n pass", "while"),

1749+ ("iff x > 5:\n pass", "if"),

1750+ ("if x:\n pass\nelseif y:\n pass", "elif"),

1751+ ("tyo:\n pass\nexcept y:\n pass", "try"),

1752+ ("classe MyClass:\n pass", "class"),

1753+ ("impor math", "import"),

1754+ ("form x import y", "from"),

1755+ ("defn calculate_sum(a, b):\n return a + b", "def"),

1756+ ("def foo():\n returm result", "return"),

1757+ ("lamda x: x ** 2", "lambda"),

1758+ ("def foo():\n yeld i", "yield"),

1759+ ("def foo():\n globel counter", "global"),

1760+ ("frum math import sqrt", "from"),

1761+ ("asynch def fetch_data():\n pass", "async"),

1762+ ("async def foo():\n awaid fetch_data()", "await"),

1763+ ('raisee ValueError("Error")', "raise"),

1764+ ("[x for x\nin range(3)\nof x]", "if"),

1765+ ("[123 fur x\nin range(3)\nif x]", "for"),

1766+ ("for x im n:\n pass", "in"),

1767+ ]

1768+1769+deftest_keyword_suggestions_from_file(self):

1770+withtempfile.TemporaryDirectory() asscript_dir:

1771+fori, (code, expected_kw) inenumerate(self.TYPO_CASES):

1772+withself.subTest(typo=expected_kw):

1773+source=textwrap.dedent(code).strip()

1774+script_name=make_script(script_dir, f"script_{i}", source)

1775+rc, stdout, stderr=assert_python_failure(script_name)

1776+stderr_text=stderr.decode('utf-8')

1777+self.assertIn(f"Did you mean '{expected_kw}'", stderr_text)

1778+1779+deftest_keyword_suggestions_from_command_string(self):

1780+forcode, expected_kwinself.TYPO_CASES:

1781+withself.subTest(typo=expected_kw):

1782+source=textwrap.dedent(code).strip()

1783+rc, stdout, stderr=assert_python_failure('-c', source)

1784+stderr_text=stderr.decode('utf-8')

1785+self.assertIn(f"Did you mean '{expected_kw}'", stderr_text)

1743178617441787@requires_debug_ranges()

17451788@force_not_colorized_test_class