mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2026-06-20 01:24:08 +02:00
24ee843945
* gnu/packages/patches/python-lsp-server-python-3.13-compatibility.patch: Add patch, taken from upstream pull request 692. * gnu/local.mk: Record patch. * gnu/packages/python-xyz.scm (python-lsp-server)[origin]<patches>: Add patch. Change-Id: Ia310b621afbf6a30666dcd4ab44365b987afcafa Signed-off-by: Sharlatan Hellseher <sharlatanus@gmail.com>
222 lines
8.2 KiB
Diff
222 lines
8.2 KiB
Diff
From 5097d3ca3f63952273d8f4a7a6fa72fde9d72d2e Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= <mcepl@cepl.eu>
|
|
Date: Tue, 30 Dec 2025 15:43:23 +0100
|
|
Subject: [PATCH 1/3] Fix: Prevent server crash on shutdown if not initialized
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Check if self.config is None in _hook to avoid AttributeError when
|
|
shutdown is called without a prior successful initialize request.
|
|
|
|
Signed-off-by: Matěj Cepl <mcepl@cepl.eu>
|
|
---
|
|
pylsp/python_lsp.py | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/pylsp/python_lsp.py b/pylsp/python_lsp.py
|
|
index bdc072d4..75d9b56a 100644
|
|
--- a/pylsp/python_lsp.py
|
|
+++ b/pylsp/python_lsp.py
|
|
@@ -266,6 +266,8 @@ def _match_uri_to_workspace(self, uri):
|
|
|
|
def _hook(self, hook_name, doc_uri=None, **kwargs):
|
|
"""Calls hook_name and returns a list of results from all registered handlers"""
|
|
+ if self.config is None:
|
|
+ return []
|
|
workspace = self._match_uri_to_workspace(doc_uri)
|
|
doc = workspace.get_document(doc_uri) if doc_uri else None
|
|
hook_handlers = self.config.plugin_manager.subset_hook_caller(
|
|
|
|
From 37f296689966631a8cb4a63212356556efc7733f Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= <mcepl@cepl.eu>
|
|
Date: Tue, 30 Dec 2025 15:46:37 +0100
|
|
Subject: [PATCH 2/3] Tests: Improve robustness and logging
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
- Add exception logging in jedi_completion plugin.
|
|
- Explicitly disable pylsp_rope in autoimport notebook tests to prevent interference.
|
|
- Make flake8 argument assertions more flexible to accommodate local configurations.
|
|
|
|
Signed-off-by: Matěj Cepl <mcepl@cepl.eu>
|
|
---
|
|
pylsp/plugins/jedi_completion.py | 1 +
|
|
test/plugins/test_autoimport.py | 3 +++
|
|
test/plugins/test_flake8_lint.py | 5 +++--
|
|
3 files changed, 7 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/pylsp/plugins/jedi_completion.py b/pylsp/plugins/jedi_completion.py
|
|
index 51c3589c..803b2d98 100644
|
|
--- a/pylsp/plugins/jedi_completion.py
|
|
+++ b/pylsp/plugins/jedi_completion.py
|
|
@@ -230,6 +230,7 @@ def _resolve_completion(completion, d, markup_kind: str, signature_config: dict)
|
|
signature_config=signature_config,
|
|
)
|
|
except Exception:
|
|
+ log.exception("Failed to format docstring")
|
|
docs = ""
|
|
completion["documentation"] = docs
|
|
return completion
|
|
diff --git a/test/plugins/test_autoimport.py b/test/plugins/test_autoimport.py
|
|
index cbe3dde1..84bddac4 100644
|
|
--- a/test/plugins/test_autoimport.py
|
|
+++ b/test/plugins/test_autoimport.py
|
|
@@ -288,6 +288,9 @@ def test_autoimport_code_actions_and_completions_for_notebook_document(
|
|
"enabled": True,
|
|
"completions": {"enabled": True},
|
|
},
|
|
+ "pylsp_rope": {
|
|
+ "enabled": False,
|
|
+ },
|
|
}
|
|
}
|
|
},
|
|
diff --git a/test/plugins/test_flake8_lint.py b/test/plugins/test_flake8_lint.py
|
|
index ad1dc4ff..5ec7bb52 100644
|
|
--- a/test/plugins/test_flake8_lint.py
|
|
+++ b/test/plugins/test_flake8_lint.py
|
|
@@ -195,13 +195,14 @@ def test_flake8_multiline(workspace) -> None:
|
|
call_args = popen_mock.call_args[0][0]
|
|
|
|
init_file = os.path.join("blah", "__init__.py")
|
|
- assert call_args == [
|
|
+ for arg in [
|
|
"flake8",
|
|
"-",
|
|
"--exclude=blah/,file_2.py",
|
|
"--stdin-display-name",
|
|
init_file,
|
|
- ]
|
|
+ ]:
|
|
+ assert arg in call_args
|
|
|
|
os.unlink(os.path.join(workspace.root_path, "setup.cfg"))
|
|
|
|
|
|
From 926f80d23b20f2b02ccbc660d58756c128c417b7 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= <mcepl@cepl.eu>
|
|
Date: Tue, 30 Dec 2025 15:46:40 +0100
|
|
Subject: [PATCH 3/3] Tests: Skip NumPy/Pandas tests if Jedi inference fails
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
In some environments (e.g. NumPy 2.x on Python 3.13), Jedi might
|
|
fail to provide completions, definitions, or hover info.
|
|
Update tests to skip gracefully instead of failing when these
|
|
libraries cannot be analyzed.
|
|
|
|
Signed-off-by: Matěj Cepl <mcepl@cepl.eu>
|
|
---
|
|
test/plugins/test_completion.py | 6 +++++
|
|
test/plugins/test_definitions.py | 5 ++++
|
|
test/plugins/test_hover.py | 42 ++++++++++++++++++--------------
|
|
3 files changed, 35 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/test/plugins/test_completion.py b/test/plugins/test_completion.py
|
|
index ae5021f5..729722c6 100644
|
|
--- a/test/plugins/test_completion.py
|
|
+++ b/test/plugins/test_completion.py
|
|
@@ -297,6 +297,9 @@ def test_numpy_completions(config, workspace) -> None:
|
|
doc = Document(DOC_URI, workspace, doc_numpy)
|
|
items = pylsp_jedi_completions(config, doc, com_position)
|
|
|
|
+ if items is None or len(items) == 0:
|
|
+ pytest.skip("Jedi was unable to find completions for numpy")
|
|
+
|
|
assert items
|
|
assert any("array" in i["label"] for i in items)
|
|
|
|
@@ -307,6 +310,9 @@ def test_pandas_completions(config, workspace) -> None:
|
|
doc = Document(DOC_URI, workspace, doc_pandas)
|
|
items = pylsp_jedi_completions(config, doc, com_position)
|
|
|
|
+ if items is None or len(items) == 0:
|
|
+ pytest.skip("Jedi was unable to find completions for pandas")
|
|
+
|
|
assert items
|
|
assert any("DataFrame" in i["label"] for i in items)
|
|
|
|
diff --git a/test/plugins/test_definitions.py b/test/plugins/test_definitions.py
|
|
index 7923524b..16d96a97 100644
|
|
--- a/test/plugins/test_definitions.py
|
|
+++ b/test/plugins/test_definitions.py
|
|
@@ -97,6 +97,11 @@ def test_numpy_definition(config, workspace) -> None:
|
|
|
|
doc = Document(DOC_URI, workspace, DOC)
|
|
defns = pylsp_definitions(config, doc, cursor_pos)
|
|
+
|
|
+ if not defns:
|
|
+ import pytest
|
|
+ pytest.skip("Jedi was unable to find definitions for numpy.ones")
|
|
+
|
|
assert len(defns) > 0, defns
|
|
|
|
|
|
diff --git a/test/plugins/test_hover.py b/test/plugins/test_hover.py
|
|
index 4c0d75e8..06be446a 100644
|
|
--- a/test/plugins/test_hover.py
|
|
+++ b/test/plugins/test_hover.py
|
|
@@ -40,35 +40,41 @@ def test_numpy_hover(workspace) -> None:
|
|
contents = ""
|
|
assert contents in pylsp_hover(doc._config, doc, no_hov_position)["contents"]
|
|
|
|
+ hover_res = pylsp_hover(doc._config, doc, numpy_hov_position_1)
|
|
+ if hover_res["contents"] == "":
|
|
+ import pytest
|
|
+ pytest.skip("Jedi was unable to find hover information for numpy")
|
|
+
|
|
contents = "NumPy\n=====\n\nProvides\n"
|
|
- assert (
|
|
- contents
|
|
- in pylsp_hover(doc._config, doc, numpy_hov_position_1)["contents"]["value"]
|
|
- )
|
|
+ if isinstance(hover_res["contents"], dict) and "value" in hover_res["contents"]:
|
|
+ assert contents in hover_res["contents"]["value"]
|
|
+ else:
|
|
+ assert contents in hover_res["contents"]
|
|
|
|
contents = "NumPy\n=====\n\nProvides\n"
|
|
- assert (
|
|
- contents
|
|
- in pylsp_hover(doc._config, doc, numpy_hov_position_2)["contents"]["value"]
|
|
- )
|
|
+ hover_res = pylsp_hover(doc._config, doc, numpy_hov_position_2)
|
|
+ if isinstance(hover_res["contents"], dict) and "value" in hover_res["contents"]:
|
|
+ assert contents in hover_res["contents"]["value"]
|
|
+ else:
|
|
+ assert contents in hover_res["contents"]
|
|
|
|
contents = "NumPy\n=====\n\nProvides\n"
|
|
- assert (
|
|
- contents
|
|
- in pylsp_hover(doc._config, doc, numpy_hov_position_3)["contents"]["value"]
|
|
- )
|
|
+ hover_res = pylsp_hover(doc._config, doc, numpy_hov_position_3)
|
|
+ if isinstance(hover_res["contents"], dict) and "value" in hover_res["contents"]:
|
|
+ assert contents in hover_res["contents"]["value"]
|
|
+ else:
|
|
+ assert contents in hover_res["contents"]
|
|
|
|
# https://github.com/davidhalter/jedi/issues/1746
|
|
import numpy as np
|
|
|
|
if np.lib.NumpyVersion(np.__version__) < "1.20.0":
|
|
contents = "Trigonometric sine, element-wise.\n\n"
|
|
- assert (
|
|
- contents
|
|
- in pylsp_hover(doc._config, doc, numpy_sin_hov_position)["contents"][
|
|
- "value"
|
|
- ]
|
|
- )
|
|
+ hover_res = pylsp_hover(doc._config, doc, numpy_sin_hov_position)
|
|
+ if isinstance(hover_res["contents"], dict) and "value" in hover_res["contents"]:
|
|
+ assert contents in hover_res["contents"]["value"]
|
|
+ else:
|
|
+ assert contents in hover_res["contents"]
|
|
|
|
|
|
def test_hover(workspace) -> None:
|