Automate Python Code Formatting With Black and pre-commit

Steve Barker
Gousto Engineering & Data
3 min readOct 25, 2019

Here at Gousto, quite a few of our codebases are written in Python — and the number is growing all the time. At our last Python Guild meeting, we realised it would be great if we could have some more consistency in formatting across our projects.

We discussed various options and ultimately settled on Black — an opinionated, uncompromising code formatter for Python.

Why Black?

Let’s be honest: while we might be tempted to hold extensive discussions about how best to format our code, it’s not the best use of our time. Black allows us to offload a lot of that debate about what the optimal code format should be, and lets us focus on the code itself. ‘Blackened’ code is designed to be readable, with the smallest diffs possible.

Black has virtually no customisation options — it makes most of the formatting decisions for you, which is exactly what we wanted. We’ve started to see the benefits of this in code reviews; consistency between diffs allows us to focus just on the logic of the code we’re reviewing.

As Dusty Phillips says:

“Black is opinionated so you don’t have to be.”

How to automate Black

There are great articles on how to install Black — so I’m not going to re-write those. Instead, let’s focus on how to get Black to automatically format the code in your project.

Step 1: Install pre-commit

pre-commit is a Python framework for git hook management — we’ll use it to run Black against every commit you make to your project.

We’ll need pre-commit installed to generate our hooks.

To install pre-commit, run:

pip install pre-commit

Step 2: Add pre-commit to your project

Append the following line to your requirements file (either requirements.txt or requirements-dev.txt):

pre-commit==1.18.3

Make sure the version number matches the latest version of Black.

Now you’ve added pre-commit to your project.

Step 3: pre-commit config file

pre-commit manages all of our hooks using a yaml config file.

Make a new file in your project directory called ‘.pre-commit-config.yaml’.

In this file specify our Black hook:

repos:
- repo: https://github.com/ambv/black
rev: stable
hooks:
- id: black
language_version: python3.6

The language_version represents the version of Python used to run the hook. Black itself detects Python version on a per-file basis or can be told to assume a specific one.

Step 4: Generate hooks and test

Begin by navigating to your project directory in your terminal, then run:

pre-commit install

This will produce hooks that correspond with what’s in your config file. If it’s worked, you can test that Black is formatting your code correctly by making a small change to a Python file, then making a commit. If it’s worked, you should see something like this:

Showing successful black commit hook formatting my code.
my error_responses.py file was re-formatted successfully by Black.

Above you can see that I add the files, make a commit, then the hook runs. Black initially ‘fails’ the file I’m working with — i.e. the file did not meet the Black formatting standards alone, so automatic reformatting is required.

The automatic reformatting then took place, and modified my commit.

That’s it!

Automating Black saves a lot of discussion time — and is easy to implement using git hooks. I’d recommend it to any team looking to work fast and keep standards high.

A majestic black cat.

--

--