Python code formatters comparison: Black, autopep8 and YAPF

Following some discussions at work and the will of the team to adopt a python code formatter, I set out to explore some of them. No need to say, the contenders had to aim towards pep8 compliance. Here are my findings on three of them.

Black

  • Source: https://github.com/ambv/black
  • Version at time of writing: 18.6b1
  • First commit: Wed Mar 14 12:55:32 2018 -0700
  • Watch count: 94
  • Stars: 4626
  • Forks:  174
  • Issues: 47

Black is what I would call a strict formatter. It will apply its style guide even where pep8 was not violated. Black is highly opinionated and has close to zero configuration. As the readme states it:

Black reformats entire files in place. It is not configurable.

Clear enough. That’s a design decision. There are in fact only two configurable formatting options: maximal line length and whether to normalize string quotes/prefixes or not. That’s it. If you are curious to learn why black formats the way it does, the readme contains a bunch of great rational explanations.

Personally, here is an example of formatting done by black that I dislike. For this input:

data = {
    'key' : {
        'subkey': 'value',
        'foo': 'bar'
    }
}

It reformats as:

data = {"key": {"subkey": "value", "foo": "bar"}}

But that’s just me, and I get it. One of the points for having a formatter is to make code uniform without having discussions around it. Black took it to another level: there is almost not even any discussions possible at the configuration level. If you really insist on having it NOT touch some sections of code, you can surround them with # fmt: off/on.

One nice feature: the --check flag. Use it in your favourite CI tool to see your build fail if the code is not formatted as Blacks would.

A last note: I have not experienced any issues myself with black but some of my colleagues did. It’s still very new and I suppose it is to be expected.

autopep8

  • Source: https://github.com/hhatto/autopep8
  • Version at time of writing: 1.3.5
  • First commit: Thu Dec 30 05:27:29 2010 +0900
  • Watch count: 60
  • Stars: 2253
  • Forks:  163
  • Issues: 66

autopep8 is what I would call a loose formatter. Its aim is fixing pep8 errors, not making the code uniform. If we take the two code samples above, in the Black section, they are both pep8 compliant so autopep8 would not change them. Because it only modifies code that is not pep8 compliant, it cannot be use as a way to stop having to manually manage uniformity of coding styles.

Basically, autopep8 is great in helping with pep8 compliance and that’s it.

YAPF

  • Source: https://github.com/hhatto/autopep8
  • Version at time of writing: 0.22.0
  • First commit: Wed Mar 18 13:36:07 2015 -0700
  • Watch count: 200
  • Stars: 7427
  • Forks:  496
  • Issues: 156

What does YAPF stands for? I don’t know. Maybe “Yet Another Python Formatter”? But that’s just a supposition.

YAPF is made by google, but as the readme states:

YAPF is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.

Like Black, it is what I would call a strict formatter. One major difference: it can be configured. It comes with three built-in styles: pep8, google and chromium, but the documentation doesn’t bother highlighting the differences. On top of that, you can fine tweak your style of choice with “knobs”, as they call it. Again, the documentation fails to explain clearly what some of them do. Configurations can be saved to a file that will be looked upon at launch.

YAPF also has a “leave this section alone” functionality with # yapf: disable/enable.

I would have loved to see a flag like the --check from Black to validate the formatting. Since YAPF doesn’t provide anything similar, I have crafted a working bash command.

yapf --diff --recursive . | wc -l | xargs test 0 -eq

Sad me though: If you look at the first code sample again, I cannot get YAPF to leave it alone either.


As mentioned earlier, I started digging this topic after a colleague introduced us to Black. As a team, we decided not to use it because it behaves in ways we disagreed with. About autopep8, I am already using it, but it doesn’t make the code uniform so we are looking for a bigger weapon. YAPF seems like a strong contender.

Clearly, there are more formatters out there that I did not try. Any of them worth my attention? Mention it in the comments!

Leave a Reply