Skip to content

Commit

Permalink
Make is_irrefutable a method on Pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
dhruvmanila committed May 27, 2024
1 parent 2248ca8 commit 264d659
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 15 additions & 0 deletions crates/ruff_python_ast/src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 264d659

Please sign in to comment.