Skip to content

Commit b30acab

Browse files
Copilotrchiodo
andcommitted
Filter newly-added cells by kind in notebook_did_change; add test
Co-authored-by: rchiodo <19672699+rchiodo@users.noreply.github.com>
1 parent b3f93c9 commit b30acab

2 files changed

Lines changed: 112 additions & 1 deletion

File tree

bundled/tool/lsp_server.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,17 @@ def notebook_did_change(params: lsp.DidChangeNotebookDocumentParams) -> None:
167167
lsp.PublishDiagnosticsParams(uri=document.uri, diagnostics=diagnostics)
168168
)
169169

170-
# Lint newly added cells.
170+
# Lint newly added cells (code cells only).
171171
if change.cells and change.cells.structure and change.cells.structure.did_open:
172+
# Build a URI→cell map so we can check each cell's kind before linting.
173+
cell_kind_by_uri = {
174+
cell.document: cell.kind
175+
for cell in nb.cells
176+
if cell.document is not None
177+
}
172178
for cell_doc in change.cells.structure.did_open:
179+
if cell_kind_by_uri.get(cell_doc.uri) != lsp.NotebookCellKind.Code:
180+
continue
173181
document = LSP_SERVER.workspace.get_text_document(cell_doc.uri)
174182
diagnostics = _linting_helper(document)
175183
LSP_SERVER.text_document_publish_diagnostics(

src/test/python_tests/test_notebook.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,109 @@ def _handler(params):
269269
), f"Expected diagnostics for {cell_uri!r}, got: {received}"
270270

271271

272+
def test_notebook_did_change_new_cell_kind_filter():
273+
"""Diagnostics are only published for newly added code cells, not markdown cells.
274+
275+
When a notebook change adds both a code cell and a markdown cell via
276+
structure.did_open, only the code cell should receive diagnostics.
277+
"""
278+
nb_path = str(constants.TEST_DATA / "sample1" / "sample.ipynb")
279+
nb_uri = _make_notebook_uri(nb_path)
280+
code_cell_id = "cell_code"
281+
md_cell_id = "cell_md"
282+
code_cell_uri = _make_cell_uri(nb_path, code_cell_id)
283+
md_cell_uri = _make_cell_uri(nb_path, md_cell_id)
284+
285+
with session.LspSession() as ls_session:
286+
ls_session.initialize(defaults.VSCODE_DEFAULT_INITIALIZE)
287+
288+
# Open an initially empty notebook
289+
ls_session.notify_notebook_did_open(
290+
{
291+
"notebookDocument": {
292+
"uri": nb_uri,
293+
"notebookType": "jupyter-notebook",
294+
"version": 1,
295+
"metadata": {},
296+
"cells": [],
297+
},
298+
"cellTextDocuments": [],
299+
}
300+
)
301+
302+
received = []
303+
done = Event()
304+
305+
def _handler(params):
306+
received.append(params)
307+
done.set()
308+
309+
ls_session.set_notification_callback(session.PUBLISH_DIAGNOSTICS, _handler)
310+
311+
# Add both a code cell (kind=2) and a markdown cell (kind=1) at once
312+
ls_session.notify_notebook_did_change(
313+
{
314+
"notebookDocument": {
315+
"uri": nb_uri,
316+
"version": 2,
317+
},
318+
"change": {
319+
"metadata": None,
320+
"cells": {
321+
"structure": {
322+
"array": {
323+
"start": 0,
324+
"deleteCount": 0,
325+
"cells": [
326+
{
327+
"kind": 2, # Code
328+
"document": code_cell_uri,
329+
"metadata": {},
330+
"executionSummary": None,
331+
},
332+
{
333+
"kind": 1, # Markdown
334+
"document": md_cell_uri,
335+
"metadata": {},
336+
"executionSummary": None,
337+
},
338+
],
339+
},
340+
"didOpen": [
341+
{
342+
"uri": code_cell_uri,
343+
"languageId": "python",
344+
"version": 1,
345+
"text": "x = 1\n",
346+
},
347+
{
348+
"uri": md_cell_uri,
349+
"languageId": "markdown",
350+
"version": 1,
351+
"text": "# heading\n",
352+
},
353+
],
354+
"didClose": None,
355+
},
356+
"data": None,
357+
"textContent": None,
358+
},
359+
},
360+
}
361+
)
362+
363+
done.wait(TIMEOUT)
364+
365+
# The code cell should receive diagnostics; the markdown cell must not.
366+
uris_with_diagnostics = {r.get("uri") for r in received}
367+
assert code_cell_uri in uris_with_diagnostics, (
368+
f"Expected diagnostics for code cell {code_cell_uri!r}, got: {received}"
369+
)
370+
assert md_cell_uri not in uris_with_diagnostics, (
371+
f"Markdown cell {md_cell_uri!r} should not receive diagnostics, got: {received}"
372+
)
373+
374+
272375
def test_notebook_did_close():
273376
"""Diagnostics are cleared for all cells when a notebook is closed.
274377

0 commit comments

Comments
 (0)