diff --git a/crates/ruff_linter/resources/test/fixtures/pylint/too_many_boolean_expressions.py b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_boolean_expressions.py new file mode 100644 index 0000000000000..a83f387c6dda8 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pylint/too_many_boolean_expressions.py @@ -0,0 +1,54 @@ +if a: + ... +elif (a and b): + ... +elif (a and b) and c: + ... +elif (a and b) and c and d: + ... +elif (a and b) and c and d and e: + ... +elif (a and b) and c and d and e and f: + ... +elif (a and b) and c and d and e and f and g: + ... +elif (a and b) and c and d and e and f and g and h: + ... +elif (a and b) and c and d and e and f and g and h and i: + ... +elif (a and b) and c and d and e and f and g and h and i and j: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y: + ... +elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y and z: + ... +else: + ... diff --git a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs index a39fd0734355c..5bdbb6b904b3d 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/statement.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/statement.rs @@ -1067,6 +1067,9 @@ pub(crate) fn statement(stmt: &Stmt, checker: &mut Checker) { if checker.enabled(Rule::CheckAndRemoveFromSet) { refurb::rules::check_and_remove_from_set(checker, if_); } + if checker.enabled(Rule::TooManyBooleanExpressions) { + pylint::rules::too_many_boolean_expressions(checker, if_); + } if checker.source_type.is_stub() { if checker.any_enabled(&[ Rule::UnrecognizedVersionInfoCheck, diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index a0722c0741b9b..c43e80ae5283f 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -246,6 +246,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "R0912") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyBranches), (Pylint, "R0913") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyArguments), (Pylint, "R0915") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyStatements), + (Pylint, "R0916") => (RuleGroup::Unspecified, rules::pylint::rules::TooManyBooleanExpressions), (Pylint, "R1701") => (RuleGroup::Unspecified, rules::pylint::rules::RepeatedIsinstanceCalls), (Pylint, "R1711") => (RuleGroup::Unspecified, rules::pylint::rules::UselessReturn), (Pylint, "R1714") => (RuleGroup::Unspecified, rules::pylint::rules::RepeatedEqualityComparison), diff --git a/crates/ruff_linter/src/rules/pylint/mod.rs b/crates/ruff_linter/src/rules/pylint/mod.rs index 21b0c0250f911..10f8fa6d87361 100644 --- a/crates/ruff_linter/src/rules/pylint/mod.rs +++ b/crates/ruff_linter/src/rules/pylint/mod.rs @@ -228,6 +228,22 @@ mod tests { Ok(()) } + #[test] + fn max_boolean_expressions() -> Result<()> { + let diagnostics = test_path( + Path::new("pylint/too_many_boolean_expressions.py"), + &LinterSettings { + pylint: pylint::settings::Settings { + max_bools: 5, + ..pylint::settings::Settings::default() + }, + ..LinterSettings::for_rule(Rule::TooManyBooleanExpressions) + }, + )?; + assert_messages!(diagnostics); + Ok(()) + } + #[test] fn max_statements() -> Result<()> { let diagnostics = test_path( diff --git a/crates/ruff_linter/src/rules/pylint/rules/mod.rs b/crates/ruff_linter/src/rules/pylint/rules/mod.rs index 317657266794b..1d589e18f9694 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/mod.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/mod.rs @@ -43,6 +43,7 @@ pub(crate) use subprocess_popen_preexec_fn::*; pub(crate) use subprocess_run_without_check::*; pub(crate) use sys_exit_alias::*; pub(crate) use too_many_arguments::*; +pub(crate) use too_many_boolean_expressions::*; pub(crate) use too_many_branches::*; pub(crate) use too_many_public_methods::*; pub(crate) use too_many_return_statements::*; @@ -103,6 +104,7 @@ mod subprocess_popen_preexec_fn; mod subprocess_run_without_check; mod sys_exit_alias; mod too_many_arguments; +mod too_many_boolean_expressions; mod too_many_branches; mod too_many_public_methods; mod too_many_return_statements; diff --git a/crates/ruff_linter/src/rules/pylint/rules/too_many_boolean_expressions.rs b/crates/ruff_linter/src/rules/pylint/rules/too_many_boolean_expressions.rs new file mode 100644 index 0000000000000..151dac305c9aa --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/rules/too_many_boolean_expressions.rs @@ -0,0 +1,84 @@ +use ast::{Expr, StmtIf}; +use ruff_diagnostics::{Diagnostic, Violation}; +use ruff_macros::{derive_message_formats, violation}; +use ruff_python_ast::{self as ast}; +use ruff_text_size::Ranged; + +use crate::checkers::ast::Checker; + +/// ## What it does +/// Checks for too many boolean expressions in an `if` statement. +/// +/// ## Why is this bad? +/// Too many boolean expressions in an `if` statement can make the code +/// harder to understand. +/// +/// ## Example +/// ```python +/// if a and b and c and d and e and f and g and h: +/// ... +/// ``` +/// +/// ## Options +/// - `pylint.max-bools` +#[violation] +pub struct TooManyBooleanExpressions { + expressions: usize, + max_expressions: usize, +} + +impl Violation for TooManyBooleanExpressions { + #[derive_message_formats] + fn message(&self) -> String { + let TooManyBooleanExpressions { + expressions, + max_expressions, + } = self; + format!("Too many boolean expressions ({expressions} > {max_expressions})") + } +} + +fn count_bools(expr: &Expr) -> usize { + match expr { + Expr::BoolOp(ast::ExprBoolOp { op, values, .. }) => match op { + ast::BoolOp::And | ast::BoolOp::Or => { + (values.len() - 1) + values.iter().map(count_bools).sum::() + } + }, + Expr::Compare(ast::ExprCompare { + left, comparators, .. + }) => count_bools(left) + comparators.iter().map(count_bools).sum::(), + _ => 0, + } +} + +/// PLR0916 +pub(crate) fn too_many_boolean_expressions(checker: &mut Checker, stmt: &StmtIf) { + let test_bool_count = count_bools(stmt.test.as_ref()); + + if test_bool_count > checker.settings.pylint.max_bools { + checker.diagnostics.push(Diagnostic::new( + TooManyBooleanExpressions { + expressions: test_bool_count, + max_expressions: checker.settings.pylint.max_bools, + }, + stmt.test.as_ref().range(), + )); + } + + for elif in &stmt.elif_else_clauses { + if let Some(test) = elif.test.as_ref() { + let elif_bool_count = count_bools(test); + + if elif_bool_count > checker.settings.pylint.max_bools { + checker.diagnostics.push(Diagnostic::new( + TooManyBooleanExpressions { + expressions: elif_bool_count, + max_expressions: checker.settings.pylint.max_bools, + }, + test.range(), + )); + } + } + } +} diff --git a/crates/ruff_linter/src/rules/pylint/settings.rs b/crates/ruff_linter/src/rules/pylint/settings.rs index e09e4835f8279..430f0549d54a9 100644 --- a/crates/ruff_linter/src/rules/pylint/settings.rs +++ b/crates/ruff_linter/src/rules/pylint/settings.rs @@ -40,6 +40,7 @@ pub struct Settings { pub allow_magic_value_types: Vec, pub max_args: usize, pub max_returns: usize, + pub max_bools: usize, pub max_branches: usize, pub max_statements: usize, pub max_public_methods: usize, @@ -51,6 +52,7 @@ impl Default for Settings { allow_magic_value_types: vec![ConstantType::Str, ConstantType::Bytes], max_args: 5, max_returns: 6, + max_bools: 5, max_branches: 12, max_statements: 50, max_public_methods: 20, diff --git a/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_boolean_expressions.snap b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_boolean_expressions.snap new file mode 100644 index 0000000000000..2d7057ec8ba59 --- /dev/null +++ b/crates/ruff_linter/src/rules/pylint/snapshots/ruff_linter__rules__pylint__tests__max_boolean_expressions.snap @@ -0,0 +1,204 @@ +--- +source: crates/ruff_linter/src/rules/pylint/mod.rs +--- +too_many_boolean_expressions.py:13:6: PLR0916 Too many boolean expressions (6 > 5) + | +11 | elif (a and b) and c and d and e and f: +12 | ... +13 | elif (a and b) and c and d and e and f and g: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +14 | ... +15 | elif (a and b) and c and d and e and f and g and h: + | + +too_many_boolean_expressions.py:15:6: PLR0916 Too many boolean expressions (7 > 5) + | +13 | elif (a and b) and c and d and e and f and g: +14 | ... +15 | elif (a and b) and c and d and e and f and g and h: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +16 | ... +17 | elif (a and b) and c and d and e and f and g and h and i: + | + +too_many_boolean_expressions.py:17:6: PLR0916 Too many boolean expressions (8 > 5) + | +15 | elif (a and b) and c and d and e and f and g and h: +16 | ... +17 | elif (a and b) and c and d and e and f and g and h and i: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +18 | ... +19 | elif (a and b) and c and d and e and f and g and h and i and j: + | + +too_many_boolean_expressions.py:19:6: PLR0916 Too many boolean expressions (9 > 5) + | +17 | elif (a and b) and c and d and e and f and g and h and i: +18 | ... +19 | elif (a and b) and c and d and e and f and g and h and i and j: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +20 | ... +21 | elif (a and b) and c and d and e and f and g and h and i and j and k: + | + +too_many_boolean_expressions.py:21:6: PLR0916 Too many boolean expressions (10 > 5) + | +19 | elif (a and b) and c and d and e and f and g and h and i and j: +20 | ... +21 | elif (a and b) and c and d and e and f and g and h and i and j and k: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +22 | ... +23 | elif (a and b) and c and d and e and f and g and h and i and j and k and l: + | + +too_many_boolean_expressions.py:23:6: PLR0916 Too many boolean expressions (11 > 5) + | +21 | elif (a and b) and c and d and e and f and g and h and i and j and k: +22 | ... +23 | elif (a and b) and c and d and e and f and g and h and i and j and k and l: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +24 | ... +25 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m: + | + +too_many_boolean_expressions.py:25:6: PLR0916 Too many boolean expressions (12 > 5) + | +23 | elif (a and b) and c and d and e and f and g and h and i and j and k and l: +24 | ... +25 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +26 | ... +27 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n: + | + +too_many_boolean_expressions.py:27:6: PLR0916 Too many boolean expressions (13 > 5) + | +25 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m: +26 | ... +27 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +28 | ... +29 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o: + | + +too_many_boolean_expressions.py:29:6: PLR0916 Too many boolean expressions (14 > 5) + | +27 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n: +28 | ... +29 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +30 | ... +31 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p: + | + +too_many_boolean_expressions.py:31:6: PLR0916 Too many boolean expressions (15 > 5) + | +29 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o: +30 | ... +31 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +32 | ... +33 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q: + | + +too_many_boolean_expressions.py:33:6: PLR0916 Too many boolean expressions (16 > 5) + | +31 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p: +32 | ... +33 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +34 | ... +35 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r: + | + +too_many_boolean_expressions.py:35:6: PLR0916 Too many boolean expressions (17 > 5) + | +33 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q: +34 | ... +35 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +36 | ... +37 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s: + | + +too_many_boolean_expressions.py:37:6: PLR0916 Too many boolean expressions (18 > 5) + | +35 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r: +36 | ... +37 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +38 | ... +39 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t: + | + +too_many_boolean_expressions.py:39:6: PLR0916 Too many boolean expressions (19 > 5) + | +37 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s: +38 | ... +39 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +40 | ... +41 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u: + | + +too_many_boolean_expressions.py:41:6: PLR0916 Too many boolean expressions (20 > 5) + | +39 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t: +40 | ... +41 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +42 | ... +43 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v: + | + +too_many_boolean_expressions.py:43:6: PLR0916 Too many boolean expressions (21 > 5) + | +41 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u: +42 | ... +43 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +44 | ... +45 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w: + | + +too_many_boolean_expressions.py:45:6: PLR0916 Too many boolean expressions (22 > 5) + | +43 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v: +44 | ... +45 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +46 | ... +47 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x: + | + +too_many_boolean_expressions.py:47:6: PLR0916 Too many boolean expressions (23 > 5) + | +45 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w: +46 | ... +47 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +48 | ... +49 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y: + | + +too_many_boolean_expressions.py:49:6: PLR0916 Too many boolean expressions (24 > 5) + | +47 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x: +48 | ... +49 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +50 | ... +51 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y and z: + | + +too_many_boolean_expressions.py:51:6: PLR0916 Too many boolean expressions (25 > 5) + | +49 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y: +50 | ... +51 | elif (a and b) and c and d and e and f and g and h and i and j and k and l and m and n and o and p and q and r and s and t and u and v and w and x and y and z: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PLR0916 +52 | ... +53 | else: + | + + diff --git a/crates/ruff_workspace/src/options.rs b/crates/ruff_workspace/src/options.rs index dd1772a795d4a..11a007c0d07bd 100644 --- a/crates/ruff_workspace/src/options.rs +++ b/crates/ruff_workspace/src/options.rs @@ -2390,6 +2390,11 @@ pub struct PylintOptions { example = r"max-public-methods = 20" )] pub max_public_methods: Option, + + /// Maximum number of boolean expressions allowed for a single if statement + /// (see: `PLR0916`). + #[option(default = r"5", value_type = "int", example = r"max-bools = 5")] + pub max_bools: Option, } impl PylintOptions { @@ -2400,6 +2405,7 @@ impl PylintOptions { .allow_magic_value_types .unwrap_or(defaults.allow_magic_value_types), max_args: self.max_args.unwrap_or(defaults.max_args), + max_bools: self.max_bools.unwrap_or(defaults.max_bools), max_returns: self.max_returns.unwrap_or(defaults.max_returns), max_branches: self.max_branches.unwrap_or(defaults.max_branches), max_statements: self.max_statements.unwrap_or(defaults.max_statements), diff --git a/ruff.schema.json b/ruff.schema.json index 7be275a4100e0..c423bb5f969b9 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2224,6 +2224,15 @@ "format": "uint", "minimum": 0.0 }, + "max-bools": { + "description": "Maximum number of boolean expressions allowed for a single if statement (see: `PLR0916`).", + "type": [ + "integer", + "null" + ], + "format": "uint", + "minimum": 0.0 + }, "max-branches": { "description": "Maximum number of branches allowed for a function or method body (see: `PLR0912`).", "type": [ @@ -2956,6 +2965,7 @@ "PLR0912", "PLR0913", "PLR0915", + "PLR0916", "PLR1", "PLR17", "PLR170", diff --git a/scripts/check_docs_formatted.py b/scripts/check_docs_formatted.py index b1d09ab068676..78334cc3b5f9a 100755 --- a/scripts/check_docs_formatted.py +++ b/scripts/check_docs_formatted.py @@ -68,6 +68,7 @@ "surrounding-whitespace", "tab-indentation", "too-few-spaces-before-inline-comment", + "too-many-boolean-expressions", "trailing-comma-on-bare-tuple", "triple-single-quotes", "under-indentation",