PEP 8: Hanging Indentation and Closing Brackets in Python

Not complying with the PEP 8 standard makes you vulnerable in the Python space. Many PEP 8 purists are ready to instantly attack you and your code if they catch you.

For instance, many Python coders put their braces, brackets, or parentheses into a separate line to make it easier to grasp nested lists or dictionaries. This article shows how to line up the closing braces, brackets, and parentheses correctly in Python.

A quick example shows how you can create a multi-line construct that complies with the PEP 8 standard:

age = {
    'Alice': 24,
    'Bob': 28,
    'Ann': 26,
    }

So how to correctly intend list or dictionary data enclosed in braces, brackets, and parentheses?

According to the PEP 8 standard, there are two ways to line up the closing braces, brackets, or parentheses. First, line it up with the first non-whitespace character of the previous line. Second, line it up with the first character that starts the multi-line construct.

This sounds a bit confusing so let’s hop into practical examples.

Where to Put the Closing Brace, Bracket, or Parenthesis?

For multi-line constructs, there are two basic options of how to correctly intend the data.

1. Align the closing brace with the first non-whitespace character of the previous line:

age = {
    'Alice': 24,
    'Bob': 28,
    'Ann': 26,
    }

2. Align the closing brace with the first character that starts the multi-line construct:

age = {
    'Alice': 24,
    'Bob': 28,
    'Ann': 26,
}

Both ways of indentation are equally valid according to the PEP 8 standard. But note that in any case, the opening and closing braces (brackets, parentheses) should be placed in their own line. So the following would be a violation of the PEP 8 standard:

# NOT PEP 8 COMPLIANT
age = {'Alice': 24,
       'Bob': 28,
       'Ann': 26,
       }

The reason is that both opening and closing braces (brackets, parentheses) should be placed in their own line.

However, the PEP 8 standard allows NOT to place both opening and closing braces (brackets, parentheses) into their own line—IF the arguments or items align. Here are three PEP 8 compliant examples:

def f(argument_1, argument_2,
      argument_3, argument_4):
    None


def f(argument_1,
      argument_2,
      argument_3,
      argument_4):
    None


def f(argument_1, argument_2, argument_3, argument_4):
    None

Although the opening and closing parentheses are not placed into their own lines, it’s still PEP 8 compliant because the arguments align in the first two examples.

Why End Python List with Trailing Comma?

We’ve seen many examples of multi-line constructs where there’s a trailing comma after the last list element:

age = {
    'Alice': 24,
    'Bob': 28,
    'Ann': 26,
    }

The trailing comma after the last line in the dictionary ('Ann' : 26,) is optional according to the PEP 8 standard.

Be aware: you’ll find many opinions on the web where “experts” tell you that the trailing comma is required (like here). But this is not explicitly stated in the standard. In fact, the standard recommends that you use the comma if your “items [are] expected to be extended over time” (source). In this case, it’s easier to copy&paste new items into the list (or dictionary) without having to manually add a trailing comma to the old last item and removing the trailing comma after the new last item.

In other words, the following multi-line construct is also valid and implicitly follows the PEP 8 standard:

age = {
    'Alice': 24,
    'Bob': 28,
    'Ann': 26
    }

Note that the trailing comma is missing. But if you don’t plan to extend your list over time, it’s fine to use this—even if some Python code style checkers (“Linters”) complain.

Nested Multi-Line Constructs

Now, you simply need to decide about which of the above methods you prepare to write opening and closing braces, brackets, or parentheses. Here’s how you can nest those and comply with the PEP 8 standard:

data = [
    'string',
    42,
    {
        1: '1',
        2: '2',
        42: '21',
    },
    (1, 2, 3),
    (
        [1, 2, 3],
        [4, 5, 6],
    )
]

You see that we place each brace, bracket, and parenthesis in one line. The next line starts with four whitespace indentations. Then comes the item, followed by a comma. The item itself can be a multi-line construct as well. But if you understand how to write one multi-line construct, you’ll also understand how to nest them.

Similar Questions

Should curly braces appear on their own line?

Yes, they should appear on their own line. An exception is if you write the whole sequence of items in one line. In this case, the closing brace, bracket, or parenthesis should appear at the end of the same line, too.

Where to Put the Closing Brace?

As discussed previously, you line it up with the first non-whitespace character of the previous line, or with the first character that starts the multi-line construct.