Consider match-case stmts for C901, PLR0912, and PLR0915 (#11521)

Resolves #11421

## Summary

Instead of counting match/case as one statement, consider each `case` as
a conditional.

## Test Plan

`cargo test`
This commit is contained in:
Ahmed Ilyas 2024-05-24 11:14:46 +02:00 committed by GitHub
parent 3e30962077
commit 33fd50027c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 50 additions and 5 deletions

View file

@ -96,8 +96,8 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize {
complexity += get_complexity_number(orelse);
}
Stmt::Match(ast::StmtMatch { cases, .. }) => {
complexity += 1;
for case in cases {
complexity += 1;
complexity += get_complexity_number(&case.body);
}
}
@ -429,4 +429,19 @@ def with_lock():
assert_eq!(get_complexity_number(&stmts), 2);
Ok(())
}
#[test]
fn match_case() -> Result<()> {
let source = r"
def f():
match a:
case 30:
print('foo')
case _:
print('bar')
";
let stmts = parse_suite(source)?;
assert_eq!(get_complexity_number(&stmts), 3);
Ok(())
}
}

View file

@ -176,10 +176,11 @@ fn num_branches(stmts: &[Stmt]) -> usize {
.sum::<usize>()
}
Stmt::Match(ast::StmtMatch { cases, .. }) => {
1 + cases
.iter()
.map(|case| num_branches(&case.body))
.sum::<usize>()
cases.len()
+ cases
.iter()
.map(|case| num_branches(&case.body))
.sum::<usize>()
}
// The `with` statement is not considered a branch but the statements inside the `with` should be counted.
Stmt::With(ast::StmtWith { body, .. }) => num_branches(body),
@ -278,6 +279,19 @@ else:
Ok(())
}
#[test]
fn match_case() -> Result<()> {
let source: &str = r"
match x: # 2
case 0:
pass
case 1:
pass
";
test_helper(source, 2)?;
Ok(())
}
#[test]
fn for_else() -> Result<()> {
let source: &str = r"

View file

@ -90,6 +90,7 @@ fn num_statements(stmts: &[Stmt]) -> usize {
Stmt::Match(ast::StmtMatch { cases, .. }) => {
count += 1;
for case in cases {
count += 1;
count += num_statements(&case.body);
}
}
@ -233,6 +234,21 @@ def f():
Ok(())
}
#[test]
fn match_case() -> Result<()> {
let source: &str = r"
def f():
match x:
case 3:
pass
case _:
pass
";
let stmts = parse_suite(source)?;
assert_eq!(num_statements(&stmts), 6);
Ok(())
}
#[test]
fn many_statements() -> Result<()> {
let source: &str = r"