Formatting and Linting Python Code with isort, black, and flake8

Manishankar Jaiswal
4 min readJan 15, 2025

--

When working on Python projects, maintaining clean and consistent code is critical for readability, maintainability, and collaboration. Tools like isort, black, and flake8 simplify this process by automating code formatting and linting.

Formatting and Linting Python Code with isort, black, and flake8
Formatting and Linting Python Code with isort, black, and flake8

In this blog post, we’ll explore these tools, their features, and how to integrate them with a pre-commit hook for seamless code management. We’ll also dive into the role of pyproject.toml in consolidating configuration settings.

Why Use isort, black, and flake8?

1. isort

isort automatically sorts and organizes Python imports. Clean import statements make your code easier to read and prevent common issues, like circular imports or unused imports.

Key Features:

  • Groups imports into sections (standard library, third-party, and local imports).
  • Automatically removes unused imports.
  • Configurable via pyproject.toml or other configuration files.

Example:

Before:

import os
from django.conf import settings
import sys

After (using isort):

import os
import sys

from django.conf import settings

2. black

black is an uncompromising code formatter for Python. Its goal is to standardize formatting, eliminating debates over style choices.

Key Features:

  • Opinionated and consistent: Adheres to PEP 8 by default.
  • Supports most Python versions.
  • Automatically reformats code for readability.

Example:

Before:

def greet(name): print(f"Hello, {name}")

After (using black):

def greet(name):
print(f"Hello, {name}")

3. flake8

flake8 is a linter that checks your code against PEP 8 standards and identifies errors and potential bugs.

Key Features:

  • Detects syntax errors and undefined variables.
  • Integrates with plugins for extended functionality (e.g., cyclomatic complexity checks).
  • Outputs detailed reports to help fix issues.

Example:

Code with issues:

def add(a,b):return a+b

Issues flagged by flake8:

  • Missing spaces around the + operator.
  • Function definition not compliant with PEP 8.

Fixed code:

def add(a, b):
return a + b

Using isort, black, and flake8 Together

These tools complement each other. Here’s how they interact:

  • isort handles import organization.
  • black formats the entire code, including line breaks and indentation.
  • flake8 ensures code adheres to PEP 8 and identifies bugs.

Running isort, black, and flake8 Explicitly

You can run these tools directly from the command line to check or format your code:

Run isort

Sort imports with:

isort .

Check for unsorted imports without changing files:

isort . --check-only

Run black

Format your code:

black .

Check formatting without making changes:

black . --check

Run flake8

Check code for linting issues:

flake8 .

Setting Up Pre-Commit Hook

Pre-commit is a framework for managing and running pre-commit hooks. By integrating isort, black, and flake8 into your workflow, you ensure that code is formatted and linted before being committed.

Steps to Set Up:

  1. Install Dependencies:
pip install isort black flake8 pre-commit

2. Create a .pre-commit-config.yaml File: This file defines the hooks to run before each commit.

repos:
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
name: isort
args: ["--profile", "black"]

- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
name: black
- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
hooks:
- id: flake8
args: ["--exclude=venv,.venv,__pycache__,.git"]

3. Install Pre-Commit Hooks: Run the following command to install hooks:

pre-commit install

4. Test the Setup: Run all hooks manually:

pre-commit run --all-files

Now, every time you commit code, isort, black, and flake8 will automatically process your files.

The Role of pyproject.toml

The pyproject.toml file serves as a centralized configuration file for Python tools. It simplifies project setup by consolidating settings for tools like isort, black, and others.

Example Configuration:

[tool.black]
line-length = 79
target-version = ["py311"]
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
| venv
| \.env
| \.flake8
)/
'''

[tool.isort]
profile = "black"
line_length = 79
known_third_party = ["django"] # Add other third-party libraries as needed
src_paths = ["src", "apps"] # Adjust paths as per your project structure

[tool.flake8]
max-line-length = 79
extend-ignore = ["E203", "W503"] # For compatibility with Black (optional)

Why Use pyproject.toml?

  • Reduces clutter by replacing multiple configuration files.
  • Enhances portability and consistency.
  • Supported by most modern Python tools.

Putting It All Together

Here’s how the workflow looks with isort, black, flake8, and pre-commit:

  1. Write your Python code.
  2. Run pre-commit hooks when committing changes.
  3. Let isort organize imports, black format the code, and flake8 check for issues.
  4. Fix any errors flagged by flake8 and repeat as needed.

Conclusion

Using isort, black, and flake8 together ensures clean, readable, and error-free Python code. Integrating these tools with pre-commit hooks and configuring them via pyproject.toml streamlines the development process. Whether you’re a beginner or an experienced developer, these tools are essential for maintaining high-quality code.

--

--

Responses (1)