From 54214538f350fe9ed3f9572cbe29cbd2d434eff1 Mon Sep 17 00:00:00 2001 From: Dhruv Manilawala Date: Wed, 14 Aug 2024 17:48:34 +0530 Subject: [PATCH] Address review suggestions, update rule docs --- .../rules/useless_comparison.rs | 6 +-- .../rules/useless_expression.rs | 6 +-- .../rules/module_import_not_at_top_of_file.rs | 5 +- .../src/rules/pydocstyle/rules/not_missing.rs | 2 + docs/configuration.md | 47 +++++++++++++++++-- 5 files changed, 55 insertions(+), 11 deletions(-) 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 373ef37732b6e0..2ef88e7c3ef822 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,6 +10,9 @@ 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 @@ -43,9 +46,6 @@ impl Violation for UselessComparison { /// B015 pub(crate) fn useless_comparison(checker: &mut Checker, expr: &Expr) { if expr.is_compare_expr() { - // For Jupyter Notebooks, ignore 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. if checker.source_type.is_ipynb() && at_last_top_level_expression_in_cell( checker.semantic(), 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 7da0a109035b7d..c51bf49f79e7c8 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,6 +11,9 @@ 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 @@ -81,9 +84,6 @@ pub(crate) fn useless_expression(checker: &mut Checker, value: &Expr) { return; } - // For Jupyter Notebooks, ignore 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. if checker.source_type.is_ipynb() && at_last_top_level_expression_in_cell( checker.semantic(), 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 db5b213bc9b17c..d7270903c6b732 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 @@ -6,8 +6,9 @@ use ruff_text_size::Ranged; 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. +/// 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 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 347e0a6a833043..9b444d56fe0411 100644 --- a/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs +++ b/crates/ruff_linter/src/rules/pydocstyle/rules/not_missing.rs @@ -10,6 +10,8 @@ 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. /// diff --git a/docs/configuration.md b/docs/configuration.md index 8aaeb2fbfaec1f..9475c5209f9930 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -367,9 +367,8 @@ You can also change the default selection using the [`include`](settings.md#incl Ruff has built-in support for linting and formatting [Jupyter Notebooks](https://jupyter.org/). !!! info - Notebooks are linted and formatted by default from Ruff version `0.6.0` onwards which marks - Jupyter Notebook support as stable. You can opt-out of linting and formatting notebooks by - adding `*.ipynb` to [`extend-exclude`](settings.md#extend-exclude). + Jupyter Notebook support is marked as stable from Ruff version `0.6.0` onwards and will + be linted and formatted by default. 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 @@ -405,6 +404,48 @@ And, conversely, the following would only format Jupyter Notebook files and not exclude = ["*.ipynb"] ``` +You can completely disable Jupyter Notebook support by updating the +[`extend-exclude`](settings.md#extend-exclude) settings: + +=== "pyproject.toml" + + ```toml + [tool.ruff] + extend-exclude = ["*.ipynb"] + ``` + +=== "ruff.toml" + + ```toml + extend-exclude = ["*.ipynb"] + ``` + +### Rule Selection + +Ruff uses the default rule set for both Python and Jupyter Notebook files. If you'd like to +customize the rule set specifically for Jupyter Notebook files, you can do so by using the +[`per-file-ignores`](settings.md#per-file-ignores) setting: + +=== "pyproject.toml" + + ```toml + [tool.ruff.lint.per-file-ignores] + "*.ipynb" = ["T20"] + ``` + +=== "ruff.toml" + + ```toml + [lint.per-file-ignores] + "*.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. + ## Command-line interface Some configuration options can be provided or overridden via dedicated flags on the command line.