Skip to content

Commit b5aab35

Browse files
[spelling] Ignore spelling in type/mypy type ignore comments (#8370)
enchant does not understand class name well enough so it creates false positives, and mypy type ignore comments with additional text are a syntax error anyway, so raising a spelling mistakes for it is not really important.
1 parent 5337e62 commit b5aab35

File tree

3 files changed

+28
-37
lines changed

3 files changed

+28
-37
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix false positive for ``wrong-spelling-in-comment`` with class names in a python 2 type comment.
2+
3+
Closes #8370

pylint/checkers/spelling.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ def _next(self) -> tuple[str, Literal[0]]:
191191

192192

193193
CODE_FLANKED_IN_BACKTICK_REGEX = re.compile(r"(\s|^)(`{1,2})([^`]+)(\2)([^`]|$)")
194-
MYPY_IGNORE_DIRECTIVE_RULE_REGEX = re.compile(r"(\s|^)(type\: ignore\[[^\]]+\])(.*)")
195194

196195

197196
def _strip_code_flanked_in_backticks(line: str) -> str:
@@ -209,23 +208,6 @@ def replace_code_but_leave_surrounding_characters(match_obj: re.Match[str]) -> s
209208
)
210209

211210

212-
def _strip_mypy_ignore_directive_rule(line: str) -> str:
213-
"""Alter line so mypy rule name is ignored.
214-
215-
Pyenchant parses anything flanked by spaces as an individual token,
216-
so this cannot be done at the individual filter level.
217-
"""
218-
219-
def replace_rule_name_but_leave_surrounding_characters(
220-
match_obj: re.Match[str],
221-
) -> str:
222-
return match_obj.group(1) + match_obj.group(3)
223-
224-
return MYPY_IGNORE_DIRECTIVE_RULE_REGEX.sub(
225-
replace_rule_name_but_leave_surrounding_characters, line
226-
)
227-
228-
229211
class SpellingChecker(BaseTokenChecker):
230212
"""Check spelling in comments and docstrings."""
231213

@@ -380,7 +362,6 @@ def _check_spelling(self, msgid: str, line: str, line_num: int) -> None:
380362
starts_with_comment = False
381363

382364
line = _strip_code_flanked_in_backticks(line)
383-
line = _strip_mypy_ignore_directive_rule(line)
384365

385366
for word, word_start_at in self.tokenizer(line.strip()):
386367
word_start_at += initial_space
@@ -454,6 +435,10 @@ def process_tokens(self, tokens: list[tokenize.TokenInfo]) -> None:
454435
if token.startswith("# pylint:"):
455436
# Skip pylint enable/disable comments
456437
continue
438+
if token.startswith("# type: "):
439+
# Skip python 2 type comments and mypy type ignore comments
440+
# mypy do not support additional text in type comments
441+
continue
457442
self._check_spelling("wrong-spelling-in-comment", token, start_row)
458443

459444
@only_required_for_messages("wrong-spelling-in-docstring")

tests/checkers/unittest_spelling.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,27 @@ def test_skip_urls(self) -> None:
258258
self.checker.process_tokens(_tokenize_str("# https://github.com/rfk/pyenchant"))
259259
assert not self.linter.release_messages()
260260

261+
@skip_on_missing_package_or_dict
262+
@set_config(spelling_dict=spell_dict)
263+
@pytest.mark.parametrize(
264+
"type_comment",
265+
[
266+
"# type: (NotAWord) -> NotAWord",
267+
"# type: List[NotAWord] -> List[NotAWord]",
268+
"# type: Dict[NotAWord] -> Dict[NotAWord]",
269+
"# type: NotAWord",
270+
"# type: List[NotAWord]",
271+
"# type: Dict[NotAWord]",
272+
"# type: ImmutableList[Manager]",
273+
# will result in error: Invalid "type: ignore" comment [syntax]
274+
# when analyzed with mypy 1.02
275+
"# type: ignore[attr-defined] NotAWord",
276+
],
277+
)
278+
def test_skip_type_comments(self, type_comment: str) -> None:
279+
self.checker.process_tokens(_tokenize_str(type_comment))
280+
assert not self.linter.release_messages()
281+
261282
@skip_on_missing_package_or_dict
262283
@set_config(spelling_dict=spell_dict)
263284
def test_skip_sphinx_directives(self) -> None:
@@ -363,24 +384,6 @@ def test_skip_code_flanked_in_single_backticks(self) -> None:
363384
):
364385
self.checker.process_tokens(_tokenize_str(full_comment))
365386

366-
@skip_on_missing_package_or_dict
367-
@set_config(spelling_dict=spell_dict)
368-
def test_skip_mypy_ignore_directives(self) -> None:
369-
full_comment = "# type: ignore[attr-defined] attr"
370-
with self.assertAddsMessages(
371-
MessageTest(
372-
"wrong-spelling-in-comment",
373-
line=1,
374-
args=(
375-
"attr",
376-
full_comment,
377-
" ^^^^",
378-
self._get_msg_suggestions("attr"),
379-
),
380-
)
381-
):
382-
self.checker.process_tokens(_tokenize_str(full_comment))
383-
384387
@skip_on_missing_package_or_dict
385388
@set_config(
386389
spelling_dict=spell_dict,

0 commit comments

Comments
 (0)