From cb319a1ab0e5e2c2b8f13d0045fb633cabc3daf3 Mon Sep 17 00:00:00 2001 From: Alex Carney Date: Sat, 24 Aug 2024 10:28:16 +0100 Subject: [PATCH] lsp: Migrate to pygls v2 --- .pre-commit-config.yaml | 2 +- docs/requirements.txt | 3 +- lib/esbonio/changes/882.misc.md | 1 + lib/esbonio/esbonio/server/_configuration.py | 2 +- lib/esbonio/esbonio/server/features/log.py | 4 ++- .../features/preview_manager/__init__.py | 2 +- .../features/preview_manager/webview.py | 23 +++++++-------- .../server/features/sphinx_manager/manager.py | 28 +++++++++++-------- lib/esbonio/esbonio/server/server.py | 22 ++++++++------- lib/esbonio/esbonio/server/setup.py | 6 ++-- lib/esbonio/hatch.toml | 5 +++- lib/esbonio/pyproject.toml | 5 ++-- lib/esbonio/tests/e2e/test_e2e_diagnostics.py | 8 +++--- lib/esbonio/tests/e2e/test_e2e_directives.py | 8 +++--- lib/esbonio/tests/e2e/test_e2e_roles.py | 16 +++++------ lib/esbonio/tests/e2e/test_e2e_symbols.py | 4 +-- lib/esbonio/tests/e2e/test_sphinx_manager.py | 6 ++-- .../tests/server/test_configuration.py | 2 +- .../tests/sphinx-agent/test_sa_build.py | 4 +-- 19 files changed, 81 insertions(+), 70 deletions(-) create mode 100644 lib/esbonio/changes/882.misc.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d4badfb4e..0e70a9455 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,7 +45,7 @@ repos: additional_dependencies: - aiosqlite - platformdirs - - pygls + - pygls>=2a0 - pytest_lsp>=0.3 - sphinx - tomli diff --git a/docs/requirements.txt b/docs/requirements.txt index 54d647289..6d29ac8b0 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,6 +4,7 @@ sphinx sphinx-design furo myst-parser -pytest_lsp +pytest_lsp>=1.0b0 +pygls>=2.0a0 platformdirs aiosqlite diff --git a/lib/esbonio/changes/882.misc.md b/lib/esbonio/changes/882.misc.md new file mode 100644 index 000000000..d89c711ec --- /dev/null +++ b/lib/esbonio/changes/882.misc.md @@ -0,0 +1 @@ +Migrate to pygls v2 diff --git a/lib/esbonio/esbonio/server/_configuration.py b/lib/esbonio/esbonio/server/_configuration.py index 34f329dcc..e988e938c 100644 --- a/lib/esbonio/esbonio/server/_configuration.py +++ b/lib/esbonio/esbonio/server/_configuration.py @@ -441,7 +441,7 @@ async def update_workspace_configuration(self): ) try: - results = await self.server.get_configuration_async(params) + results = await self.server.workspace_configuration_async(params) except Exception: self.logger.error("Unable to get workspace configuration", exc_info=True) return diff --git a/lib/esbonio/esbonio/server/features/log.py b/lib/esbonio/esbonio/server/features/log.py index 9fd179a29..5b76e4b73 100644 --- a/lib/esbonio/esbonio/server/features/log.py +++ b/lib/esbonio/esbonio/server/features/log.py @@ -36,7 +36,9 @@ def emit(self, record: logging.LogRecord) -> None: return log = self.format(record).strip() - self.server.show_message_log(log) + self.server.window_log_message( + types.LogMessageParams(message=log, type=types.MessageType.Log) + ) @attrs.define diff --git a/lib/esbonio/esbonio/server/features/preview_manager/__init__.py b/lib/esbonio/esbonio/server/features/preview_manager/__init__.py index 4b966b935..1ba0ab776 100644 --- a/lib/esbonio/esbonio/server/features/preview_manager/__init__.py +++ b/lib/esbonio/esbonio/server/features/preview_manager/__init__.py @@ -202,7 +202,7 @@ async def show_preview_uri(self) -> Optional[Uri]: self.logger.info("Preview available at: %s", uri.as_string(encode=False)) if self.supports_show_document: - result = await self.server.show_document_async( + result = await self.server.window_show_document_async( types.ShowDocumentParams( uri=uri.as_string(encode=False), external=True, take_focus=False ) diff --git a/lib/esbonio/esbonio/server/features/preview_manager/webview.py b/lib/esbonio/esbonio/server/features/preview_manager/webview.py index 33de4b1b0..408023988 100644 --- a/lib/esbonio/esbonio/server/features/preview_manager/webview.py +++ b/lib/esbonio/esbonio/server/features/preview_manager/webview.py @@ -9,7 +9,7 @@ from lsprotocol import types from pygls.protocol import JsonRPCProtocol from pygls.protocol import default_converter -from pygls.server import Server +from pygls.server import JsonRPCServer from pygls.server import WebSocketTransportAdapter from websockets.server import serve @@ -21,20 +21,20 @@ from .config import PreviewConfig -class WebviewServer(Server): +class WebviewServer(JsonRPCServer): """The webview server controlls the webpage hosting the preview. Used to implement automatic reloads and features like sync scrolling. """ - lsp: JsonRPCProtocol + protocol: JsonRPCProtocol def __init__(self, logger: logging.Logger, config: PreviewConfig, *args, **kwargs): super().__init__(JsonRPCProtocol, default_converter, *args, **kwargs) self.config = config self.logger = logger.getChild("WebviewServer") - self.lsp._send_only_body = True + self.protocol._send_only_body = True self._connected = False self._ws_server: WebSocketServer | None = None @@ -74,13 +74,10 @@ def connected(self) -> bool: """Indicates when we have an active connection to the client.""" return self._connected - def feature(self, feature_name: str, options=None): - return self.lsp.fm.feature(feature_name, options) - def reload(self): """Reload the current view.""" if self.connected: - self.lsp.notify("view/reload", {}) + self.protocol.notify("view/reload", {}) def scroll(self, uri: str, line: int): """Called by the editor to scroll the current webview.""" @@ -93,7 +90,7 @@ def scroll(self, uri: str, line: int): self._current_uri = uri self._editor_in_control = asyncio.create_task(self.cooldown("editor")) - self.lsp.notify("view/scroll", {"uri": uri, "line": line}) + self.protocol.notify("view/scroll", {"uri": uri, "line": line}) async def cooldown(self, name: str): """Create a cooldown.""" @@ -128,13 +125,13 @@ async def connection(websocket): loop = asyncio.get_running_loop() transport = WebSocketTransportAdapter(websocket, loop) - self.lsp.connection_made(transport) # type: ignore[arg-type] + self.protocol.connection_made(transport) # type: ignore[arg-type] self._connected = True self.logger.debug("Connected") async for message in websocket: - self.lsp._procedure_handler( - json.loads(message, object_hook=self.lsp._deserialize_message) + self.protocol._procedure_handler( + json.loads(message, object_hook=self.protocol._deserialize_message) ) self.logger.debug("Connection lost") @@ -168,7 +165,7 @@ def on_scroll(ls: WebviewServer, params): server._view_in_control = asyncio.create_task(server.cooldown("view")) - esbonio.lsp.show_document( + esbonio.window_show_document( types.ShowDocumentParams( uri=params.uri, external=False, diff --git a/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py b/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py index 1c91f7e79..c02462887 100644 --- a/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py +++ b/lib/esbonio/esbonio/server/features/sphinx_manager/manager.py @@ -185,7 +185,7 @@ async def trigger_build(self, uri: Uri): known_src_uris = await project.get_src_uris() for src_uri in known_src_uris: - doc = self.server.workspace.get_document(str(src_uri)) + doc = self.server.workspace.get_text_document(str(src_uri)) doc_version = doc.version or 0 saved_version = getattr(doc, "saved_version", 0) @@ -197,7 +197,9 @@ async def trigger_build(self, uri: Uri): try: result = await client.build(content_overrides=content_overrides) except Exception as exc: - self.server.show_message(f"{exc}", lsp.MessageType.Error) + self.server.window_show_message( + lsp.ShowMessageParams(message=f"{exc}", type=lsp.MessageType.Error) + ) return finally: self.stop_progress(client) @@ -268,7 +270,7 @@ async def _create_or_replace_client( # If there was a previous client, stop it. if (previous_client := self.clients.pop(event.scope, None)) is not None: - self.server.lsp.notify( + self.server.protocol.notify( "sphinx/clientDestroyed", ClientDestroyedNotification(id=previous_client.id), ) @@ -282,7 +284,7 @@ async def _create_or_replace_client( self.clients[event.scope] = client = self.client_factory(self, resolved) client.add_listener("state-change", partial(self._on_state_change, event.scope)) - self.server.lsp.notify( + self.server.protocol.notify( "sphinx/clientCreated", ClientCreatedNotification(id=client.id, scope=event.scope, config=resolved), ) @@ -303,7 +305,7 @@ def _on_state_change( if old_state == ClientState.Starting and new_state == ClientState.Running: if (sphinx_info := client.sphinx_info) is not None: self.project_manager.register_project(scope, client.db) - self.server.lsp.notify( + self.server.protocol.notify( "sphinx/appCreated", AppCreatedNotification(id=client.id, application=sphinx_info), ) @@ -318,8 +320,10 @@ def _on_state_change( traceback.format_exception(type(exc), exc, exc.__traceback__) ) - self.server.lsp.show_message(error, lsp.MessageType.Error) - self.server.lsp.notify( + self.server.window_show_message( + lsp.ShowMessageParams(message=error, type=lsp.MessageType.Error) + ) + self.server.protocol.notify( "sphinx/clientErrored", ClientErroredNotification(id=client.id, error=error, detail=detail), ) @@ -331,13 +335,13 @@ async def start_progress(self, client: SphinxClient): self.logger.debug("Starting progress: '%s'", token) try: - await self.server.progress.create_async(token) + await self.server.work_done_progress.create_async(token) except Exception as exc: self.logger.debug("Unable to create progress token: %s", exc) return self._progress_tokens[client.id] = token - self.server.progress.begin( + self.server.work_done_progress.begin( token, lsp.WorkDoneProgressBegin(title="sphinx-build", cancellable=False), ) @@ -346,7 +350,9 @@ def stop_progress(self, client: SphinxClient): if (token := self._progress_tokens.pop(client.id, None)) is None: return - self.server.progress.end(token, lsp.WorkDoneProgressEnd(message="Finished")) + self.server.work_done_progress.end( + token, lsp.WorkDoneProgressEnd(message="Finished") + ) def report_progress(self, client: SphinxClient, progress: types.ProgressParams): """Report progress done for the given client.""" @@ -357,7 +363,7 @@ def report_progress(self, client: SphinxClient, progress: types.ProgressParams): if (token := self._progress_tokens.get(client.id, None)) is None: return - self.server.progress.report( + self.server.work_done_progress.report( token, lsp.WorkDoneProgressReport( message=progress.message, diff --git a/lib/esbonio/esbonio/server/server.py b/lib/esbonio/esbonio/server/server.py index 7bba62a6e..d97430b5f 100644 --- a/lib/esbonio/esbonio/server/server.py +++ b/lib/esbonio/esbonio/server/server.py @@ -13,7 +13,7 @@ import cattrs from lsprotocol import types from pygls.capabilities import get_capability -from pygls.server import LanguageServer +from pygls.lsp.server import LanguageServer from pygls.workspace import TextDocument from pygls.workspace import Workspace @@ -35,19 +35,19 @@ class EsbonioWorkspace(Workspace): """A modified version of pygls' workspace that ensures uris are always resolved.""" - def get_document(self, doc_uri: str) -> TextDocument: + def get_text_document(self, doc_uri: str) -> TextDocument: uri = str(Uri.parse(doc_uri).resolve()) return super().get_text_document(uri) - def put_document(self, text_document: types.TextDocumentItem): + def put_text_document(self, text_document: types.TextDocumentItem): text_document.uri = str(Uri.parse(text_document.uri).resolve()) return super().put_text_document(text_document) - def remove_document(self, doc_uri: str): + def remove_text_document(self, doc_uri: str): doc_uri = str(Uri.parse(doc_uri).resolve()) return super().remove_text_document(doc_uri) - def update_document( + def update_text_document( self, text_doc: types.VersionedTextDocumentIdentifier, change: types.TextDocumentContentChangeEvent, @@ -99,7 +99,7 @@ def ready(self) -> asyncio.Future: @property def converter(self) -> cattrs.Converter: """The cattrs converter instance we should use.""" - return self.lsp._converter + return self.protocol._converter def _finish_task(self, task: asyncio.Task[Any]): """Cleanup a finished task.""" @@ -133,7 +133,7 @@ def initialize(self, params: types.InitializeParams): self.logger.info("Language client: %s %s", client.name, client.version) # TODO: Propose patch to pygls for providing custom Workspace implementations. - self.lsp._workspace = EsbonioWorkspace( + self.protocol._workspace = EsbonioWorkspace( self.workspace.root_uri, self.workspace._sync_kind, list(self.workspace.folders.values()), @@ -307,7 +307,9 @@ def sync_diagnostics(self) -> None: for uri, diag_list in diagnostics.items(): self.logger.debug("Publishing %d diagnostics for: %s", len(diag_list), uri) - self.publish_diagnostics(str(uri), diag_list.data) + self.text_document_publish_diagnostics( + types.PublishDiagnosticsParams(uri=str(uri), diagnostics=diag_list.data) + ) async def _register_did_change_watched_files_handler(self): """Register the server's handler for ``workspace/didChangeWatchedFiles``.""" @@ -326,7 +328,7 @@ async def _register_did_change_watched_files_handler(self): return try: - await self.register_capability_async( + await self.client_register_capability_async( types.RegistrationParams( registrations=[ types.Registration( @@ -375,7 +377,7 @@ async def _register_did_change_configuration_handler(self): return try: - await self.register_capability_async( + await self.client_register_capability_async( types.RegistrationParams( registrations=[ types.Registration( diff --git a/lib/esbonio/esbonio/server/setup.py b/lib/esbonio/esbonio/server/setup.py index 3b6894472..c05c62866 100644 --- a/lib/esbonio/esbonio/server/setup.py +++ b/lib/esbonio/esbonio/server/setup.py @@ -84,7 +84,7 @@ async def on_document_save( ls: EsbonioLanguageServer, params: types.DidSaveTextDocumentParams ): # Record the version number of the document - doc = ls.workspace.get_document(params.text_document.uri) + doc = ls.workspace.get_text_document(params.text_document.uri) doc.saved_version = doc.version or 0 await call_features(ls, "document_save", params) @@ -135,9 +135,7 @@ async def on_workspace_diagnostic( ) ) - # Typing issues should be fixed in a future version of lsprotocol - # see: https://github.com/microsoft/lsprotocol/pull/285 - return types.WorkspaceDiagnosticReport(items=reports) # type: ignore[arg-type] + return types.WorkspaceDiagnosticReport(items=reports) @server.feature(types.TEXT_DOCUMENT_DOCUMENT_SYMBOL) async def on_document_symbol( diff --git a/lib/esbonio/hatch.toml b/lib/esbonio/hatch.toml index d3a838d32..ad91c6ee5 100644 --- a/lib/esbonio/hatch.toml +++ b/lib/esbonio/hatch.toml @@ -10,9 +10,12 @@ packages = ["esbonio"] [envs.hatch-test] default-args = ["tests/server"] -extra-dependencies = ["pytest-lsp>=0.3.1,<1"] +extra-dependencies = ["pytest-lsp>=1.0b0"] matrix-name-format = "{variable}{value}" +[envs.hatch-test.env-vars] +UV_PRERELEASE="allow" + [[envs.hatch-test.matrix]] python = ["3.9", "3.10", "3.11", "3.12", "3.13"] diff --git a/lib/esbonio/pyproject.toml b/lib/esbonio/pyproject.toml index 54a6bd61f..f41b84320 100644 --- a/lib/esbonio/pyproject.toml +++ b/lib/esbonio/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "aiosqlite", "platformdirs", "docutils", - "pygls>=1.1.0", + "pygls>=2.0a0", "tomli ; python_version<'3.11'", "websockets", ] @@ -42,7 +42,7 @@ dependencies = [ esbonio = "esbonio.server.cli:main" [project.optional-dependencies] -typecheck = ["mypy", "pytest-lsp>=0.3.1", "types-docutils", "types-pygments"] +typecheck = ["mypy", "pytest-lsp>=1.0b0", "types-docutils", "types-pygments"] [tool.coverage.run] parallel = true @@ -60,6 +60,7 @@ exclude_also = [ [tool.pytest.ini_options] addopts = "--doctest-glob='*.txt'" asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" [tool.mypy] mypy_path = "$MYPY_CONFIG_FILE_DIR" diff --git a/lib/esbonio/tests/e2e/test_e2e_diagnostics.py b/lib/esbonio/tests/e2e/test_e2e_diagnostics.py index b869b457e..2c108b9ef 100644 --- a/lib/esbonio/tests/e2e/test_e2e_diagnostics.py +++ b/lib/esbonio/tests/e2e/test_e2e_diagnostics.py @@ -13,7 +13,7 @@ TEST_DIR = pathlib.Path(__file__).parent.parent -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_rst_document_diagnostic(client: LanguageClient, uri_for): """Ensure that we can get the diagnostics for a single rst document correctly.""" @@ -40,7 +40,7 @@ async def test_rst_document_diagnostic(client: LanguageClient, uri_for): assert len(client.diagnostics) == 0, "Server should not publish diagnostics" -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_myst_document_diagnostic(client: LanguageClient, uri_for): """Ensure that we can get the diagnostics for a single myst document correctly.""" @@ -67,7 +67,7 @@ async def test_myst_document_diagnostic(client: LanguageClient, uri_for): assert len(client.diagnostics) == 0, "Server should not publish diagnostics" -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_workspace_diagnostic(client: LanguageClient, uri_for): """Ensure that we can get diagnostics for the whole workspace correctly.""" report = await client.workspace_diagnostic_async( @@ -172,7 +172,7 @@ async def pub_client(lsp_client: LanguageClient, uri_for, tmp_path_factory): print("Gave up waiting for process to exit") -@pytest.mark.asyncio(scope="module") +@pytest.mark.asyncio(loop_scope="module") async def test_publish_diagnostics(pub_client: LanguageClient, uri_for): """Ensure that the server publishes the diagnostics it finds""" workspace_uri = uri_for("workspaces", "demo") diff --git a/lib/esbonio/tests/e2e/test_e2e_directives.py b/lib/esbonio/tests/e2e/test_e2e_directives.py index 7f1e67767..7b2ed3b7b 100644 --- a/lib/esbonio/tests/e2e/test_e2e_directives.py +++ b/lib/esbonio/tests/e2e/test_e2e_directives.py @@ -55,7 +55,7 @@ (" .. c:", RST_EXPECTED, RST_UNEXPECTED), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_rst_directive_completions( client: LanguageClient, uri_for, @@ -92,7 +92,7 @@ async def test_rst_directive_completions( types.DidChangeTextDocumentParams( text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2), content_changes=[ - types.TextDocumentContentChangeEvent_Type1( + types.TextDocumentContentChangePartial( text=text, range=types.Range( start=types.Position(line=linum, character=0), @@ -150,7 +150,7 @@ async def test_rst_directive_completions( (" ```{c:", MYST_EXPECTED, MYST_UNEXPECTED), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_myst_directive_completions( client: LanguageClient, uri_for, @@ -186,7 +186,7 @@ async def test_myst_directive_completions( types.DidChangeTextDocumentParams( text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2), content_changes=[ - types.TextDocumentContentChangeEvent_Type1( + types.TextDocumentContentChangePartial( text=text, range=types.Range( start=types.Position(line=linum, character=0), diff --git a/lib/esbonio/tests/e2e/test_e2e_roles.py b/lib/esbonio/tests/e2e/test_e2e_roles.py index 3558bb4d4..1831fa490 100644 --- a/lib/esbonio/tests/e2e/test_e2e_roles.py +++ b/lib/esbonio/tests/e2e/test_e2e_roles.py @@ -52,7 +52,7 @@ ("(:c:func", EXPECTED, UNEXPECTED), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_rst_role_completions( client: LanguageClient, uri_for, @@ -88,7 +88,7 @@ async def test_rst_role_completions( types.DidChangeTextDocumentParams( text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2), content_changes=[ - types.TextDocumentContentChangeEvent_Type1( + types.TextDocumentContentChangePartial( text=text, range=types.Range( start=types.Position(line=linum, character=0), @@ -160,7 +160,7 @@ async def test_rst_role_completions( (":py:func:`", {"counters.pattern.count_numbers"}, set()), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_rst_role_target_completions( client: LanguageClient, uri_for, @@ -197,7 +197,7 @@ async def test_rst_role_target_completions( types.DidChangeTextDocumentParams( text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2), content_changes=[ - types.TextDocumentContentChangeEvent_Type1( + types.TextDocumentContentChangePartial( text=text, range=types.Range( start=types.Position(line=linum, character=0), @@ -249,7 +249,7 @@ async def test_rst_role_target_completions( ("({c:func", EXPECTED, UNEXPECTED), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_myst_role_completions( client: LanguageClient, uri_for, @@ -285,7 +285,7 @@ async def test_myst_role_completions( types.DidChangeTextDocumentParams( text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2), content_changes=[ - types.TextDocumentContentChangeEvent_Type1( + types.TextDocumentContentChangePartial( text=text, range=types.Range( start=types.Position(line=linum, character=0), @@ -357,7 +357,7 @@ async def test_myst_role_completions( ("{py:func}`", {"counters.pattern.count_numbers"}, set()), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_myst_role_target_completions( client: LanguageClient, uri_for, @@ -393,7 +393,7 @@ async def test_myst_role_target_completions( types.DidChangeTextDocumentParams( text_document=types.VersionedTextDocumentIdentifier(uri=uri, version=2), content_changes=[ - types.TextDocumentContentChangeEvent_Type1( + types.TextDocumentContentChangePartial( text=text, range=types.Range( start=types.Position(line=linum, character=0), diff --git a/lib/esbonio/tests/e2e/test_e2e_symbols.py b/lib/esbonio/tests/e2e/test_e2e_symbols.py index ef2990091..0cbd98b48 100644 --- a/lib/esbonio/tests/e2e/test_e2e_symbols.py +++ b/lib/esbonio/tests/e2e/test_e2e_symbols.py @@ -94,7 +94,7 @@ def document_symbol( ), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_document_symbols( client: LanguageClient, uri_for, @@ -242,7 +242,7 @@ async def test_document_symbols( ("--not-a-real-symbol-name--", None), ], ) -@pytest.mark.asyncio(scope="session") +@pytest.mark.asyncio(loop_scope="session") async def test_workspace_symbols( client: LanguageClient, query: str, diff --git a/lib/esbonio/tests/e2e/test_sphinx_manager.py b/lib/esbonio/tests/e2e/test_sphinx_manager.py index 66840409d..52acc8183 100644 --- a/lib/esbonio/tests/e2e/test_sphinx_manager.py +++ b/lib/esbonio/tests/e2e/test_sphinx_manager.py @@ -46,7 +46,7 @@ async def server_manager(demo_workspace: Uri, docs_workspace): loop = asyncio.get_running_loop() esbonio = create_language_server(EsbonioLanguageServer, [], loop=loop) - esbonio.lsp.transport = StdOutTransportAdapter(io.BytesIO(), sys.stderr.buffer) + esbonio.protocol.transport = StdOutTransportAdapter(io.BytesIO(), sys.stderr.buffer) project_manager = ProjectManager(esbonio) esbonio.add_feature(project_manager) @@ -58,7 +58,7 @@ async def server_manager(demo_workspace: Uri, docs_workspace): def initialize(init_options): # Initialize the server. - esbonio.lsp._procedure_handler( + esbonio.protocol._procedure_handler( lsp.InitializeRequest( id=1, params=lsp.InitializeParams( @@ -72,7 +72,7 @@ def initialize(init_options): ) ) - esbonio.lsp._procedure_handler( + esbonio.protocol._procedure_handler( lsp.InitializedNotification(params=lsp.InitializedParams()) ) return esbonio, sphinx_manager diff --git a/lib/esbonio/tests/server/test_configuration.py b/lib/esbonio/tests/server/test_configuration.py index b72f47df0..00da608cd 100644 --- a/lib/esbonio/tests/server/test_configuration.py +++ b/lib/esbonio/tests/server/test_configuration.py @@ -472,7 +472,7 @@ def test_get_configuration( for idx, uri in enumerate(workspace_config.keys()) if uri != "" ] - server.lsp._workspace = Workspace(None, workspace_folders=workspace_folders) + server.protocol._workspace = Workspace(None, workspace_folders=workspace_folders) scope_uri = Uri.parse(scope) if scope else None diff --git a/lib/esbonio/tests/sphinx-agent/test_sa_build.py b/lib/esbonio/tests/sphinx-agent/test_sa_build.py index c77a30b63..3c6cef6e2 100644 --- a/lib/esbonio/tests/sphinx-agent/test_sa_build.py +++ b/lib/esbonio/tests/sphinx-agent/test_sa_build.py @@ -67,7 +67,7 @@ async def test_build_content_override(client: SubprocessSphinxClient, uri_for): assert expected in index_html.read_text() -@pytest_asyncio.fixture(scope="module") +@pytest_asyncio.fixture(scope="module", loop_scope="module") async def client_build_error(uri_for, tmp_path_factory): """A sphinx client that will error when a build is triggered.""" build_dir = tmp_path_factory.mktemp("build") @@ -105,7 +105,7 @@ async def client_build_error(uri_for, tmp_path_factory): await sphinx_client.stop() -@pytest.mark.asyncio(scope="module") +@pytest.mark.asyncio(loop_scope="module") async def test_build_error(client_build_error: SubprocessSphinxClient): """Ensure that when a build error occurs, useful information is reported."""