Of course! "Python autoformat" refers to the process of automatically reformatting your Python code to conform to a standard style guide. This is a cornerstone of modern Python development, as it enforces consistency, readability, and reduces the "style wars" in team projects.

The two most important tools for this are Black (for formatting) and isort (for import sorting). A third tool, Ruff, is becoming extremely popular as a much faster, all-in-one alternative.
Here’s a complete guide covering the best practices, tools, and how to set them up.
The Big Three: Black, isort, and Ruff
Black: The Uncompromising Code Formatter
Black is the industry standard for code formatting. Its main philosophy is "there should be one—and preferably only one—obvious way to do it." It reformats your code according to the PEP 8 style guide, but with its own stricter, opinionated rules.
What it does:

- Sets a line length (default is 88 characters).
- Standardizes quotes, spacing, commas, and function definitions.
- Removes unnecessary parentheses and semicolons.
- Produces consistent, predictable output.
Before (unformatted code):
import os,sys
from my_module import a, b, c, d, e, f
def calculate_sum( x,y,z ):
result = x + y + z
return(result)
if __name__ == "__main__":
print(calculate_sum(1,2,3))
print( "hello world" )
After black is run:
import os
import sys
from my_module import a, b, c, d, e, f
def calculate_sum(x, y, z):
result = x + y + z
return result
if __name__ == "__main__":
print(calculate_sum(1, 2, 3))
print("hello world")
isort: The Import Sorter
isort is a utility to sort and organize Python import statements according to PEP 8. It groups imports into sections:
- Standard library imports (
import os) - Third-party library imports (
import requests) - Local application/library imports (
from my_project import utils)
Before (unsorted imports):

from my_project.utils import helper import os import requests import sys
After isort is run:
import os import sys import requests from my_project.utils import helper
Ruff: The Ultra-Fast All-in-One Linter and Formatter
Ruff is a game-changer. It's written in Rust and is orders of magnitude faster than its predecessors. It can do the jobs of black, isort, flake8, pyupgrade, and many other linter/formatting tools all at once.
- Ruff Formatter: A drop-in replacement for Black. It's compatible with Black's output in most cases.
- Ruff Linter: A very fast linter that catches bugs, enforces style, and can even automatically fix many of the issues it finds.
How to Set Up Autoformatting in Your Project
The best way to manage this is with a configuration file in your project's root directory. This ensures everyone on the team uses the same settings.
Step 1: Install the Tools
It's best to use a virtual environment.
# Create and activate a virtual environment python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install the tools pip install black isort ruff
Step 2: Create a Configuration File
Create a file named pyproject.toml in your project's root directory. This file will configure Black, isort, and Ruff.
pyproject.toml:
# --- Black Configuration ---
[tool.black]
line-length = 88
target-version = ['py39']
include = '\.pyi?$'
extend-exclude = '''
/(
# directories
\.eggs
| \.git
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| build
| dist
)/
'''
# --- isort Configuration ---
[tool.isort]
profile = "black" # Use the "black" profile for compatibility
multi_line_output = 3
line_length = 88
known_first_party = ["my_project"] # Replace with your project's name
# --- Ruff Configuration ---
[tool.ruff]
# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"venv",
]
# Same line-length as Black.
line-length = 88
# Assume Python 3.9
target-version = "py39"
[tool.ruff.lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
select = [
# pycodestyle
"E",
# Pyflakes
"F",
# pyupgrade
"UP",
# flake8-bugbear
"B",
# flake8-simplify
"SIM",
]
ignore = [
# Star imports are used by __init__.py files
"F401",
]
# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
Step 3: Add Scripts to pyproject.toml
You can add scripts to your pyproject.toml to make running the formatters easier.
Add this to the end of your pyproject.toml:
[tool.poetry.scripts] # If you use Poetry # Or under a [project.scripts] section if you use setuptools # Or just define them here for consistency [scripts] format = "scripts.format:format" check = "scripts.format:check"
Now, create a scripts directory in your project and add a format.py file inside it.
scripts/format.py:
import subprocess
import sys
def run_command(command: list[str]) -> None:
"""Runs a command and exits if it fails."""
print(f"Running: {' '.join(command)}")
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
print("Error output:")
print(result.stderr)
sys.exit(result.returncode)
print("Success!")
def format() -> None:
"""Formats the code using isort and black."""
print("--- Formatting code ---")
run_command(["isort", "."])
run_command(["black", "."])
print("--- Formatting complete ---")
def check() -> None:
"""Checks for formatting issues without modifying files."""
print("--- Checking code formatting ---")
run_command(["isort", "--check-only", "."])
run_command(["black", "--check", "."])
print("--- Formatting check passed ---")
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "check":
check()
else:
format()
Step 4: Run the Formatters
Now you can run the formatters from your terminal:
# Format all files in the current directory python -m scripts.format # Or using the script alias you defined python -m scripts format # Check if files are formatted correctly without changing them python -m scripts.check
Integrating with Your Editor (VS Code)
This is the final, and most important, step for a seamless workflow. You can configure your editor to format your code automatically on save.
-
Install the Extensions:
- In VS Code, go to the Extensions view (Ctrl+Shift+X).
- Install Python by Microsoft.
- Install Ruff by Astral. (This is the best one as it uses the fast Ruff linter).
-
Configure VS Code Settings:
- Open your VS Code settings (Ctrl+,).
- Search for
format on saveand check the box. - Search for
default formatterand set it to Ruff.
Your
.vscode/settings.jsonfile should look something like this:{ "python.analysis.typeCheckingMode": "basic", "editor.formatOnSave": true, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff" }, "ruff.enable": true, // Optional: Organize imports on save "ruff.organizeImports": true, // Optional: Fix auto-fixable issues on save "ruff.fixAll": true }
Now, every time you save a Python file, VS Code will automatically run Ruff to format the code and fix any linting issues, giving you a perfectly styled file every time.
Summary of Best Practices
- Use
blackfor formatting to enforce a single, consistent style. - Use
isortfor import sorting to keep imports clean and organized. - Use
Ruffas a linter to catch bugs and enforce style rules that Black/isort don't cover. - Commit a
pyproject.tomlto your repository so everyone uses the same settings. - Integrate with your editor (like VS Code) to format on save for a frictionless workflow.
