diff --git a/lib/pytest-lsp/changes/177.misc.md b/lib/pytest-lsp/changes/177.misc.md new file mode 100644 index 0000000..d89c711 --- /dev/null +++ b/lib/pytest-lsp/changes/177.misc.md @@ -0,0 +1 @@ +Migrate to pygls v2 diff --git a/lib/pytest-lsp/hatch.toml b/lib/pytest-lsp/hatch.toml index 0e7cf09..ff88486 100644 --- a/lib/pytest-lsp/hatch.toml +++ b/lib/pytest-lsp/hatch.toml @@ -11,6 +11,9 @@ packages = ["pytest_lsp"] [envs.hatch-test] dependencies = ["pytest-asyncio"] +[envs.hatch-test.env-vars] +UV_PRERELEASE="allow" + [[envs.hatch-test.matrix]] python = ["3.9", "3.10", "3.11", "3.12", "3.13"] pytest = ["8"] diff --git a/lib/pytest-lsp/pyproject.toml b/lib/pytest-lsp/pyproject.toml index a22842f..e0c3a65 100644 --- a/lib/pytest-lsp/pyproject.toml +++ b/lib/pytest-lsp/pyproject.toml @@ -11,7 +11,7 @@ requires-python = ">=3.9" license = { text = "MIT" } authors = [{ name = "Alex Carney", email = "alcarneyme@gmail.com" }] classifiers = [ - "Development Status :: 3 - Alpha", + "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Framework :: Pytest", "Programming Language :: Python", @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "packaging", - "pygls>=1.1.0", + "pygls>=2.0.0a1", "pytest", "pytest-asyncio>=0.23", ] diff --git a/lib/pytest-lsp/pytest_lsp/checks.py b/lib/pytest-lsp/pytest_lsp/checks.py index 8720d8a..9ac8005 100644 --- a/lib/pytest-lsp/pytest_lsp/checks.py +++ b/lib/pytest-lsp/pytest_lsp/checks.py @@ -260,7 +260,7 @@ def work_done_progress_create( @check_params_of(method=types.WORKSPACE_CONFIGURATION) def workspace_configuration( capabilities: types.ClientCapabilities, - params: types.WorkspaceConfigurationParams, + params: types.ConfigurationParams, ): """Ensure that the client has support for ``workspace/configuration`` requests.""" is_supported = get_capability(capabilities, "workspace.configuration", False) diff --git a/lib/pytest-lsp/tests/examples/client-capabilities/server.py b/lib/pytest-lsp/tests/examples/client-capabilities/server.py index 7f63083..340d104 100644 --- a/lib/pytest-lsp/tests/examples/client-capabilities/server.py +++ b/lib/pytest-lsp/tests/examples/client-capabilities/server.py @@ -4,7 +4,7 @@ CompletionParams, InsertTextFormat, ) -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("hello-world", "v1") diff --git a/lib/pytest-lsp/tests/examples/diagnostics/server.py b/lib/pytest-lsp/tests/examples/diagnostics/server.py index 5b07c58..0379395 100644 --- a/lib/pytest-lsp/tests/examples/diagnostics/server.py +++ b/lib/pytest-lsp/tests/examples/diagnostics/server.py @@ -1,28 +1,24 @@ -from lsprotocol.types import ( - TEXT_DOCUMENT_DID_OPEN, - Diagnostic, - DidOpenTextDocumentParams, - Position, - Range, -) -from pygls.server import LanguageServer +from lsprotocol import types +from pygls.lsp.server import LanguageServer server = LanguageServer("diagnostic-server", "v1") -@server.feature(TEXT_DOCUMENT_DID_OPEN) -def did_open(ls: LanguageServer, params: DidOpenTextDocumentParams): - ls.publish_diagnostics( - params.text_document.uri, - [ - Diagnostic( - message="There is an error here.", - range=Range( - start=Position(line=1, character=1), - end=Position(line=1, character=10), - ), - ) - ], +@server.feature(types.TEXT_DOCUMENT_DID_OPEN) +def did_open(ls: LanguageServer, params: types.DidOpenTextDocumentParams): + ls.text_document_publish_diagnostics( + types.PublishDiagnosticsParams( + uri=params.text_document.uri, + diagnostics=[ + types.Diagnostic( + message="There is an error here.", + range=types.Range( + start=types.Position(line=1, character=1), + end=types.Position(line=1, character=10), + ), + ) + ], + ) ) diff --git a/lib/pytest-lsp/tests/examples/fixture-passthrough/server.py b/lib/pytest-lsp/tests/examples/fixture-passthrough/server.py index 333c1b5..da8fc40 100644 --- a/lib/pytest-lsp/tests/examples/fixture-passthrough/server.py +++ b/lib/pytest-lsp/tests/examples/fixture-passthrough/server.py @@ -1,5 +1,5 @@ from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("hello-world", "v1") diff --git a/lib/pytest-lsp/tests/examples/fixture-scope/server.py b/lib/pytest-lsp/tests/examples/fixture-scope/server.py index 333c1b5..da8fc40 100644 --- a/lib/pytest-lsp/tests/examples/fixture-scope/server.py +++ b/lib/pytest-lsp/tests/examples/fixture-scope/server.py @@ -1,5 +1,5 @@ from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("hello-world", "v1") diff --git a/lib/pytest-lsp/tests/examples/generic-rpc/server.py b/lib/pytest-lsp/tests/examples/generic-rpc/server.py index 3381860..20cc043 100644 --- a/lib/pytest-lsp/tests/examples/generic-rpc/server.py +++ b/lib/pytest-lsp/tests/examples/generic-rpc/server.py @@ -1,27 +1,29 @@ from pygls.protocol import JsonRPCProtocol, default_converter -from pygls.server import Server +from pygls.server import JsonRPCServer -server = Server(protocol_cls=JsonRPCProtocol, converter_factory=default_converter) +server = JsonRPCServer( + protocol_cls=JsonRPCProtocol, converter_factory=default_converter +) -@server.lsp.fm.feature("math/add") -def addition(ls: Server, params): +@server.feature("math/add") +def addition(ls: JsonRPCServer, params): a = params.a b = params.b - ls.lsp.notify("log/message", dict(message=f"{a=}")) - ls.lsp.notify("log/message", dict(message=f"{b=}")) + ls.protocol.notify("log/message", dict(message=f"{a=}")) + ls.protocol.notify("log/message", dict(message=f"{b=}")) return dict(total=a + b) -@server.lsp.fm.feature("math/sub") -def subtraction(ls: Server, params): +@server.feature("math/sub") +def subtraction(ls: JsonRPCServer, params): a = params.a b = params.b - ls.lsp.notify("log/message", dict(message=f"{a=}")) - ls.lsp.notify("log/message", dict(message=f"{b=}")) + ls.protocol.notify("log/message", dict(message=f"{a=}")) + ls.protocol.notify("log/message", dict(message=f"{b=}")) return dict(total=b - a) diff --git a/lib/pytest-lsp/tests/examples/getting-started-fail/server.py b/lib/pytest-lsp/tests/examples/getting-started-fail/server.py index a14d5a2..025b6cc 100644 --- a/lib/pytest-lsp/tests/examples/getting-started-fail/server.py +++ b/lib/pytest-lsp/tests/examples/getting-started-fail/server.py @@ -1,5 +1,5 @@ from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("hello-world", "v1") diff --git a/lib/pytest-lsp/tests/examples/getting-started/server.py b/lib/pytest-lsp/tests/examples/getting-started/server.py index 333c1b5..da8fc40 100644 --- a/lib/pytest-lsp/tests/examples/getting-started/server.py +++ b/lib/pytest-lsp/tests/examples/getting-started/server.py @@ -1,5 +1,5 @@ from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("hello-world", "v1") diff --git a/lib/pytest-lsp/tests/examples/parameterised-clients/server.py b/lib/pytest-lsp/tests/examples/parameterised-clients/server.py index 333c1b5..da8fc40 100644 --- a/lib/pytest-lsp/tests/examples/parameterised-clients/server.py +++ b/lib/pytest-lsp/tests/examples/parameterised-clients/server.py @@ -1,5 +1,5 @@ from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("hello-world", "v1") diff --git a/lib/pytest-lsp/tests/examples/server-stderr/server.py b/lib/pytest-lsp/tests/examples/server-stderr/server.py index c4886e5..0f53138 100644 --- a/lib/pytest-lsp/tests/examples/server-stderr/server.py +++ b/lib/pytest-lsp/tests/examples/server-stderr/server.py @@ -1,7 +1,7 @@ import sys from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("server-stderr", "v1") diff --git a/lib/pytest-lsp/tests/examples/window-create-progress/server.py b/lib/pytest-lsp/tests/examples/window-create-progress/server.py index b2819fa..47044fd 100644 --- a/lib/pytest-lsp/tests/examples/window-create-progress/server.py +++ b/lib/pytest-lsp/tests/examples/window-create-progress/server.py @@ -1,7 +1,7 @@ from unittest.mock import Mock from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("window-create-progress", "v1") @@ -10,21 +10,21 @@ async def do_progress(ls: LanguageServer, *args): token = "a-token" - await ls.progress.create_async(token) + await ls.work_done_progress.create_async(token) # Begin - ls.progress.begin( + ls.work_done_progress.begin( token, types.WorkDoneProgressBegin(title="Indexing", percentage=0), ) # Report for i in range(1, 4): - ls.progress.report( + ls.work_done_progress.report( token, types.WorkDoneProgressReport(message=f"{i * 25}%", percentage=i * 25), ) # End - ls.progress.end(token, types.WorkDoneProgressEnd(message="Finished")) + ls.work_done_progress.end(token, types.WorkDoneProgressEnd(message="Finished")) return "a result" @@ -34,11 +34,11 @@ async def duplicate_progress(ls: LanguageServer, *args): token = "duplicate-token" # Need to stop pygls preventing us from using the progress API wrong. - ls.progress._check_token_registered = Mock() - await ls.progress.create_async(token) + ls.work_done_progress._check_token_registered = Mock() + await ls.work_done_progress.create_async(token) # pytest-lsp should return an error here. - await ls.progress.create_async(token) + await ls.work_done_progress.create_async(token) @server.command("no.progress") @@ -46,18 +46,18 @@ async def no_progress(ls: LanguageServer, *args): token = "undefined-token" # Begin - ls.progress.begin( + ls.work_done_progress.begin( token, types.WorkDoneProgressBegin(title="Indexing", percentage=0, cancellable=False), ) # Report for i in range(1, 4): - ls.progress.report( + ls.work_done_progress.report( token, types.WorkDoneProgressReport(message=f"{i * 25}%", percentage=i * 25), ) # End - ls.progress.end(token, types.WorkDoneProgressEnd(message="Finished")) + ls.work_done_progress.end(token, types.WorkDoneProgressEnd(message="Finished")) if __name__ == "__main__": diff --git a/lib/pytest-lsp/tests/examples/window-log-message-fail/server.py b/lib/pytest-lsp/tests/examples/window-log-message-fail/server.py index b9f762b..8794e30 100644 --- a/lib/pytest-lsp/tests/examples/window-log-message-fail/server.py +++ b/lib/pytest-lsp/tests/examples/window-log-message-fail/server.py @@ -1,16 +1,21 @@ -from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from lsprotocol import types +from pygls.lsp.server import LanguageServer server = LanguageServer("window-log-message", "v1") -@server.feature(TEXT_DOCUMENT_COMPLETION) -def completion(ls: LanguageServer, params: CompletionParams): +@server.feature(types.TEXT_DOCUMENT_COMPLETION) +def completion(ls: LanguageServer, params: types.CompletionParams): items = [] for i in range(10): - ls.show_message_log(f"Suggesting item {i}") - items.append(CompletionItem(label=f"item-{i}")) + ls.window_log_message( + types.LogMessageParams( + message=f"Suggesting item {i}", + type=types.MessageType.Log, + ) + ) + items.append(types.CompletionItem(label=f"item-{i}")) return items diff --git a/lib/pytest-lsp/tests/examples/window-log-message/server.py b/lib/pytest-lsp/tests/examples/window-log-message/server.py index b9f762b..12fa57d 100644 --- a/lib/pytest-lsp/tests/examples/window-log-message/server.py +++ b/lib/pytest-lsp/tests/examples/window-log-message/server.py @@ -1,16 +1,20 @@ -from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from lsprotocol import types +from pygls.lsp.server import LanguageServer server = LanguageServer("window-log-message", "v1") -@server.feature(TEXT_DOCUMENT_COMPLETION) -def completion(ls: LanguageServer, params: CompletionParams): +@server.feature(types.TEXT_DOCUMENT_COMPLETION) +def completion(ls: LanguageServer, params: types.CompletionParams): items = [] for i in range(10): - ls.show_message_log(f"Suggesting item {i}") - items.append(CompletionItem(label=f"item-{i}")) + ls.window_log_message( + types.LogMessageParams( + message=f"Suggesting item {i}", type=types.MessageType.Log + ) + ) + items.append(types.CompletionItem(label=f"item-{i}")) return items diff --git a/lib/pytest-lsp/tests/examples/window-show-document/server.py b/lib/pytest-lsp/tests/examples/window-show-document/server.py index 2cf056b..17f3527 100644 --- a/lib/pytest-lsp/tests/examples/window-show-document/server.py +++ b/lib/pytest-lsp/tests/examples/window-show-document/server.py @@ -1,21 +1,18 @@ -from lsprotocol.types import ( - TEXT_DOCUMENT_COMPLETION, - CompletionItem, - CompletionParams, - ShowDocumentParams, -) -from pygls.server import LanguageServer +from lsprotocol import types +from pygls.lsp.server import LanguageServer server = LanguageServer("window-show-document", "v1") -@server.feature(TEXT_DOCUMENT_COMPLETION) -async def completion(ls: LanguageServer, params: CompletionParams): +@server.feature(types.TEXT_DOCUMENT_COMPLETION) +async def completion(ls: LanguageServer, params: types.CompletionParams): items = [] - await ls.show_document_async(ShowDocumentParams(uri=params.text_document.uri)) + await ls.window_show_document_async( + types.ShowDocumentParams(uri=params.text_document.uri) + ) for i in range(10): - items.append(CompletionItem(label=f"item-{i}")) + items.append(types.CompletionItem(label=f"item-{i}")) return items diff --git a/lib/pytest-lsp/tests/examples/window-show-message/server.py b/lib/pytest-lsp/tests/examples/window-show-message/server.py index 9b272ca..bc39e7a 100644 --- a/lib/pytest-lsp/tests/examples/window-show-message/server.py +++ b/lib/pytest-lsp/tests/examples/window-show-message/server.py @@ -1,16 +1,21 @@ -from lsprotocol.types import TEXT_DOCUMENT_COMPLETION, CompletionItem, CompletionParams -from pygls.server import LanguageServer +from lsprotocol import types +from pygls.lsp.server import LanguageServer server = LanguageServer("window-show-message", "v1") -@server.feature(TEXT_DOCUMENT_COMPLETION) -def completion(ls: LanguageServer, params: CompletionParams): +@server.feature(types.TEXT_DOCUMENT_COMPLETION) +def completion(ls: LanguageServer, params: types.CompletionParams): items = [] for i in range(10): - ls.show_message(f"Suggesting item {i}") - items.append(CompletionItem(label=f"item-{i}")) + ls.window_show_message( + types.ShowMessageParams( + message=f"Suggesting item {i}", + type=types.MessageType.Log, + ) + ) + items.append(types.CompletionItem(label=f"item-{i}")) return items diff --git a/lib/pytest-lsp/tests/examples/workspace-configuration/server.py b/lib/pytest-lsp/tests/examples/workspace-configuration/server.py index 3d35bde..a7fad45 100644 --- a/lib/pytest-lsp/tests/examples/workspace-configuration/server.py +++ b/lib/pytest-lsp/tests/examples/workspace-configuration/server.py @@ -1,13 +1,13 @@ from lsprotocol import types -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer server = LanguageServer("workspace-configuration", "v1") @server.command("server.configuration") async def configuration(ls: LanguageServer, *args): - results = await ls.get_configuration_async( - types.WorkspaceConfigurationParams( + results = await ls.workspace_configuration_async( + types.ConfigurationParams( items=[ types.ConfigurationItem(scope_uri="file://workspace/file.txt"), types.ConfigurationItem(section="not.found"), diff --git a/lib/pytest-lsp/tests/servers/capabilities.py b/lib/pytest-lsp/tests/servers/capabilities.py index ee5840c..ebd404b 100644 --- a/lib/pytest-lsp/tests/servers/capabilities.py +++ b/lib/pytest-lsp/tests/servers/capabilities.py @@ -1,5 +1,5 @@ from lsprotocol.converters import get_converter -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer converter = get_converter() server = LanguageServer(name="capabilities-server", version="v1.0") diff --git a/lib/pytest-lsp/tests/servers/completion_exit.py b/lib/pytest-lsp/tests/servers/completion_exit.py index ddb8289..5c2defc 100644 --- a/lib/pytest-lsp/tests/servers/completion_exit.py +++ b/lib/pytest-lsp/tests/servers/completion_exit.py @@ -1,10 +1,8 @@ # A server that exits mid request. import sys -from lsprotocol.types import TEXT_DOCUMENT_COMPLETION -from lsprotocol.types import CompletionItem -from lsprotocol.types import CompletionParams -from pygls.server import LanguageServer +from lsprotocol import types +from pygls.lsp.server import LanguageServer class CountingLanguageServer(LanguageServer): @@ -14,13 +12,13 @@ class CountingLanguageServer(LanguageServer): server = CountingLanguageServer(name="completion-exit-server", version="v1.0") -@server.feature(TEXT_DOCUMENT_COMPLETION) -def on_complete(server: CountingLanguageServer, params: CompletionParams): +@server.feature(types.TEXT_DOCUMENT_COMPLETION) +def on_complete(server: CountingLanguageServer, params: types.CompletionParams): server.count += 1 if server.count == 5: sys.exit(0) - return [CompletionItem(label=f"{server.count}")] + return [types.CompletionItem(label=f"{server.count}")] if __name__ == "__main__": diff --git a/lib/pytest-lsp/tests/servers/invalid_json.py b/lib/pytest-lsp/tests/servers/invalid_json.py index b1d10bf..149394c 100644 --- a/lib/pytest-lsp/tests/servers/invalid_json.py +++ b/lib/pytest-lsp/tests/servers/invalid_json.py @@ -1,10 +1,8 @@ # A server that returns a message that cannot be parsed as JSON. import json -from lsprotocol.types import TEXT_DOCUMENT_COMPLETION -from lsprotocol.types import CompletionItem -from lsprotocol.types import CompletionParams -from pygls.server import LanguageServer +from lsprotocol import types +from pygls.lsp.server import LanguageServer server = LanguageServer(name="completion-exit-server", version="v1.0") @@ -14,7 +12,7 @@ def bad_send_data(data): if not data: return - self = server.lsp + self = server.protocol body = json.dumps(data, default=self._serialize_message) body = body.replace('"', "'").encode(self.CHARSET) header = ( @@ -25,10 +23,10 @@ def bad_send_data(data): self.transport.write(header + body) -@server.feature(TEXT_DOCUMENT_COMPLETION) -def on_complete(server: LanguageServer, params: CompletionParams): - server.lsp._send_data = bad_send_data - return [CompletionItem(label="item-one")] +@server.feature(types.TEXT_DOCUMENT_COMPLETION) +def on_complete(server: LanguageServer, params: types.CompletionParams): + server.protocol._send_data = bad_send_data + return [types.CompletionItem(label="item-one")] if __name__ == "__main__": diff --git a/lib/pytest-lsp/tests/test_checks.py b/lib/pytest-lsp/tests/test_checks.py index a815c90..1e71516 100644 --- a/lib/pytest-lsp/tests/test_checks.py +++ b/lib/pytest-lsp/tests/test_checks.py @@ -36,7 +36,7 @@ workspace=types.WorkspaceClientCapabilities(configuration=False) ), types.WORKSPACE_CONFIGURATION, - types.WorkspaceConfigurationParams(items=[]), + types.ConfigurationParams(items=[]), "does not support 'workspace/configuration'", ), ( @@ -44,7 +44,7 @@ workspace=types.WorkspaceClientCapabilities(configuration=True) ), types.WORKSPACE_CONFIGURATION, - types.WorkspaceConfigurationParams(items=[]), + types.ConfigurationParams(items=[]), None, ), ], @@ -104,7 +104,7 @@ def test_params_check_warning( types.ClientCapabilities( text_document=types.TextDocumentClientCapabilities( completion=types.CompletionClientCapabilities( - completion_item=types.CompletionClientCapabilitiesCompletionItemType( + completion_item=types.ClientCompletionItemOptions( commit_characters_support=True ) ) @@ -135,7 +135,7 @@ def test_params_check_warning( types.ClientCapabilities( text_document=types.TextDocumentClientCapabilities( completion=types.CompletionClientCapabilities( - completion_item=types.CompletionClientCapabilitiesCompletionItemType( + completion_item=types.ClientCompletionItemOptions( documentation_format=[types.MarkupKind.Markdown] ) ) @@ -171,7 +171,7 @@ def test_params_check_warning( types.ClientCapabilities( text_document=types.TextDocumentClientCapabilities( completion=types.CompletionClientCapabilities( - completion_item=types.CompletionClientCapabilitiesCompletionItemType( + completion_item=types.ClientCompletionItemOptions( snippet_support=True ) )