Skip to content

Commit

Permalink
Experimental release for Jupyter notebook integration (#5363)
Browse files Browse the repository at this point in the history
## Summary

Experimental release for Jupyter Notebook integration.

Currently, this requires a user to explicitly opt-in using the
[include](https://beta.ruff.rs/docs/settings/#include) configuration:

```toml
[tool.ruff]
include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"]
```

Or, a user can pass in the file directly:

```sh
ruff check path/to/notebook.ipynb
```

For known limitations, please refer #5188 

## Test Plan

Following command should work without the `--all-features` flag:

```sh
cargo dev round-trip /path/to/notebook.ipynb
```

Following command should work with the above config file along with
`select = ["ALL"]`:

```sh
cargo run --bin ruff -- check --no-cache --config=../test-repos/openai-cookbook/pyproject.toml --fix ../test-repos/openai-cookbook/
```

Passing the Jupyter notebook directly:

```sh
cargo run --bin ruff -- check --no-cache --isolated --select=ALL --fix ../test-repos/openai-cookbook/examples/Classification_using_embeddings.ipynb
```
  • Loading branch information
dhruvmanila committed Jun 26, 2023
1 parent fa1b85b commit 2fc38d8
Show file tree
Hide file tree
Showing 8 changed files with 21 additions and 29 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion crates/ruff/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,3 @@ colored = { workspace = true, features = ["no-color"] }
[features]
default = []
schemars = ["dep:schemars"]
jupyter_notebook = []
21 changes: 0 additions & 21 deletions crates/ruff/src/jupyter/notebook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@ pub fn round_trip(path: &Path) -> anyhow::Result<String> {
Ok(String::from_utf8(writer)?)
}

/// Return `true` if the [`Path`] appears to be that of a jupyter notebook file (`.ipynb`).
pub fn is_jupyter_notebook(path: &Path) -> bool {
path.extension()
.map_or(false, |ext| ext == JUPYTER_NOTEBOOK_EXT)
// For now this is feature gated here, the long term solution depends on
// https://github.com/astral-sh/ruff/issues/3410
&& cfg!(feature = "jupyter_notebook")
}

impl Cell {
/// Return the [`SourceValue`] of the cell.
fn source(&self) -> &SourceValue {
Expand Down Expand Up @@ -452,8 +443,6 @@ mod tests {
use test_case::test_case;

use crate::jupyter::index::JupyterIndex;
#[cfg(feature = "jupyter_notebook")]
use crate::jupyter::is_jupyter_notebook;
use crate::jupyter::schema::Cell;
use crate::jupyter::Notebook;
use crate::registry::Rule;
Expand Down Expand Up @@ -512,16 +501,6 @@ mod tests {
Ok(())
}

#[test]
#[cfg(feature = "jupyter_notebook")]
fn inclusions() {
let path = Path::new("foo/bar/baz");
assert!(!is_jupyter_notebook(path));

let path = Path::new("foo/bar/baz.ipynb");
assert!(is_jupyter_notebook(path));
}

#[test]
fn test_concat_notebook() -> Result<()> {
let notebook = read_jupyter_notebook(Path::new("valid.ipynb"))?;
Expand Down
3 changes: 0 additions & 3 deletions crates/ruff_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ wild = { version = "2" }
assert_cmd = { version = "2.0.8" }
ureq = { version = "2.6.2", features = [] }

[features]
jupyter_notebook = ["ruff/jupyter_notebook"]

[target.'cfg(target_os = "windows")'.dependencies]
mimalloc = "0.1.34"

Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_cli/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_hash::FxHashMap;
use similar::TextDiff;

use ruff::fs;
use ruff::jupyter::{is_jupyter_notebook, Notebook};
use ruff::jupyter::Notebook;
use ruff::linter::{lint_fix, lint_only, FixTable, FixerResult, LinterResult};
use ruff::logging::DisplayParseError;
use ruff::message::Message;
Expand All @@ -23,7 +23,7 @@ use ruff::settings::{flags, AllSettings, Settings};
use ruff::source_kind::SourceKind;
use ruff_python_ast::imports::ImportMap;
use ruff_python_ast::source_code::{LineIndex, SourceCode, SourceFileBuilder};
use ruff_python_stdlib::path::is_project_toml;
use ruff_python_stdlib::path::{is_jupyter_notebook, is_project_toml};

use crate::cache::Cache;

Expand Down
1 change: 1 addition & 0 deletions crates/ruff_dev/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ruff = { path = "../ruff", features = ["schemars"] }
ruff_cli = { path = "../ruff_cli" }
ruff_diagnostics = { path = "../ruff_diagnostics" }
ruff_python_formatter = { path = "../ruff_python_formatter" }
ruff_python_stdlib = { path = "../ruff_python_stdlib" }
ruff_textwrap = { path = "../ruff_textwrap" }

anyhow = { workspace = true }
Expand Down
3 changes: 2 additions & 1 deletion crates/ruff_dev/src/round_trip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use anyhow::Result;

use ruff::jupyter;
use ruff::round_trip;
use ruff_python_stdlib::path::is_jupyter_notebook;

#[derive(clap::Args)]
pub(crate) struct Args {
Expand All @@ -18,7 +19,7 @@ pub(crate) struct Args {

pub(crate) fn main(args: &Args) -> Result<()> {
let path = args.file.as_path();
if jupyter::is_jupyter_notebook(path) {
if is_jupyter_notebook(path) {
println!("{}", jupyter::round_trip(path)?);
} else {
let contents = fs::read_to_string(&args.file)?;
Expand Down
16 changes: 15 additions & 1 deletion crates/ruff_python_stdlib/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@ pub fn is_python_stub_file(path: &Path) -> bool {
path.extension().map_or(false, |ext| ext == "pyi")
}

/// Return `true` if the [`Path`] appears to be that of a Jupyter notebook (`.ipynb`).
pub fn is_jupyter_notebook(path: &Path) -> bool {
path.extension().map_or(false, |ext| ext == "ipynb")
}

#[cfg(test)]
mod tests {
use std::path::Path;

use crate::path::is_python_file;
use crate::path::{is_jupyter_notebook, is_python_file};

#[test]
fn inclusions() {
Expand All @@ -37,4 +42,13 @@ mod tests {
let path = Path::new("foo/bar/baz");
assert!(!is_python_file(path));
}

#[test]
fn test_is_jupyter_notebook() {
let path = Path::new("foo/bar/baz.ipynb");
assert!(is_jupyter_notebook(path));

let path = Path::new("foo/bar/baz.py");
assert!(!is_jupyter_notebook(path));
}
}

0 comments on commit 2fc38d8

Please sign in to comment.