Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ruff server: Support Jupyter Notebook (*.ipynb) files #11206

Merged
merged 21 commits into from
May 21, 2024
Merged

Conversation

snowsignal
Copy link
Contributor

@snowsignal snowsignal commented Apr 29, 2024

Summary

Closes #10858.

ruff server now supports *.ipynb (aka Jupyter Notebook) files. Extensive internal changes have been made to facilitate this, which I've done some work to contextualize with documentation and an pre-review that highlights notable sections of the code.

*.ipynb cells should behave similarly to *.py documents, with one major exception. The format command ruff.applyFormat will only apply to the currently selected notebook cell - if you want to format an entire notebook document, use Format Notebook from the VS Code context menu.

Test Plan

The VS Code extension does not yet have Jupyter Notebook support enabled, so you'll first need to enable it manually. To do this, checkout the pre-release branch and modify src/common/server.ts as follows:

Before:
Screenshot 2024-05-13 at 10 59 06 PM

After:
Screenshot 2024-05-13 at 10 58 24 PM

I recommend testing this PR with large, complicated notebook files. I used notebook files from this popular repository in my preliminary testing.

The main thing to test is ensuring that notebook cells behave the same as Python documents, besides the aforementioned issue with ruff.applyFormat. You should also test adding and deleting cells (in particular, deleting all the code cells and ensure that doesn't break anything), changing the kind of a cell (i.e. from markup -> code or vice versa), and creating a new notebook file from scratch. Finally, you should also test that source actions work as expected (and across the entire notebook).

Note: ruff.applyAutofix and ruff.applyOrganizeImports are currently broken for notebook files, and I suspect it has something to do with #11248. Once this is fixed, I will update the test plan accordingly.

@snowsignal snowsignal added the server Related to the LSP server label Apr 29, 2024
@snowsignal snowsignal added this to the Ruff Server: Beta milestone Apr 29, 2024
Copy link
Contributor

github-actions bot commented Apr 29, 2024

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@snowsignal snowsignal force-pushed the jupyter-notebook branch 5 times, most recently from 3a721e2 to ef8727f Compare May 9, 2024 09:02
@snowsignal snowsignal force-pushed the jupyter-notebook branch 13 times, most recently from 4fb4f0f to a8e00a6 Compare May 14, 2024 05:40
Copy link
Contributor Author

@snowsignal snowsignal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some comments to add context for a few parts of the code and also to remind myself to refactor a few things before we merge 🙂

crates/ruff_server/src/edit/range.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/session/index.rs Show resolved Hide resolved
crates/ruff_server/src/session/index.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/fix.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/lint.rs Show resolved Hide resolved
crates/ruff_server/src/lint.rs Show resolved Hide resolved
crates/ruff_server/src/lint.rs Outdated Show resolved Hide resolved
@snowsignal snowsignal marked this pull request as ready for review May 14, 2024 06:55
Copy link
Member

@dhruvmanila dhruvmanila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've provided some initial comments and I plan to look at other changes soon. It's quite a big PR :)

It would be helpful if you could briefly enumerate all the changes made in the PR description. I'd especially find the list of refactoring useful. It would be also useful for posterity to provide any context on the reasoning behind the implementation and if there were any other solutions that you thought of but didn't implement it.

Can you also update the test plan with all the cases that you've tested this against? Ideally it could contain the VS Code settings used and the action performed (command, code action, etc.). There are so many VS Code settings, commands and code actions for Notebook 😅

crates/ruff_notebook/src/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_notebook/src/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/notebook.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/range.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/edit/range.rs Outdated Show resolved Hide resolved
crates/ruff_server/src/lint.rs Show resolved Hide resolved
Comment on lines 262 to 266
types::NotebookDocumentFilter::ByType {
notebook_type: "jupyter-notebook".to_string(),
scheme: Some("file".to_string()),
pattern: None,
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this specific to VS Code? I'm referring to the "jupyter-notebook" type. For reference, we don't use any notebook document filter in ruff-lsp:

https://github.com/astral-sh/ruff-lsp/blob/b8a48009f35756dc51268beb6bbc39c21a1e3a46/ruff_lsp/server.py#L129-L140

This asks to only send the request to sync the Python code cells as we aren't interested in any kind of cell.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got this from the LSP specification:
Screenshot 2024-05-15 at 9 37 34 PM

I assume this would be the same across editors.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I'm not sure where does the jupyter-notebook type comes from.

I assume this would be the same across editors.

I think it depends - If it is set by VS Code, then I don't think it would be same.

I don't think we need to worry about this now but, just to be on the safer side, I'd probably keep this same as ruff-lsp.

Does this work on unsaved Notebook files? Like, a new notebook file is opened in VS Code but it doesn't exists on disk yet.

Copy link
Contributor Author

@snowsignal snowsignal May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work on unsaved Notebook files? Like, a new notebook file is opened in VS Code but it doesn't exists on disk yet.

This does fail - I think it might be because an unsaved URL isn't a valid file path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm.... it seems like, in general, that the server doesn't support files created from Ctrl+N in VS Code if they aren't saved to the file system. I'll create a follow-up issue for this.

Copy link
Member

@dhruvmanila dhruvmanila May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does fail, but only because new notebook cell url gets passed into didOpenTextDocument, which isn't expected. Do we need to support 'unattached' notebook cells?

I just checked, we do support it. It's probably because we never touch the filesystem in ruff-lsp and always work with stdin with ruff command.

crates/ruff_server/src/server/api.rs Show resolved Hide resolved
crates/ruff_server/src/session.rs Outdated Show resolved Hide resolved
@snowsignal snowsignal enabled auto-merge (squash) May 21, 2024 22:26
@snowsignal snowsignal merged commit b0731ef into main May 21, 2024
18 checks passed
@snowsignal snowsignal deleted the jupyter-notebook branch May 21, 2024 22:29
snowsignal added a commit that referenced this pull request May 22, 2024
…#11492)

## Summary

Recent changes made in the [Jupyter Notebook feature
PR](#11206) caused automatic
configuration reloading to stop working. This was because we would check
for paths to reload using the changed path, when we should have been
using the parent path of the changed path (to get the directory it was
changed in).

Additionally, this PR fixes an issue where `ruff.toml` and `.ruff.toml`
files were not being automatically reloaded.

Finally, this PR improves configuration reloading by actively publishing
diagnostics for notebook documents (which won't be affected by the
workspace refresh since they don't use pull diagnostics). It will also
publish diagnostics for text documents if pull diagnostics aren't
supported.

## Test Plan
To test this, open an existing configuration file in a codebase, and
make modifications that will affect one or more open Python / Jupyter
Notebook files. You should observe that the diagnostics for both kinds
of files update automatically when the file changes are saved.

Here's a test video showing what a successful test should look like:



https://github.com/astral-sh/ruff/assets/19577865/7172b598-d6de-4965-b33c-6cb8b911ef6c
dhruvmanila added a commit that referenced this pull request Jul 30, 2024
## Summary

This PR fixes a bug where the server wouldn't retain the cell content in
case of a reorder change request.

As mentioned in
#12573 (comment),
this change request is modeled as (a) remove these cell URIs and (b) add
these cell URIs. The cell content isn't provided. But, the way we've
modeled the `NotebookCell` (it contains the underlying `TextDocument`),
we need to keep track of the deleted cells to get the content.

This is not an ideal solution and a better long term solution would be
to model it as per the spec but that is a big structural change and will
affect multiple parts of the server. Modeling as per the spec would also
avoid bugs like #11864. For
context, that model would add complexity per
#11206 (comment).

fixes: #12573

## Test Plan

This video shows the before and after the bug is fixed:


https://github.com/user-attachments/assets/2fcad4b5-f9af-4776-8640-4cd1fa16e325
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
server Related to the LSP server
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ruff server: Support .ipynb (Jupyter Notebook) files
3 participants