From 1c016248ebd5221ac9dd0b2358c585245784a597 Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Thu, 5 Jun 2025 16:36:48 +0200 Subject: [PATCH] Multilspy: slightly more logging and better typing --- src/multilspy/language_server.py | 14 ++++++-------- src/multilspy/lsp_protocol_handler/server.py | 16 +++++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/multilspy/language_server.py b/src/multilspy/language_server.py index 4e2e624a..dcf36ef2 100644 --- a/src/multilspy/language_server.py +++ b/src/multilspy/language_server.py @@ -19,7 +19,7 @@ from collections import defaultdict from contextlib import asynccontextmanager, contextmanager from copy import copy from pathlib import Path, PurePath -from typing import AsyncIterator, Dict, Iterator, List, Optional, Tuple, Union, cast +from typing import AsyncIterator, Callable, Dict, Iterator, List, Optional, Tuple, Union, cast import pathspec @@ -31,6 +31,7 @@ from .lsp_protocol_handler.server import ( Error, LanguageServerHandler, ProcessLaunchInfo, + StringDict, ) from .multilspy_config import Language, MultilspyConfig from .multilspy_exceptions import MultilspyException @@ -232,18 +233,15 @@ class LanguageServer: self.completions_available = asyncio.Event() if config.trace_lsp_communication: - - def logging_fn(source, target, msg): + def logging_fn(source: str, target: str, msg: StringDict | str): self.logger.log(f"LSP: {source} -> {target}: {str(msg)}", logging.DEBUG) - else: - - def logging_fn(source, target, msg): - pass + logging_fn = None + # cmd is obtained from the child classes, which provide the language specific command to start the language server # LanguageServerHandler provides the functionality to start the language server and communicate with it - self.server: LanguageServerHandler = LanguageServerHandler( + self.server = LanguageServerHandler( process_launch_info, logger=logging_fn, start_independent_lsp_process=config.start_independent_lsp_process, diff --git a/src/multilspy/lsp_protocol_handler/server.py b/src/multilspy/lsp_protocol_handler/server.py index 81a9dc4a..85e8ac5c 100644 --- a/src/multilspy/lsp_protocol_handler/server.py +++ b/src/multilspy/lsp_protocol_handler/server.py @@ -34,7 +34,7 @@ import json import logging import os import psutil -from typing import Any, Dict, List, Optional, Union +from typing import Any, Callable, Dict, List, Optional, Union from .lsp_requests import LspNotification, LspRequest from .lsp_types import ErrorCodes @@ -184,7 +184,7 @@ class LanguageServerHandler: def __init__( self, process_launch_info: ProcessLaunchInfo, - logger=None, + logger: Optional[Callable[[str, str, StringDict | str], None]] = None, start_independent_lsp_process=True, ) -> None: """ @@ -366,11 +366,11 @@ class LanguageServerHandler: # in the run_forever and run_forever_stderr methods await asyncio.sleep(0) - def _log(self, message: str) -> None: + def _log(self, message: str | StringDict) -> None: """ Create a log message """ - if self.logger: + if self.logger is not None: self.logger("client", "logger", message) async def run_forever(self) -> bool: @@ -470,7 +470,7 @@ class LanguageServerHandler: ) self.task_counter += 1 - async def send_request(self, method: str, params: Optional[dict] = None) -> None: + async def send_request(self, method: str, params: Optional[dict] = None) -> PayloadLike: """ Send request to the server, register the request id, and wait for the response """ @@ -480,9 +480,12 @@ class LanguageServerHandler: self._response_handlers[request_id] = request async with request.cv: await self._send_payload(make_request(method, request_id, params)) + self._log(f"Waiting for asyncio condition for request {method} with params:\n{params}") await request.cv.wait() + self._log(f"Finished waiting, processing result") if isinstance(request.error, Error): raise MultilspyException(f"Could not process request {method} with params:\n{params}.\n Language server error: {request.error}") from request.error + self._log(f"Returning non-error result, which is:\n{request.result}") return request.result def _send_payload_sync(self, payload: StringDict) -> None: @@ -502,9 +505,8 @@ class LanguageServerHandler: """ if not self.process or not self.process.stdin: return + self._log(payload) msg = create_message(payload) - if self.logger: - self.logger("client", "server", payload) self.process.stdin.writelines(msg) await self.process.stdin.drain()