Functions that are deemed too complex are functions that have too much branching logic. Branching logic includes if/elif/else and for/while loops.

Anti-pattern

The following example has a complexity score of 5, because there are five potential branches.

def post_comment(self):
    if self.success:
        comment = 'Build succeeded'
    elif self.warning:
        comment = 'Build had issues'
    elif self.failed:
        comment = 'Build failed'

    if self.success:
        self.post(comment, type='success')
    else:
        self.post(comment, type='error')

Best practice

To reduce the complexity of a function you should make the function do less. In the example above, the function actually does two things: formats a comment and posts the comment. Let’s split that up into two specific functions that have only one task each.

def get_comment(self):
    comments = {
        'success': 'Build succeeded',
        'warning': 'Build had issues',
        'failed': 'Build failed'
    }
    return comments[self.type]

def post_comment(self, comment):
    self.post(comment, type=self.type)

These two functions now have a complexity of 1.