R0912 too-many-branches

Message

'Too many branches (%s/%s)'

Description

Used when a function or method has too many branches, making it hard to follow.

Example

For the examples, pylint was configured to accept at max five branches (default is twelve).

def example(a, b, c):
    res = 0
    if a == 1: res = 1
    if a == 2: res = 1
    if a == 3: res = 1
    if a == 4: res = 1
    if a == 5: res = 1
    if a == 6: res = 1

    return res
1:0: R0912: Too many branches (6/5)

Not only if clauses are branches, also loops and try-except clauses have conditional characteristics and thus are counted as well.

def example(a):
    try:
        a = int(a)
    except ValueError:
        a = 1

    res = 0
    if a == 1: res = 1
    if a == 2: res = 1

    while a > 100:
        a = a / 2

    for x in range(10):
        for y in range(10):
            a += x * y

    return res
1:0: R0912: Too many branches (6/5)

Why bother?

Functions and methods with too many branches are hard to understand.

How to fix it?

Usually, functions with too many branches fall in one of two categories: (A) functions that do more than one thing or (B) functions that are just a map lookup.

For case (A) it is hard to give general advice, but usually one should check if parts can be extracted into their own function or method, see Extract Method refactoring.

The lookup case (B) is easy to refactor into a map (dict) lookup:

def bad(a):
    if a == 1: return "A"
    if a == 2: return "B"
    if a == 3: return "D"
    if a == 4: return "G"
    if a == 5: return "M"
    if a == 6: return "X"

    return "Z"

def better(a):
    return _LOOKUP.get(a, "Z")

_LOOKUP = {
    1: "A",
    2: "B",
    3: "D",
    4: "G",
    5: "M",
    6: "X",
}
1:0: R0912: Too many branches (6/5)

Running Pylint locally? In your CI?

There is a better way! Run PyCodeQual & get Pylint findings with history, diffs and statistics.

Click here to find out more.