Skip to content

Commit 6959698

Browse files
committed
Do not raise on missing contentChanges in didSave
1 parent fe8bbe2 commit 6959698

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

py_src/jupyter_lsp/tests/test_virtual_documents_shadow.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ def did_change(uri, changes: List):
6060
}
6161

6262

63+
def did_save_with_text(uri, text):
64+
return {
65+
"method": "textDocument/didSave",
66+
"params": {"textDocument": {"uri": uri, "text": text}},
67+
}
68+
69+
70+
def did_save_without_text(uri):
71+
return {"method": "textDocument/didSave", "params": {"textDocument": {"uri": uri}}}
72+
73+
6374
@pytest.fixture
6475
def shadow_path(tmpdir):
6576
return str(tmpdir.mkdir(".virtual_documents"))
@@ -71,6 +82,7 @@ def shadow_path(tmpdir):
7182
[
7283
[did_open, "content\nof\nopened\nfile", "content\nof\nopened\nfile"],
7384
[did_change, [{"text": "content after change"}], "content after change"],
85+
[did_save_with_text, "content at save", "content at save"],
7486
],
7587
)
7688
async def test_shadow(shadow_path, message_func, content, expected_content):
@@ -89,6 +101,7 @@ async def test_shadow(shadow_path, message_func, content, expected_content):
89101
async def test_shadow_failures(shadow_path):
90102

91103
shadow = setup_shadow_filesystem(Path(shadow_path).as_uri())
104+
ok_file_uri = (Path(shadow_path) / "test.py").as_uri()
92105

93106
def run_shadow(message):
94107
return shadow("client", message, ["python"], None)
@@ -110,3 +123,16 @@ def run_shadow(message):
110123
# should NOT intercept (nor shadow) files from location other than shadow_path
111124
result = await run_shadow(did_open("file:///other/path.py", "content"))
112125
assert result is None
126+
127+
# should fail silently on missing text in didSave
128+
result = await run_shadow(did_save_without_text(ok_file_uri))
129+
assert result is None
130+
131+
# should raise on missing changes in didChange
132+
with pytest.raises(ShadowFilesystemError, match=".* is missing contentChanges"):
133+
await run_shadow(
134+
{
135+
"method": "textDocument/didChange",
136+
"params": {"textDocument": {"uri": ok_file_uri}},
137+
}
138+
)

py_src/jupyter_lsp/virtual_documents_shadow.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,21 @@ async def shadow_virtual_documents(scope, message, languages, manager):
130130
text = extract_or_none(document, ["text"])
131131

132132
if text is not None:
133+
# didOpen and didSave may provide text within the document
133134
changes = [{"text": text}]
134135
else:
136+
# didChange is the only one which can also provide it in params (as contentChanges)
137+
if message["method"] != "textDocument/didChange":
138+
return
139+
if "contentChanges" not in message["params"]:
140+
raise ShadowFilesystemError(
141+
"textDocument/didChange is missing contentChanges"
142+
)
135143
changes = message["params"]["contentChanges"]
136144

137145
if len(changes) > 1:
138146
manager.log.warn( # pragma: no cover
139-
"LSP warning: up to one change" " supported for textDocument/didChange"
147+
"LSP warning: up to one change supported for textDocument/didChange"
140148
)
141149

142150
for change in changes[:1]:

0 commit comments

Comments
 (0)