Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to open the online message documentation as quick fix action #298

Merged
merged 3 commits into from
Mar 13, 2023
Merged
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
14 changes: 13 additions & 1 deletion bundled/tool/lsp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def update_sys_path(path_to_add: str, strategy: str) -> None:
# **********************************************************
TOOL_MODULE = "pylint"
TOOL_DISPLAY = "Pylint"
DOCUMENTATION_HOME = "https://pylint.readthedocs.io/en/latest/user_guide/messages"

# Default arguments always passed to pylint.
TOOL_ARGS = ["--reports=n", "--output-format=json"]
Expand Down Expand Up @@ -136,6 +137,14 @@ def _get_severity(
return lsp.DiagnosticSeverity.Error


def _build_message_doc_url(code: str) -> str:
"""Build the URL to the documentation for this diagnostic message."""
msg_id, message = code.split(":")
category = utils.get_message_category(msg_id)
uri = f"{category}/{message}.html" if category else DOCUMENTATION_HOME
return f"{DOCUMENTATION_HOME}/{uri}"


def _parse_output(
content: str,
severity: Dict[str, str],
Expand Down Expand Up @@ -164,13 +173,17 @@ def _parse_output(
# points to.
end = start

code = f"{data.get('message-id')}:{data.get('symbol')}"
documentation_url = _build_message_doc_url(code)

diagnostic = lsp.Diagnostic(
range=lsp.Range(start=start, end=end),
message=data.get("message"),
severity=_get_severity(
data.get("symbol"), data.get("message-id"), data.get("type"), severity
),
code=f"{data.get('message-id')}:{data.get('symbol')}",
code_description=lsp.CodeDescription(href=documentation_url),
source=TOOL_DISPLAY,
)

Expand Down Expand Up @@ -253,7 +266,6 @@ def code_action(params: lsp.CodeActionParams) -> List[lsp.CodeAction]:
func = QUICK_FIXES.solutions(diagnostic.code)
if func:
code_actions.extend(func(document, [diagnostic]))

return code_actions


Expand Down
13 changes: 13 additions & 0 deletions bundled/tool/lsp_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
# Save the working directory used when loading this module
SERVER_CWD = os.getcwd()
CWD_LOCK = threading.Lock()
CATEGORIES = {
"F": "fatal",
"E": "error",
"W": "warning",
"C": "convention",
"R": "refactor",
"I": "information",
}


def as_list(content: Union[Any, List[Any], Tuple[Any]]) -> Union[List[Any], Tuple[Any]]:
Expand All @@ -26,6 +34,11 @@ def as_list(content: Union[Any, List[Any], Tuple[Any]]) -> Union[List[Any], Tupl
return [content]


def get_message_category(code: str) -> Optional[str]:
"""Get the full name of the message category."""
return CATEGORIES.get(code[0].upper())


# pylint: disable-next=consider-using-generator
_site_paths = tuple(
[
Expand Down
28 changes: 28 additions & 0 deletions src/test/python_tests/test_linting.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
TEST_FILE_URI = utils.as_uri(str(TEST_FILE_PATH))
LINTER = utils.get_server_info_defaults()
TIMEOUT = 10 # 10 seconds
DOCUMENTATION_HOME = "https://pylint.readthedocs.io/en/latest/user_guide/messages"


def test_publish_diagnostics_on_open():
Expand Down Expand Up @@ -60,6 +61,9 @@ def _handler(params):
"message": "Missing module docstring",
"severity": 3,
"code": "C0114:missing-module-docstring",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/convention/missing-module-docstring.html"
},
"source": LINTER["name"],
},
{
Expand All @@ -73,6 +77,9 @@ def _handler(params):
"message": "Undefined variable 'x'",
"severity": 1,
"code": "E0602:undefined-variable",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/error/undefined-variable.html"
},
"source": LINTER["name"],
},
{
Expand All @@ -86,6 +93,9 @@ def _handler(params):
"message": "Unused import sys",
"severity": 2,
"code": "W0611:unused-import",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/warning/unused-import.html"
},
"source": LINTER["name"],
},
],
Expand Down Expand Up @@ -136,6 +146,9 @@ def _handler(params):
"message": "Missing module docstring",
"severity": 3,
"code": "C0114:missing-module-docstring",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/convention/missing-module-docstring.html"
},
"source": LINTER["name"],
},
{
Expand All @@ -149,6 +162,9 @@ def _handler(params):
"message": "Undefined variable 'x'",
"severity": 1,
"code": "E0602:undefined-variable",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/error/undefined-variable.html"
},
"source": LINTER["name"],
},
{
Expand All @@ -162,6 +178,9 @@ def _handler(params):
"message": "Unused import sys",
"severity": 2,
"code": "W0611:unused-import",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/warning/unused-import.html"
},
"source": LINTER["name"],
},
],
Expand Down Expand Up @@ -273,6 +292,9 @@ def _handler(params):
"message": "Missing module docstring",
"severity": 3,
"code": "C0114:missing-module-docstring",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/convention/missing-module-docstring.html"
},
"source": LINTER["name"],
},
{
Expand All @@ -286,6 +308,9 @@ def _handler(params):
"message": "Undefined variable 'x'",
"severity": 1,
"code": "E0602:undefined-variable",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/error/undefined-variable.html"
},
"source": LINTER["name"],
},
{
Expand All @@ -299,6 +324,9 @@ def _handler(params):
"message": "Unused import sys",
"severity": 1,
"code": "W0611:unused-import",
"codeDescription": {
"href": f"{DOCUMENTATION_HOME}/warning/unused-import.html"
},
"source": LINTER["name"],
},
],
Expand Down