From d245510d692887b1c934d397c60117c7c3b93616 Mon Sep 17 00:00:00 2001 From: Francesco Bertolaccini Date: Tue, 9 Apr 2024 11:57:48 +0200 Subject: [PATCH] Fix pylint --- .github/workflows/pylint.yaml | 1 + pyproject.toml | 20 +++++- slither_lsp/app/app.py | 2 +- .../feature_analyses/slither_diagnostics.py | 2 +- .../analysis/get_detector_list.py | 5 +- .../request_handlers/analysis/get_version.py | 5 +- .../app/request_handlers/call_hierarchy.py | 2 +- .../request_handlers/compilation/__init__.py | 1 - .../compilation/autogenerate_standard_json.py | 67 ------------------- .../compilation/get_command_line_args.py | 4 +- .../request_handlers/goto_def_impl_refs.py | 2 + slither_lsp/app/request_handlers/symbols.py | 30 +++++---- .../app/request_handlers/type_hierarchy.py | 4 +- slither_lsp/app/request_handlers/types.py | 8 +-- slither_lsp/app/slither_server.py | 8 ++- slither_lsp/app/types/analysis_structures.py | 22 +++--- slither_lsp/app/utils/file_paths.py | 2 +- 17 files changed, 65 insertions(+), 120 deletions(-) delete mode 100644 slither_lsp/app/request_handlers/compilation/autogenerate_standard_json.py diff --git a/.github/workflows/pylint.yaml b/.github/workflows/pylint.yaml index 67eac11..f040b81 100644 --- a/.github/workflows/pylint.yaml +++ b/.github/workflows/pylint.yaml @@ -37,6 +37,7 @@ run: | mkdir -p .github/linters cp pyproject.toml .github/linters + pip install . - name: Register pylint problem matcher run: | diff --git a/pyproject.toml b/pyproject.toml index e495365..3af5b2c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,8 +40,22 @@ slither-lsp = "slither_lsp.__main__:main" max-line-length = 120 disable = """ -import-outside-toplevel, missing-module-docstring, -useless-return, -duplicate-code +missing-class-docstring, +missing-function-docstring, +unnecessary-lambda, +cyclic-import, +line-too-long, +invalid-name, +fixme, +too-many-return-statements, +too-many-ancestors, +logging-fstring-interpolation, +logging-not-lazy, +duplicate-code, +import-error, +unsubscriptable-object, +unnecessary-lambda-assignment, +too-few-public-methods, +too-many-instance-attributes """ \ No newline at end of file diff --git a/slither_lsp/app/app.py b/slither_lsp/app/app.py index 1af439b..57673f8 100644 --- a/slither_lsp/app/app.py +++ b/slither_lsp/app/app.py @@ -1,8 +1,8 @@ from importlib.metadata import version as pkg_version from logging import Logger -import slither_lsp.app.request_handlers as request_handlers import slither_lsp.app.types.params as slsp +from slither_lsp.app import request_handlers from slither_lsp.app.slither_server import SlitherServer diff --git a/slither_lsp/app/feature_analyses/slither_diagnostics.py b/slither_lsp/app/feature_analyses/slither_diagnostics.py index 5ae13d5..303cb42 100644 --- a/slither_lsp/app/feature_analyses/slither_diagnostics.py +++ b/slither_lsp/app/feature_analyses/slither_diagnostics.py @@ -136,7 +136,7 @@ def clear(self) -> None: :return: None """ # Loop through all diagnostic files, publish new diagnostics for each file with no items. - for file_uri in self.diagnostics.keys(): + for file_uri, _ in self.diagnostics: self._clear_single(file_uri, False) # Clear the dictionary diff --git a/slither_lsp/app/request_handlers/analysis/get_detector_list.py b/slither_lsp/app/request_handlers/analysis/get_detector_list.py index 14233dd..7393579 100644 --- a/slither_lsp/app/request_handlers/analysis/get_detector_list.py +++ b/slither_lsp/app/request_handlers/analysis/get_detector_list.py @@ -1,10 +1,7 @@ -from typing import Any - -from pygls.server import LanguageServer from slither.__main__ import get_detectors_and_printers, output_detectors_json -def get_detector_list(ls: LanguageServer, params: Any) -> Any: +def get_detector_list(): """ Handler which invokes slither to obtain a list of all detectors and some properties that describe them. """ diff --git a/slither_lsp/app/request_handlers/analysis/get_version.py b/slither_lsp/app/request_handlers/analysis/get_version.py index be940c9..70caab3 100644 --- a/slither_lsp/app/request_handlers/analysis/get_version.py +++ b/slither_lsp/app/request_handlers/analysis/get_version.py @@ -1,10 +1,7 @@ from importlib.metadata import version as pkg_version -from typing import Any -from pygls.server import LanguageServer - -def get_version(ls: LanguageServer, params: Any) -> Any: +def get_version(): """ Handler which retrieves versions for slither, crytic-compile, and related applications. """ diff --git a/slither_lsp/app/request_handlers/call_hierarchy.py b/slither_lsp/app/request_handlers/call_hierarchy.py index 68afa4f..e7fe283 100644 --- a/slither_lsp/app/request_handlers/call_hierarchy.py +++ b/slither_lsp/app/request_handlers/call_hierarchy.py @@ -70,7 +70,7 @@ def on_prepare_call_hierarchy( "offset": offset, }, ) - return [elem for elem in res.values()] + return list(res.values()) def register_on_get_incoming_calls(ls: "SlitherServer"): diff --git a/slither_lsp/app/request_handlers/compilation/__init__.py b/slither_lsp/app/request_handlers/compilation/__init__.py index c684564..0ffb63f 100644 --- a/slither_lsp/app/request_handlers/compilation/__init__.py +++ b/slither_lsp/app/request_handlers/compilation/__init__.py @@ -1,2 +1 @@ -from .autogenerate_standard_json import autogenerate_standard_json from .get_command_line_args import get_command_line_args diff --git a/slither_lsp/app/request_handlers/compilation/autogenerate_standard_json.py b/slither_lsp/app/request_handlers/compilation/autogenerate_standard_json.py deleted file mode 100644 index ed461d4..0000000 --- a/slither_lsp/app/request_handlers/compilation/autogenerate_standard_json.py +++ /dev/null @@ -1,67 +0,0 @@ -import os -from typing import Any, Iterable, Set - -from crytic_compile.platform.solc_standard_json import SolcStandardJson -from pygls.server import LanguageServer - - -def get_solidity_files(folders: Iterable[str], recursive=True) -> Set: - """ - Loops through all provided folders and obtains a list of all solidity files existing in them. - This skips 'node_module' folders created by npm/yarn. - :param folders: A list of folders to search for Solidity files within. - :param recursive: Indicates if the search for Solidity files should be recursive. - :return: A list of Solidity file paths which were discovered in the provided folders. - """ - # Create our resulting set - solidity_files = set() - for folder in folders: - for root, dirs, files in os.walk(folder): - # Loop through all files and determine if any have a .sol extension - for file in files: - filename_base, file_extension = os.path.splitext(file) - if file_extension is not None and file_extension.lower() == ".sol": - solidity_files.add(os.path.join(root, file)) - - # If recursive, join our set with any other discovered files in subdirectories. - if recursive: - solidity_files.update( - get_solidity_files([os.path.join(root, d) for d in dirs], recursive) - ) - - # Return all discovered solidity files - return solidity_files - - -def autogenerate_standard_json(ls: LanguageServer, params: Any) -> Any: - """ - Handler which auto-generates solc standard JSON manifests for Solidity files under a given - directory. - """ - - # Obtain our target files and folders. - files = set() - folders = set() - if "files" in params and isinstance(params["files"], list): - files.update(params["files"]) - if "folders" in params and isinstance(params["folders"], list): - folders.update(params["folders"]) - - # Get a list of all solidity files in our folders - files.update(get_solidity_files(folders)) - - # TODO: Parse import strings, create remappings for unresolved imports. - # Regex: import\s+[^"]*"([^"]+)".*; - - # TODO: Parse semvers, find incompatibilities, put them into different compilation buckets - # and potentially return data about satisfactory solc versions, which may enable us to - # use solc-select to compile all. - # Regex: pragma\s+solidity\s+(.*); - - # TODO: For now we return a single json manifest, but we want to split them if we have - # version conflicts. - standard_json = SolcStandardJson() - for file in files: - standard_json.add_source_file(file) - - return [standard_json.to_dict()] diff --git a/slither_lsp/app/request_handlers/compilation/get_command_line_args.py b/slither_lsp/app/request_handlers/compilation/get_command_line_args.py index 7e0c921..029f68d 100644 --- a/slither_lsp/app/request_handlers/compilation/get_command_line_args.py +++ b/slither_lsp/app/request_handlers/compilation/get_command_line_args.py @@ -1,11 +1,9 @@ from argparse import ArgumentParser -from typing import Any from crytic_compile.cryticparser.cryticparser import init as crytic_parser_init -from pygls.server import LanguageServer -def get_command_line_args(ls: LanguageServer, params: Any) -> Any: +def get_command_line_args(): """ Handler which obtains data regarding all command line arguments available in crytic-compile. """ diff --git a/slither_lsp/app/request_handlers/goto_def_impl_refs.py b/slither_lsp/app/request_handlers/goto_def_impl_refs.py index 83f3170..1a024f4 100644 --- a/slither_lsp/app/request_handlers/goto_def_impl_refs.py +++ b/slither_lsp/app/request_handlers/goto_def_impl_refs.py @@ -1,3 +1,5 @@ +# pylint: disable=broad-exception-caught + from typing import TYPE_CHECKING, Callable, List, Optional, Set import lsprotocol.types as lsp diff --git a/slither_lsp/app/request_handlers/symbols.py b/slither_lsp/app/request_handlers/symbols.py index 7b5ecea..35a0197 100644 --- a/slither_lsp/app/request_handlers/symbols.py +++ b/slither_lsp/app/request_handlers/symbols.py @@ -1,3 +1,5 @@ +# pylint: disable=too-many-branches + from typing import TYPE_CHECKING, List, Optional import lsprotocol.types as lsp @@ -24,6 +26,16 @@ def document_symbol( for analysis, comp in ls.get_analyses_containing(target_filename_str): filename = comp.filename_lookup(target_filename_str) + def add_child(children, obj, kind): + children.append( + lsp.DocumentSymbol( + name=obj.name, + kind=kind, + range=source_to_range(obj.source_mapping), + selection_range=get_object_name_range(obj, comp), + ) + ) + for contract in analysis.contracts: if ( not contract.source_mapping @@ -36,35 +48,25 @@ def document_symbol( kind = lsp.SymbolKind.Class children: List[lsp.DocumentSymbol] = [] - def add_child(obj, kind): - children.append( - lsp.DocumentSymbol( - name=obj.name, - kind=kind, - range=source_to_range(obj.source_mapping), - selection_range=get_object_name_range(obj, comp), - ) - ) - for struct in contract.structures_declared: if struct.source_mapping is None: continue - add_child(struct, lsp.SymbolKind.Struct) + add_child(children, struct, lsp.SymbolKind.Struct) for enum in contract.enums_declared: if enum.source_mapping is None: continue - add_child(enum, lsp.SymbolKind.Enum) + add_child(children, enum, lsp.SymbolKind.Enum) for event in contract.events_declared: if event.source_mapping is None: continue - add_child(event, lsp.SymbolKind.Enum) + add_child(children, event, lsp.SymbolKind.Enum) for func in contract.functions_and_modifiers_declared: if func.source_mapping is None: continue - add_child(func, lsp.SymbolKind.Function) + add_child(children, func, lsp.SymbolKind.Function) res.append( lsp.DocumentSymbol( diff --git a/slither_lsp/app/request_handlers/type_hierarchy.py b/slither_lsp/app/request_handlers/type_hierarchy.py index b3d3301..a22e7e1 100644 --- a/slither_lsp/app/request_handlers/type_hierarchy.py +++ b/slither_lsp/app/request_handlers/type_hierarchy.py @@ -48,7 +48,7 @@ def on_prepare_type_hierarchy( if not isinstance(obj, Contract): continue offset = get_definition(obj, comp).start - range = get_object_name_range(obj, comp) + range_ = get_object_name_range(obj, comp) if obj.is_interface: kind = lsp.SymbolKind.Interface else: @@ -56,7 +56,7 @@ def on_prepare_type_hierarchy( res.add( TypeItem( name=obj.name, - range=to_range(range), + range=to_range(range_), kind=kind, filename=source.filename.absolute, offset=offset, diff --git a/slither_lsp/app/request_handlers/types.py b/slither_lsp/app/request_handlers/types.py index 68d052b..1eb281a 100644 --- a/slither_lsp/app/request_handlers/types.py +++ b/slither_lsp/app/request_handlers/types.py @@ -10,13 +10,13 @@ def to_lsp_pos(pos: Pos) -> lsp.Position: return lsp.Position(line=pos[0], character=pos[1]) -def to_lsp_range(range: Range) -> lsp.Range: - return lsp.Range(start=to_lsp_pos(range[0]), end=to_lsp_pos(range[1])) +def to_lsp_range(range_: Range) -> lsp.Range: + return lsp.Range(start=to_lsp_pos(range_[0]), end=to_lsp_pos(range_[1])) def to_pos(pos: lsp.Position) -> Pos: return (pos.line, pos.character) -def to_range(range: lsp.Range) -> Range: - return (to_pos(range.start), to_pos(range.end)) +def to_range(range_: lsp.Range) -> Range: + return (to_pos(range_.start), to_pos(range_.end)) diff --git a/slither_lsp/app/slither_server.py b/slither_lsp/app/slither_server.py index 73f3eac..9439f1a 100644 --- a/slither_lsp/app/slither_server.py +++ b/slither_lsp/app/slither_server.py @@ -1,3 +1,5 @@ +# pylint: disable=broad-exception-caught, protected-access + import logging from collections import defaultdict from concurrent.futures import ThreadPoolExecutor @@ -102,7 +104,7 @@ def on_initialize(ls: SlitherServer, params): ls._on_initialize(params) @self.feature(lsp.INITIALIZED) - def on_initialized(ls: SlitherServer, params): + def on_initialized(ls: SlitherServer): ls.show_message("slither-lsp initialized", lsp.MessageType.Debug) @self.thread() @@ -179,7 +181,7 @@ def queue_compile_workspace(self, uri: str): path = uri_to_fs_path(uri) workspace_name = split(path)[1] - def compile(): + def do_compile(): detector_classes, _ = get_detectors_and_printers() with self.workspace_in_progress[uri]: self.show_message( @@ -232,7 +234,7 @@ def compile(): ) self._refresh_detector_output() - self.analysis_pool.submit(compile) + self.analysis_pool.submit(do_compile) def _on_did_change_workspace_folders( self, params: lsp.DidChangeWorkspaceFoldersParams diff --git a/slither_lsp/app/types/analysis_structures.py b/slither_lsp/app/types/analysis_structures.py index fdbcadc..b39dcc3 100644 --- a/slither_lsp/app/types/analysis_structures.py +++ b/slither_lsp/app/types/analysis_structures.py @@ -59,15 +59,15 @@ class SlitherDetectorResultElement: """ The type of item this represents (contract, function, etc.) """ @staticmethod - def from_dict(dict): + def from_dict(dict_): return SlitherDetectorResultElement( - name=dict["name"], + name=dict_["name"], source_mapping=( - SlitherDetectorResultElementSourceMapping(**dict["source_mapping"]) - if dict["source_mapping"] + SlitherDetectorResultElementSourceMapping(**dict_["source_mapping"]) + if dict_["source_mapping"] else None ), - type=dict["type"], + type=dict_["type"], ) @@ -93,15 +93,15 @@ class SlitherDetectorResult: """ Source mapped elements that are relevant to this detector result. """ @staticmethod - def from_dict(dict): + def from_dict(dict_): return SlitherDetectorResult( - check=dict["check"], - confidence=dict["confidence"], - impact=dict["impact"], - description=dict["description"], + check=dict_["check"], + confidence=dict_["confidence"], + impact=dict_["impact"], + description=dict_["description"], elements=[ SlitherDetectorResultElement.from_dict(elem) - for elem in dict["elements"] + for elem in dict_["elements"] ], ) diff --git a/slither_lsp/app/utils/file_paths.py b/slither_lsp/app/utils/file_paths.py index 3235b15..0fa94b4 100644 --- a/slither_lsp/app/utils/file_paths.py +++ b/slither_lsp/app/utils/file_paths.py @@ -5,7 +5,7 @@ def is_solidity_file(path: str) -> bool: - filename_base, file_extension = os.path.splitext(path) + _, file_extension = os.path.splitext(path) return file_extension is not None and file_extension.lower() == ".sol"