diff --git a/lib/esbonio/changes/866.misc.md b/lib/esbonio/changes/866.misc.md new file mode 100644 index 00000000..3d6e35f6 --- /dev/null +++ b/lib/esbonio/changes/866.misc.md @@ -0,0 +1 @@ +Drop Sphinx `5.x` support, add Sphinx `8.x` support diff --git a/lib/esbonio/esbonio/sphinx_agent/handlers/symbols.py b/lib/esbonio/esbonio/sphinx_agent/handlers/symbols.py index a91c9668..b2196bf0 100644 --- a/lib/esbonio/esbonio/sphinx_agent/handlers/symbols.py +++ b/lib/esbonio/esbonio/sphinx_agent/handlers/symbols.py @@ -66,7 +66,7 @@ def update_symbols(app: Sphinx, docname: str, source): destination=NullOutput(), ) publisher.settings = settings - publisher.set_source(source="\n".join(source), source_path=filename) + publisher.set_source(source="\n".join(source), source_path=str(filename)) publisher.publish() document = publisher.document diff --git a/lib/esbonio/esbonio/sphinx_agent/util.py b/lib/esbonio/esbonio/sphinx_agent/util.py index 66a6a900..4fcc26c0 100644 --- a/lib/esbonio/esbonio/sphinx_agent/util.py +++ b/lib/esbonio/esbonio/sphinx_agent/util.py @@ -13,7 +13,7 @@ def _serialize_message(obj): if dataclasses.is_dataclass(obj): - return dataclasses.asdict(obj) + return dataclasses.asdict(obj) # type: ignore[call-overload] if isinstance(obj, (_TranslationProxy, pathlib.Path)): return str(obj) diff --git a/lib/esbonio/hatch.toml b/lib/esbonio/hatch.toml index 29f7b342..773ca288 100644 --- a/lib/esbonio/hatch.toml +++ b/lib/esbonio/hatch.toml @@ -17,12 +17,12 @@ matrix-name-format = "{variable}{value}" python = ["3.9", "3.10", "3.11", "3.12", "3.13"] [[envs.hatch-test.matrix]] -python = ["3.9", "3.10", "3.11", "3.12"] -sphinx = ["5", "6", "7"] +python = ["3.9", "3.10", "3.11", "3.12", "3.13"] +sphinx = ["6", "7"] [[envs.hatch-test.matrix]] -python = ["3.13"] -sphinx = ["6", "7"] +python = ["3.10", "3.11", "3.12", "3.13"] +sphinx = ["8"] [envs.hatch-test.overrides] @@ -30,9 +30,9 @@ matrix.sphinx.dependencies = [ "furo", "sphinx-design", "myst-parser", - { value = "sphinx>=5,<6", if = ["5"] }, { value = "sphinx>=6,<7", if = ["6"] }, { value = "sphinx>=7,<8", if = ["7"] }, + { value = "sphinx>=8,<9", if = ["8"] }, ] [envs.hatch-test.overrides.matrix.sphinx.default-args] diff --git a/lib/esbonio/tests/e2e/test_e2e_diagnostics.py b/lib/esbonio/tests/e2e/test_e2e_diagnostics.py index 885d81df..e20ba464 100644 --- a/lib/esbonio/tests/e2e/test_e2e_diagnostics.py +++ b/lib/esbonio/tests/e2e/test_e2e_diagnostics.py @@ -6,6 +6,7 @@ from lsprotocol import types from pytest_lsp import ClientServerConfig from pytest_lsp import LanguageClient +from sphinx import version_info as sphinx_version SERVER_CMD = ["-m", "esbonio"] TEST_DIR = pathlib.Path(__file__).parent.parent @@ -25,12 +26,15 @@ async def test_rst_document_diagnostic(client: LanguageClient, uri_for): assert report.kind == "full" + if sphinx_version[0] >= 8: + message = "image file not readable: not-an-image.png [image.not_readable]" + else: + message = "image file not readable: not-an-image.png" + # We will only check the diagnostic message, full details will be handled by other # test cases. messages = {d.message for d in report.items} - assert messages == { - "image file not readable: not-an-image.png", - } + assert messages == {message} assert len(client.diagnostics) == 0, "Server should not publish diagnostics" @@ -49,12 +53,15 @@ async def test_myst_document_diagnostic(client: LanguageClient, uri_for): assert report.kind == "full" + if sphinx_version[0] >= 8: + message = "image file not readable: not-an-image.png [image.not_readable]" + else: + message = "image file not readable: not-an-image.png" + # We will only check the diagnostic message, full details will be handled by other # test cases. messages = {d.message for d in report.items} - assert messages == { - "image file not readable: not-an-image.png", - } + assert messages == {message} assert len(client.diagnostics) == 0, "Server should not publish diagnostics" @@ -66,14 +73,15 @@ async def test_workspace_diagnostic(client: LanguageClient, uri_for): types.WorkspaceDiagnosticParams(previous_result_ids=[]) ) + if sphinx_version[0] >= 8: + message = "image file not readable: not-an-image.png [image.not_readable]" + else: + message = "image file not readable: not-an-image.png" + workspace_uri = uri_for("workspaces", "demo") expected = { - str(workspace_uri / "rst" / "diagnostics.rst"): { - "image file not readable: not-an-image.png", - }, - str(workspace_uri / "myst" / "diagnostics.md"): { - "image file not readable: not-an-image.png", - }, + str(workspace_uri / "rst" / "diagnostics.rst"): {message}, + str(workspace_uri / "myst" / "diagnostics.md"): {message}, } assert len(report.items) == len(expected) for item in report.items: @@ -159,13 +167,15 @@ async def pub_client(lsp_client: LanguageClient, uri_for, tmp_path_factory): 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") + + if sphinx_version[0] >= 8: + message = "image file not readable: not-an-image.png [image.not_readable]" + else: + message = "image file not readable: not-an-image.png" + expected = { - str(workspace_uri / "rst" / "diagnostics.rst"): { - "image file not readable: not-an-image.png", - }, - str(workspace_uri / "myst" / "diagnostics.md"): { - "image file not readable: not-an-image.png", - }, + str(workspace_uri / "rst" / "diagnostics.rst"): {message}, + str(workspace_uri / "myst" / "diagnostics.md"): {message}, } # The server might not have published its diagnostics yet diff --git a/lib/esbonio/tests/sphinx-agent/handlers/test_diagnostics.py b/lib/esbonio/tests/sphinx-agent/handlers/test_diagnostics.py index 41f188da..8994b44b 100644 --- a/lib/esbonio/tests/sphinx-agent/handlers/test_diagnostics.py +++ b/lib/esbonio/tests/sphinx-agent/handlers/test_diagnostics.py @@ -5,6 +5,7 @@ import pytest from pygls.protocol import default_converter +from sphinx import version_info as sphinx_version from esbonio.server import Uri from esbonio.server.features.project_manager import Project @@ -36,10 +37,15 @@ async def test_diagnostics(client: SubprocessSphinxClient, project: Project, uri rst_diagnostics_uri = uri_for("workspaces/demo/rst/diagnostics.rst") myst_diagnostics_uri = uri_for("workspaces/demo/myst/diagnostics.md") + if sphinx_version[0] >= 8: + message = "image file not readable: not-an-image.png [image.not_readable]" + else: + message = "image file not readable: not-an-image.png" + expected = { rst_diagnostics_uri: [ types.Diagnostic( - message="image file not readable: not-an-image.png", + message=message, severity=types.DiagnosticSeverity.Warning, range=types.Range( start=types.Position(line=5, character=0), @@ -49,7 +55,7 @@ async def test_diagnostics(client: SubprocessSphinxClient, project: Project, uri ], myst_diagnostics_uri: [ types.Diagnostic( - message="image file not readable: not-an-image.png", + message=message, severity=types.DiagnosticSeverity.Warning, range=types.Range( start=types.Position(line=0, character=0),