summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Sassoulas <pierre.sassoulas@gmail.com>2023-03-02 21:18:40 +0100
committerGitHub <noreply@github.com>2023-03-02 21:18:40 +0100
commitb5aab35a6f20efad94ae8da07392fad6d1c28aad (patch)
tree10ad12004fc030e4adc99cd0f65d87499b6957cb
parent5337e6280e76e13d1922b03ffeba7887a00e6356 (diff)
downloadpylint-git-b5aab35a6f20efad94ae8da07392fad6d1c28aad.tar.gz
[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.
-rw-r--r--doc/whatsnew/fragments/8370.false_positive3
-rw-r--r--pylint/checkers/spelling.py23
-rw-r--r--tests/checkers/unittest_spelling.py39
3 files changed, 28 insertions, 37 deletions
diff --git a/doc/whatsnew/fragments/8370.false_positive b/doc/whatsnew/fragments/8370.false_positive
new file mode 100644
index 000000000..a641ecbbf
--- /dev/null
+++ b/doc/whatsnew/fragments/8370.false_positive
@@ -0,0 +1,3 @@
+Fix false positive for ``wrong-spelling-in-comment`` with class names in a python 2 type comment.
+
+Closes #8370
diff --git a/pylint/checkers/spelling.py b/pylint/checkers/spelling.py
index d39229ad0..3fbd017f8 100644
--- a/pylint/checkers/spelling.py
+++ b/pylint/checkers/spelling.py
@@ -191,7 +191,6 @@ class ForwardSlashChunker(Chunker): # type: ignore[misc]
CODE_FLANKED_IN_BACKTICK_REGEX = re.compile(r"(\s|^)(`{1,2})([^`]+)(\2)([^`]|$)")
-MYPY_IGNORE_DIRECTIVE_RULE_REGEX = re.compile(r"(\s|^)(type\: ignore\[[^\]]+\])(.*)")
def _strip_code_flanked_in_backticks(line: str) -> str:
@@ -209,23 +208,6 @@ def _strip_code_flanked_in_backticks(line: str) -> str:
)
-def _strip_mypy_ignore_directive_rule(line: str) -> str:
- """Alter line so mypy rule name is ignored.
-
- Pyenchant parses anything flanked by spaces as an individual token,
- so this cannot be done at the individual filter level.
- """
-
- def replace_rule_name_but_leave_surrounding_characters(
- match_obj: re.Match[str],
- ) -> str:
- return match_obj.group(1) + match_obj.group(3)
-
- return MYPY_IGNORE_DIRECTIVE_RULE_REGEX.sub(
- replace_rule_name_but_leave_surrounding_characters, line
- )
-
-
class SpellingChecker(BaseTokenChecker):
"""Check spelling in comments and docstrings."""
@@ -380,7 +362,6 @@ class SpellingChecker(BaseTokenChecker):
starts_with_comment = False
line = _strip_code_flanked_in_backticks(line)
- line = _strip_mypy_ignore_directive_rule(line)
for word, word_start_at in self.tokenizer(line.strip()):
word_start_at += initial_space
@@ -454,6 +435,10 @@ class SpellingChecker(BaseTokenChecker):
if token.startswith("# pylint:"):
# Skip pylint enable/disable comments
continue
+ if token.startswith("# type: "):
+ # Skip python 2 type comments and mypy type ignore comments
+ # mypy do not support additional text in type comments
+ continue
self._check_spelling("wrong-spelling-in-comment", token, start_row)
@only_required_for_messages("wrong-spelling-in-docstring")
diff --git a/tests/checkers/unittest_spelling.py b/tests/checkers/unittest_spelling.py
index d716def60..b02cf73a8 100644
--- a/tests/checkers/unittest_spelling.py
+++ b/tests/checkers/unittest_spelling.py
@@ -260,6 +260,27 @@ class TestSpellingChecker(CheckerTestCase): # pylint:disable=too-many-public-me
@skip_on_missing_package_or_dict
@set_config(spelling_dict=spell_dict)
+ @pytest.mark.parametrize(
+ "type_comment",
+ [
+ "# type: (NotAWord) -> NotAWord",
+ "# type: List[NotAWord] -> List[NotAWord]",
+ "# type: Dict[NotAWord] -> Dict[NotAWord]",
+ "# type: NotAWord",
+ "# type: List[NotAWord]",
+ "# type: Dict[NotAWord]",
+ "# type: ImmutableList[Manager]",
+ # will result in error: Invalid "type: ignore" comment [syntax]
+ # when analyzed with mypy 1.02
+ "# type: ignore[attr-defined] NotAWord",
+ ],
+ )
+ def test_skip_type_comments(self, type_comment: str) -> None:
+ self.checker.process_tokens(_tokenize_str(type_comment))
+ assert not self.linter.release_messages()
+
+ @skip_on_missing_package_or_dict
+ @set_config(spelling_dict=spell_dict)
def test_skip_sphinx_directives(self) -> None:
stmt = astroid.extract_node(
'class ComentAbc(object):\n """This is :class:`ComentAbc` with a bad coment"""\n pass'
@@ -364,24 +385,6 @@ class TestSpellingChecker(CheckerTestCase): # pylint:disable=too-many-public-me
self.checker.process_tokens(_tokenize_str(full_comment))
@skip_on_missing_package_or_dict
- @set_config(spelling_dict=spell_dict)
- def test_skip_mypy_ignore_directives(self) -> None:
- full_comment = "# type: ignore[attr-defined] attr"
- with self.assertAddsMessages(
- MessageTest(
- "wrong-spelling-in-comment",
- line=1,
- args=(
- "attr",
- full_comment,
- " ^^^^",
- self._get_msg_suggestions("attr"),
- ),
- )
- ):
- self.checker.process_tokens(_tokenize_str(full_comment))
-
- @skip_on_missing_package_or_dict
@set_config(
spelling_dict=spell_dict,
spelling_ignore_comment_directives="newdirective:,noqa",