From 16e57bde2a78b575d2e7a4917c3e6e810d254f4b Mon Sep 17 00:00:00 2001 From: Shrey Pandey Date: Fri, 11 Oct 2024 15:45:28 +0530 Subject: [PATCH 1/4] Removed deprecated method call in lsp client --- pylspclient/lsp_client.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pylspclient/lsp_client.py b/pylspclient/lsp_client.py index 863cca3..69afb78 100644 --- a/pylspclient/lsp_client.py +++ b/pylspclient/lsp_client.py @@ -124,9 +124,9 @@ def documentSymbol(self, textDocument: TextDocumentIdentifier) -> list[DocumentS """ result_dict = self.lsp_endpoint.call_method("textDocument/documentSymbol", textDocument=textDocument.dict()) try: - return [DocumentSymbol.parse_obj(sym) for sym in result_dict] + return [DocumentSymbol.model_validate(sym) for sym in result_dict] except ValidationError: - return [SymbolInformation.parse_obj(sym) for sym in result_dict] + return [SymbolInformation.model_validate(sym) for sym in result_dict] def typeDefinition( @@ -141,7 +141,7 @@ def typeDefinition( :param Position position: The position inside the text document. """ result_dict = self.lsp_endpoint.call_method("textDocument/typeDefinition", textDocument=textDocument, position=position) - return [Location.parse_obj(result) for result in result_dict] + return [Location.model_validate(result) for result in result_dict] def signatureHelp( @@ -158,7 +158,7 @@ def signatureHelp( :param Position position: The position inside the text document. """ result_dict = self.lsp_endpoint.call_method("textDocument/signatureHelp", textDocument=textDocument, position=position) - return SignatureHelp.parse_obj(result_dict) + return SignatureHelp.model_validate(result_dict) def completion( @@ -177,9 +177,9 @@ def completion( """ result_dict = self.lsp_endpoint.call_method("textDocument/completion", textDocument=textDocument, position=position, context=context) if "isIncomplete" in result_dict: - return CompletionList.parse_obj(result_dict) + return CompletionList.model_validate(result_dict) - return [CompletionItem.parse_obj(result) for result in result_dict] + return [CompletionItem.model_validate(result) for result in result_dict] def declaration( @@ -199,12 +199,12 @@ def declaration( """ result_dict = self.lsp_endpoint.call_method("textDocument/declaration", textDocument=textDocument, position=position) if "uri" in result_dict: - return Location.parse_obj(result_dict) + return Location.model_validate(result_dict) try: - return [Location.parse_obj(result) for result in result_dict] + return [Location.model_validate(result) for result in result_dict] except ValidationError: - return [LocationLink.parse_obj(result) for result in result_dict] + return [LocationLink.model_validate(result) for result in result_dict] @@ -227,9 +227,9 @@ def definition( """ result_dict = self.lsp_endpoint.call_method("textDocument/definition", textDocument=textDocument, position=position) if "uri" in result_dict: - return Location.parse_obj(result_dict) + return Location.model_validate(result_dict) try: - return [Location.parse_obj(result) for result in result_dict] + return [Location.model_validate(result) for result in result_dict] except ValidationError: - return [LocationLink.parse_obj(result) for result in result_dict] + return [LocationLink.model_validate(result) for result in result_dict] From 1d353196b207d4bc0ca68e12e4447efc8bbf30ba Mon Sep 17 00:00:00 2001 From: Shrey Pandey Date: Fri, 11 Oct 2024 16:22:44 +0530 Subject: [PATCH 2/4] Added precommit config --- .pre-commit-config.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..07d17f3 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,17 @@ +repos: +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.9 + hooks: + - id: ruff +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.11.2 + hooks: + - id: mypy + args: ["--config-file=pyproject.toml", "pylspclient"] +- repo: local + hooks: + - id: poetry-pytest + name: Run Tests with Poetry and Pytest + entry: bash -c "poetry install --no-interaction --no-root --with tests && poetry run pytest $(PYTEST_FLAGS)" + language: system + types: [python] \ No newline at end of file From 2ef00b6c6c3b4822c144bb9528f15515e998625c Mon Sep 17 00:00:00 2001 From: Shrey Pandey Date: Fri, 11 Oct 2024 19:20:34 +0530 Subject: [PATCH 3/4] Working precommit hook --- .pre-commit-config.yaml | 17 +- pylspclient/__init__.py | 7 +- pylspclient/json_rpc_endpoint.py | 58 +++-- pylspclient/lsp_client.py | 233 ++++++++++-------- pylspclient/lsp_endpoint.py | 4 +- tests/test-workspace/__init__.py | 8 - tests/test_pylsp_integration.py | 2 +- tests/test_workspace/__init__.py | 7 + .../json_rpc_endpoint.py | 2 +- .../lsp_client.py | 2 +- .../lsp_endpoint.py | 3 +- .../lsp_structs.py | 2 +- 12 files changed, 190 insertions(+), 155 deletions(-) delete mode 100644 tests/test-workspace/__init__.py create mode 100644 tests/test_workspace/__init__.py rename tests/{test-workspace => test_workspace}/json_rpc_endpoint.py (98%) rename tests/{test-workspace => test_workspace}/lsp_client.py (99%) rename tests/{test-workspace => test_workspace}/lsp_endpoint.py (99%) rename tests/{test-workspace => test_workspace}/lsp_structs.py (99%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 07d17f3..b04ad97 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,15 +3,16 @@ repos: rev: v0.6.9 hooks: - id: ruff -- repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.2 +- repo: local hooks: - id: mypy - args: ["--config-file=pyproject.toml", "pylspclient"] + name: Install Poetry Dependencies and Run mypy + entry: bash -c "poetry install --no-interaction --no-root --with tests && poetry run mypy pylspclient" + language: system - repo: local hooks: - - id: poetry-pytest - name: Run Tests with Poetry and Pytest - entry: bash -c "poetry install --no-interaction --no-root --with tests && poetry run pytest $(PYTEST_FLAGS)" - language: system - types: [python] \ No newline at end of file + - id: poetry-pytest + name: Run Tests with Poetry and Pytest + entry: bash -c "poetry install --no-interaction --no-root --with tests && poetry run pytest" + language: system + types: [python] \ No newline at end of file diff --git a/pylspclient/__init__.py b/pylspclient/__init__.py index a1df7c9..5392b76 100644 --- a/pylspclient/__init__.py +++ b/pylspclient/__init__.py @@ -1,7 +1,6 @@ from typing import Any __all__: list[Any] = [] -from pylspclient.json_rpc_endpoint import JsonRpcEndpoint -from pylspclient.lsp_client import LspClient -from pylspclient.lsp_endpoint import LspEndpoint -from pylspclient import lsp_errors +from .json_rpc_endpoint import JsonRpcEndpoint +from .lsp_client import LspClient +from .lsp_endpoint import LspEndpoint diff --git a/pylspclient/json_rpc_endpoint.py b/pylspclient/json_rpc_endpoint.py index ccc234e..35c61be 100644 --- a/pylspclient/json_rpc_endpoint.py +++ b/pylspclient/json_rpc_endpoint.py @@ -1,8 +1,8 @@ from __future__ import print_function import json -from pylspclient.lsp_errors import ErrorCodes, ResponseError import threading from typing import Any, IO +from .lsp_errors import ErrorCodes, ResponseError JSON_RPC_REQ_FORMAT = "Content-Length: {json_string_len}\r\n\r\n{json_string}" LEN_HEADER = "Content-Length: " @@ -12,81 +12,89 @@ # TODO: add content-type -class MyEncoder(json.JSONEncoder): +class MyEncoder(json.JSONEncoder): """ Encodes an object in JSON """ - def default(self, o: Any): # pylint: disable=E0202 - return o.__dict__ + + def default(self, o: Any): # pylint: disable=E0202 + return o.__dict__ class JsonRpcEndpoint(object): - ''' + """ Thread safe JSON RPC endpoint implementation. Responsible to recieve and send JSON RPC messages, as described in the protocol. More information can be found: https://www.jsonrpc.org/ - ''' + """ + def __init__(self, stdin: IO, stdout: IO): self.stdin = stdin self.stdout = stdout - self.read_lock = threading.Lock() - self.write_lock = threading.Lock() + self.read_lock = threading.Lock() + self.write_lock = threading.Lock() @staticmethod def __add_header(json_string: str) -> str: - ''' + """ Adds a header for the given json string - + :param str json_string: The string :return: the string with the header - ''' - return JSON_RPC_REQ_FORMAT.format(json_string_len=len(json_string), json_string=json_string) - + """ + return JSON_RPC_REQ_FORMAT.format( + json_string_len=len(json_string), json_string=json_string + ) def send_request(self, message: Any) -> None: - ''' + """ Sends the given message. - :param dict message: The message to send. - ''' + :param dict message: The message to send. + """ json_string = json.dumps(message, cls=MyEncoder) jsonrpc_req = self.__add_header(json_string) with self.write_lock: self.stdin.write(jsonrpc_req.encode()) self.stdin.flush() - def recv_response(self) -> Any: - ''' + """ Recives a message. :return: a message - ''' + """ with self.read_lock: message_size = None while True: - #read header + # read header line = self.stdout.readline() if not line: # server quit return None line = line.decode("utf-8") if not line.endswith("\r\n"): - raise ResponseError(ErrorCodes.ParseError, "Bad header: missing newline") - #remove the "\r\n" + raise ResponseError( + ErrorCodes.ParseError, "Bad header: missing newline" + ) + # remove the "\r\n" line = line[:-2] if line == "": # done with the headers break elif line.startswith(LEN_HEADER): - line = line[len(LEN_HEADER):] + line = line[len(LEN_HEADER) :] if not line.isdigit(): - raise ResponseError(ErrorCodes.ParseError, "Bad header: size is not int") + raise ResponseError( + ErrorCodes.ParseError, "Bad header: size is not int" + ) message_size = int(line) elif line.startswith(TYPE_HEADER): # nothing todo with type for now. pass else: - raise ResponseError(ErrorCodes.ParseError, "Bad header: unkown header") + raise ResponseError( + ErrorCodes.ParseError, "Bad header: unkown header" + ) if not message_size: raise ResponseError(ErrorCodes.ParseError, "Bad header: missing size") diff --git a/pylspclient/lsp_client.py b/pylspclient/lsp_client.py index 69afb78..8340a1e 100644 --- a/pylspclient/lsp_client.py +++ b/pylspclient/lsp_client.py @@ -1,9 +1,23 @@ from typing import Any, Optional from pydantic import ValidationError -from pylspclient.lsp_endpoint import LspEndpoint -from pylspclient.lsp_pydantic_strcuts import TextDocumentItem, TextDocumentIdentifier, DocumentSymbol, SymbolInformation, LocationLink, Location -from pylspclient.lsp_pydantic_strcuts import Position, SignatureHelp, CompletionContext, CompletionItem, CompletionList +from .lsp_endpoint import LspEndpoint +from .lsp_pydantic_strcuts import ( + TextDocumentItem, + TextDocumentIdentifier, + DocumentSymbol, + SymbolInformation, + LocationLink, + Location, +) +from .lsp_pydantic_strcuts import ( + Position, + SignatureHelp, + CompletionContext, + CompletionItem, + CompletionList, +) + class LspClient(object): def __init__(self, lsp_endpoint: LspEndpoint): @@ -14,7 +28,6 @@ def __init__(self, lsp_endpoint: LspEndpoint): """ self.lsp_endpoint = lsp_endpoint - def initialize( self, processId: Optional[int] = None, @@ -26,15 +39,15 @@ def initialize( workspaceFolders: Optional[list] = None, ): """ - The initialize request is sent as the first request from the client to the server. If the server receives a request or notification + The initialize request is sent as the first request from the client to the server. If the server receives a request or notification before the initialize request it should act as follows: 1. For a request the response should be an error with code: -32002. The message can be picked by the server. 2. Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request. - - Until the server has responded to the initialize request with an InitializeResult, the client must not send any additional requests or - notifications to the server. In addition the server is not allowed to send any requests or notifications to the client until it has responded - with an InitializeResult, with the exception that during the initialize request the server is allowed to send the notifications window/showMessage, + + Until the server has responded to the initialize request with an InitializeResult, the client must not send any additional requests or + notifications to the server. In addition the server is not allowed to send any requests or notifications to the client until it has responded + with an InitializeResult, with the exception that during the initialize request the server is allowed to send the notifications window/showMessage, window/logMessage and telemetry/event as well as the window/showMessageRequest request to the client. The initialize request may only be sent once. @@ -51,10 +64,18 @@ def initialize( It can be `null` if the client supports workspace folders but none are configured. """ if capabilities is None: - raise ValueError("capabilities is required") + raise ValueError("capabilities is required") self.lsp_endpoint.start() - return self.lsp_endpoint.call_method("initialize", processId=processId, rootPath=rootPath, rootUri=rootUri, initializationOptions=initializationOptions, capabilities=capabilities, trace=trace, workspaceFolders=workspaceFolders) - + return self.lsp_endpoint.call_method( + "initialize", + processId=processId, + rootPath=rootPath, + rootUri=rootUri, + initializationOptions=initializationOptions, + capabilities=capabilities, + trace=trace, + workspaceFolders=workspaceFolders, + ) def initialized(self): """ @@ -64,7 +85,6 @@ def initialized(self): """ self.lsp_endpoint.send_notification("initialized") - def shutdown(self): """ The initialized notification is sent from the client to the server after the client received the result of the initialize request @@ -73,8 +93,7 @@ def shutdown(self): """ self.lsp_endpoint.stop() return self.lsp_endpoint.call_method("shutdown") - - + def exit(self): """ The initialized notification is sent from the client to the server after the client received the result of the initialize request @@ -83,56 +102,60 @@ def exit(self): """ self.lsp_endpoint.send_notification("exit") - def didOpen(self, textDocument: TextDocumentItem): """ The document open notification is sent from the client to the server to signal newly opened text documents. The document's truth is - now managed by the client and the server must not try to read the document's truth using the document's uri. Open in this sense + now managed by the client and the server must not try to read the document's truth using the document's uri. Open in this sense means it is managed by the client. It doesn't necessarily mean that its content is presented in an editor. An open notification must - not be sent more than once without a corresponding close notification send before. This means open and close notification must be - balanced and the max open count for a particular textDocument is one. Note that a server's ability to fulfill requests is independent + not be sent more than once without a corresponding close notification send before. This means open and close notification must be + balanced and the max open count for a particular textDocument is one. Note that a server's ability to fulfill requests is independent of whether a text document is open or closed. - The DidOpenTextDocumentParams contain the language id the document is associated with. If the language Id of a document changes, the - client needs to send a textDocument/didClose to the server followed by a textDocument/didOpen with the new language id if the server + The DidOpenTextDocumentParams contain the language id the document is associated with. If the language Id of a document changes, the + client needs to send a textDocument/didClose to the server followed by a textDocument/didOpen with the new language id if the server handles the new language id as well. :param TextDocumentItem textDocument: The document that was opened. """ - self.lsp_endpoint.send_notification("textDocument/didOpen", textDocument=textDocument) - - + self.lsp_endpoint.send_notification( + "textDocument/didOpen", textDocument=textDocument + ) + def didChange(self, textDocument: TextDocumentItem, contentChanges): """ - The document change notification is sent from the client to the server to signal changes to a text document. + The document change notification is sent from the client to the server to signal changes to a text document. In 2.0 the shape of the params has changed to include proper version numbers and language ids. :param VersionedTextDocumentIdentifier textDocument: The initial trace setting. If omitted trace is disabled ('off'). :param TextDocumentContentChangeEvent[] contentChanges: The actual content changes. The content changes describe single state changes - to the document. So if there are two content changes c1 and c2 for a document in state S then c1 move the document + to the document. So if there are two content changes c1 and c2 for a document in state S then c1 move the document to S' and c2 to S''. """ - self.lsp_endpoint.send_notification("textDocument/didChange", textDocument=textDocument, contentChanges=contentChanges) - - - def documentSymbol(self, textDocument: TextDocumentIdentifier) -> list[DocumentSymbol] | list[SymbolInformation]: + self.lsp_endpoint.send_notification( + "textDocument/didChange", + textDocument=textDocument, + contentChanges=contentChanges, + ) + + def documentSymbol( + self, textDocument: TextDocumentIdentifier + ) -> list[DocumentSymbol] | list[SymbolInformation]: """ - The document symbol request is sent from the client to the server to return a flat list of all symbols found in a given text document. + The document symbol request is sent from the client to the server to return a flat list of all symbols found in a given text document. Neither the symbol's location range nor the symbol's container name should be used to infer a hierarchy. :param TextDocumentItem textDocument: The text document. """ - result_dict = self.lsp_endpoint.call_method("textDocument/documentSymbol", textDocument=textDocument.dict()) + result_dict = self.lsp_endpoint.call_method( + "textDocument/documentSymbol", textDocument=textDocument.dict() + ) try: return [DocumentSymbol.model_validate(sym) for sym in result_dict] except ValidationError: return [SymbolInformation.model_validate(sym) for sym in result_dict] - def typeDefinition( - self, - textDocument: TextDocumentIdentifier, - position: Position + self, textDocument: TextDocumentIdentifier, position: Position ) -> list[Location]: """ The goto type definition request is sent from the client to the server to resolve the type definition location of a symbol at a given text document position. @@ -140,96 +163,102 @@ def typeDefinition( :param TextDocumentItem textDocument: The text document. :param Position position: The position inside the text document. """ - result_dict = self.lsp_endpoint.call_method("textDocument/typeDefinition", textDocument=textDocument, position=position) + result_dict = self.lsp_endpoint.call_method( + "textDocument/typeDefinition", textDocument=textDocument, position=position + ) return [Location.model_validate(result) for result in result_dict] - def signatureHelp( self, textDocument: TextDocumentIdentifier, position: Position, workDoneToken: Optional[str] = None, - partialResultToken: Optional[str] = None + partialResultToken: Optional[str] = None, ) -> SignatureHelp: - """ - The signature help request is sent from the client to the server to request signature information at a given cursor position. - - :param TextDocumentItem textDocument: The text document. - :param Position position: The position inside the text document. - """ - result_dict = self.lsp_endpoint.call_method("textDocument/signatureHelp", textDocument=textDocument, position=position) - return SignatureHelp.model_validate(result_dict) + """ + The signature help request is sent from the client to the server to request signature information at a given cursor position. + :param TextDocumentItem textDocument: The text document. + :param Position position: The position inside the text document. + """ + result_dict = self.lsp_endpoint.call_method( + "textDocument/signatureHelp", textDocument=textDocument, position=position + ) + return SignatureHelp.model_validate(result_dict) def completion( self, textDocument: TextDocumentIdentifier, position: Position, - context: CompletionContext + context: CompletionContext, ) -> list[CompletionItem] | CompletionList: - """ - The signature help request is sent from the client to the server to request signature information at a given cursor position. - - :param TextDocumentItem textDocument: The text document. - :param Position position: The position inside the text document. - :param CompletionContext context: The completion context. This is only available if the client specifies - CompletionContext to send this using `ClientCapabilities.textDocument.completion.contextSupport === true` - """ - result_dict = self.lsp_endpoint.call_method("textDocument/completion", textDocument=textDocument, position=position, context=context) - if "isIncomplete" in result_dict: - return CompletionList.model_validate(result_dict) - - return [CompletionItem.model_validate(result) for result in result_dict] - - + """ + The signature help request is sent from the client to the server to request signature information at a given cursor position. + + :param TextDocumentItem textDocument: The text document. + :param Position position: The position inside the text document. + :param CompletionContext context: The completion context. This is only available if the client specifies + CompletionContext to send this using `ClientCapabilities.textDocument.completion.contextSupport === true` + """ + result_dict = self.lsp_endpoint.call_method( + "textDocument/completion", + textDocument=textDocument, + position=position, + context=context, + ) + if "isIncomplete" in result_dict: + return CompletionList.model_validate(result_dict) + + return [CompletionItem.model_validate(result) for result in result_dict] + def declaration( - self, - textDocument: TextDocumentIdentifier, - position: Position + self, textDocument: TextDocumentIdentifier, position: Position ) -> Location | list[Location] | list[LocationLink]: - """ - The go to declaration request is sent from the client to the server to resolve the declaration location of a - symbol at a given text document position. - - The result type LocationLink[] got introduce with version 3.14.0 and depends in the corresponding client - capability `clientCapabilities.textDocument.declaration.linkSupport`. + """ + The go to declaration request is sent from the client to the server to resolve the declaration location of a + symbol at a given text document position. - :param TextDocumentItem textDocument: The text document. - :param Position position: The position inside the text document. - """ - result_dict = self.lsp_endpoint.call_method("textDocument/declaration", textDocument=textDocument, position=position) - if "uri" in result_dict: - return Location.model_validate(result_dict) + The result type LocationLink[] got introduce with version 3.14.0 and depends in the corresponding client + capability `clientCapabilities.textDocument.declaration.linkSupport`. - try: - return [Location.model_validate(result) for result in result_dict] - except ValidationError: - return [LocationLink.model_validate(result) for result in result_dict] + :param TextDocumentItem textDocument: The text document. + :param Position position: The position inside the text document. + """ + result_dict = self.lsp_endpoint.call_method( + "textDocument/declaration", textDocument=textDocument, position=position + ) + if "uri" in result_dict: + return Location.model_validate(result_dict) - + try: + return [Location.model_validate(result) for result in result_dict] + except ValidationError: + return [LocationLink.model_validate(result) for result in result_dict] def definition( self, textDocument: TextDocumentIdentifier, position: Position, workDoneToken: Optional[str] = None, - partialResultToken: Optional[str] = None + partialResultToken: Optional[str] = None, ) -> Location | list[Location] | list[LocationLink]: - """ - The go to definition request is sent from the client to the server to resolve the declaration location of a - symbol at a given text document position. - - The result type LocationLink[] got introduce with version 3.14.0 and depends in the corresponding client - capability `clientCapabilities.textDocument.declaration.linkSupport`. - - :param TextDocumentItem textDocument: The text document. - :param Position position: The position inside the text document. - """ - result_dict = self.lsp_endpoint.call_method("textDocument/definition", textDocument=textDocument, position=position) - if "uri" in result_dict: - return Location.model_validate(result_dict) - - try: - return [Location.model_validate(result) for result in result_dict] - except ValidationError: - return [LocationLink.model_validate(result) for result in result_dict] + """ + The go to definition request is sent from the client to the server to resolve the declaration location of a + symbol at a given text document position. + + The result type LocationLink[] got introduce with version 3.14.0 and depends in the corresponding client + capability `clientCapabilities.textDocument.declaration.linkSupport`. + + :param TextDocumentItem textDocument: The text document. + :param Position position: The position inside the text document. + """ + result_dict = self.lsp_endpoint.call_method( + "textDocument/definition", textDocument=textDocument, position=position + ) + if "uri" in result_dict: + return Location.model_validate(result_dict) + + try: + return [Location.model_validate(result) for result in result_dict] + except ValidationError: + return [LocationLink.model_validate(result) for result in result_dict] diff --git a/pylspclient/lsp_endpoint.py b/pylspclient/lsp_endpoint.py index 09d56e4..ff2f921 100644 --- a/pylspclient/lsp_endpoint.py +++ b/pylspclient/lsp_endpoint.py @@ -1,8 +1,8 @@ from __future__ import print_function import threading -from pylspclient.lsp_errors import ErrorCodes, ResponseError -from pylspclient import JsonRpcEndpoint from typing import Any, Dict, Callable, Union, Optional, Tuple, TypeAlias, TypedDict +from .lsp_errors import ErrorCodes, ResponseError +from .json_rpc_endpoint import JsonRpcEndpoint ResultType: TypeAlias = Optional[Dict[str, Any]] diff --git a/tests/test-workspace/__init__.py b/tests/test-workspace/__init__.py deleted file mode 100644 index 1cb55c7..0000000 --- a/tests/test-workspace/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -#from __future__ import absolute_import - -__all__ = [] - -from pylspclient.json_rpc_endpoint import JsonRpcEndpoint -from pylspclient.lsp_client import LspClient -from pylspclient.lsp_endpoint import LspEndpoint -from pylspclient import lsp_structs diff --git a/tests/test_pylsp_integration.py b/tests/test_pylsp_integration.py index 68a8147..beeb82e 100644 --- a/tests/test_pylsp_integration.py +++ b/tests/test_pylsp_integration.py @@ -50,7 +50,7 @@ def server_process() -> subprocess.Popen: } } } -DEFAULT_ROOT = path.abspath("./tests/test-workspace/") +DEFAULT_ROOT = path.abspath("./tests/test_workspace/") @pytest.fixture diff --git a/tests/test_workspace/__init__.py b/tests/test_workspace/__init__.py new file mode 100644 index 0000000..bfb8d65 --- /dev/null +++ b/tests/test_workspace/__init__.py @@ -0,0 +1,7 @@ +#from __future__ import absolute_import + +__all__ = [] + +from .json_rpc_endpoint import JsonRpcEndpoint +from .lsp_client import LspClient +from .lsp_endpoint import LspEndpoint diff --git a/tests/test-workspace/json_rpc_endpoint.py b/tests/test_workspace/json_rpc_endpoint.py similarity index 98% rename from tests/test-workspace/json_rpc_endpoint.py rename to tests/test_workspace/json_rpc_endpoint.py index 04f2e39..adee01a 100644 --- a/tests/test-workspace/json_rpc_endpoint.py +++ b/tests/test_workspace/json_rpc_endpoint.py @@ -1,6 +1,6 @@ from __future__ import print_function import json -from pylspclient import lsp_structs +from . import lsp_structs import threading JSON_RPC_REQ_FORMAT = "Content-Length: {json_string_len}\r\n\r\n{json_string}" diff --git a/tests/test-workspace/lsp_client.py b/tests/test_workspace/lsp_client.py similarity index 99% rename from tests/test-workspace/lsp_client.py rename to tests/test_workspace/lsp_client.py index 7219f4e..aea80e9 100644 --- a/tests/test-workspace/lsp_client.py +++ b/tests/test_workspace/lsp_client.py @@ -1,4 +1,4 @@ -from pylspclient import lsp_structs +from . import lsp_structs from .lsp_endpoint import LspEndpoint class LspClient(object): diff --git a/tests/test-workspace/lsp_endpoint.py b/tests/test_workspace/lsp_endpoint.py similarity index 99% rename from tests/test-workspace/lsp_endpoint.py rename to tests/test_workspace/lsp_endpoint.py index 3df745d..4f83703 100644 --- a/tests/test-workspace/lsp_endpoint.py +++ b/tests/test_workspace/lsp_endpoint.py @@ -1,7 +1,6 @@ from __future__ import print_function import threading -from pylspclient import lsp_structs - +from . import lsp_structs class LspEndpoint(threading.Thread): def __init__(self, json_rpc_endpoint, method_callbacks={}, notify_callbacks={}, timeout=2): diff --git a/tests/test-workspace/lsp_structs.py b/tests/test_workspace/lsp_structs.py similarity index 99% rename from tests/test-workspace/lsp_structs.py rename to tests/test_workspace/lsp_structs.py index 6b6e012..927ff2a 100644 --- a/tests/test-workspace/lsp_structs.py +++ b/tests/test_workspace/lsp_structs.py @@ -8,7 +8,7 @@ def to_type(o, new_type): :param object|dict o: The object to convert :param Type new_type: The type to convert to. ''' - if new_type == type(o): + if isinstance(o, new_type): return o else: return new_type(**o) From 824c279fb01aac3d2a6e5bbaa83130b59d37bd40 Mon Sep 17 00:00:00 2001 From: Shrey Pandey Date: Fri, 11 Oct 2024 19:35:58 +0530 Subject: [PATCH 4/4] Updated precommit hook --- .pre-commit-config.yaml | 18 +++++++++++++----- pylspclient/lsp_client.py | 1 - 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b04ad97..3219dfd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,16 +3,24 @@ repos: rev: v0.6.9 hooks: - id: ruff -- repo: local +- repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.11.2 hooks: - id: mypy - name: Install Poetry Dependencies and Run mypy - entry: bash -c "poetry install --no-interaction --no-root --with tests && poetry run mypy pylspclient" - language: system + args: ["pylspclient"] + pass_filenames: false + additional_dependencies: [pydantic~=2.5.2] - repo: local hooks: + - id: poetry-install + name: Poetry install + entry: poetry install --no-interaction --no-root --with tests + language: system + types: [python] + pass_filenames: false - id: poetry-pytest name: Run Tests with Poetry and Pytest - entry: bash -c "poetry install --no-interaction --no-root --with tests && poetry run pytest" + entry: poetry run pytest language: system + pass_filenames: false types: [python] \ No newline at end of file diff --git a/pylspclient/lsp_client.py b/pylspclient/lsp_client.py index 8340a1e..3528af0 100644 --- a/pylspclient/lsp_client.py +++ b/pylspclient/lsp_client.py @@ -1,5 +1,4 @@ from typing import Any, Optional - from pydantic import ValidationError from .lsp_endpoint import LspEndpoint from .lsp_pydantic_strcuts import (