diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs index 2ef88e7c3ef822..d9d217799f7489 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_comparison.rs @@ -10,9 +10,6 @@ use super::super::helpers::at_last_top_level_expression_in_cell; /// ## What it does /// Checks for useless comparisons. /// -/// For Jupyter Notebooks, this rule ignores to check the last top-level expression for each cell. -/// This is because it's common to have a cell that ends with an expression to display it's value. -/// /// ## Why is this bad? /// Useless comparisons have no effect on the program, and are often included /// by mistake. If the comparison is intended to enforce an invariant, prepend @@ -28,6 +25,11 @@ use super::super::helpers::at_last_top_level_expression_in_cell; /// assert foo == bar, "`foo` and `bar` should be equal." /// ``` /// +/// ## Notebook behavior +/// For Jupyter Notebooks, this rule is not applied to the last top-level expression in a cell. +/// This is because it's common to have a notebook cell that ends with an expression, +/// which will result in the `repr` of the evaluated expression being printed as the cell's output. +/// /// ## References /// - [Python documentation: `assert` statement](https://docs.python.org/3/reference/simple_stmts.html#the-assert-statement) #[violation] diff --git a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs index c51bf49f79e7c8..a431bb1d92c697 100644 --- a/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs +++ b/crates/ruff_linter/src/rules/flake8_bugbear/rules/useless_expression.rs @@ -11,9 +11,6 @@ use super::super::helpers::at_last_top_level_expression_in_cell; /// ## What it does /// Checks for useless expressions. /// -/// For Jupyter Notebooks, this rule ignores to check the last top-level expression for each cell. -/// This is because it's common to have a cell that ends with an expression to display it's value. -/// /// ## Why is this bad? /// Useless expressions have no effect on the program, and are often included /// by mistake. Assign a useless expression to a variable, or remove it @@ -29,6 +26,11 @@ use super::super::helpers::at_last_top_level_expression_in_cell; /// foo = 1 + 1 /// ``` /// +/// ## Notebook behavior +/// For Jupyter Notebooks, this rule is not applied to the last top-level expression in a cell. +/// This is because it's common to have a notebook cell that ends with an expression, +/// which will result in the `repr` of the evaluated expression being printed as the cell's output. +/// /// ## Known problems /// This rule ignores expression types that are commonly used for their side /// effects, such as function calls. diff --git a/crates/ruff_linter/src/rules/pycodestyle/rules/module_import_not_at_top_of_file.rs b/crates/ruff_linter/src/rules/pycodestyle/rules/module_import_not_at_top_of_file.rs index d7270903c6b732..6e923f12d80787 100644 --- a/crates/ruff_linter/src/rules/pycodestyle/rules/module_import_not_at_top_of_file.rs +++ b/crates/ruff_linter/src/rules/pycodestyle/rules/module_import_not_at_top_of_file.rs @@ -8,8 +8,6 @@ use crate::checkers::ast::Checker; /// ## What it does /// Checks for imports that are not at the top of the file. /// -/// For Jupyter notebooks, this checks for imports that are not at the top of the cell. -/// /// ## Why is this bad? /// According to [PEP 8], "imports are always put at the top of the file, just after any /// module comments and docstrings, and before module globals and constants." @@ -37,6 +35,9 @@ use crate::checkers::ast::Checker; /// a = 1 /// ``` /// +/// ## Notebook behavior +/// For Jupyter notebooks, this rule checks for imports that are not at the top of a *cell*. +/// /// [PEP 8]: https://peps.python.org/pep-0008/#imports #[violation] pub struct ModuleImportNotAtTopOfFile { diff --git a/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs b/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs index 9b444d56fe0411..a2b2a806f9d1e0 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs @@ -10,8 +10,6 @@ use ruff_text_size::TextRange; use crate::checkers::ast::Checker; use crate::registry::Rule; -/// This rule is ignored for Jupyter Notebooks. -/// /// ## What it does /// Checks for undocumented public module definitions. /// @@ -55,6 +53,9 @@ use crate::registry::Rule; /// def calculate_speed(distance: float, time: float) -> float: ... /// ``` /// +/// ## Notebook behavior +/// This rule is ignored for Jupyter Notebooks. +/// /// ## References /// - [PEP 257 – Docstring Conventions](https://peps.python.org/pep-0257/) /// - [PEP 287 – reStructuredText Docstring Format](https://peps.python.org/pep-0287/) diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index eb7e066f8c849e..775c53e0fe7207 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -241,8 +241,9 @@ pub struct Options { /// included here not for configuration but because we lint whether e.g. the /// `[project]` matches the schema. /// - /// Starting from Ruff version 0.6.0, the default also includes notebook files (`.ipynb` - /// extension). + /// Notebook files (`.ipynb` extension) are included by default on Ruff 0.6.0+. + /// On older versions, they are included by default only if + /// [preview](https://docs.astral.sh/ruff/preview/) mode is enabled. /// /// For more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax). #[option( diff --git a/docs/configuration.md b/docs/configuration.md index e3022cac9813ae..6f2ee8e638dcc2 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -364,14 +364,11 @@ You can also change the default selection using the [`include`](settings.md#incl ## Jupyter Notebook discovery -Ruff has built-in support for linting and formatting [Jupyter Notebooks](https://jupyter.org/). - -!!! info - Jupyter Notebook support is marked as stable from Ruff version `0.6.0` onwards and will - be linted and formatted by default. +Ruff has built-in support for linting and formatting [Jupyter Notebooks](https://jupyter.org/), +which are linted and formatted by default on version `0.6.0` and higher. If you'd prefer to either only lint or only format Jupyter Notebook files, you can use the -section specific `exclude` option to do so. For example, the following would only lint Jupyter +section-specific `exclude` option to do so. For example, the following would only lint Jupyter Notebook files and not format them: === "pyproject.toml" @@ -405,7 +402,7 @@ And, conversely, the following would only format Jupyter Notebook files and not ``` You can completely disable Jupyter Notebook support by updating the -[`extend-exclude`](settings.md#extend-exclude) settings: +[`extend-exclude`](settings.md#extend-exclude) setting: === "pyproject.toml" @@ -437,11 +434,12 @@ using the [`per-file-ignores`](settings.md#per-file-ignores) setting: "*.ipynb" = ["T20"] ``` -There are certain rules that has different behavior when applied to Jupyter Notebook files. For -example, the [`module-import-not-at-top-of-file` (`E402`)](rules/module-import-not-at-top-of-file.md) -rule works at the cell level where the rule is violated only if an import statement is not at the -top of the **cell**. The rule documentation will specify if it has different behavior for Jupyter -Notebook files. +Some rules have different behavior when applied to Jupyter Notebook files. For +example, when applied to `.py` files the +[`module-import-not-at-top-of-file` (`E402`)](rules/module-import-not-at-top-of-file.md) +rule detect imports at the top of a file, but for notebooks it detects imports at the top of a +**cell**. For a given rule, the rule's documentation will always specify if it has different +behavior when applied to Jupyter Notebook files. ## Command-line interface diff --git a/ruff.schema.json b/ruff.schema.json index 84ba27de34a0a3..4492656684b7f9 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -444,7 +444,7 @@ ] }, "include": { - "description": "A list of file patterns to include when linting.\n\nInclusion are based on globs, and should be single-path patterns, like `*.pyw`, to include any file with the `.pyw` extension. `pyproject.toml` is included here not for configuration but because we lint whether e.g. the `[project]` matches the schema.\n\nStarting from Ruff version 0.6.0, the default also includes notebook files (`.ipynb` extension).\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", + "description": "A list of file patterns to include when linting.\n\nInclusion are based on globs, and should be single-path patterns, like `*.pyw`, to include any file with the `.pyw` extension. `pyproject.toml` is included here not for configuration but because we lint whether e.g. the `[project]` matches the schema.\n\nNotebook files (`.ipynb` extension) are included by default on Ruff 0.6.0+. On older versions, they are included by default only if [preview](https://docs.astral.sh/ruff/preview/) mode is enabled.\n\nFor more information on the glob syntax, refer to the [`globset` documentation](https://docs.rs/globset/latest/globset/#syntax).", "type": [ "array", "null"