From 8d73f0fdb964dcccfe8f49272c6be6cbff2dc6d5 Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 13 Jun 2023 17:58:24 -0400 Subject: [PATCH 1/4] Link to mypy's error code documentation --- bundled/tool/lsp_server.py | 11 ++++++ bundled/tool/lsp_utils.py | 56 +++++++++++++++++++++++++++ src/test/python_tests/test_linting.py | 9 +++++ 3 files changed, 76 insertions(+) diff --git a/bundled/tool/lsp_server.py b/bundled/tool/lsp_server.py index f639b22..3fc5f67 100644 --- a/bundled/tool/lsp_server.py +++ b/bundled/tool/lsp_server.py @@ -142,6 +142,14 @@ def _get_group_dict(line: str) -> Optional[Dict[str, str]]: return None +def _build_message_doc_url(code: str) -> str: + """Build the URL to the documentation for this warning.""" + anchor = utils.ERROR_CODE_ANCHORS.get(code) + if anchor is None: + return "" + return utils.ERROR_CODE_BASE_URL + anchor + + def _parse_output_using_regex( content: str, severity: Dict[str, str] ) -> list[lsp.Diagnostic]: @@ -174,6 +182,8 @@ def _parse_output_using_regex( character=end_column, # ignore col_offset for end ) + documentation_url = _build_message_doc_url(data["code"]) + diagnostic = lsp.Diagnostic( range=lsp.Range( start=start, @@ -182,6 +192,7 @@ def _parse_output_using_regex( message=data.get("message"), severity=_get_severity(data["code"], data["type"], severity), code=data["code"], + code_description=lsp.CodeDescription(href=documentation_url), source=TOOL_DISPLAY, ) diagnostics.append(diagnostic) diff --git a/bundled/tool/lsp_utils.py b/bundled/tool/lsp_utils.py index 57695f5..bb84c5f 100644 --- a/bundled/tool/lsp_utils.py +++ b/bundled/tool/lsp_utils.py @@ -18,6 +18,62 @@ # Save the working directory used when loading this module SERVER_CWD = os.getcwd() CWD_LOCK = threading.Lock() +ERROR_CODE_BASE_URL = "https://mypy.readthedocs.io/en/stable/" +ERROR_CODE_ANCHORS = { + "attr-defined": "error_code_list.html#check-that-attribute-exists-attr-defined", + "union-attr": "error_code_list.html#check-that-attribute-exists-in-each-union-item-union-attr", + "name-defined": "error_code_list.html#check-that-name-is-defined-name-defined", + "used-before-def": "error_code_list.html#check-that-a-variable-is-not-used-before-it-s-defined-used-before-def", + "call-arg": "error_code_list.html#check-arguments-in-calls-call-arg", + "arg-type": "error_code_list.html#check-argument-types-arg-type", + "call-overload": "error_code_list.html#check-calls-to-overloaded-functions-call-overload", + "valid-type": "error_code_list.html#check-validity-of-types-valid-type", + "var-annotated": "error_code_list.html#require-annotation-if-variable-type-is-unclear-var-annotated", + "override": "error_code_list.html#check-validity-of-overrides-override", + "return": "error_code_list.html#check-that-function-returns-a-value-return", + "return-value": "error_code_list.html#check-that-return-value-is-compatible-return-value", + "assignment": "error_code_list.html#check-types-in-assignment-statement-assignment", + "method-assign": "error_code_list.html#check-that-assignment-target-is-not-a-method-method-assign", + "type-var": "error_code_list.html#check-type-variable-values-type-var", + "operator": "error_code_list.html#check-uses-of-various-operators-operator", + "index": "error_code_list.html#check-indexing-operations-index", + "list-item": "error_code_list.html#check-list-items-list-item", + "dict-item": "error_code_list.html#check-dict-items-dict-item", + "typeddict-item": "error_code_list.html#check-typeddict-items-typeddict-item", + "typeddict-unknown-key": "error_code_list.html#check-typeddict-keys-typeddict-unknown-key", + "has-type": "error_code_list.html#check-that-type-of-target-is-known-has-type", + "import": "error_code_list.html#check-that-import-target-can-be-found-import", + "no-redef": "error_code_list.html#check-that-each-name-is-defined-once-no-redef", + "func-returns-value": "error_code_list.html#check-that-called-function-returns-a-value-func-returns-value", + "abstract": "error_code_list.html#check-instantiation-of-abstract-classes-abstract", + "type-abstract": "error_code_list.html#safe-handling-of-abstract-type-object-types-type-abstract", + "safe-super": "error_code_list.html#check-that-call-to-an-abstract-method-via-super-is-valid-safe-super", + "valid-newtype": "error_code_list.html#check-the-target-of-newtype-valid-newtype", + "exit-return": "error_code_list.html#check-the-return-type-of-exit-exit-return", + "name-match": "error_code_list.html#check-that-naming-is-consistent-name-match", + "literal-required": "error_code_list.html#check-that-literal-is-used-where-expected-literal-required", + "no-overload-impl": "error_code_list.html#check-that-overloaded-functions-have-an-implementation-no-overload-impl", + "unused-coroutine": "error_code_list.html#check-that-coroutine-return-value-is-used-unused-coroutine", + "assert-type": "error_code_list.html#check-types-in-assert-type-assert-type", + "truthy-function": "error_code_list.html#check-that-function-isn-t-used-in-boolean-context-truthy-function", + "str-bytes-safe": "error_code_list.html#check-for-implicit-bytes-coercions-str-bytes-safe", + "syntax": "error_code_list.html#report-syntax-errors-syntax", + "misc": "error_code_list.html#miscellaneous-checks-misc", + "type-arg": "error_code_list2.html#check-that-type-arguments-exist-type-arg", + "no-untyped-def": "error_code_list2.html#check-that-every-function-has-an-annotation-no-untyped-def", + "redundant-cast": "error_code_list2.html#check-that-cast-is-not-redundant-redundant-cast", + "redundant-self": "error_code_list2.html#check-that-methods-do-not-have-redundant-self-annotations-redundant-self", + "comparison-overlap": "error_code_list2.html#check-that-comparisons-are-overlapping-comparison-overlap", + "no-untyped-call": "error_code_list2.html#check-that-no-untyped-functions-are-called-no-untyped-call", + "no-any-return": "error_code_list2.html#check-that-function-does-not-return-any-value-no-any-return", + "no-any-unimported": "error_code_list2.html#check-that-types-have-no-any-components-due-to-missing-imports-no-any-unimported", + "unreachable": "error_code_list2.html#check-that-statement-or-expression-is-unreachable-unreachable", + "redundant-expr": "error_code_list2.html#check-that-expression-is-redundant-redundant-expr", + "truthy-bool": "error_code_list2.html#check-that-expression-is-not-implicitly-true-in-boolean-context-truthy-bool", + "truthy-iterable": "error_code_list2.html#check-that-iterable-is-not-implicitly-true-in-boolean-context-truthy-iterable", + "undefined": "error_code_list2.html#check-that-type-ignore-include-an-error-code-ignore-without-code", + "unused-awaitable": "error_code_list2.html#check-that-awaitable-return-value-is-used-unused-awaitable" +} def as_list(content: Union[Any, List[Any], Tuple[Any]]) -> List[Any]: diff --git a/src/test/python_tests/test_linting.py b/src/test/python_tests/test_linting.py index cf5661f..3164937 100644 --- a/src/test/python_tests/test_linting.py +++ b/src/test/python_tests/test_linting.py @@ -63,6 +63,9 @@ def _log_handler(params): "message": 'Name "x" is not defined ', "severity": 1, "code": "name-defined", + "codeDescription": { + "href": "https://mypy.readthedocs.io/en/stable/error_code_list.html#check-that-name-is-defined-name-defined" + }, "source": "Mypy", } ], @@ -117,6 +120,9 @@ def _log_handler(params): "message": 'Name "x" is not defined ', "severity": 1, "code": "name-defined", + "codeDescription": { + "href": "https://mypy.readthedocs.io/en/stable/error_code_list.html#check-that-name-is-defined-name-defined" + }, "source": "Mypy", } ], @@ -236,6 +242,9 @@ def _log_handler(params): "message": 'Name "x" is not defined ', "severity": 2, "code": "name-defined", + "codeDescription": { + "href": "https://mypy.readthedocs.io/en/stable/error_code_list.html#check-that-name-is-defined-name-defined" + }, "source": "Mypy", } ], From f22021df0794e076c37e7434b2841fe2ffca4a6f Mon Sep 17 00:00:00 2001 From: Avasam Date: Tue, 13 Jun 2023 22:41:37 -0400 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Karthik Nadig --- bundled/tool/lsp_server.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bundled/tool/lsp_server.py b/bundled/tool/lsp_server.py index 3fc5f67..b07f2c8 100644 --- a/bundled/tool/lsp_server.py +++ b/bundled/tool/lsp_server.py @@ -142,12 +142,12 @@ def _get_group_dict(line: str) -> Optional[Dict[str, str]]: return None -def _build_message_doc_url(code: str) -> str: +def _get_code_description(code: str) -> Optional[lsp.CodeDescription]: """Build the URL to the documentation for this warning.""" anchor = utils.ERROR_CODE_ANCHORS.get(code) if anchor is None: - return "" - return utils.ERROR_CODE_BASE_URL + anchor + return None + return lsp.CodeDescription(href=utils.ERROR_CODE_BASE_URL + anchor) def _parse_output_using_regex( @@ -182,8 +182,6 @@ def _parse_output_using_regex( character=end_column, # ignore col_offset for end ) - documentation_url = _build_message_doc_url(data["code"]) - diagnostic = lsp.Diagnostic( range=lsp.Range( start=start, @@ -192,7 +190,7 @@ def _parse_output_using_regex( message=data.get("message"), severity=_get_severity(data["code"], data["type"], severity), code=data["code"], - code_description=lsp.CodeDescription(href=documentation_url), + code_description=_get_code_description(data["code"]), source=TOOL_DISPLAY, ) diagnostics.append(diagnostic) From b0f280d4fc98071102ac0c7d754683cf593a4a5a Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 14 Jun 2023 03:36:39 -0400 Subject: [PATCH 3/4] Ran black --- bundled/tool/lsp_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundled/tool/lsp_utils.py b/bundled/tool/lsp_utils.py index bb84c5f..1f93673 100644 --- a/bundled/tool/lsp_utils.py +++ b/bundled/tool/lsp_utils.py @@ -72,7 +72,7 @@ "truthy-bool": "error_code_list2.html#check-that-expression-is-not-implicitly-true-in-boolean-context-truthy-bool", "truthy-iterable": "error_code_list2.html#check-that-iterable-is-not-implicitly-true-in-boolean-context-truthy-iterable", "undefined": "error_code_list2.html#check-that-type-ignore-include-an-error-code-ignore-without-code", - "unused-awaitable": "error_code_list2.html#check-that-awaitable-return-value-is-used-unused-awaitable" + "unused-awaitable": "error_code_list2.html#check-that-awaitable-return-value-is-used-unused-awaitable", } From a73b36e4527f888d19040a42e2bec28f7a20cadb Mon Sep 17 00:00:00 2001 From: Avasam Date: Thu, 15 Jun 2023 10:36:07 -0400 Subject: [PATCH 4/4] Updated to use the new consistent error code anchors --- bundled/tool/lsp_server.py | 12 ++---- bundled/tool/lsp_utils.py | 57 +-------------------------- src/test/python_tests/test_linting.py | 6 +-- 3 files changed, 7 insertions(+), 68 deletions(-) diff --git a/bundled/tool/lsp_server.py b/bundled/tool/lsp_server.py index b07f2c8..ea227c5 100644 --- a/bundled/tool/lsp_server.py +++ b/bundled/tool/lsp_server.py @@ -142,14 +142,6 @@ def _get_group_dict(line: str) -> Optional[Dict[str, str]]: return None -def _get_code_description(code: str) -> Optional[lsp.CodeDescription]: - """Build the URL to the documentation for this warning.""" - anchor = utils.ERROR_CODE_ANCHORS.get(code) - if anchor is None: - return None - return lsp.CodeDescription(href=utils.ERROR_CODE_BASE_URL + anchor) - - def _parse_output_using_regex( content: str, severity: Dict[str, str] ) -> list[lsp.Diagnostic]: @@ -190,7 +182,9 @@ def _parse_output_using_regex( message=data.get("message"), severity=_get_severity(data["code"], data["type"], severity), code=data["code"], - code_description=_get_code_description(data["code"]), + code_description=lsp.CodeDescription( + href=utils.ERROR_CODE_BASE_URL + data["code"] + ), source=TOOL_DISPLAY, ) diagnostics.append(diagnostic) diff --git a/bundled/tool/lsp_utils.py b/bundled/tool/lsp_utils.py index 1f93673..0a0845e 100644 --- a/bundled/tool/lsp_utils.py +++ b/bundled/tool/lsp_utils.py @@ -18,62 +18,7 @@ # Save the working directory used when loading this module SERVER_CWD = os.getcwd() CWD_LOCK = threading.Lock() -ERROR_CODE_BASE_URL = "https://mypy.readthedocs.io/en/stable/" -ERROR_CODE_ANCHORS = { - "attr-defined": "error_code_list.html#check-that-attribute-exists-attr-defined", - "union-attr": "error_code_list.html#check-that-attribute-exists-in-each-union-item-union-attr", - "name-defined": "error_code_list.html#check-that-name-is-defined-name-defined", - "used-before-def": "error_code_list.html#check-that-a-variable-is-not-used-before-it-s-defined-used-before-def", - "call-arg": "error_code_list.html#check-arguments-in-calls-call-arg", - "arg-type": "error_code_list.html#check-argument-types-arg-type", - "call-overload": "error_code_list.html#check-calls-to-overloaded-functions-call-overload", - "valid-type": "error_code_list.html#check-validity-of-types-valid-type", - "var-annotated": "error_code_list.html#require-annotation-if-variable-type-is-unclear-var-annotated", - "override": "error_code_list.html#check-validity-of-overrides-override", - "return": "error_code_list.html#check-that-function-returns-a-value-return", - "return-value": "error_code_list.html#check-that-return-value-is-compatible-return-value", - "assignment": "error_code_list.html#check-types-in-assignment-statement-assignment", - "method-assign": "error_code_list.html#check-that-assignment-target-is-not-a-method-method-assign", - "type-var": "error_code_list.html#check-type-variable-values-type-var", - "operator": "error_code_list.html#check-uses-of-various-operators-operator", - "index": "error_code_list.html#check-indexing-operations-index", - "list-item": "error_code_list.html#check-list-items-list-item", - "dict-item": "error_code_list.html#check-dict-items-dict-item", - "typeddict-item": "error_code_list.html#check-typeddict-items-typeddict-item", - "typeddict-unknown-key": "error_code_list.html#check-typeddict-keys-typeddict-unknown-key", - "has-type": "error_code_list.html#check-that-type-of-target-is-known-has-type", - "import": "error_code_list.html#check-that-import-target-can-be-found-import", - "no-redef": "error_code_list.html#check-that-each-name-is-defined-once-no-redef", - "func-returns-value": "error_code_list.html#check-that-called-function-returns-a-value-func-returns-value", - "abstract": "error_code_list.html#check-instantiation-of-abstract-classes-abstract", - "type-abstract": "error_code_list.html#safe-handling-of-abstract-type-object-types-type-abstract", - "safe-super": "error_code_list.html#check-that-call-to-an-abstract-method-via-super-is-valid-safe-super", - "valid-newtype": "error_code_list.html#check-the-target-of-newtype-valid-newtype", - "exit-return": "error_code_list.html#check-the-return-type-of-exit-exit-return", - "name-match": "error_code_list.html#check-that-naming-is-consistent-name-match", - "literal-required": "error_code_list.html#check-that-literal-is-used-where-expected-literal-required", - "no-overload-impl": "error_code_list.html#check-that-overloaded-functions-have-an-implementation-no-overload-impl", - "unused-coroutine": "error_code_list.html#check-that-coroutine-return-value-is-used-unused-coroutine", - "assert-type": "error_code_list.html#check-types-in-assert-type-assert-type", - "truthy-function": "error_code_list.html#check-that-function-isn-t-used-in-boolean-context-truthy-function", - "str-bytes-safe": "error_code_list.html#check-for-implicit-bytes-coercions-str-bytes-safe", - "syntax": "error_code_list.html#report-syntax-errors-syntax", - "misc": "error_code_list.html#miscellaneous-checks-misc", - "type-arg": "error_code_list2.html#check-that-type-arguments-exist-type-arg", - "no-untyped-def": "error_code_list2.html#check-that-every-function-has-an-annotation-no-untyped-def", - "redundant-cast": "error_code_list2.html#check-that-cast-is-not-redundant-redundant-cast", - "redundant-self": "error_code_list2.html#check-that-methods-do-not-have-redundant-self-annotations-redundant-self", - "comparison-overlap": "error_code_list2.html#check-that-comparisons-are-overlapping-comparison-overlap", - "no-untyped-call": "error_code_list2.html#check-that-no-untyped-functions-are-called-no-untyped-call", - "no-any-return": "error_code_list2.html#check-that-function-does-not-return-any-value-no-any-return", - "no-any-unimported": "error_code_list2.html#check-that-types-have-no-any-components-due-to-missing-imports-no-any-unimported", - "unreachable": "error_code_list2.html#check-that-statement-or-expression-is-unreachable-unreachable", - "redundant-expr": "error_code_list2.html#check-that-expression-is-redundant-redundant-expr", - "truthy-bool": "error_code_list2.html#check-that-expression-is-not-implicitly-true-in-boolean-context-truthy-bool", - "truthy-iterable": "error_code_list2.html#check-that-iterable-is-not-implicitly-true-in-boolean-context-truthy-iterable", - "undefined": "error_code_list2.html#check-that-type-ignore-include-an-error-code-ignore-without-code", - "unused-awaitable": "error_code_list2.html#check-that-awaitable-return-value-is-used-unused-awaitable", -} +ERROR_CODE_BASE_URL = "https://mypy.readthedocs.io/en/latest/_refs.html#code-" def as_list(content: Union[Any, List[Any], Tuple[Any]]) -> List[Any]: diff --git a/src/test/python_tests/test_linting.py b/src/test/python_tests/test_linting.py index 3164937..fb2fce9 100644 --- a/src/test/python_tests/test_linting.py +++ b/src/test/python_tests/test_linting.py @@ -64,7 +64,7 @@ def _log_handler(params): "severity": 1, "code": "name-defined", "codeDescription": { - "href": "https://mypy.readthedocs.io/en/stable/error_code_list.html#check-that-name-is-defined-name-defined" + "href": "https://mypy.readthedocs.io/en/latest/_refs.html#code-name-defined" }, "source": "Mypy", } @@ -121,7 +121,7 @@ def _log_handler(params): "severity": 1, "code": "name-defined", "codeDescription": { - "href": "https://mypy.readthedocs.io/en/stable/error_code_list.html#check-that-name-is-defined-name-defined" + "href": "https://mypy.readthedocs.io/en/latest/_refs.html#code-name-defined" }, "source": "Mypy", } @@ -243,7 +243,7 @@ def _log_handler(params): "severity": 2, "code": "name-defined", "codeDescription": { - "href": "https://mypy.readthedocs.io/en/stable/error_code_list.html#check-that-name-is-defined-name-defined" + "href": "https://mypy.readthedocs.io/en/latest/_refs.html#code-name-defined" }, "source": "Mypy", }