Skip to content

Commit 5e0223b

Browse files
[spelling checker] Better help message and code organization (#8338)
Following a failed attempt to add functional tests for spelling checker in #6137
1 parent 5786d88 commit 5e0223b

File tree

2 files changed

+50
-17
lines changed

2 files changed

+50
-17
lines changed

pylint/checkers/spelling.py

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import sys
1111
import tokenize
1212
from re import Pattern
13-
from typing import TYPE_CHECKING
13+
from typing import TYPE_CHECKING, Any
1414

1515
from astroid import nodes
1616

@@ -35,8 +35,11 @@
3535
WikiWordFilter,
3636
get_tokenizer,
3737
)
38-
except ImportError:
38+
39+
PYENCHANT_AVAILABLE = True
40+
except ImportError: # pragma: no cover
3941
enchant = None
42+
PYENCHANT_AVAILABLE = False
4043

4144
class EmailFilter: # type: ignore[no-redef]
4245
...
@@ -62,17 +65,33 @@ def get_tokenizer(
6265
return Filter()
6366

6467

65-
if enchant is not None:
66-
br = enchant.Broker()
67-
dicts = br.list_dicts()
68-
dict_choices = [""] + [d[0] for d in dicts]
69-
dicts = [f"{d[0]} ({d[1].name})" for d in dicts]
70-
dicts = ", ".join(dicts)
71-
instr = ""
72-
else:
73-
dicts = "none"
74-
dict_choices = [""]
75-
instr = " To make it work, install the 'python-enchant' package."
68+
def _get_enchant_dicts() -> list[tuple[Any, enchant.ProviderDesc]]:
69+
# Broker().list_dicts() is not typed in enchant, but it does return tuples
70+
return enchant.Broker().list_dicts() if PYENCHANT_AVAILABLE else [] # type: ignore[no-any-return]
71+
72+
73+
def _get_enchant_dict_choices(
74+
inner_enchant_dicts: list[tuple[Any, enchant.ProviderDesc]]
75+
) -> list[str]:
76+
return [""] + [d[0] for d in inner_enchant_dicts]
77+
78+
79+
def _get_enchant_dict_help(
80+
inner_enchant_dicts: list[tuple[Any, enchant.ProviderDesc]],
81+
pyenchant_available: bool,
82+
) -> str:
83+
if inner_enchant_dicts:
84+
dict_as_str = [f"{d[0]} ({d[1].name})" for d in inner_enchant_dicts]
85+
enchant_help = f"Available dictionaries: {', '.join(dict_as_str)}"
86+
else:
87+
enchant_help = "No available dictionaries : You need to install "
88+
if not pyenchant_available:
89+
enchant_help += "both the python package and "
90+
enchant_help += "the system dependency for enchant to work."
91+
return f"Spelling dictionary name. {enchant_help}."
92+
93+
94+
enchant_dicts = _get_enchant_dicts()
7695

7796

7897
class WordsWithDigitsFilter(Filter): # type: ignore[misc]
@@ -237,9 +256,8 @@ class SpellingChecker(BaseTokenChecker):
237256
"default": "",
238257
"type": "choice",
239258
"metavar": "<dict name>",
240-
"choices": dict_choices,
241-
"help": "Spelling dictionary name. "
242-
f"Available dictionaries: {dicts}.{instr}",
259+
"choices": _get_enchant_dict_choices(enchant_dicts),
260+
"help": _get_enchant_dict_help(enchant_dicts, PYENCHANT_AVAILABLE),
243261
},
244262
),
245263
(
@@ -297,7 +315,7 @@ class SpellingChecker(BaseTokenChecker):
297315

298316
def open(self) -> None:
299317
self.initialized = False
300-
if enchant is None:
318+
if not PYENCHANT_AVAILABLE:
301319
return
302320
dict_name = self.linter.config.spelling_dict
303321
if not dict_name:

tests/checkers/unittest_spelling.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pytest
99

1010
from pylint.checkers import spelling
11+
from pylint.checkers.spelling import _get_enchant_dict_help
1112
from pylint.testutils import CheckerTestCase, MessageTest, _tokenize_str, set_config
1213

1314
# try to create enchant dictionary
@@ -39,6 +40,20 @@ def _get_msg_suggestions(self, word: str, count: int = 4) -> str:
3940
suggestions = "' or '".join(self.checker.spelling_dict.suggest(word)[:count])
4041
return f"'{suggestions}'"
4142

43+
def test_spelling_dict_help_no_enchant(self) -> None:
44+
assert "both the python package and the system dep" in _get_enchant_dict_help(
45+
[], pyenchant_available=False
46+
)
47+
assert "need to install the system dep" in _get_enchant_dict_help(
48+
[], pyenchant_available=True
49+
)
50+
51+
@skip_on_missing_package_or_dict
52+
def test_spelling_dict_help_enchant(self) -> None:
53+
assert "Available dictionaries: " in _get_enchant_dict_help(
54+
enchant.Broker().list_dicts(), pyenchant_available=True
55+
)
56+
4257
@skip_on_missing_package_or_dict
4358
@set_config(spelling_dict=spell_dict)
4459
def test_check_bad_coment(self) -> None:

0 commit comments

Comments
 (0)