DEV Community

Alessandro Pischedda
Alessandro Pischedda

Posted on

Let's meet Black: Python Code Formatting

While each developer may have different preferences for coding style, the importance of a unified style is very important for maintaining readable code.
This has a bigger importance if you think of a project in which many developers are involved.

In Python exists the 'Style Guide for Python Code' known as PEP 8, which recommends specific code conventions to maintain a standardized code format.
This style guide is about:

  • indentation
  • imports
  • max line length
  • name conventions
  • comments
  • etc

In the realm of Python development, there is a multitude of code formatters that adhere to PEP 8 guidelines. Today, we will briefly discuss how to install and utilize black.

Basics

Let's stop talking and get our hands dirty because it's a great way to learn.

First of all, let's install it using pip:

$ pip install black
Enter fullscreen mode Exit fullscreen mode

Once installed, to use it, just execute the following command:

$ black {source_file_or_directory}
Enter fullscreen mode Exit fullscreen mode

This command will initiate black with the standard configuration and reformat all the Python files it finds.

Options

As you can see running Black is quite simple but what if we want not to change the file/s but perform only a check ?
We can use the options furnished by Black.

--check

Do not change the file but return only the exit value:

  • 0, nothing to change
  • 1, some files would be reformatted
  • 123, an internal error occurred.

Example

black --check main.py 
would reformat main.py

Oh no! 💥 💔 💥
1 file would be reformatted.

Enter fullscreen mode Exit fullscreen mode

--diff

Even this command does not reformat the files but prints the diff which indicates the changes.
[Note]: use --color if you want colored diff.

I suggest reading the documentation for a complete list of options.
In my opinion some of the most useful are:

  • --required-version
  • --exclude.

Example

black --diff --color main.py 
--- main.py 2023-09-08 21:03:49.860827+00:00
+++ main.py 2024-02-04 22:31:31.130282+00:00
@@ -5,29 +5,31 @@
 from starlette.middleware.base import BaseHTTPMiddleware

 from app.frontend import pages
-from app.core import config 
+from app.core import config

-app.include_router(pages.router, prefix='')
+app.include_router(pages.router, prefix="")
-
-
-
-
-
would reformat main.py

All done! ✨ 🍰 ✨
1 file would be reformatted.
Enter fullscreen mode Exit fullscreen mode

Configuration

If you want to customize the configuration of Black you can remember the list of the options or configure it using a configuration file.

Black uses by default the pyproject.toml file.
This file contains a section for each different tool we want to use. The use of a configuration file like pyproject.toml is quite a good choice and helps the contributors to use the same tools and configurations you're using.

Black uses [tool.black] section, the option names/keys are the same as the long names of options used in the command line. Below you can see an example:

[tool.black]
line-length = 80
target-version = ['py37']
Enter fullscreen mode Exit fullscreen mode

Conclusion

We've explored, briefly, the formatted called Black talking about the aim of this tool, how to use and how to configure it using a configuration file.
I hope this post can help you to improve your repository and code.

Top comments (4)

Collapse
 
michalmazurek profile image
Michal Mazurek

Checkout ruff, does the same thing but is much faster, black was so good for many years, and it was "the" Python formatter. Now ruff written in rust with formatter and linter, is fully black compatible just outpaces black like F1 bolid against Prius.

Collapse
 
cereal84 profile image
Alessandro Pischedda

@michalmazurek thank you so much : ).

Collapse
 
fpsd profile image
Francesco • Edited

Thanks for the post!

Do you think it would be feasible to integrate black in a CI/CD pipeline to, at least, help with code style conventions across a medium/big org or codebase?

Collapse
 
cereal84 profile image
Alessandro Pischedda

Surely it is a great idea to integrate it in a CI/CD pipeline, I suggest adding it into pre-commit in order to execute it before a commit.
Probably I'll cover it in a future post or add a new section to this post, thank you.