diff --git a/crates/ruff_linter/src/rules/mccabe/rules/function_is_too_complex.rs b/crates/ruff_linter/src/rules/mccabe/rules/function_is_too_complex.rs index dd52de066d148..f9586b975b6d1 100644 --- a/crates/ruff_linter/src/rules/mccabe/rules/function_is_too_complex.rs +++ b/crates/ruff_linter/src/rules/mccabe/rules/function_is_too_complex.rs @@ -1,4 +1,4 @@ -use ruff_python_ast::{self as ast, ExceptHandler, Pattern, Stmt}; +use ruff_python_ast::{self as ast, ExceptHandler, Stmt}; use ruff_diagnostics::{Diagnostic, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -101,7 +101,19 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize { complexity += get_complexity_number(&case.body); } if let Some(last_case) = cases.last() { - if is_irrefutable_pattern(&last_case.pattern) && last_case.guard.is_none() { + // The complexity of an irrefutable pattern is similar to an `else` block of an `if` statement. + // + // For example: + // ```python + // match subject: + // case 1: ... + // case _: ... + // + // match subject: + // case 1: ... + // case foo: ... + // ``` + if last_case.guard.is_none() && last_case.pattern.is_irrefutable() { complexity -= 1; } } @@ -140,29 +152,6 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize { complexity } -fn is_irrefutable_pattern(last_pattern: &Pattern) -> bool { - // The complexity of an irrefutable pattern is similar to an `else` block of an `if` statement. - // This is either a wildcard pattern or a named catch-all pattern. - // - // For example: - // ```python - // match subject: - // case 1: ... - // case _: ... - // - // match subject: - // case 1: ... - // case foo: ... - // ``` - // - // Irrefutable pattern: https://peps.python.org/pep-0634/#irrefutable-case-blocks - match last_pattern { - Pattern::MatchAs(p) => p.pattern.is_none(), - Pattern::MatchOr(p) => p.patterns.iter().any(is_irrefutable_pattern), - _ => false, - } -} - pub(crate) fn function_is_too_complex( stmt: &Stmt, name: &str, diff --git a/crates/ruff_python_ast/src/nodes.rs b/crates/ruff_python_ast/src/nodes.rs index b50d2ec0b51cf..03074f5a2e742 100644 --- a/crates/ruff_python_ast/src/nodes.rs +++ b/crates/ruff_python_ast/src/nodes.rs @@ -2998,6 +2998,21 @@ pub enum Pattern { MatchOr(PatternMatchOr), } +impl Pattern { + /// Checks if the [`Pattern`] is an [irrefutable pattern]. + /// + /// [irrefutable pattern]: https://peps.python.org/pep-0634/#irrefutable-case-blocks + pub fn is_irrefutable(&self) -> bool { + match self { + Pattern::MatchAs(PatternMatchAs { pattern: None, .. }) => true, + Pattern::MatchOr(PatternMatchOr { patterns, .. }) => { + patterns.iter().any(Pattern::is_irrefutable) + } + _ => false, + } + } +} + /// See also [MatchValue](https://docs.python.org/3/library/ast.html#ast.MatchValue) #[derive(Clone, Debug, PartialEq)] pub struct PatternMatchValue {