| name | black |
| description | [Applies to: **/*.py] Enforce consistent Python code formatting using Black, automate style checks, and integrate seamlessly into development workflows to eliminate style debates and speed up code reviews. |
| source | cursor_mdc |
black Best Practices
black is the uncompromising Python code formatter. Our team adopts black as the definitive style guide for all Python projects. By using black, you cede control over formatting minutiae, gaining speed, determinism, and freedom from style debates.
🚨 IMPORTANT: For new projects, or if migrating, strongly consider Ruff instead of black. Ruff offers superior performance and combines formatting, linting, and import sorting into a single tool. If your project is already committed to black, these guidelines apply.
1. Core Principle: Cede Control
black is opinionated by design. Do not fight its formatting. Embrace its defaults to achieve ultimate consistency across the codebase.
2. Installation and Configuration
Always install the latest stable version of black (v25.12.0 as of Dec 2025) and configure it via pyproject.toml.
2.1. Project Dependency
Declare black as a development dependency.
❌ BAD: Global installation or missing dependency
✅ GOOD: black as a development dependency
[project]
name = "my-project"
version = "0.1.0"
[tool.poetry.dependencies]
python = ">=3.10,<3.13"
[tool.poetry.group.dev.dependencies]
black = "^25.12.0"
2.2. pyproject.toml Configuration
Stick to black's defaults. Only configure line length if absolutely necessary for legacy reasons (e.g., integrating with an older codebase that has a different standard).
❌ BAD: Over-configuring black
[tool.black]
line-length = 100
skip-string-normalization = true
✅ GOOD: Minimal black configuration (default 88 chars)
[tool.black]
3. Automated Formatting Workflow
Integrate black into your development pipeline to ensure continuous consistency.
3.1. Pre-commit Hooks
Use pre-commit to automatically format files before every commit. This catches formatting issues early.
❌ BAD: Manual formatting or relying on CI only
git commit -m "feat: new feature"
✅ GOOD: black via pre-commit
repos:
- repo: https://github.com/psf/black
rev: 25.12.0
hooks:
- id: black
language_version: python3.11
Action: Install pre-commit (pip install pre-commit) and set up hooks (pre-commit install).
3.2. CI/CD Integration
Ensure your CI pipeline checks for black compliance and fails the build on any formatting mismatch.
❌ BAD: CI passes even with unformatted code
✅ GOOD: CI enforces black formatting
- name: Check code style with Black
run: pip install black==25.12.0 && black --check .
4. Code Organization and Structure
black ensures consistent formatting, which indirectly improves code organization and readability.
4.1. Import Sorting
black does not sort imports. Pair it with isort (or Ruff's built-in import sorting) for a complete solution.
❌ BAD: Unsorted imports
import os
from my_module import ClassA
import sys
from third_party import lib
✅ GOOD: Sorted imports (with isort or Ruff)
import os
import sys
from third_party import lib
from my_module import ClassA
Action: Add isort to your pre-commit-config.yaml or use Ruff.
4.2. Consistent String Quotes and Trailing Commas
black enforces double quotes for strings and trailing commas in multi-line constructs.
❌ BAD: Inconsistent quotes, missing trailing commas
my_string = 'hello world'
my_list = [
1,
2
]
✅ GOOD: black-formatted strings and lists
my_string = "hello world"
my_list = [
1,
2,
]
5. Type Hints
black consistently formats type hints, making them more readable. Always use explicit type hints.
❌ BAD: Inconsistent spacing or missing type hints
def process_data(data : list):
return len(data)
def get_name(user):
return user.name
✅ GOOD: black-formatted and explicit type hints
from typing import Any
def process_data(data: list[Any]) -> int:
return len(data)
def get_name(user: Any) -> str:
return user.name
6. Testing Approaches
black ensures your test files are as consistently formatted and readable as your application code. This aids in test maintenance and debugging.
❌ BAD: Unformatted or inconsistently formatted test files
def test_addition():
assert 1+1 == 2
✅ GOOD: black-formatted test files
def test_addition():
assert 1 + 1 == 2
Action: Ensure black runs on your tests/ directory.
7. Common Pitfalls and Gotchas
7.1. Version Mismatches
Inconsistent black versions across the team or CI can lead to re-formatting churn.
❌ BAD: Different black versions in use
✅ GOOD: Standardized black version
[tool.poetry.group.dev.dependencies]
black = "==25.12.0"
Action: Pin black to an exact version in pyproject.toml and pre-commit-config.yaml.
7.2. Ignoring black
Disabling black for specific files or sections without a strong, documented reason undermines consistency.
❌ BAD: Disabling black for convenience
def ugly_function():
✅ GOOD: Trust black's formatting
def ugly_function():
result = (
"a_very_long_string_that_black_will_wrap_nicely"
+ "another_part_of_the_string"
)
return result
Action: Only use fmt: off/fmt: on directives as a last resort for genuinely un-black-able code, and document why.