Else after return: yea or nay?
Tags: python, pylint
Published: 2018-07-13 09:58:48

---
title: Else after return: yea or nay?
published: true
tags: [python, pylint]
canonical_url: https://dmerej.info/blog/post/else-after-return-yea-or-nay/
---

_Originally published on [my blog](https://dmerej.info/blog/post/else-after-return-yea-or-nay/)._

# Introduction

As you may know, I use [pylint](https://www.pylint.org/) for most of my Python projects. [^1]

A few weeks ago, I upgraded pylint and a new warning appeared. This tends to happen when you have a pretty large code base: new checks are added to pylint all the time, so new warnings are bound to show up.

Here’s a minimal example of the kind of code that triggered the new warning:

```python
def foo():
    if bar:
        return baz
    else:
        return qux
```

```
$ pylint foo.py
...
Unnecessary "else" after "return" (no-else-return)

```

Indeed, the code after the first return will never execute if `bar` is true, so there’s no need for the `else`.

In other words, the code should be written like this:

```python
def foo():
    if bar:
        return baz
    return qux
```

Well, the code is shorter. But is it _better_?

# The problem

If you think about it, the question about whether the code is _better_ in the first form (let’s call it _explicit else_) or in the second form (let’s call it _implicit else_) is hard to answer because you have no clue about the _meaning_ of the `foo` function, or the `bar`, `baz` and `qux` variables.

So let’s try to come up with better examples.

# Guard clauses

Sometimes you’ll find code written this way:

```python
def try_something():
    if precondition():
         result = compute_something()
         return result
    else:
        display_error()
        return None
```

In other words, you are trying to do something but that’s only possible if a condition is true. If the condition is false, you need to display an error.

The `else` is explicit here.

The version with an implicit `else` looks like this:

```python
def try_something():
    if precondition():
         result = compute_something()
         return result
    display_error()
    return None
```

So far, it’s not very clear what version is better.

Note there’s a third way to write the same code, by using `if not precondition()` instead:

```python
# Implicit else, inverted condition
def try_something():
    if not precondition():
        display_error()
        return None

    result = compute_something()
    return result
```

Now, watch what happens when we add several preconditions:

```python
# Explicit else
def try_something():
    if precondition_one():
        if precondition_two():
            result = compute_something()
            return result
        else:
            display_error_two()
            return
    else:
        display_error_one()
```

```python
# Implicit else, inverted condition
def try_something():

    if not precondition_one():
        display_error_one()
        return

    if not precondition_two():
        display_error_two()
        return

    result = compute_something()
    return result
```

I hope you’ll agree the second version is better.

There’s one less level of indentation, and the line that _displays_ the error is right after the line that _checks_ for the error.

Clear win for the _implicit else_ here.

# Symmetric conditions

Let’s take an other example.

Suppose you are writing a script that will check all the links in documentation written as a set of HTML pages.

You’ve got a list of all the possible pages, and then you need to check both _internal links_ (with a `href` looking like`../other-page`) and _external links_ like (with a `href` like `http://example.com`).

Let’s take a look at the two variants:

```python
# Implicit else
def check_link(link) -> bool:
    if is_internal_link(link):
        return check_internal_link(link)
    return check_external_link(link)

# Explicit else
def check_link(link) -> bool:
    if is_internal_link(link):
        return check_internal_link(link)
    else:
        return check_external_link(link)
```

This time, I hope you’ll agree the explicit else is better.

There are two things to be done, and visually they are at them at the same level of indentation.

The symmetry between the type of the link and the check that needs to be done is preserved.

We could say that the algorithm I’ve described as text in the last paragraph is better _expressed_ in the second version.

# Conclusion

Pylint is a great tool, but be careful before deciding whether you want to follow its refactoring pieces of advice.

Second, make sure your code is _easy to read_ and _reveal your intention_. Conciseness is not the only factor here.

Last, be careful with code samples that are too abstract :)

Cheers!

_Thanks for reading this far :)_

_I'd love to hear what you have to say, so please feel free to leave a comment below, or read the [feedback page](https://dmerej.info/blog/pages/feedback/) for more ways to get in touch with me._

[^1]: I already blogged about this in [Some pylint tips](https://dmerej.info/blog/post/some-pylint-tips/) and [How I lint my Python](https://dmerej.info/blog/post/how-i-lint/).