diff --git a/crates/ruff_linter/src/rules/pylint/rules/too_many_branches.rs b/crates/ruff_linter/src/rules/pylint/rules/too_many_branches.rs index 9a1ea12053..43af2390a4 100644 --- a/crates/ruff_linter/src/rules/pylint/rules/too_many_branches.rs +++ b/crates/ruff_linter/src/rules/pylint/rules/too_many_branches.rs @@ -5,7 +5,9 @@ use ruff_macros::{derive_message_formats, violation}; use ruff_python_ast::identifier::Identifier; /// ## What it does -/// Checks for functions or methods with too many branches. +/// Checks for functions or methods with too many branches, including (nested) +/// `if`, `elif`, and `else` branches, `for` loops, `try`-`except` clauses, and +/// `match` and `case` statements. /// /// By default, this rule allows up to 12 branches. This can be configured /// using the [`lint.pylint.max-branches`] option. @@ -15,6 +17,7 @@ use ruff_python_ast::identifier::Identifier; /// and maintain than functions or methods with fewer branches. /// /// ## Example +/// Given: /// ```python /// def capital(country): /// if country == "Australia": @@ -66,6 +69,77 @@ use ruff_python_ast::identifier::Identifier; /// return city /// ``` /// +/// Given: +/// ```python +/// def grades_to_average_number(grades): +/// numbers = [] +/// for grade in grades: # 1st branch +/// if len(grade) not in {1, 2}: +/// raise ValueError(f"Invalid grade: {grade}") +/// +/// if len(grade) == 2 and grade[1] not in {"+", "-"}: +/// raise ValueError(f"Invalid grade: {grade}") +/// +/// letter = grade[0] +/// +/// if letter in {"F", "E"}: +/// number = 0.0 +/// elif letter == "D": +/// number = 1.0 +/// elif letter == "C": +/// number = 2.0 +/// elif letter == "B": +/// number = 3.0 +/// elif letter == "A": +/// number = 4.0 +/// else: +/// raise ValueError(f"Invalid grade: {grade}") +/// +/// modifier = 0.0 +/// if letter != "F" and grade[-1] == "+": +/// modifier = 0.3 +/// elif letter != "F" and grade[-1] == "-": +/// modifier = -0.3 +/// +/// numbers.append(max(0.0, min(number + modifier, 4.0))) +/// +/// try: +/// return sum(numbers) / len(numbers) +/// except ZeroDivisionError: # 13th branch +/// return 0 +/// ``` +/// +/// Use instead: +/// ```python +/// def grades_to_average_number(grades): +/// grade_values = {"F": 0.0, "E": 0.0, "D": 1.0, "C": 2.0, "B": 3.0, "A": 4.0} +/// modifier_values = {"+": 0.3, "-": -0.3} +/// +/// numbers = [] +/// for grade in grades: +/// if len(grade) not in {1, 2}: +/// raise ValueError(f"Invalid grade: {grade}") +/// +/// letter = grade[0] +/// if letter not in grade_values: +/// raise ValueError(f"Invalid grade: {grade}") +/// number = grade_values[letter] +/// +/// if len(grade) == 2 and grade[1] not in modifier_values: +/// raise ValueError(f"Invalid grade: {grade}") +/// modifier = modifier_values.get(grade[-1], 0.0) +/// +/// if letter == "F": +/// numbers.append(0.0) +/// else: +/// numbers.append(max(0.0, min(number + modifier, 4.0))) +/// +/// try: +/// return sum(numbers) / len(numbers) +/// except ZeroDivisionError: +/// return 0 +/// ``` +/// /// ## Options /// - `lint.pylint.max-branches` #[violation]