Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Lib/test/test_traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -1815,6 +1815,18 @@ class TestKeywordTypoSuggestions(unittest.TestCase):
("[x for x\nin range(3)\nof x]", "if"),
("[123 fur x\nin range(3)\nif x]", "for"),
("for x im n:\n pass", "in"),
("mach x:", "match"),
("math x:", "match"),
("match 1:\n cse 1:", "case"),
("typ x = int", "type"),
("typed x = int", "type"),
Comment on lines +1821 to +1822

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two tests for match and type, no tests for lazy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

("lazi import x", "lazy"),
("lezi import x", "lazy"),
("switch x:\n case:", "match"),
("delete x", "del"),
("function f():", "def"),
("func f():", "def"),
("void f():", "def"),
]

def test_keyword_suggestions_from_file(self):
Expand Down
32 changes: 30 additions & 2 deletions Lib/traceback.py
Original file line number Diff line number Diff line change
Expand Up @@ -1485,11 +1485,22 @@ def _find_keyword_typos(self):
# Limit the number of possible matches to try
max_matches = 3
matches = []

hint = _get_cross_language_keyword_hint(wrong_name)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hint = _get_cross_language_keyword_hint(wrong_name)
hint = _CROSS_LANGUAGE_KEYWORD_HINTS.get(wrong_name)

If it is only used once, and is marked as a "private" method, I would suggest calling the body directly

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this. I still think a get method looks nicer..

if hint:
matches.append(hint)
if _suggestions is not None:
suggestion = _suggestions._generate_suggestions(keyword.kwlist, wrong_name)
suggestion = _suggestions._generate_suggestions(keyword.kwlist + keyword.softkwlist, wrong_name)
if suggestion:
matches.append(suggestion)
matches.extend(difflib.get_close_matches(wrong_name, keyword.kwlist, n=max_matches, cutoff=0.5))
matches.extend(
difflib.get_close_matches(
wrong_name,
keyword.kwlist + keyword.softkwlist,
n=max_matches,
cutoff=0.5
)
)
matches = matches[:max_matches]
for suggestion in matches:
if not suggestion or suggestion == wrong_name:
Expand Down Expand Up @@ -1787,6 +1798,17 @@ def print(self, *, file=None, chain=True, **kwargs):
})


# Cross-language keyword suggestions.
_CROSS_LANGUAGE_KEYWORD_HINTS = frozendict({
# C/C++ equivalents
'switch': 'match',
'delete': 'del',
# function define equivalents
'function': 'def',
'func': 'def',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'func': 'def',
'func': 'def',
'void': 'def'

Long shot. But maybe?

'void': 'def',
})

def _substitution_cost(ch_a, ch_b):
if ch_a == ch_b:
return 0
Expand Down Expand Up @@ -1866,6 +1888,12 @@ def _get_cross_language_hint(obj, wrong_name):
return None


def _get_cross_language_keyword_hint(wrong_name):
"""Check if wrong_name is a common keyword from another language
"""
return _CROSS_LANGUAGE_KEYWORD_HINTS.get(wrong_name)


def _get_safe___dir__(obj):
# Use obj.__dir__() to avoid a TypeError when calling dir(obj).
# See gh-131001 and gh-139933.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Cross-language keyword suggestions are now shown for :exc:`SyntaxError` messages.
For example, ``switch x:`` suggests ``match``, ``delete x`` suggests ``del``,
``function f():`` suggests ``def``. Contributed by Zang Langyan.
Loading