diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 0e85eb8e..d5fd459d 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -38,14 +38,12 @@ jobs: # If we don't install pycodestyle, pylint will throw an unused-argument error in pylsp/plugins/pycodestyle_lint.py:72 # This error cannot be resolved by adding a pylint: disable=unused-argument comment ... - run: | - pip install -e .[pylint,pycodestyle,pyflakes] - pip install black - - name: Pylint checks - run: pylint pylsp test - - name: Code style checks with black - run: black --check pylsp test - - name: Pyflakes checks - run: pyflakes pylsp test + pip install -e .[pylint,pycodestyle] + pip install ruff + - name: ruff linter and code style checks + run: ruff check pylsp test + - name: ruff code formatter check + run: ruff format --check pylsp test - name: Validate JSON schema run: echo {} | jsonschema pylsp/config/schema.json - name: Ensure JSON schema and Markdown docs are in sync diff --git a/.pylintrc b/.pylintrc index ebe4f30f..fe36d8cb 100644 --- a/.pylintrc +++ b/.pylintrc @@ -28,4 +28,4 @@ reports = no generated-members = pylsp_* - cache_clear + cache_clear \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index e82d1f50..52e77143 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,5 +2,6 @@ include README.md include versioneer.py include pylsp/_version.py include LICENSE +include ruff.toml include .pylintrc recursive-include test *.py diff --git a/README.md b/README.md index f77a73bd..51ec4f7e 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,13 @@ To run the test suite: pytest ``` +Running ruff as a linter and code formatter on the repo: +```sh +ruff check . # linter +ruff check --fix . # fix all auto-fixable lint issues +ruff format . # format the document +``` + After adding configuration options to `schema.json`, refresh the `CONFIGURATION.md` file with ``` diff --git a/pylsp/__init__.py b/pylsp/__init__.py index eeb80bdc..f363ad86 100644 --- a/pylsp/__init__.py +++ b/pylsp/__init__.py @@ -2,7 +2,9 @@ # Copyright 2021- Python Language Server Contributors. import os + import pluggy + from . import _version from ._version import __version__ diff --git a/pylsp/__main__.py b/pylsp/__main__.py index d6691740..61bd015b 100644 --- a/pylsp/__main__.py +++ b/pylsp/__main__.py @@ -9,16 +9,16 @@ try: import ujson as json -except Exception: # pylint: disable=broad-except +except Exception: import json +from ._version import __version__ from .python_lsp import ( PythonLSPServer, start_io_lang_server, start_tcp_lang_server, start_ws_lang_server, ) -from ._version import __version__ LOG_FORMAT = "%(asctime)s {0} - %(levelname)s - %(name)s - %(message)s".format( time.localtime().tm_zone diff --git a/pylsp/_utils.py b/pylsp/_utils.py index f694a36a..e1d2b53c 100644 --- a/pylsp/_utils.py +++ b/pylsp/_utils.py @@ -61,7 +61,7 @@ def throttle(seconds=1): def decorator(func): @functools.wraps(func) - def wrapper(*args, **kwargs): # pylint: disable=inconsistent-return-statements + def wrapper(*args, **kwargs): if not hasattr(wrapper, "last_call"): wrapper.last_call = 0 if time.time() - wrapper.last_call >= seconds: diff --git a/pylsp/config/config.py b/pylsp/config/config.py index 454ee4b3..0d9f2635 100644 --- a/pylsp/config/config.py +++ b/pylsp/config/config.py @@ -1,6 +1,5 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -# pylint: disable=import-outside-toplevel import logging import sys @@ -10,7 +9,7 @@ import pluggy from pluggy._hooks import HookImpl -from pylsp import _utils, hookspecs, uris, PYLSP +from pylsp import PYLSP, _utils, hookspecs, uris # See compatibility note on `group` keyword: # https://docs.python.org/3/library/importlib.metadata.html#entry-points @@ -38,7 +37,7 @@ def _hookexec( # enable_tracing will set its own wrapping function at self._inner_hookexec try: return self._inner_hookexec(hook_name, methods, kwargs, firstresult) - except Exception as e: # pylint: disable=broad-except + except Exception as e: log.warning(f"Failed to load hook {hook_name}: {e}", exc_info=True) return [] @@ -79,7 +78,7 @@ def __init__(self, root_uri, init_opts, process_id, capabilities): for entry_point in entry_points(group=PYLSP): try: entry_point.load() - except Exception as e: # pylint: disable=broad-except + except Exception as e: log.info( "Failed to load %s entry point '%s': %s", PYLSP, entry_point.name, e ) diff --git a/pylsp/config/flake8_conf.py b/pylsp/config/flake8_conf.py index ca3b199c..5e969d97 100644 --- a/pylsp/config/flake8_conf.py +++ b/pylsp/config/flake8_conf.py @@ -3,7 +3,9 @@ import logging import os + from pylsp._utils import find_parents + from .source import ConfigSource log = logging.getLogger(__name__) diff --git a/pylsp/config/pycodestyle_conf.py b/pylsp/config/pycodestyle_conf.py index 98d8a1b1..ed15a802 100644 --- a/pylsp/config/pycodestyle_conf.py +++ b/pylsp/config/pycodestyle_conf.py @@ -2,9 +2,10 @@ # Copyright 2021- Python Language Server Contributors. import pycodestyle + from pylsp._utils import find_parents -from .source import ConfigSource +from .source import ConfigSource CONFIG_KEY = "pycodestyle" USER_CONFIGS = [pycodestyle.USER_CONFIG] if pycodestyle.USER_CONFIG else [] diff --git a/pylsp/hookspecs.py b/pylsp/hookspecs.py index 9c9cf387..a2549fbc 100644 --- a/pylsp/hookspecs.py +++ b/pylsp/hookspecs.py @@ -1,7 +1,6 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -# pylint: disable=redefined-builtin, unused-argument from pylsp import hookspec diff --git a/pylsp/plugins/_resolvers.py b/pylsp/plugins/_resolvers.py index d0d2dc4c..835b3aff 100644 --- a/pylsp/plugins/_resolvers.py +++ b/pylsp/plugins/_resolvers.py @@ -1,15 +1,14 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -from collections import defaultdict import logging +from collections import defaultdict from time import time from jedi.api.classes import Completion from pylsp import lsp - log = logging.getLogger(__name__) @@ -77,7 +76,7 @@ def resolve(self, completion): try: sig = completion.get_signatures() return self.callback(completion, sig) - except Exception as e: # pylint: disable=broad-except + except Exception as e: log.warning( f"Something went wrong when resolving label for {completion}: {e}" ) diff --git a/pylsp/plugins/_rope_task_handle.py b/pylsp/plugins/_rope_task_handle.py index 841d6fee..a72ef56e 100644 --- a/pylsp/plugins/_rope_task_handle.py +++ b/pylsp/plugins/_rope_task_handle.py @@ -1,13 +1,12 @@ from __future__ import annotations import logging - from typing import Callable, ContextManager, List, Optional, Sequence from rope.base.taskhandle import BaseJobSet, BaseTaskHandle -from pylsp.workspace import Workspace from pylsp._utils import throttle +from pylsp.workspace import Workspace log = logging.getLogger(__name__) Report = Callable[[str, int], None] diff --git a/pylsp/plugins/autopep8_format.py b/pylsp/plugins/autopep8_format.py index 1ae3e5f1..b3a04837 100644 --- a/pylsp/plugins/autopep8_format.py +++ b/pylsp/plugins/autopep8_format.py @@ -4,7 +4,8 @@ import logging import pycodestyle -from autopep8 import fix_code, continued_indentation as autopep8_c_i +from autopep8 import continued_indentation as autopep8_c_i +from autopep8 import fix_code from pylsp import hookimpl from pylsp._utils import get_eol_chars @@ -13,18 +14,14 @@ @hookimpl(tryfirst=True) # Prefer autopep8 over YAPF -def pylsp_format_document( - config, workspace, document, options -): # pylint: disable=unused-argument +def pylsp_format_document(config, workspace, document, options): with workspace.report_progress("format: autopep8"): log.info("Formatting document %s with autopep8", document) return _format(config, document) @hookimpl(tryfirst=True) # Prefer autopep8 over YAPF -def pylsp_format_range( - config, workspace, document, range, options -): # pylint: disable=redefined-builtin,unused-argument +def pylsp_format_range(config, workspace, document, range, options): log.info("Formatting document %s in range %s with autopep8", document, range) # First we 'round' the range up/down to full lines only diff --git a/pylsp/plugins/definition.py b/pylsp/plugins/definition.py index 53eda915..67abfb71 100644 --- a/pylsp/plugins/definition.py +++ b/pylsp/plugins/definition.py @@ -1,16 +1,18 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. from __future__ import annotations + import logging -from typing import Any, Dict, List, TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Dict, List import jedi -from pylsp import hookimpl, uris, _utils +from pylsp import _utils, hookimpl, uris if TYPE_CHECKING: from jedi.api import Script from jedi.api.classes import Name + from pylsp.config.config import Config from pylsp.workspace import Document diff --git a/pylsp/plugins/flake8_lint.py b/pylsp/plugins/flake8_lint.py index 77aa22b9..eed673f7 100644 --- a/pylsp/plugins/flake8_lint.py +++ b/pylsp/plugins/flake8_lint.py @@ -141,9 +141,7 @@ def run_flake8(flake8_executable, args, document, source): ) cmd = [sys.executable, "-m", "flake8"] cmd.extend(args) - p = Popen( # pylint: disable=consider-using-with - cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, **popen_kwargs - ) + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, **popen_kwargs) (stdout, stderr) = p.communicate(source.encode()) if stderr: log.error("Error while running flake8 '%s'", stderr.decode()) diff --git a/pylsp/plugins/highlight.py b/pylsp/plugins/highlight.py index 0dd896c6..c4c12406 100644 --- a/pylsp/plugins/highlight.py +++ b/pylsp/plugins/highlight.py @@ -2,7 +2,8 @@ # Copyright 2021- Python Language Server Contributors. import logging -from pylsp import hookimpl, lsp, _utils + +from pylsp import _utils, hookimpl, lsp log = logging.getLogger(__name__) diff --git a/pylsp/plugins/hover.py b/pylsp/plugins/hover.py index ae07b3dc..ca69d1b3 100644 --- a/pylsp/plugins/hover.py +++ b/pylsp/plugins/hover.py @@ -3,7 +3,7 @@ import logging -from pylsp import hookimpl, _utils +from pylsp import _utils, hookimpl log = logging.getLogger(__name__) diff --git a/pylsp/plugins/jedi_completion.py b/pylsp/plugins/jedi_completion.py index 65f75239..2796a093 100644 --- a/pylsp/plugins/jedi_completion.py +++ b/pylsp/plugins/jedi_completion.py @@ -38,7 +38,6 @@ @hookimpl def pylsp_completions(config, document, position): """Get formatted completions for current code position""" - # pylint: disable=too-many-locals settings = config.plugin_settings("jedi_completion", document_path=document.path) resolve_eagerly = settings.get("eager", False) code_position = _utils.position_to_jedi_linecolumn(document, position) @@ -209,7 +208,6 @@ def use_snippets(document, position): def _resolve_completion(completion, d, markup_kind: str): - # pylint: disable=broad-except completion["detail"] = _detail(d) try: docs = _utils.format_docstring( diff --git a/pylsp/plugins/jedi_rename.py b/pylsp/plugins/jedi_rename.py index 9c89c1de..5606a881 100644 --- a/pylsp/plugins/jedi_rename.py +++ b/pylsp/plugins/jedi_rename.py @@ -3,15 +3,13 @@ import logging -from pylsp import hookimpl, uris, _utils +from pylsp import _utils, hookimpl, uris log = logging.getLogger(__name__) @hookimpl -def pylsp_rename( - config, workspace, document, position, new_name -): # pylint: disable=unused-argument +def pylsp_rename(config, workspace, document, position, new_name): log.debug( "Executing rename of %s to %s", document.word_at_position(position), new_name ) @@ -20,7 +18,6 @@ def pylsp_rename( try: refactoring = document.jedi_script().rename(**kwargs) except NotImplementedError as exc: - # pylint: disable=broad-exception-raised raise Exception( "No support for renaming in Python 2/3.5 with Jedi. " "Consider using the rope_rename plugin instead" diff --git a/pylsp/plugins/mccabe_lint.py b/pylsp/plugins/mccabe_lint.py index f115a3ce..0e2cba2e 100644 --- a/pylsp/plugins/mccabe_lint.py +++ b/pylsp/plugins/mccabe_lint.py @@ -3,7 +3,9 @@ import ast import logging + import mccabe + from pylsp import hookimpl, lsp log = logging.getLogger(__name__) diff --git a/pylsp/plugins/preload_imports.py b/pylsp/plugins/preload_imports.py index 0b98febe..a45a6666 100644 --- a/pylsp/plugins/preload_imports.py +++ b/pylsp/plugins/preload_imports.py @@ -2,6 +2,7 @@ # Copyright 2021- Python Language Server Contributors. import logging + from pylsp import hookimpl log = logging.getLogger(__name__) @@ -71,7 +72,7 @@ def pylsp_initialize(config): try: __import__(mod_name) log.debug("Preloaded module %s", mod_name) - except Exception: # pylint: disable=broad-except + except Exception: # Catch any exception since not only ImportError can be raised here # For example, old versions of NumPy can cause a ValueError. # See spyder-ide/spyder#13985 diff --git a/pylsp/plugins/pydocstyle_lint.py b/pylsp/plugins/pydocstyle_lint.py index 3a4df1c1..7d04bdf0 100644 --- a/pylsp/plugins/pydocstyle_lint.py +++ b/pylsp/plugins/pydocstyle_lint.py @@ -8,6 +8,7 @@ import sys import pydocstyle + from pylsp import hookimpl, lsp log = logging.getLogger(__name__) @@ -28,7 +29,6 @@ def pylsp_settings(): @hookimpl def pylsp_lint(config, workspace, document): - # pylint: disable=too-many-locals with workspace.report_progress("lint: pydocstyle"): settings = config.plugin_settings("pydocstyle", document_path=document.path) log.debug("Got pydocstyle settings: %s", settings) diff --git a/pylsp/plugins/pyflakes_lint.py b/pylsp/plugins/pyflakes_lint.py index 28a37b3f..e23f9a0f 100644 --- a/pylsp/plugins/pyflakes_lint.py +++ b/pylsp/plugins/pyflakes_lint.py @@ -1,7 +1,9 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -from pyflakes import api as pyflakes_api, messages +from pyflakes import api as pyflakes_api +from pyflakes import messages + from pylsp import hookimpl, lsp # Pyflakes messages that should be reported as Errors instead of Warns diff --git a/pylsp/plugins/pylint_lint.py b/pylsp/plugins/pylint_lint.py index 4dbb137d..784627b1 100644 --- a/pylsp/plugins/pylint_lint.py +++ b/pylsp/plugins/pylint_lint.py @@ -5,17 +5,17 @@ """Linter plugin for pylint.""" import collections import logging -import sys -import re -from subprocess import Popen, PIPE import os +import re import shlex +import sys +from subprocess import PIPE, Popen from pylsp import hookimpl, lsp try: import ujson as json -except Exception: # pylint: disable=broad-except +except Exception: import json log = logging.getLogger(__name__) @@ -48,9 +48,7 @@ class PylintLinter: last_diags = collections.defaultdict(list) @classmethod - def lint( - cls, document, is_saved, flags="" - ): # pylint: disable=too-many-locals,too-many-branches + def lint(cls, document, is_saved, flags=""): """Plugin interface to pylsp linter. Args: @@ -289,9 +287,7 @@ def _run_pylint_stdio(pylint_executable, document, flags): cmd = [sys.executable, "-m", "pylint"] cmd.extend(flags) cmd.extend(["--from-stdin", document.path]) - p = Popen( # pylint: disable=consider-using-with - cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE - ) + p = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) (stdout, stderr) = p.communicate(document.source.encode()) if stderr: log.error("Error while running pylint '%s'", stderr.decode()) diff --git a/pylsp/plugins/references.py b/pylsp/plugins/references.py index fadf1de8..a4c61b52 100644 --- a/pylsp/plugins/references.py +++ b/pylsp/plugins/references.py @@ -2,7 +2,8 @@ # Copyright 2021- Python Language Server Contributors. import logging -from pylsp import hookimpl, uris, _utils + +from pylsp import _utils, hookimpl, uris log = logging.getLogger(__name__) diff --git a/pylsp/plugins/rope_autoimport.py b/pylsp/plugins/rope_autoimport.py index b3626408..1a235c3d 100644 --- a/pylsp/plugins/rope_autoimport.py +++ b/pylsp/plugins/rope_autoimport.py @@ -1,8 +1,8 @@ # Copyright 2022- Python Language Server Contributors. import logging -from typing import Any, Dict, Generator, List, Optional, Set, Union import threading +from typing import Any, Dict, Generator, List, Optional, Set, Union import parso from jedi import Script @@ -94,7 +94,6 @@ def pylsp_settings() -> Dict[str, Dict[str, Dict[str, Any]]]: } -# pylint: disable=too-many-return-statements def _should_insert(expr: tree.BaseNode, word_node: tree.Leaf) -> bool: """ Check if we should insert the word_node on the given expr. @@ -214,7 +213,7 @@ def _process_statements( "kind": "quickfix", "edit": {"changes": {doc_uri: [edit]}}, # data is a supported field for codeAction responses - # See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction # pylint: disable=line-too-long + # See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction "data": {"sortText": _sort_import(score)}, } else: @@ -225,7 +224,7 @@ def get_names(script: Script) -> Set[str]: """Get all names to ignore from the current file.""" raw_names = script.get_names(definitions=True) log.debug(raw_names) - return set(name.name for name in raw_names) + return {name.name for name in raw_names} @hookimpl @@ -257,13 +256,11 @@ def pylsp_completions( ) autoimport = workspace._rope_autoimport(rope_config) suggestions = list(autoimport.search_full(word, ignored_names=ignored_names)) - results = list( - sorted( - _process_statements( - suggestions, document.uri, word, autoimport, document, "completions" - ), - key=lambda statement: statement["sortText"], - ) + results = sorted( + _process_statements( + suggestions, document.uri, word, autoimport, document, "completions" + ), + key=lambda statement: statement["sortText"], ) if len(results) > MAX_RESULTS_COMPLETIONS: results = results[:MAX_RESULTS_COMPLETIONS] @@ -279,7 +276,7 @@ def _get_score( ) -> int: import_length = len("import") full_statement_score = len(full_statement) - import_length - suggested_name_score = ((len(suggested_name) - len(desired_name))) ** 2 + suggested_name_score = (len(suggested_name) - len(desired_name)) ** 2 source_score = 20 * source return suggested_name_score + full_statement_score + source_score @@ -306,7 +303,7 @@ def pylsp_code_actions( config: Config, workspace: Workspace, document: Document, - range: Dict, # pylint: disable=redefined-builtin + range: Dict, context: Dict, ) -> List[Dict]: """ @@ -348,18 +345,16 @@ def pylsp_code_actions( autoimport = workspace._rope_autoimport(rope_config) suggestions = list(autoimport.search_full(word)) log.debug("autoimport: suggestions: %s", suggestions) - results = list( - sorted( - _process_statements( - suggestions, - document.uri, - word, - autoimport, - document, - "code_actions", - ), - key=lambda statement: statement["data"]["sortText"], - ) + results = sorted( + _process_statements( + suggestions, + document.uri, + word, + autoimport, + document, + "code_actions", + ), + key=lambda statement: statement["data"]["sortText"], ) if len(results) > MAX_RESULTS_CODE_ACTIONS: diff --git a/pylsp/plugins/rope_completion.py b/pylsp/plugins/rope_completion.py index ca0d4349..b3a1f066 100644 --- a/pylsp/plugins/rope_completion.py +++ b/pylsp/plugins/rope_completion.py @@ -2,11 +2,11 @@ # Copyright 2021- Python Language Server Contributors. import logging + from rope.contrib.codeassist import code_assist, sorted_proposals from pylsp import _utils, hookimpl, lsp - log = logging.getLogger(__name__) @@ -17,7 +17,6 @@ def pylsp_settings(): def _resolve_completion(completion, data, markup_kind): - # pylint: disable=broad-except try: doc = _utils.format_docstring(data.get_doc(), markup_kind=markup_kind) except Exception as e: @@ -30,8 +29,6 @@ def _resolve_completion(completion, data, markup_kind): @hookimpl def pylsp_completions(config, workspace, document, position): - # pylint: disable=too-many-locals - settings = config.plugin_settings("rope_completion", document_path=document.path) resolve_eagerly = settings.get("eager", False) @@ -63,7 +60,7 @@ def pylsp_completions(config, workspace, document, position): definitions = code_assist( rope_project, document.source, offset, document_rope, maxfixes=3 ) - except Exception as e: # pylint: disable=broad-except + except Exception as e: log.debug("Failed to run Rope code assist: %s", e) return [] diff --git a/pylsp/plugins/rope_rename.py b/pylsp/plugins/rope_rename.py index a4323a42..9e386944 100644 --- a/pylsp/plugins/rope_rename.py +++ b/pylsp/plugins/rope_rename.py @@ -6,7 +6,7 @@ from rope.base import libutils from rope.refactor.rename import Rename -from pylsp import hookimpl, uris, _utils +from pylsp import _utils, hookimpl, uris log = logging.getLogger(__name__) diff --git a/pylsp/plugins/signature.py b/pylsp/plugins/signature.py index 4fc93dfb..7ad5b208 100644 --- a/pylsp/plugins/signature.py +++ b/pylsp/plugins/signature.py @@ -3,7 +3,8 @@ import logging import re -from pylsp import hookimpl, _utils + +from pylsp import _utils, hookimpl log = logging.getLogger(__name__) diff --git a/pylsp/plugins/symbols.py b/pylsp/plugins/symbols.py index e3c961c7..4e1890c1 100644 --- a/pylsp/plugins/symbols.py +++ b/pylsp/plugins/symbols.py @@ -12,12 +12,6 @@ @hookimpl def pylsp_document_symbols(config, document): - # pylint: disable=broad-except - # pylint: disable=too-many-nested-blocks - # pylint: disable=too-many-locals - # pylint: disable=too-many-branches - # pylint: disable=too-many-statements - symbols_settings = config.plugin_settings("jedi_symbols") all_scopes = symbols_settings.get("all_scopes", True) add_import_symbols = symbols_settings.get("include_import_symbols", True) @@ -150,7 +144,7 @@ def _container(definition): # as children of the module. if parent.parent(): return parent.name - except: # pylint: disable=bare-except + except: return None return None diff --git a/pylsp/plugins/yapf_format.py b/pylsp/plugins/yapf_format.py index 4a8111be..72aa7404 100644 --- a/pylsp/plugins/yapf_format.py +++ b/pylsp/plugins/yapf_format.py @@ -4,11 +4,10 @@ import logging import os +import whatthepatch from yapf.yapflib import file_resources, style from yapf.yapflib.yapf_api import FormatCode -import whatthepatch - from pylsp import hookimpl from pylsp._utils import get_eol_chars @@ -23,7 +22,7 @@ def pylsp_format_document(workspace, document, options): @hookimpl -def pylsp_format_range(document, range, options): # pylint: disable=redefined-builtin +def pylsp_format_range(document, range, options): log.info("Formatting document %s in range %s with yapf", document, range) # First we 'round' the range up/down to full lines only range["start"]["character"] = 0 diff --git a/pylsp/python_lsp.py b/pylsp/python_lsp.py index a31e7612..a3f737ac 100644 --- a/pylsp/python_lsp.py +++ b/pylsp/python_lsp.py @@ -1,23 +1,23 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -from functools import partial import logging import os import socketserver import threading import uuid -from typing import List, Dict, Any -import ujson as json +from functools import partial +from typing import Any, Dict, List +import ujson as json from pylsp_jsonrpc.dispatchers import MethodDispatcher from pylsp_jsonrpc.endpoint import Endpoint from pylsp_jsonrpc.streams import JsonRpcStreamReader, JsonRpcStreamWriter -from . import lsp, _utils, uris -from .config import config -from .workspace import Workspace, Document, Notebook, Cell +from . import _utils, lsp, uris from ._version import __version__ +from .config import config +from .workspace import Cell, Document, Notebook, Workspace log = logging.getLogger(__name__) @@ -45,7 +45,6 @@ def handle(self): if os.name == "nt": # Catch and pass on ConnectionResetError when parent process # dies - # pylint: disable=no-member, undefined-variable if isinstance(e, WindowsError) and e.winerror == 10054: pass @@ -57,7 +56,6 @@ def start_tcp_lang_server(bind_addr, port, check_parent_process, handler_class): raise ValueError("Handler class must be an instance of PythonLSPServer") def shutdown_server(check_parent_process, *args): - # pylint: disable=unused-argument if check_parent_process: log.debug("Shutting down server") # Shutdown call must be done on a thread, to prevent deadlocks @@ -103,12 +101,11 @@ def start_ws_lang_server(port, check_parent_process, handler_class): if not issubclass(handler_class, PythonLSPServer): raise ValueError("Handler class must be an instance of PythonLSPServer") - # pylint: disable=import-outside-toplevel - # imports needed only for websockets based server try: import asyncio from concurrent.futures import ThreadPoolExecutor + import websockets except ImportError as e: raise ImportError( @@ -135,20 +132,18 @@ async def pylsp_ws(websocket): async for message in websocket: try: log.debug("consuming payload and feeding it to LSP handler") - # pylint: disable=c-extension-no-member request = json.loads(message) loop = asyncio.get_running_loop() await loop.run_in_executor(tpool, pylsp_handler.consume, request) - except Exception as e: # pylint: disable=broad-except + except Exception as e: log.exception("Failed to process request %s, %s", message, str(e)) def send_message(message, websocket): """Handler to send responses of processed requests to respective web socket clients""" try: - # pylint: disable=c-extension-no-member payload = json.dumps(message, ensure_ascii=False) asyncio.run(websocket.send(payload)) - except Exception as e: # pylint: disable=broad-except + except Exception as e: log.exception("Failed to write message %s, %s", message, str(e)) async def run_server(): @@ -164,8 +159,6 @@ class PythonLSPServer(MethodDispatcher): https://github.com/Microsoft/language-server-protocol/blob/master/versions/protocol-1-x.md """ - # pylint: disable=too-many-public-methods,redefined-builtin - def __init__( self, rx, tx, check_parent_process=False, consumer=None, *, endpoint_cls=None ): @@ -454,9 +447,7 @@ def _lint_text_document(self, doc_uri, workspace, is_saved): doc_uri, flatten(self._hook("pylsp_lint", doc_uri, is_saved=is_saved)) ) - def _lint_notebook_document( - self, notebook_document, workspace - ): # pylint: disable=too-many-locals + def _lint_notebook_document(self, notebook_document, workspace): """ Lint a notebook document. @@ -808,9 +799,7 @@ def m_workspace__did_change_configuration(self, settings=None): for doc_uri in workspace.documents: self.lint(doc_uri, is_saved=False) - def m_workspace__did_change_workspace_folders( - self, event=None, **_kwargs - ): # pylint: disable=too-many-locals + def m_workspace__did_change_workspace_folders(self, event=None, **_kwargs): if event is None: return added = event.get("added", []) diff --git a/pylsp/uris.py b/pylsp/uris.py index 7e5c4d05..45ad280b 100644 --- a/pylsp/uris.py +++ b/pylsp/uris.py @@ -7,6 +7,7 @@ """ import re from urllib import parse + from pylsp import IS_WIN RE_DRIVE_LETTER_PATH = re.compile(r"^\/[a-zA-Z]:") diff --git a/pylsp/workspace.py b/pylsp/workspace.py index 5e8e548f..c1b32f20 100644 --- a/pylsp/workspace.py +++ b/pylsp/workspace.py @@ -1,19 +1,19 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. +import functools import io import logging -from contextlib import contextmanager import os import re import uuid -import functools -from typing import Optional, Generator, Callable, List +from contextlib import contextmanager from threading import RLock +from typing import Callable, Generator, List, Optional import jedi -from . import lsp, uris, _utils +from . import _utils, lsp, uris log = logging.getLogger(__name__) @@ -36,8 +36,6 @@ def wrapper(self, *args, **kwargs): class Workspace: - # pylint: disable=too-many-public-methods - M_PUBLISH_DIAGNOSTICS = "textDocument/publishDiagnostics" M_PROGRESS = "$/progress" M_INITIALIZE_PROGRESS = "window/workDoneProgress/create" @@ -65,7 +63,6 @@ def _rope_autoimport( rope_config: Optional, memory: bool = False, ): - # pylint: disable=import-outside-toplevel from rope.contrib.autoimport.sqlite import AutoImport if self.__rope_autoimport is None: @@ -74,7 +71,6 @@ def _rope_autoimport( return self.__rope_autoimport def _rope_project_builder(self, rope_config): - # pylint: disable=import-outside-toplevel from rope.base.project import Project # TODO: we could keep track of dirty files and validate only those @@ -236,7 +232,6 @@ def progress_message( def dummy_progress_message( message: str, percentage: Optional[int] = None ) -> None: - # pylint: disable=unused-argument pass yield dummy_progress_message @@ -255,7 +250,7 @@ def _progress_begin( self._endpoint.request( self.M_INITIALIZE_PROGRESS, {"token": token} ).result(timeout=1.0) - except Exception: # pylint: disable=broad-exception-caught + except Exception: log.warning( "There was an error while trying to initialize progress reporting." "Likely progress reporting was used in a synchronous LSP handler, " @@ -412,7 +407,6 @@ def __str__(self): return str(self.uri) def _rope_resource(self, rope_config): - # pylint: disable=import-outside-toplevel from rope.base import libutils return libutils.path_to_resource( @@ -653,7 +647,7 @@ def jedi_names( names.update(cell_document.jedi_names(all_scopes, definitions, references)) if cell_uri == up_to_cell_uri: break - return set(name.name for name in names) + return {name.name for name in names} class Cell(Document): diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 00000000..2393ac6d --- /dev/null +++ b/ruff.toml @@ -0,0 +1,79 @@ +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] + +# Same as Black. +line-length = 88 +indent-width = 4 + +# Assume Python 3.8 +target-version = "py38" + +[lint] +# https://docs.astral.sh/ruff/rules/ +select = ["E", "F", "W", "C", "I"] +ignore = [ + "C901", # McCabe complexity warning + "E501", # Line too long + "E722", # Do not use bare `except` +] + +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[format] +# Like Black, use double quotes for strings. +quote-style = "double" + +# Like Black, indent with spaces, rather than tabs. +indent-style = "space" + +# Like Black, respect magic trailing commas. +skip-magic-trailing-comma = false + +# Like Black, automatically detect the appropriate line ending. +line-ending = "auto" + +# Enable auto-formatting of code examples in docstrings. Markdown, +# reStructuredText code/literal blocks and doctests are all supported. +# +# This is currently disabled by default, but it is planned for this +# to be opt-out in the future. +docstring-code-format = false + +# Set the line length limit used when formatting code snippets in +# docstrings. +# +# This only has an effect when the `docstring-code-format` setting is +# enabled. +docstring-code-line-length = "dynamic" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index b606d41a..00000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright 2017-2020 Palantir Technologies, Inc. -# Copyright 2021- Python Language Server Contributors. - -[pycodestyle] -ignore = E203, E226, E722, W503, W504 -max-line-length = 120 -exclude = test/plugins/.ropeproject,test/.ropeproject diff --git a/setup.py b/setup.py index b419c0f5..762deb8a 100755 --- a/setup.py +++ b/setup.py @@ -3,8 +3,7 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -from setuptools import setup, find_packages - +from setuptools import setup if __name__ == "__main__": setup( diff --git a/test/__init__.py b/test/__init__.py index bb216698..0936e783 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -2,8 +2,8 @@ # Copyright 2021- Python Language Server Contributors. import pytest -from pylsp import IS_WIN +from pylsp import IS_WIN unix_only = pytest.mark.skipif(IS_WIN, reason="Unix only") windows_only = pytest.mark.skipif(not IS_WIN, reason="Windows only") diff --git a/test/conftest.py b/test/conftest.py index 332866c5..5c4ab8f1 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -3,6 +3,7 @@ """ py.test configuration""" import logging + from pylsp.__main__ import LOG_FORMAT logging.basicConfig(level=logging.DEBUG, format=LOG_FORMAT) diff --git a/test/fixtures.py b/test/fixtures.py index 11c302b0..81a8b082 100644 --- a/test/fixtures.py +++ b/test/fixtures.py @@ -3,12 +3,10 @@ import os from io import StringIO +from test.test_utils import CALL_TIMEOUT_IN_SECONDS, ClientServerPair from unittest.mock import MagicMock -from test.test_utils import ClientServerPair, CALL_TIMEOUT_IN_SECONDS - import pytest - from pylsp_jsonrpc.dispatchers import MethodDispatcher from pylsp_jsonrpc.endpoint import Endpoint from pylsp_jsonrpc.exceptions import JsonRpcException @@ -16,8 +14,7 @@ from pylsp import uris from pylsp.config.config import Config from pylsp.python_lsp import PythonLSPServer -from pylsp.workspace import Workspace, Document - +from pylsp.workspace import Document, Workspace DOC_URI = uris.from_fs_path(__file__) DOC = """import sys @@ -107,7 +104,7 @@ def consumer(): @pytest.fixture() -def endpoint(consumer): # pylint: disable=redefined-outer-name +def endpoint(consumer): class Dispatcher(FakeEditorMethodsMixin, MethodDispatcher): pass @@ -115,7 +112,7 @@ class Dispatcher(FakeEditorMethodsMixin, MethodDispatcher): @pytest.fixture -def workspace(tmpdir, endpoint): # pylint: disable=redefined-outer-name +def workspace(tmpdir, endpoint): """Return a workspace.""" ws = Workspace(uris.from_fs_path(str(tmpdir)), endpoint) ws._config = Config(ws.root_uri, {}, 0, {}) @@ -124,7 +121,7 @@ def workspace(tmpdir, endpoint): # pylint: disable=redefined-outer-name @pytest.fixture -def workspace_other_root_path(tmpdir, endpoint): # pylint: disable=redefined-outer-name +def workspace_other_root_path(tmpdir, endpoint): """Return a workspace with a root_path other than tmpdir.""" ws_path = str(tmpdir.mkdir("test123").mkdir("test456")) ws = Workspace(uris.from_fs_path(ws_path), endpoint) @@ -133,7 +130,7 @@ def workspace_other_root_path(tmpdir, endpoint): # pylint: disable=redefined-ou @pytest.fixture -def config(workspace): # pylint: disable=redefined-outer-name +def config(workspace): """Return a config object.""" cfg = Config(workspace.root_uri, {}, 0, {}) cfg._plugin_settings = { @@ -143,12 +140,12 @@ def config(workspace): # pylint: disable=redefined-outer-name @pytest.fixture -def doc(workspace): # pylint: disable=redefined-outer-name +def doc(workspace): return Document(DOC_URI, workspace, DOC) @pytest.fixture -def temp_workspace_factory(workspace): # pylint: disable=redefined-outer-name +def temp_workspace_factory(workspace): """ Returns a function that creates a temporary workspace from the files dict. The dict is in the format {"file_name": "file_contents"} diff --git a/test/plugins/test_autoimport.py b/test/plugins/test_autoimport.py index 6d3eeb50..0d1e2d73 100644 --- a/test/plugins/test_autoimport.py +++ b/test/plugins/test_autoimport.py @@ -1,10 +1,9 @@ # Copyright 2022- Python Language Server Contributors. -from typing import Any, Dict, List -from unittest.mock import Mock, patch - from test.test_notebook_document import wait_for_condition from test.test_utils import send_initialize_request, send_notebook_did_open +from typing import Any, Dict, List +from unittest.mock import Mock, patch import jedi import parso @@ -24,7 +23,6 @@ ) from pylsp.workspace import Workspace - DOC_URI = uris.from_fs_path(__file__) @@ -62,7 +60,6 @@ def autoimport_workspace(tmp_path_factory) -> Workspace: workspace.close() -# pylint: disable=redefined-outer-name @pytest.fixture def completions(config: Config, autoimport_workspace: Workspace, request): document, position = request.param @@ -232,7 +229,7 @@ class sfa: sfiosifo """ results = get_names(jedi.Script(code=source)) - assert results == set(["blah", "bleh", "e", "hello", "someone", "sfa", "a", "b"]) + assert results == {"blah", "bleh", "e", "hello", "someone", "sfa", "a", "b"} # Tests ruff, flake8 and pyflakes messages diff --git a/test/plugins/test_completion.py b/test/plugins/test_completion.py index f64e81ed..4b598be8 100644 --- a/test/plugins/test_completion.py +++ b/test/plugins/test_completion.py @@ -4,21 +4,19 @@ import math import os import sys - from pathlib import Path -from typing import NamedTuple, Dict +from typing import Dict, NamedTuple import pytest -from pylsp import uris, lsp -from pylsp.workspace import Document -from pylsp.plugins.jedi_completion import pylsp_completions as pylsp_jedi_completions +from pylsp import lsp, uris +from pylsp._utils import JEDI_VERSION from pylsp.plugins.jedi_completion import ( pylsp_completion_item_resolve as pylsp_jedi_completion_item_resolve, ) +from pylsp.plugins.jedi_completion import pylsp_completions as pylsp_jedi_completions from pylsp.plugins.rope_completion import pylsp_completions as pylsp_rope_completions -from pylsp._utils import JEDI_VERSION - +from pylsp.workspace import Document PY2 = sys.version[0] == "2" LINUX = sys.platform.startswith("linux") diff --git a/test/plugins/test_definitions.py b/test/plugins/test_definitions.py index c366e8ca..5da04ff3 100644 --- a/test/plugins/test_definitions.py +++ b/test/plugins/test_definitions.py @@ -7,7 +7,6 @@ from pylsp.plugins.definition import pylsp_definitions from pylsp.workspace import Document - DOC_URI = uris.from_fs_path(__file__) DOC = """def a(): pass @@ -21,8 +20,8 @@ def __init__(self): def add_member(self, id, name): self.members[id] = name - - + + subscripted_before_reference = {} subscripted_before_reference[0] = 0 subscripted_before_reference diff --git a/test/plugins/test_flake8_lint.py b/test/plugins/test_flake8_lint.py index c2d711e7..bdc180fd 100644 --- a/test/plugins/test_flake8_lint.py +++ b/test/plugins/test_flake8_lint.py @@ -1,15 +1,15 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -import tempfile import os +import tempfile from textwrap import dedent from unittest.mock import patch + from pylsp import lsp, uris from pylsp.plugins import flake8_lint from pylsp.workspace import Document - DOC_URI = uris.from_fs_path(__file__) DOC = """import pylsp diff --git a/test/plugins/test_highlight.py b/test/plugins/test_highlight.py index e7bd5075..fcc9809c 100644 --- a/test/plugins/test_highlight.py +++ b/test/plugins/test_highlight.py @@ -2,9 +2,8 @@ # Copyright 2021- Python Language Server Contributors. from pylsp import lsp, uris -from pylsp.workspace import Document from pylsp.plugins.highlight import pylsp_document_highlight - +from pylsp.workspace import Document DOC_URI = uris.from_fs_path(__file__) DOC = """a = "hello" diff --git a/test/plugins/test_hover.py b/test/plugins/test_hover.py index 7049becc..a65f92dc 100644 --- a/test/plugins/test_hover.py +++ b/test/plugins/test_hover.py @@ -59,7 +59,6 @@ def test_numpy_hover(workspace): ) # https://github.com/davidhalter/jedi/issues/1746 - # pylint: disable=import-outside-toplevel import numpy as np if np.lib.NumpyVersion(np.__version__) < "1.20.0": diff --git a/test/plugins/test_jedi_rename.py b/test/plugins/test_jedi_rename.py index d88a9297..753303d4 100644 --- a/test/plugins/test_jedi_rename.py +++ b/test/plugins/test_jedi_rename.py @@ -4,11 +4,11 @@ import os import pytest + from pylsp import uris from pylsp.plugins.jedi_rename import pylsp_rename from pylsp.workspace import Document - DOC_NAME = "test1.py" DOC = """class Test1(): pass @@ -33,7 +33,7 @@ def tmp_workspace(temp_workspace_factory): ) -def test_jedi_rename(tmp_workspace, config): # pylint: disable=redefined-outer-name +def test_jedi_rename(tmp_workspace, config): # rename the `Test1` class position = {"line": 0, "character": 6} DOC_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC_NAME)) diff --git a/test/plugins/test_mccabe_lint.py b/test/plugins/test_mccabe_lint.py index 009d8cfc..6c420b12 100644 --- a/test/plugins/test_mccabe_lint.py +++ b/test/plugins/test_mccabe_lint.py @@ -2,8 +2,8 @@ # Copyright 2021- Python Language Server Contributors. from pylsp import lsp, uris -from pylsp.workspace import Document from pylsp.plugins import mccabe_lint +from pylsp.workspace import Document DOC_URI = uris.from_fs_path(__file__) DOC = """def hello(): diff --git a/test/plugins/test_pycodestyle_lint.py b/test/plugins/test_pycodestyle_lint.py index dd24daac..5d83648f 100644 --- a/test/plugins/test_pycodestyle_lint.py +++ b/test/plugins/test_pycodestyle_lint.py @@ -6,8 +6,8 @@ import pytest from pylsp import lsp, uris -from pylsp.workspace import Document from pylsp.plugins import pycodestyle_lint +from pylsp.workspace import Document DOC_URI = uris.from_fs_path(__file__) DOC = """import sys diff --git a/test/plugins/test_pydocstyle_lint.py b/test/plugins/test_pydocstyle_lint.py index df352da8..22f10d02 100644 --- a/test/plugins/test_pydocstyle_lint.py +++ b/test/plugins/test_pydocstyle_lint.py @@ -2,9 +2,10 @@ # Copyright 2021- Python Language Server Contributors. import os + from pylsp import lsp, uris -from pylsp.workspace import Document from pylsp.plugins import pydocstyle_lint +from pylsp.workspace import Document DOC_URI = uris.from_fs_path(os.path.join(os.path.dirname(__file__), "pydocstyle.py")) TEST_DOC_URI = uris.from_fs_path(__file__) diff --git a/test/plugins/test_pyflakes_lint.py b/test/plugins/test_pyflakes_lint.py index e33457f2..6ad774c1 100644 --- a/test/plugins/test_pyflakes_lint.py +++ b/test/plugins/test_pyflakes_lint.py @@ -4,8 +4,8 @@ import sys from pylsp import lsp, uris -from pylsp.workspace import Document from pylsp.plugins import pyflakes_lint +from pylsp.workspace import Document DOC_URI = uris.from_fs_path(__file__) DOC = """import sys diff --git a/test/plugins/test_pylint_lint.py b/test/plugins/test_pylint_lint.py index 210e1cff..8ce10eb9 100644 --- a/test/plugins/test_pylint_lint.py +++ b/test/plugins/test_pylint_lint.py @@ -3,13 +3,13 @@ # Copyright 2021- Python Language Server Contributors. import contextlib -from pathlib import Path import os import tempfile +from pathlib import Path from pylsp import lsp, uris -from pylsp.workspace import Document, Workspace from pylsp.plugins import pylint_lint +from pylsp.workspace import Document, Workspace DOC_URI = uris.from_fs_path(__file__) DOC = """import sys diff --git a/test/plugins/test_references.py b/test/plugins/test_references.py index e8030a42..6990317e 100644 --- a/test/plugins/test_references.py +++ b/test/plugins/test_references.py @@ -6,9 +6,8 @@ import pytest from pylsp import uris -from pylsp.workspace import Document from pylsp.plugins.references import pylsp_references - +from pylsp.workspace import Document DOC1_NAME = "test1.py" DOC2_NAME = "test2.py" @@ -36,7 +35,7 @@ def tmp_workspace(temp_workspace_factory): ) -def test_references(tmp_workspace): # pylint: disable=redefined-outer-name +def test_references(tmp_workspace): # Over 'Test1' in class Test1(): position = {"line": 0, "character": 8} DOC1_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC1_NAME)) @@ -66,7 +65,7 @@ def test_references(tmp_workspace): # pylint: disable=redefined-outer-name assert doc2_usage_ref["range"]["end"] == {"line": 3, "character": 9} -def test_references_builtin(tmp_workspace): # pylint: disable=redefined-outer-name +def test_references_builtin(tmp_workspace): # Over 'UnicodeError': position = {"line": 4, "character": 7} doc2_uri = uris.from_fs_path(os.path.join(str(tmp_workspace.root_path), DOC2_NAME)) diff --git a/test/plugins/test_rope_rename.py b/test/plugins/test_rope_rename.py index 9b9039ba..c55ead0a 100644 --- a/test/plugins/test_rope_rename.py +++ b/test/plugins/test_rope_rename.py @@ -4,11 +4,11 @@ import os import pytest + from pylsp import uris from pylsp.plugins.rope_rename import pylsp_rename from pylsp.workspace import Document - DOC_NAME = "test1.py" DOC = """class Test1(): pass @@ -26,7 +26,7 @@ def tmp_workspace(temp_workspace_factory): return temp_workspace_factory({DOC_NAME: DOC, DOC_NAME_SIMPLE: DOC_SIMPLE}) -def test_rope_rename(tmp_workspace, config): # pylint: disable=redefined-outer-name +def test_rope_rename(tmp_workspace, config): position = {"line": 0, "character": 6} DOC_URI = uris.from_fs_path(os.path.join(tmp_workspace.root_path, DOC_NAME)) doc = Document(DOC_URI, tmp_workspace) diff --git a/test/plugins/test_signature.py b/test/plugins/test_signature.py index 0ba28ac5..7c285721 100644 --- a/test/plugins/test_signature.py +++ b/test/plugins/test_signature.py @@ -2,6 +2,7 @@ # Copyright 2021- Python Language Server Contributors. import pytest + from pylsp import uris from pylsp.plugins import signature from pylsp.workspace import Document diff --git a/test/plugins/test_symbols.py b/test/plugins/test_symbols.py index 0f54e9db..4dc74bc6 100644 --- a/test/plugins/test_symbols.py +++ b/test/plugins/test_symbols.py @@ -7,11 +7,10 @@ import pytest from pylsp import uris -from pylsp.plugins.symbols import pylsp_document_symbols from pylsp.lsp import SymbolKind +from pylsp.plugins.symbols import pylsp_document_symbols from pylsp.workspace import Document - PY2 = sys.version[0] == "2" LINUX = sys.platform.startswith("linux") CI = os.environ.get("CI") diff --git a/test/plugins/test_yapf_format.py b/test/plugins/test_yapf_format.py index d89eb37d..fddd68b4 100644 --- a/test/plugins/test_yapf_format.py +++ b/test/plugins/test_yapf_format.py @@ -5,8 +5,8 @@ from pylsp import uris from pylsp.plugins.yapf_format import pylsp_format_document, pylsp_format_range -from pylsp.workspace import Document from pylsp.text_edit import apply_text_edits +from pylsp.workspace import Document DOC_URI = uris.from_fs_path(__file__) DOC = """A = [ diff --git a/test/test_configuration.py b/test/test_configuration.py index 91da4212..ddc6315d 100644 --- a/test/test_configuration.py +++ b/test/test_configuration.py @@ -1,15 +1,13 @@ # Copyright 2021- Python Language Server Contributors. -from unittest.mock import patch - -from test.test_utils import send_initialize_request from test.test_notebook_document import wait_for_condition +from test.test_utils import send_initialize_request +from unittest.mock import patch import pytest from pylsp import IS_WIN - INITIALIZATION_OPTIONS = { "pylsp": { "plugins": { diff --git a/test/test_document.py b/test/test_document.py index 1acb1611..7caa0abb 100644 --- a/test/test_document.py +++ b/test/test_document.py @@ -1,7 +1,8 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -from test.fixtures import DOC_URI, DOC +from test.fixtures import DOC, DOC_URI + from pylsp.workspace import Document diff --git a/test/test_language_server.py b/test/test_language_server.py index 401b1ceb..6a48638f 100644 --- a/test/test_language_server.py +++ b/test/test_language_server.py @@ -2,15 +2,13 @@ # Copyright 2021- Python Language Server Contributors. import os -import time import sys - +import time from test.test_utils import ClientServerPair, send_initialize_request +import pytest from flaky import flaky from pylsp_jsonrpc.exceptions import JsonRpcMethodNotFound -import pytest - RUNNING_IN_CI = bool(os.environ.get("CI")) @@ -46,7 +44,7 @@ def test_initialize(client_server_pair): ) def test_exit_with_parent_process_died( client_exited_server, -): # pylint: disable=redefined-outer-name +): # language server should have already exited before responding lsp_server, mock_process = ( client_exited_server.client, diff --git a/test/test_notebook_document.py b/test/test_notebook_document.py index f97088b3..c1ac1986 100644 --- a/test/test_notebook_document.py +++ b/test/test_notebook_document.py @@ -1,19 +1,18 @@ # Copyright 2021- Python Language Server Contributors. import time -from unittest.mock import patch, call - from test.test_utils import ( CALL_TIMEOUT_IN_SECONDS, send_initialize_request, send_notebook_did_open, ) +from unittest.mock import call, patch import pytest -from pylsp.workspace import Notebook from pylsp import IS_WIN from pylsp.lsp import NotebookCellKind +from pylsp.workspace import Notebook def wait_for_condition(condition, timeout=CALL_TIMEOUT_IN_SECONDS): diff --git a/test/test_text_edit.py b/test/test_text_edit.py index 63d0c904..2b49d242 100644 --- a/test/test_text_edit.py +++ b/test/test_text_edit.py @@ -1,8 +1,8 @@ # Copyright 2017-2020 Palantir Technologies, Inc. # Copyright 2021- Python Language Server Contributors. -from pylsp.text_edit import OverLappingTextEditException, apply_text_edits from pylsp import uris +from pylsp.text_edit import OverLappingTextEditException, apply_text_edits DOC_URI = uris.from_fs_path(__file__) diff --git a/test/test_uris.py b/test/test_uris.py index 59fb2094..f00973a4 100644 --- a/test/test_uris.py +++ b/test/test_uris.py @@ -2,7 +2,9 @@ # Copyright 2021- Python Language Server Contributors. from test import unix_only, windows_only + import pytest + from pylsp import uris diff --git a/test/test_utils.py b/test/test_utils.py index 8b518d72..6435efb7 100644 --- a/test/test_utils.py +++ b/test/test_utils.py @@ -4,19 +4,18 @@ import multiprocessing import os import sys -from threading import Thread import time +from threading import Thread from typing import Any, Dict, List from unittest import mock -from flaky import flaky from docstring_to_markdown import UnknownFormatError +from flaky import flaky from pylsp import _utils from pylsp.lsp import NotebookCellKind from pylsp.python_lsp import PythonLSPServer, start_io_lang_server - CALL_TIMEOUT_IN_SECONDS = 30 diff --git a/test/test_workspace.py b/test/test_workspace.py index 02ef1d22..c810bc5b 100644 --- a/test/test_workspace.py +++ b/test/test_workspace.py @@ -3,8 +3,8 @@ import pathlib import pytest -from pylsp import uris +from pylsp import uris DOC_URI = uris.from_fs_path(__file__) NOTEBOOK_URI = uris.from_fs_path("notebook_uri") @@ -238,7 +238,6 @@ def test_workspace_loads_pycodestyle_config(pylsp, tmpdir): # Test that project settings are loaded workspace2_dir = tmpdir.mkdir("NewTest456") cfg = workspace2_dir.join("pycodestyle.cfg") - # pylint: disable=implicit-str-concat cfg.write("[pycodestyle]\n" "max-line-length = 1000") workspace1 = {"uri": str(workspace1_dir)} @@ -258,7 +257,6 @@ def test_workspace_loads_pycodestyle_config(pylsp, tmpdir): # Test switching to another workspace with different settings workspace3_dir = tmpdir.mkdir("NewTest789") cfg1 = workspace3_dir.join("pycodestyle.cfg") - # pylint: disable=implicit-str-concat cfg1.write("[pycodestyle]\n" "max-line-length = 20") workspace3 = {"uri": str(workspace3_dir)}